From 9e948576e6f225bf4a428deda9d39e0f5b34a8e3 Mon Sep 17 00:00:00 2001 From: wendyyuchensun Date: Sat, 2 May 2026 10:56:47 +0800 Subject: [PATCH 1/8] feat: asccimath add back support `@...@` option --- README.md | 2 ++ src/markdown-processor/markdown-processor.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fa2196a..9074857 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ const content = seeMarkReactParse(markdown); | enableAsciimath | boolean | true | When false, AsciiMath expressions are not parsed as math. | | enableNemeth | boolean | true | When false, the Nemeth braille math extension is disabled and `@…@` syntax is not parsed. | | latexDelimiter | string | 'bracket' | The delimiter for LaTeX expressions. Options: 'bracket', 'dollar'. | +| asciimathDelimiter | string | 'graveaccent' | The delimiter for AsciiMath expressions. Options: 'graveaccent', 'asciimath'. | | documentFormat | string | 'inline' | The format of the document. Options: 'inline', 'block'. | | imageFiles | object | { [ID]: File } | A map of image IDs to File objects for image rendering. | | shouldBuildImageObjectURL | boolean | false | should build image object URL. | @@ -134,6 +135,7 @@ const toc = createTableOfContents(markdown); | enableAsciimath | boolean | true | When false, AsciiMath expressions are not parsed as math. | | enableNemeth | boolean | true | When false, the Nemeth braille math extension is disabled and `@…@` syntax is not parsed. | | latexDelimiter | string | 'bracket' | The delimiter for LaTeX expressions. Options: 'bracket', 'dollar'. Must match the renderer. | +| asciimathDelimiter | string | 'graveaccent' | The delimiter for AsciiMath expressions. Options: 'graveaccent', 'asciimath'. Must match the renderer. | ### Return value diff --git a/src/markdown-processor/markdown-processor.js b/src/markdown-processor/markdown-processor.js index 6a02285..271bcf0 100644 --- a/src/markdown-processor/markdown-processor.js +++ b/src/markdown-processor/markdown-processor.js @@ -16,7 +16,7 @@ import imageDisplayLink from './marked-extentions/image-display-link'; import iframe from './marked-extentions/iframe'; export const createMarkdownProcessor = (options = {}) => { - const asciimathDelimiter = 'graveaccent'; + const asciimathDelimiter = options.asciimathDelimiter || 'graveaccent'; const enableLatex = options.enableLatex !== false; const enableAsciimath = options.enableAsciimath !== false; From 91ff73ffea9822a115052c3dc276d26e237b4783 Mon Sep 17 00:00:00 2001 From: wendyyuchensun Date: Sat, 2 May 2026 11:03:49 +0800 Subject: [PATCH 2/8] feat: nemeth add support for `\n...\n` delimiter --- README.md | 2 +- .../markdown-processor.test.js.snap | 4 +-- .../markdown-processor.test.js | 27 +++++++++++++++++++ .../marked-extentions/nemeth.js | 12 +++++---- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9074857..edbc79c 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ const content = seeMarkReactParse(markdown); | ------------------------- | ------- | -------------- | ------------------------------------------------------------------ | | enableLatex | boolean | true | When false, LaTeX expressions are not parsed as math. | | enableAsciimath | boolean | true | When false, AsciiMath expressions are not parsed as math. | -| enableNemeth | boolean | true | When false, the Nemeth braille math extension is disabled and `@…@` syntax is not parsed. | +| enableNemeth | boolean | true | When false, the Nemeth braille math extension is disabled and `@…@` / `\n…\n` syntax is not parsed. | | latexDelimiter | string | 'bracket' | The delimiter for LaTeX expressions. Options: 'bracket', 'dollar'. | | asciimathDelimiter | string | 'graveaccent' | The delimiter for AsciiMath expressions. Options: 'graveaccent', 'asciimath'. | | documentFormat | string | 'inline' | The format of the document. Options: 'inline', 'block'. | diff --git a/src/markdown-processor/__snapshots__/markdown-processor.test.js.snap b/src/markdown-processor/__snapshots__/markdown-processor.test.js.snap index 02241b2..ec51cc8 100644 --- a/src/markdown-processor/__snapshots__/markdown-processor.test.js.snap +++ b/src/markdown-processor/__snapshots__/markdown-processor.test.js.snap @@ -9,7 +9,7 @@ exports[`markdownProcessor should handle list of math expressions, with list ite

