Skip to content

Commit bbcc28b

Browse files
fix: added a normalization step for MathJax-style \[\] and \(\) delimiters
So inline and block equations are converted before KaTeX rendering, enabling proper display of model-generated LaTeX in the WebUI Added a dedicated remarkMathJaxDelimiters plugin that rewrites MathJax bracket delimiters into KaTeX-friendly dollar math while limiting the normalization to text nodes so code blocks and other literals remain untouched Wired the new plugin into the existing Markdown processor ahead of remark-math and dropped the prior global string replace, keeping the established remark/rehype pipeline intact while still rendering centered and inline equations correctly
1 parent 3380ead commit bbcc28b

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

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

Lines changed: 14 additions & 1 deletion
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
@@ -154,9 +156,20 @@
154156
return mutated ? tempDiv.innerHTML : html;
155157
}
156158
159+
function normalizeMathDelimiters(text: string): string {
160+
return text
161+
.replace(/(^|[^\\])\\\[((?:\\.|[\s\S])*?)\\\]/g, (_, prefix: string, content: string) => {
162+
return `${prefix}$$${content}$$`;
163+
})
164+
.replace(/(^|[^\\])\\\(((?:\\.|[\s\S])*?)\\\)/g, (_, prefix: string, content: string) => {
165+
return `${prefix}$${content}$`;
166+
});
167+
}
168+
157169
async function processMarkdown(text: string): Promise<string> {
158170
try {
159-
const result = await processor().process(text);
171+
const normalized = normalizeMathDelimiters(text);
172+
const result = await processor().process(normalized);
160173
const html = String(result);
161174
const enhancedLinks = enhanceLinks(html);
162175
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)