From a8c428c06ee35995573dc4e9d0d97514c326e5d2 Mon Sep 17 00:00:00 2001 From: Chasen Le Hara Date: Fri, 16 Aug 2024 19:04:49 -0700 Subject: [PATCH] Add id attributes to heading elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes the generated HTML to include `id` attributes on any heading (e.g. `h3`) elements. Currently, `bit-docs-html-toc` will add `id` attributes when it parses the content and creates the TOC links. This means that JS has to be downloaded, parsed, and run before `bit-docs-html-toc` runs its code, and _then_ there has to be more JS to scroll down to the right fragment. This takes JS completely out of the equation by including the `id` attributes in the source HTML, so JS doesn’t need to load and `bit-docs-html-toc` isn’t required to make fragment URLs work either. Part of https://bitovi.atlassian.net/browse/LD-203 --- html_test.js | 1 + stmd.js | 15 +++++++++++++-- stmd_test.js | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 stmd_test.js diff --git a/html_test.js b/html_test.js index d2a2b01..c9adea0 100644 --- a/html_test.js +++ b/html_test.js @@ -10,6 +10,7 @@ var readFile = Q.denodeify(fs.readFile); var bitDocsHTML = require("./bit-docs"); require("./build/build_test"); +require("./stmd_test"); describe("bit-docs-generate-html", function(){ beforeEach(function(){ diff --git a/stmd.js b/stmd.js index 934937b..07f6919 100644 --- a/stmd.js +++ b/stmd.js @@ -1476,8 +1476,12 @@ var renderBlock = function(block, in_tight_list) { this.innersep); case 'ATXHeader': case 'SetextHeader': + var rendered = this.renderInlines(block.inline_content); tag = 'h' + block.level; - return inTags(tag, [], this.renderInlines(block.inline_content)); + attr = [ + ['id', makeHeadingId(rendered)] + ]; + return inTags(tag, attr, rendered); case 'IndentedCode': return inTags('pre', [], inTags('code', [], this.escape(block.string_content))); @@ -1544,4 +1548,11 @@ function HtmlRenderer(){ exports.DocParser = DocParser; exports.HtmlRenderer = HtmlRenderer; -})(typeof exports === 'undefined' ? this.stmd = {} : exports); \ No newline at end of file +})(typeof exports === 'undefined' ? this.stmd = {} : exports); + +function makeHeadingId(text) { + return (text || "") + .replace(/\s/g, "-") // replace spaces with dashes + .replace(/[^\w\-]/g, "") // remove punctuation + .toLowerCase(); +} diff --git a/stmd_test.js b/stmd_test.js new file mode 100644 index 0000000..ddc5951 --- /dev/null +++ b/stmd_test.js @@ -0,0 +1,14 @@ +var assert = require('assert'); + +var stmd = require("./stmd"); + +describe("bit-docs-generate-html/stmd", function () { + it("adds id attributes to heading elements", function () { + var parser = new stmd.DocParser(); + var renderer = new stmd.HtmlRenderer(); + var markdown = "# Hello world" + var rendered = renderer.render(parser.parse(markdown)); + var expected = '

Hello world

'; + assert.equal(rendered.trim(), expected, "id attributes are present"); + }); +});