Skip to content

Commit afb3ca4

Browse files
fix: replace hardcoded LaTeX normalization with remark plugin
1 parent ddac476 commit afb3ca4

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

tools/server/webui/src/lib/components/app/misc/MarkdownContent.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import githubLightCss from 'highlight.js/styles/github.css?inline';
1616
import { mode } from 'mode-watcher';
1717
import { remarkLiteralHtml } from '$lib/markdown/literal-html';
18+
import { remarkMathJaxDelimiters } from '$lib/markdown/mathjax-delimiters';
1819
1920
interface Props {
2021
content: string;
@@ -49,6 +50,7 @@
4950
let processor = $derived(() => {
5051
return remark()
5152
.use(remarkGfm) // GitHub Flavored Markdown
53+
.use(remarkMathJaxDelimiters) // Normalize \[\] and \(\) delimiters inside text nodes
5254
.use(remarkMath) // Parse $inline$ and $$block$$ math
5355
.use(remarkBreaks) // Convert line breaks to <br>
5456
.use(remarkLiteralHtml) // Treat raw HTML as literal text with preserved indentation
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import type { Plugin } from 'unified';
2+
import { visit } from 'unist-util-visit';
3+
import type { Root, Text } from 'mdast';
4+
5+
const BLOCK_REGEX = /(^|[^\\])\\\[((?:\\.|[\s\S])*?)\\\]/g;
6+
const INLINE_REGEX = /(^|[^\\])\\\(((?:\\.|[\s\S])*?)\\\)/g;
7+
8+
/**
9+
* remark plugin that normalizes MathJax bracket delimiters into KaTeX-compatible
10+
* dollar-delimited math nodes. The transformation only touches plain text nodes,
11+
* preserving code blocks, inline code, and other literal sections handled
12+
* elsewhere in the pipeline.
13+
*/
14+
15+
export const remarkMathJaxDelimiters: Plugin<[], Root> = () => {
16+
return (tree) => {
17+
visit(tree, 'text', (node: Text) => {
18+
const value = node.value;
19+
20+
if (!value || (!value.includes('\\[') && !value.includes('\\('))) {
21+
return;
22+
}
23+
24+
node.value = value
25+
.replace(BLOCK_REGEX, (_, prefix: string, content: string) => {
26+
return `${prefix}$$${content}$$`;
27+
})
28+
.replace(INLINE_REGEX, (_, prefix: string, content: string) => {
29+
return `${prefix}$${content}$`;
30+
});
31+
});
32+
};
33+
};

0 commit comments

Comments
 (0)