From 92b610bb3a0d8b3716cd6efd755fd187e588a434 Mon Sep 17 00:00:00 2001 From: ph1p Date: Tue, 22 Nov 2022 18:27:33 +0100 Subject: [PATCH] feature: add new option to disable anchors in headlines --- markdown.d.ts | 3 +++ src/common.h | 7 ++++--- src/fmt_html.c | 2 +- src/md.js | 11 ++++++++--- test/issue22.js | 30 ++++++++++++++++++++++++++++++ test/testutil.js | 4 ++-- 6 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 test/issue22.js diff --git a/markdown.d.ts b/markdown.d.ts index 638fd82..ef151b1 100644 --- a/markdown.d.ts +++ b/markdown.d.ts @@ -16,6 +16,9 @@ export interface ParseOptions { /** Select output format. Defaults to "html" */ format? : "html" | "xhtml" + /** Disable anchor tag in headlines. Defaults to `false` */ + disableHeadlineAnchors? : boolean + /** * bytes=true causes parse() to return the result as a Uint8Array instead of a string. * diff --git a/src/common.h b/src/common.h index 5a0c8f3..b75901e 100644 --- a/src/common.h +++ b/src/common.h @@ -63,9 +63,10 @@ typedef int32_t i32; // these should be in sync with "OutputFlags" in md.js typedef enum OutputFlags { - OutputFlagHTML = 1 << 0, - OutputFlagXHTML = 1 << 1, - OutputFlagAllowJSURI = 1 << 2, // allow "javascript:" URIs in links + OutputFlagHTML = 1 << 0, + OutputFlagXHTML = 1 << 1, + OutputFlagAllowJSURI = 1 << 2, // allow "javascript:" URIs in links + OutputFlagDisableHeadlineAnchors = 1 << 3, } OutputFlags; typedef int(*JSTextFilterFun)( diff --git a/src/fmt_html.c b/src/fmt_html.c index 6894ef4..25f5a90 100644 --- a/src/fmt_html.c +++ b/src/fmt_html.c @@ -323,7 +323,7 @@ static int enter_block_callback(MD_BLOCKTYPE type, void* detail, void* userdata) case MD_BLOCK_H: { render_literal(r, head[((MD_BLOCK_H_DETAIL*)detail)->level - 1]); - r->addanchor = 1; + r->addanchor = !(r->flags & OutputFlagDisableHeadlineAnchors); break; } case MD_BLOCK_CODE: render_open_code_block(r, (const MD_BLOCK_CODE_DETAIL*) detail); break; diff --git a/src/md.js b/src/md.js index c85a52f..ae900a0 100644 --- a/src/md.js +++ b/src/md.js @@ -43,9 +43,10 @@ export const ParseFlags = { // these should be in sync with "OutputFlags" in common.h const OutputFlags = { - HTML: 1 << 0, // Output HTML - XHTML: 1 << 1, // Output XHTML (only has effect with HTML flag set) - AllowJSURI: 1 << 2, // Allow "javascript:" URIs + HTML: 1 << 0, // Output HTML + XHTML: 1 << 1, // Output XHTML (only has effect with HTML flag set) + AllowJSURI: 1 << 2, // Allow "javascript:" URIs + DisableHeadlineAnchors: 1 << 3, // Disable anchor tag in headlines. } @@ -59,6 +60,10 @@ export function parse(source, options) { let outputFlags = options.allowJSURIs ? OutputFlags.AllowJSURI : 0 + if(options.disableHeadlineAnchors) { + outputFlags |= OutputFlags.DisableHeadlineAnchors; + }; + switch (options.format) { case "xhtml": outputFlags |= OutputFlags.HTML | OutputFlags.XHTML diff --git a/test/issue22.js b/test/issue22.js new file mode 100644 index 0000000..62f4aa6 --- /dev/null +++ b/test/issue22.js @@ -0,0 +1,30 @@ +// https://github.com/rsms/markdown-wasm/issues/22 +const { checkHTMLResult, exit } = require('./testutil'); + +checkHTMLResult('DISABLE_HEADLINE_ANCHOR', `# Test1 +## Test2 +### Test3 +#### Test4 +`, `

Test1

+

Test2

+

Test3

+

Test4

\n`, { + disableHeadlineAnchors: true, +}); + +checkHTMLResult( + 'ENABLE_HEADLINE_ANCHOR', + `# Test1 +## Test2 +### Test3 +#### Test4`, + `

Test1

+

Test2

+

Test3

+

Test4

\n`, + { + disableHeadlineAnchors: false, + } +); + +exit(); diff --git a/test/testutil.js b/test/testutil.js index f1efa9e..7cde8f9 100644 --- a/test/testutil.js +++ b/test/testutil.js @@ -10,14 +10,14 @@ const wave = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" exports.numFailures = 0 -exports.checkHTMLResult = function check(name, inputData, expectedOutputData) { +exports.checkHTMLResult = function check(name, inputData, expectedOutputData, options = {}) { if (typeof inputData == "string") { inputData = Buffer.from(inputData, "utf8") } if (typeof expectedOutputData == "string") { expectedOutputData = Buffer.from(expectedOutputData, "utf8") } - const actual = Buffer.from(md.parse(inputData, { asMemoryView: true })) + const actual = Buffer.from(md.parse(inputData, { asMemoryView: true, ...options })) if (expectedOutputData.compare(actual) == 0) { log(`${name} OK`) return true