| 
15 | 15 | 	import githubLightCss from 'highlight.js/styles/github.css?inline';  | 
16 | 16 | 	import { mode } from 'mode-watcher';  | 
17 | 17 | 	import { remarkLiteralHtml } from '$lib/markdown/literal-html';  | 
 | 18 | +	import { remarkMathJaxDelimiters } from '$lib/markdown/mathjax-delimiters';  | 
18 | 19 | 
  | 
19 | 20 | 	interface Props {  | 
20 | 21 | 		content: string;  | 
 | 
49 | 50 | 	let processor = $derived(() => {  | 
50 | 51 | 		return remark()  | 
51 | 52 | 			.use(remarkGfm) // GitHub Flavored Markdown  | 
 | 53 | +			.use(remarkMathJaxDelimiters) // Normalize \[\] and \(\) delimiters inside text nodes  | 
52 | 54 | 			.use(remarkMath) // Parse $inline$ and $$block$$ math  | 
53 | 55 | 			.use(remarkBreaks) // Convert line breaks to <br>  | 
54 | 56 | 			.use(remarkLiteralHtml) // Treat raw HTML as literal text with preserved indentation  | 
 | 
154 | 156 | 		return mutated ? tempDiv.innerHTML : html;  | 
155 | 157 | 	}  | 
156 | 158 | 
  | 
 | 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 | +
  | 
157 | 169 | 	async function processMarkdown(text: string): Promise<string> {  | 
158 | 170 | 		try {  | 
159 |  | -			const result = await processor().process(text);  | 
 | 171 | +			const normalized = normalizeMathDelimiters(text);  | 
 | 172 | +			const result = await processor().process(normalized);  | 
160 | 173 | 			const html = String(result);  | 
161 | 174 | 			const enhancedLinks = enhanceLinks(html);  | 
162 | 175 | 
  | 
 | 
0 commit comments