@@ -19,10 +19,24 @@ export function MathRenderer({ content, className = "", inline = false }: MathRe
1919 // Process the content to render LaTeX
2020 let processedContent = content ;
2121
22+ // Helper function to escape underscores in \text{} blocks for KaTeX
23+ const escapeTextUnderscores = ( latex : string ) : string => {
24+ // Replace underscores in \text{...} with \_
25+ return latex . replace ( / \\ t e x t \{ ( [ ^ } ] * ) \} / g, ( match , text ) => {
26+ // Replace underscores with escaped underscores
27+ const escapedText = text . replace ( / _ / g, '\\_' ) ;
28+ return `\\text{${ escapedText } }` ;
29+ } ) . replace ( / \\ t e x t t t \{ ( [ ^ } ] * ) \} / g, ( match , text ) => {
30+ const escapedText = text . replace ( / _ / g, '\\_' ) ;
31+ return `\\texttt{${ escapedText } }` ;
32+ } ) ;
33+ } ;
34+
2235 // Render display math ($$...$$ or \[...\])
2336 processedContent = processedContent . replace ( / \$ \$ ( [ \s \S ] + ?) \$ \$ / g, ( _ , latex ) => {
2437 try {
25- return `<span class="block my-4 overflow-x-auto">${ katex . renderToString ( latex . trim ( ) , {
38+ const escapedLatex = escapeTextUnderscores ( latex . trim ( ) ) ;
39+ return `<span class="block my-4 overflow-x-auto">${ katex . renderToString ( escapedLatex , {
2640 displayMode : true ,
2741 throwOnError : false ,
2842 trust : true ,
@@ -35,7 +49,8 @@ export function MathRenderer({ content, className = "", inline = false }: MathRe
3549 // Render display math with \[...\]
3650 processedContent = processedContent . replace ( / \\ \[ ( [ \s \S ] + ?) \\ \] / g, ( _ , latex ) => {
3751 try {
38- return `<span class="block my-4 overflow-x-auto">${ katex . renderToString ( latex . trim ( ) , {
52+ const escapedLatex = escapeTextUnderscores ( latex . trim ( ) ) ;
53+ return `<span class="block my-4 overflow-x-auto">${ katex . renderToString ( escapedLatex , {
3954 displayMode : true ,
4055 throwOnError : false ,
4156 trust : true ,
@@ -48,7 +63,8 @@ export function MathRenderer({ content, className = "", inline = false }: MathRe
4863 // Render inline math ($...$)
4964 processedContent = processedContent . replace ( / \$ ( [ ^ $ \n ] + ?) \$ / g, ( _ , latex ) => {
5065 try {
51- return katex . renderToString ( latex . trim ( ) , {
66+ const escapedLatex = escapeTextUnderscores ( latex . trim ( ) ) ;
67+ return katex . renderToString ( escapedLatex , {
5268 displayMode : false ,
5369 throwOnError : false ,
5470 trust : true ,
@@ -61,7 +77,8 @@ export function MathRenderer({ content, className = "", inline = false }: MathRe
6177 // Render inline math with \(...\) - use lazy match up to \)
6278 processedContent = processedContent . replace ( / \\ \( ( [ \s \S ] + ?) \\ \) / g, ( _ , latex ) => {
6379 try {
64- return katex . renderToString ( latex . trim ( ) , {
80+ const escapedLatex = escapeTextUnderscores ( latex . trim ( ) ) ;
81+ return katex . renderToString ( escapedLatex , {
6582 displayMode : false ,
6683 throwOnError : false ,
6784 trust : true ,
@@ -71,13 +88,27 @@ export function MathRenderer({ content, className = "", inline = false }: MathRe
7188 }
7289 } ) ;
7390
74- // Convert markdown-style headers
75- processedContent = processedContent . replace ( / ^ # # # ( .+ ) $ / gm, '<span class="block text-lg font-semibold mt-6 mb-2 text-white">$1</span>' ) ;
91+ // Convert code blocks (```python ... ``` or ``` ... ```)
92+ processedContent = processedContent . replace ( / ` ` ` ( \w * ) \n ? ( [ \s \S ] * ?) ` ` ` / g, ( _ , lang , code ) => {
93+ const langClass = lang ? `language-${ lang } ` : '' ;
94+ return `<pre class="bg-[#0a0a0f] border border-gray-700 p-3 my-3 overflow-x-auto text-sm ${ langClass } "><code class="text-cyan-300">${ code . trim ( ) . replace ( / < / g, '<' ) . replace ( / > / g, '>' ) } </code></pre>` ;
95+ } ) ;
96+
97+ // Convert inline code (`...`)
98+ processedContent = processedContent . replace ( / ` ( [ ^ ` ] + ) ` / g, '<code class="bg-gray-800 text-cyan-400 px-1 py-0.5 text-sm">$1</code>' ) ;
99+
100+ // Convert markdown-style headers (order matters - more # first)
101+ processedContent = processedContent . replace ( / ^ # # # # ( .+ ) $ / gm, '<span class="block text-base font-semibold mt-4 mb-2 text-purple-400">$1</span>' ) ;
102+ processedContent = processedContent . replace ( / ^ # # # ( .+ ) $ / gm, '<span class="block text-lg font-semibold mt-5 mb-2 text-cyan-400">$1</span>' ) ;
76103 processedContent = processedContent . replace ( / ^ # # ( .+ ) $ / gm, '<span class="block text-xl font-bold mt-6 mb-3 text-white">$1</span>' ) ;
77104
78105 // Convert **bold** to <strong>
79106 processedContent = processedContent . replace ( / \* \* ( [ ^ * ] + ) \* \* / g, '<strong class="text-white">$1</strong>' ) ;
80107
108+ // Convert bullet points
109+ processedContent = processedContent . replace ( / ^ - ( .+ ) $ / gm, '<span class="block ml-4">• $1</span>' ) ;
110+ processedContent = processedContent . replace ( / ^ \d + \. ( .+ ) $ / gm, '<span class="block ml-4 text-gray-300">$&</span>' ) ;
111+
81112 // Convert newlines to <br> for better readability
82113 processedContent = processedContent . replace ( / \n \n / g, '<br/><br/>' ) ;
83114 processedContent = processedContent . replace ( / \n / g, '<br/>' ) ;
0 commit comments