fix: prevent KaTeX from treating underscores as subscripts in plain text (#6242)

Signed-off-by: Abhijay007 <Abhijay007j@gmail.com>
This commit is contained in:
Abhijay Jain
2026-01-07 00:02:06 +05:30
committed by GitHub
parent 5835c8f88b
commit a4fd6f3beb
2 changed files with 54 additions and 2 deletions
@@ -390,4 +390,57 @@ Another very long URL: https://www.example.com/very/long/path/with/many/segments
expect(markdownContainer).toHaveClass('prose-a:overflow-wrap-anywhere');
});
});
describe('KaTeX Math Rendering - singleDollarTextMath: false', () => {
it('treats single dollar signs as plain text', async () => {
const content = 'The formula $x_i$ represents the i-th element.';
const { container } = render(<MarkdownContent content={content} />);
await waitFor(() => {
const katexElements = container.querySelectorAll('.katex');
expect(katexElements.length).toBe(0);
expect(container).toHaveTextContent('$x_i$');
});
});
it('renders double dollar signs as display math', async () => {
const content = `Calculate
$$
x^2 + y^2
$$
for the result.`;
const { container } = render(<MarkdownContent content={content} />);
await waitFor(() => {
const katexDisplay = container.querySelector('.katex-display');
expect(katexDisplay).toBeInTheDocument();
});
});
it('handles shell commands without triggering math mode', async () => {
const content = 'Run echo "$FOO_BAR" to see the value.';
const { container } = render(<MarkdownContent content={content} />);
await waitFor(() => {
const katexElements = container.querySelectorAll('.katex');
expect(katexElements.length).toBe(0);
expect(container).toHaveTextContent('$FOO_BAR');
});
});
it('preserves math in code blocks', async () => {
const content = 'The formula `math\nx^2\n` uses inline code.';
const { container } = render(<MarkdownContent content={content} />);
await waitFor(() => {
expect(container).toHaveTextContent('x^2');
});
});
});
});
@@ -155,7 +155,6 @@ const MarkdownContent = memo(function MarkdownContent({
setProcessedContent(processed);
} catch (error) {
console.error('Error processing content:', error);
// Fallback to original content if processing fails
setProcessedContent(content);
}
}, [content]);
@@ -180,7 +179,7 @@ const MarkdownContent = memo(function MarkdownContent({
prose-li:m-0 prose-li:font-sans ${className}`}
>
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkBreaks, remarkMath]}
remarkPlugins={[remarkGfm, remarkBreaks, [remarkMath, { singleDollarTextMath: false }]]}
rehypePlugins={[
[
rehypeKatex,