\\n a\\n +\\n b\\n =\\n c\\n","svg":"","position":{"start":2,"end":11}}" + data-seemark-payload="{"math":"a+b=c","typed":"latex","mathMl":"\\n a\\n +\\n b\\n =\\n c\\n","svg":"","position":{"start":2,"end":11}}" />

@@ -21,7 +21,7 @@ exports[`markdownProcessor should handle list of math expressions, with list ite

\\n c\\n \\n b\\n =\\n a\\n","svg":"","position":{"start":15,"end":24}}" + data-seemark-payload="{"math":"c-b=a","typed":"latex","mathMl":"\\n c\\n \\n b\\n =\\n a\\n","svg":"","position":{"start":15,"end":24}}" />

diff --git a/src/markdown-processor/markdown-processor.test.js b/src/markdown-processor/markdown-processor.test.js index 85d82a1..3985963 100644 --- a/src/markdown-processor/markdown-processor.test.js +++ b/src/markdown-processor/markdown-processor.test.js @@ -91,6 +91,33 @@ describe('markdownProcessor', () => { expect(container).toMatchSnapshot(); }); + it('should handle nemeth braille math expressions with backslash-n delimiter', () => { + const markdownContent = '\\n⠁⠘⠆\\n'; + const options = { + latexDelimiter: 'bracket', + documentFormat: 'inline', + imageFiles: {}, + }; + + const result = markdownProcessor(markdownContent, options); + + const container = createDOMFromHTML(result); + + const mathEl = getElementByType(container, SUPPORTED_COMPONENT_TYPES.MATH); + + expect(mathEl).toBeTruthy(); + + const payload = JSON.parse( + mathEl.getAttribute(SEE_MARK_PAYLOAD_DATA_ATTRIBUTES) + ); + + expect(payload.typed).toBe('nemeth'); + expect(payload.latex).toBe('a^2'); + expect(payload.math).toBe('⠁⠘⠆'); + expect(payload.mathMl).toBeTruthy(); + expect(payload.svg).toBeTruthy(); + }); + it('should not parse nemeth braille when enableNemeth is false', () => { const markdownContent = '@⠁⠘⠆@'; const options = { diff --git a/src/markdown-processor/marked-extentions/nemeth.js b/src/markdown-processor/marked-extentions/nemeth.js index 0946513..a47bd90 100644 --- a/src/markdown-processor/marked-extentions/nemeth.js +++ b/src/markdown-processor/marked-extentions/nemeth.js @@ -4,8 +4,8 @@ import mml2svg from '../marked-wrapper/mml-to-svg'; import { createRenderer } from './helpers'; import { SUPPORTED_COMPONENT_TYPES } from '../../shared/supported-components'; -// ^@@ -const reNemeth = /^@([\u2800-\u28FF]+)@/; +// ^@@ or ^\n\n (literal backslash+n) +const reNemeth = /^(?:@([\u2800-\u28FF]+)@|\\n([\u2800-\u28FF]+)\\n)/; const markedNemeth = ({ documentFormat }) => { const latex2mml = latex2mmlFactory({ htmlMathDisplay: documentFormat }); @@ -17,8 +17,10 @@ const markedNemeth = ({ documentFormat }) => { level: 'inline', start(src) { // @ followed by braille char (disambiguates from @[ and @!) - const result = src.match(/@(?=[\u2800-\u28FF])/); - return result?.index ?? Infinity; + // or literal \n followed by braille char + const result1 = src.match(/@(?=[\u2800-\u28FF])/); + const result2 = src.match(/\\n(?=[\u2800-\u28FF])/); + return Math.min(result1?.index ?? Infinity, result2?.index ?? Infinity); }, tokenizer(src) { const match = src.match(reNemeth); @@ -26,7 +28,7 @@ const markedNemeth = ({ documentFormat }) => { return { type: 'nemeth', raw: match[0], - math: match[1], + math: match[1] ?? match[2], }; } }, From f9dac48d1bb3d906f04e8cba7a4e8a9fb91d4aec Mon Sep 17 00:00:00 2001 From: wendyyuchensun Date: Sat, 2 May 2026 11:07:18 +0800 Subject: [PATCH 3/8] test: asccimath delimiter --- .../markdown-processor.test.js.snap | 6 +-- .../markdown-processor.test.js | 53 +++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/markdown-processor/__snapshots__/markdown-processor.test.js.snap b/src/markdown-processor/__snapshots__/markdown-processor.test.js.snap index ec51cc8..58e43a9 100644 --- a/src/markdown-processor/__snapshots__/markdown-processor.test.js.snap +++ b/src/markdown-processor/__snapshots__/markdown-processor.test.js.snap @@ -9,7 +9,7 @@ exports[`markdownProcessor should handle list of math expressions, with list ite

\\n a\\n +\\n b\\n =\\n c\\n","svg":"","position":{"start":2,"end":11}}" + data-seemark-payload="{"math":"a+b=c","typed":"latex","mathMl":"\\n a\\n +\\n b\\n =\\n c\\n","svg":"","position":{"start":2,"end":11}}" />

@@ -21,7 +21,7 @@ exports[`markdownProcessor should handle list of math expressions, with list ite

\\n c\\n \\n b\\n =\\n a\\n","svg":"","position":{"start":15,"end":24}}" + data-seemark-payload="{"math":"c-b=a","typed":"latex","mathMl":"\\n c\\n \\n b\\n =\\n a\\n","svg":"","position":{"start":15,"end":24}}" />

@@ -66,7 +66,7 @@ exports[`markdownProcessor should handle nemeth braille math expressions 1`] = `

\\n \\n a\\n 2\\n \\n","svg":"","position":{"start":0,"end":5}}" + data-seemark-payload="{"math":"⠁⠘⠆","typed":"nemeth","latex":"a^2","mathMl":"\\n \\n a\\n 2\\n \\n","svg":"","position":{"start":0,"end":5}}" />

diff --git a/src/markdown-processor/markdown-processor.test.js b/src/markdown-processor/markdown-processor.test.js index 3985963..558c1bb 100644 --- a/src/markdown-processor/markdown-processor.test.js +++ b/src/markdown-processor/markdown-processor.test.js @@ -61,6 +61,59 @@ describe('markdownProcessor', () => { expect(container).toMatchSnapshot(); }); + it('should handle asciimath expressions with graveaccent delimiter', () => { + const markdownContent = '`a+b=c`'; + const options = { + latexDelimiter: 'bracket', + documentFormat: 'inline', + imageFiles: {}, + }; + + const result = markdownProcessor(markdownContent, options); + + const container = createDOMFromHTML(result); + + const mathEl = getElementByType(container, SUPPORTED_COMPONENT_TYPES.MATH); + + expect(mathEl).toBeTruthy(); + + const payload = JSON.parse( + mathEl.getAttribute(SEE_MARK_PAYLOAD_DATA_ATTRIBUTES) + ); + + expect(payload.typed).toBe('asciimath'); + expect(payload.math).toBe('a+b=c'); + expect(payload.mathMl).toBeTruthy(); + expect(payload.svg).toBeTruthy(); + }); + + it('should handle asciimath expressions with asciimath delimiter', () => { + const markdownContent = '\\aa+b=c\\a'; + const options = { + asciimathDelimiter: 'asciimath', + latexDelimiter: 'bracket', + documentFormat: 'inline', + imageFiles: {}, + }; + + const result = markdownProcessor(markdownContent, options); + + const container = createDOMFromHTML(result); + + const mathEl = getElementByType(container, SUPPORTED_COMPONENT_TYPES.MATH); + + expect(mathEl).toBeTruthy(); + + const payload = JSON.parse( + mathEl.getAttribute(SEE_MARK_PAYLOAD_DATA_ATTRIBUTES) + ); + + expect(payload.typed).toBe('asciimath'); + expect(payload.math).toBe('a+b=c'); + expect(payload.mathMl).toBeTruthy(); + expect(payload.svg).toBeTruthy(); + }); + it('should handle nemeth braille math expressions', () => { const markdownContent = '@⠁⠘⠆@'; const options = { From 10b42f69fb4aee87e12404f6edb9fa744f593bfa Mon Sep 17 00:00:00 2001 From: wendyyuchensun Date: Sat, 2 May 2026 11:08:45 +0800 Subject: [PATCH 4/8] chore: bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fde1c7c..4894324 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@coseeing/see-mark", - "version": "1.9.0", + "version": "1.10.0", "description": "A markdown parser for a11y", "main": "./lib/see-mark.cjs", "files": [ From 3df5ad05a47dbce075a8fcaa957748b8d232cde1 Mon Sep 17 00:00:00 2001 From: wendyyuchensun Date: Sat, 2 May 2026 11:15:38 +0800 Subject: [PATCH 5/8] fix: lint --- src/markdown-processor/marked-extentions/nemeth.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/markdown-processor/marked-extentions/nemeth.js b/src/markdown-processor/marked-extentions/nemeth.js index a47bd90..cd1965e 100644 --- a/src/markdown-processor/marked-extentions/nemeth.js +++ b/src/markdown-processor/marked-extentions/nemeth.js @@ -20,7 +20,10 @@ const markedNemeth = ({ documentFormat }) => { // or literal \n followed by braille char const result1 = src.match(/@(?=[\u2800-\u28FF])/); const result2 = src.match(/\\n(?=[\u2800-\u28FF])/); - return Math.min(result1?.index ?? Infinity, result2?.index ?? Infinity); + return Math.min( + result1?.index ?? Infinity, + result2?.index ?? Infinity + ); }, tokenizer(src) { const match = src.match(reNemeth); From b9ec7fa6e9d262976142bb1e621e89a194853912 Mon Sep 17 00:00:00 2001 From: wendyyuchensun Date: Sat, 2 May 2026 11:21:33 +0800 Subject: [PATCH 6/8] chore: add back table of content code in heading test --- src/table-of-contents/create-table-of-contents.js | 3 +++ src/table-of-contents/create-table-of-contents.test.js | 10 ++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/table-of-contents/create-table-of-contents.js b/src/table-of-contents/create-table-of-contents.js index 3953966..b5940eb 100644 --- a/src/table-of-contents/create-table-of-contents.js +++ b/src/table-of-contents/create-table-of-contents.js @@ -34,6 +34,8 @@ function extractPlainText(inlineTokens = []) { * Must match the value used by the markdown renderer so that math tokens * inside headings are recognised and their text is correctly extracted. * Defaults to 'bracket'. + * @param {string} [options.asciimathDelimiter] - AsciiMath delimiter style ('graveaccent', 'asciimath'). + * Must match the value used by the markdown renderer. Defaults to 'graveaccent'. * @returns {{ level: number, id: string, text: string }[]} * * @example @@ -49,6 +51,7 @@ const createTableOfContents = (markdown, options = {}) => { enableAsciimath: options.enableAsciimath !== false, enableNemeth: options.enableNemeth !== false, latexDelimiter: options.latexDelimiter ?? 'bracket', + asciimathDelimiter: options.asciimathDelimiter ?? 'graveaccent', }); const tokens = lexer(markdown); const usedIds = new Map(); diff --git a/src/table-of-contents/create-table-of-contents.test.js b/src/table-of-contents/create-table-of-contents.test.js index fb13b82..4dc2c7b 100644 --- a/src/table-of-contents/create-table-of-contents.test.js +++ b/src/table-of-contents/create-table-of-contents.test.js @@ -77,12 +77,10 @@ describe('createTableOfContents', () => { expect(result[0].id).toBe('hello-world'); }); - // FIXME: backtick code spans conflict with the graveaccent AsciiMath delimiter. - // With seemark's math extension registered, `npm install` is tokenised as a - // math token instead of a native code span, so text extraction drops the - // expression. - it.skip('should strip code span markdown from text field', () => { - const result = createTableOfContents('## Use `npm install`'); + it('should strip code span markdown from text field', () => { + const result = createTableOfContents('## Use `npm install`', { + asciimathDelimiter: 'asciimath', // backtick code spans conflict with the graveaccent AsciiMath delimiter + }); expect(result[0].text).toBe('Use npm install'); expect(result[0].id).toBe('use-npm-install'); From 89faf1185d8dce1f5efd267940f2f4b3c40936dc Mon Sep 17 00:00:00 2001 From: wendyyuchensun Date: Sat, 2 May 2026 11:31:47 +0800 Subject: [PATCH 7/8] feat: nemeth support delimiter options --- README.md | 6 +++-- src/markdown-processor/markdown-processor.js | 2 ++ .../markdown-processor.test.js | 1 + .../marked-extentions/nemeth.js | 23 ++++++++++--------- .../marked-wrapper/marked-wrapper.js | 2 ++ .../create-table-of-contents.js | 3 +++ 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index edbc79c..dcc1778 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,10 @@ const content = seeMarkReactParse(markdown); | ------------------------- | ------- | -------------- | ------------------------------------------------------------------ | | enableLatex | boolean | true | When false, LaTeX expressions are not parsed as math. | | enableAsciimath | boolean | true | When false, AsciiMath expressions are not parsed as math. | -| enableNemeth | boolean | true | When false, the Nemeth braille math extension is disabled and `@…@` / `\n…\n` syntax is not parsed. | +| enableNemeth | boolean | true | When false, the Nemeth braille math extension is disabled. | | latexDelimiter | string | 'bracket' | The delimiter for LaTeX expressions. Options: 'bracket', 'dollar'. | | asciimathDelimiter | string | 'graveaccent' | The delimiter for AsciiMath expressions. Options: 'graveaccent', 'asciimath'. | +| nemethDelimiter | string | 'at' | The delimiter for Nemeth braille expressions. Options: 'at' (`@…@`), 'nemeth' (`\n…\n`). | | documentFormat | string | 'inline' | The format of the document. Options: 'inline', 'block'. | | imageFiles | object | { [ID]: File } | A map of image IDs to File objects for image rendering. | | shouldBuildImageObjectURL | boolean | false | should build image object URL. | @@ -133,9 +134,10 @@ const toc = createTableOfContents(markdown); | -------------- | ------- | ------------- | ------------------------------------------------------------------------------------------- | | enableLatex | boolean | true | When false, LaTeX expressions are not parsed as math. | | enableAsciimath | boolean | true | When false, AsciiMath expressions are not parsed as math. | -| enableNemeth | boolean | true | When false, the Nemeth braille math extension is disabled and `@…@` syntax is not parsed. | +| enableNemeth | boolean | true | When false, the Nemeth braille math extension is disabled. | | latexDelimiter | string | 'bracket' | The delimiter for LaTeX expressions. Options: 'bracket', 'dollar'. Must match the renderer. | | asciimathDelimiter | string | 'graveaccent' | The delimiter for AsciiMath expressions. Options: 'graveaccent', 'asciimath'. Must match the renderer. | +| nemethDelimiter | string | 'at' | The delimiter for Nemeth braille expressions. Options: 'at' (`@…@`), 'nemeth' (`\n…\n`). Must match the renderer. | ### Return value diff --git a/src/markdown-processor/markdown-processor.js b/src/markdown-processor/markdown-processor.js index 271bcf0..37632cc 100644 --- a/src/markdown-processor/markdown-processor.js +++ b/src/markdown-processor/markdown-processor.js @@ -17,6 +17,7 @@ import iframe from './marked-extentions/iframe'; export const createMarkdownProcessor = (options = {}) => { const asciimathDelimiter = options.asciimathDelimiter || 'graveaccent'; + const nemethDelimiter = options.nemethDelimiter || 'at'; const enableLatex = options.enableLatex !== false; const enableAsciimath = options.enableAsciimath !== false; @@ -25,6 +26,7 @@ export const createMarkdownProcessor = (options = {}) => { return markedProcessorFactory({ latexDelimiter: options.latexDelimiter, asciimathDelimiter, + nemethDelimiter, documentFormat: options.documentFormat, imageFiles: options.imageFiles, shouldBuildImageObjectURL: options.shouldBuildImageObjectURL, diff --git a/src/markdown-processor/markdown-processor.test.js b/src/markdown-processor/markdown-processor.test.js index 558c1bb..fdfaa64 100644 --- a/src/markdown-processor/markdown-processor.test.js +++ b/src/markdown-processor/markdown-processor.test.js @@ -148,6 +148,7 @@ describe('markdownProcessor', () => { const markdownContent = '\\n⠁⠘⠆\\n'; const options = { latexDelimiter: 'bracket', + nemethDelimiter: 'nemeth', documentFormat: 'inline', imageFiles: {}, }; diff --git a/src/markdown-processor/marked-extentions/nemeth.js b/src/markdown-processor/marked-extentions/nemeth.js index cd1965e..475d19b 100644 --- a/src/markdown-processor/marked-extentions/nemeth.js +++ b/src/markdown-processor/marked-extentions/nemeth.js @@ -4,10 +4,11 @@ import mml2svg from '../marked-wrapper/mml-to-svg'; import { createRenderer } from './helpers'; import { SUPPORTED_COMPONENT_TYPES } from '../../shared/supported-components'; -// ^@@ or ^\n\n (literal backslash+n) -const reNemeth = /^(?:@([\u2800-\u28FF]+)@|\\n([\u2800-\u28FF]+)\\n)/; +const reNemethAt = /^@([\u2800-\u28FF]+)@/; +const reNemethN = /^\\n([\u2800-\u28FF]+)\\n/; -const markedNemeth = ({ documentFormat }) => { +const markedNemeth = ({ documentFormat, nemethDelimiter = 'at' }) => { + const reNemeth = nemethDelimiter === 'nemeth' ? reNemethN : reNemethAt; const latex2mml = latex2mmlFactory({ htmlMathDisplay: documentFormat }); return { @@ -16,14 +17,14 @@ const markedNemeth = ({ documentFormat }) => { name: 'nemeth', level: 'inline', start(src) { + if (nemethDelimiter === 'nemeth') { + // literal \n followed by braille char + const result = src.match(/\\n(?=[\u2800-\u28FF])/); + return result?.index ?? Infinity; + } // @ followed by braille char (disambiguates from @[ and @!) - // or literal \n followed by braille char - const result1 = src.match(/@(?=[\u2800-\u28FF])/); - const result2 = src.match(/\\n(?=[\u2800-\u28FF])/); - return Math.min( - result1?.index ?? Infinity, - result2?.index ?? Infinity - ); + const result = src.match(/@(?=[\u2800-\u28FF])/); + return result?.index ?? Infinity; }, tokenizer(src) { const match = src.match(reNemeth); @@ -31,7 +32,7 @@ const markedNemeth = ({ documentFormat }) => { return { type: 'nemeth', raw: match[0], - math: match[1] ?? match[2], + math: match[1], }; } }, diff --git a/src/markdown-processor/marked-wrapper/marked-wrapper.js b/src/markdown-processor/marked-wrapper/marked-wrapper.js index 8d32f7f..72674d1 100644 --- a/src/markdown-processor/marked-wrapper/marked-wrapper.js +++ b/src/markdown-processor/marked-wrapper/marked-wrapper.js @@ -7,6 +7,7 @@ const markedProcessorFactory = ({ enableAsciimath = true, latexDelimiter, asciimathDelimiter, + nemethDelimiter, documentFormat, imageFiles = {}, shouldBuildImageObjectURL = false, @@ -31,6 +32,7 @@ const markedProcessorFactory = ({ enableAsciimath, latexDelimiter, asciimathDelimiter, + nemethDelimiter, documentFormat, imageFiles, shouldBuildImageObjectURL, diff --git a/src/table-of-contents/create-table-of-contents.js b/src/table-of-contents/create-table-of-contents.js index b5940eb..2fe80cf 100644 --- a/src/table-of-contents/create-table-of-contents.js +++ b/src/table-of-contents/create-table-of-contents.js @@ -36,6 +36,8 @@ function extractPlainText(inlineTokens = []) { * Defaults to 'bracket'. * @param {string} [options.asciimathDelimiter] - AsciiMath delimiter style ('graveaccent', 'asciimath'). * Must match the value used by the markdown renderer. Defaults to 'graveaccent'. + * @param {string} [options.nemethDelimiter] - Nemeth delimiter style ('at', 'nemeth'). + * Must match the value used by the markdown renderer. Defaults to 'at'. * @returns {{ level: number, id: string, text: string }[]} * * @example @@ -52,6 +54,7 @@ const createTableOfContents = (markdown, options = {}) => { enableNemeth: options.enableNemeth !== false, latexDelimiter: options.latexDelimiter ?? 'bracket', asciimathDelimiter: options.asciimathDelimiter ?? 'graveaccent', + nemethDelimiter: options.nemethDelimiter ?? 'at', }); const tokens = lexer(markdown); const usedIds = new Map(); From 54d87cb440150c5f6fc8cb98e88fb4bb93111ad2 Mon Sep 17 00:00:00 2001 From: wendyyuchensun Date: Sat, 2 May 2026 16:23:54 +0800 Subject: [PATCH 8/8] chore: add back comments --- src/markdown-processor/marked-extentions/nemeth.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/markdown-processor/marked-extentions/nemeth.js b/src/markdown-processor/marked-extentions/nemeth.js index 475d19b..bda535b 100644 --- a/src/markdown-processor/marked-extentions/nemeth.js +++ b/src/markdown-processor/marked-extentions/nemeth.js @@ -4,7 +4,9 @@ import mml2svg from '../marked-wrapper/mml-to-svg'; import { createRenderer } from './helpers'; import { SUPPORTED_COMPONENT_TYPES } from '../../shared/supported-components'; +// ^@@ const reNemethAt = /^@([\u2800-\u28FF]+)@/; +// ^\n\n (literal backslash+n) const reNemethN = /^\\n([\u2800-\u28FF]+)\\n/; const markedNemeth = ({ documentFormat, nemethDelimiter = 'at' }) => {