From 6e8e343301fb41aefdc6d0bbad4b64f709ec4821 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Tue, 20 May 2025 22:03:40 +0800 Subject: [PATCH] fix(import): Unable to handle multi line mathematical formulas when importing markdown --- .../src/services/import/markdown.spec.ts | 26 ++++++++- apps/server/src/services/import/markdown.ts | 54 ++++++++++++++----- 2 files changed, 65 insertions(+), 15 deletions(-) diff --git a/apps/server/src/services/import/markdown.spec.ts b/apps/server/src/services/import/markdown.spec.ts index 103c3fc6f..8edf1c521 100644 --- a/apps/server/src/services/import/markdown.spec.ts +++ b/apps/server/src/services/import/markdown.spec.ts @@ -194,9 +194,33 @@ second line 2
This is a formula: \\(\\mathcal{L}_{task} + \\mathcal{L}_{od}\\) inside a sentence.
`; + expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected); + }); + + it("converts math expressions inside list items into Mathtex format", () => { + const input = `- First item with formula: $E = mc^2$`; + const expected = /*html*/`\\[\sqrt{x^{2}+1}\\]
`; + const expected = /*html*/`\\[\sqrt{x^{2}+1}\\]`; expect(markdownService.renderToHtml(input, "Title")).toStrictEqual(expected); }); diff --git a/apps/server/src/services/import/markdown.ts b/apps/server/src/services/import/markdown.ts index 8d1e7ed34..e49f5eaa4 100644 --- a/apps/server/src/services/import/markdown.ts +++ b/apps/server/src/services/import/markdown.ts @@ -23,19 +23,7 @@ class CustomMarkdownRenderer extends Renderer { } paragraph(data: Tokens.Paragraph): string { - let text = super.paragraph(data).trimEnd(); - - if (text.includes("$")) { - // Display math - text = text.replaceAll(/(?\\\[$1\\\]`); - - // Inline math - text = text.replaceAll(/(?\\\($1\\\)`); - } - - return text; + return super.paragraph(data).trimEnd(); } code({ text, lang }: Tokens.Code): string { @@ -132,12 +120,18 @@ class CustomMarkdownRenderer extends Renderer { function renderToHtml(content: string, title: string) { // Double-escape slashes in math expression because they are otherwise consumed by the parser somewhere. content = content.replaceAll("\\$", "\\\\$"); + + // Extract formulas and replace them with placeholders to prevent interference from Markdown rendering + const { processedText, formulaMap } = extractFormulas(content); - let html = parse(content, { + let html = parse(processedText, { async: false, renderer: renderer }) as string; + // After rendering, replace placeholders back with the formula HTML + html = restoreFormulas(html, formulaMap); + // h1 handling needs to come before sanitization html = importUtils.handleH1(html, title); html = htmlSanitizer.sanitize(html); @@ -165,6 +159,38 @@ function getNormalizedMimeFromMarkdownLanguage(language: string | undefined) { return MIME_TYPE_AUTO; } +function extractFormulas(text: string): { processedText: string, formulaMap: Map