diff --git a/commons/src/title-extraction/extract-first-heading.spec.ts b/commons/src/title-extraction/extract-first-heading.spec.ts index 74348221f..438f04316 100644 --- a/commons/src/title-extraction/extract-first-heading.spec.ts +++ b/commons/src/title-extraction/extract-first-heading.spec.ts @@ -46,6 +46,17 @@ describe('extract first heading', () => { expect(extractFirstHeading(document)).toBe('Image Alt') }) + it('ignores MathML duplicated by KaTeX', () => { + const headline = new Element(`h${headlineIndex}`, {}, [ + new Element('span', { class: 'katex-mathml' }, [ + new Element('math', {}, [new Element('mi', {}, [new Text('alpha')])]), + ]), + new Element('span', { class: 'katex-html', 'aria-hidden': 'true' }, [new Text('alpha')]), + ]) + const document = new Document([headline]) + expect(extractFirstHeading(document)).toBe('alpha') + }) + it('extracts only the first found headline', () => { const headline1 = new Element(`h${headlineIndex}`, {}, [new Text(`headline${headlineIndex}`)]) const headline2 = new Element(`h${headlineIndex}`, {}, [new Text('headline1')]) diff --git a/commons/src/title-extraction/extract-first-heading.ts b/commons/src/title-extraction/extract-first-heading.ts index ddd77a1f5..e5a99d101 100644 --- a/commons/src/title-extraction/extract-first-heading.ts +++ b/commons/src/title-extraction/extract-first-heading.ts @@ -43,6 +43,8 @@ function extractInnerTextFromTag(node: Element): string { return '' } else if (node.name === 'img') { return findAttribute(node, 'alt')?.value ?? '' + } else if (node.name === 'math') { + return '' } else { return node.children.reduce((state, child) => { return state + extractInnerTextFromNode(child) diff --git a/markdown-it-plugins/src/toc/index.test.ts b/markdown-it-plugins/src/toc/index.test.ts index 5a2df7df1..b68cd6383 100644 --- a/markdown-it-plugins/src/toc/index.test.ts +++ b/markdown-it-plugins/src/toc/index.test.ts @@ -183,4 +183,35 @@ describe('toc', () => { `), ).toMatchSnapshot() }) + + it('includes inline math in heading names', () => { + const callback = jest.fn() + const markdownIt = new MarkdownIt().use(toc, { callback }) + markdownIt.inline.ruler.before('text', 'inlineMath', (state, silent) => { + if (state.src.slice(state.pos, state.pos + 8) !== '$\\alpha$') { + return false + } + + if (!silent) { + const token = state.push('inline_math', '', 0) + token.content = '\\alpha' + } + state.pos += 8 + return true + }) + + markdownIt.render('# $\\alpha$-foo') + + expect(callback).toHaveBeenCalledWith({ + children: [ + { + children: [], + level: 1, + name: '\\alpha-foo', + }, + ], + level: 0, + name: '', + }) + }) }) diff --git a/markdown-it-plugins/src/toc/toc-options.ts b/markdown-it-plugins/src/toc/toc-options.ts index 5564f4921..817e16908 100644 --- a/markdown-it-plugins/src/toc/toc-options.ts +++ b/markdown-it-plugins/src/toc/toc-options.ts @@ -37,6 +37,6 @@ export const defaultOptions: TocOptions = { linkClass: '', level: 1, listType: 'ol', - allowedTokenTypes: ['text', 'code_inline'], + allowedTokenTypes: ['text', 'code_inline', 'math', 'inline_math', 'display_math'], slugify: defaultSlugify, }