diff --git a/public/js/assistant/citations.js b/public/js/assistant/citations.js
index 8677e5b..2ab9948 100644
--- a/public/js/assistant/citations.js
+++ b/public/js/assistant/citations.js
@@ -6,7 +6,7 @@ export function renderAssistantMarkdown(md, sources, options) {
codeBlocks.push({ lang: (lang || '').toLowerCase(), code: code });
return '\n@@CODEBLOCK_' + idx + '@@\n';
});
- text = stripOrphanMarkdownMarkers(normalizeMarkdownText(text));
+ text = stripOrphanMarkdownMarkers(normalizeMarkdownText(text.replace(/\\\[((?:\d+\s*,\s*)*\d+)\\\]/g, '[$1]')));
text = renderLatexText(text, opts.katex);
text = normalizeAdjacentCitationClusters(text, sources || []);
diff --git a/test/assistant-citations.test.js b/test/assistant-citations.test.js
index e6aedaf..7214aac 100644
--- a/test/assistant-citations.test.js
+++ b/test/assistant-citations.test.js
@@ -31,6 +31,14 @@ test('renders citation clusters as links to matching source cards', async () =>
assert.match(html, /]*>src<\/a> ]*>src<\/a>/);
});
+test('renders escaped citation tokens as source links, not display math', async () => {
+ const { renderAssistantMarkdown } = await loadCitationModule();
+ const katex = { renderToString: function () { throw new Error('citation sent to KaTeX'); } };
+ const html = renderAssistantMarkdown('Acquired hypothyroidism is uncommon. \\[1, 2\\].', sources, { katex });
+ assert.match(html, /]*>src<\/a> ]*>src<\/a>/);
+ assert.doesNotMatch(html, /katex-display/);
+});
+
test('can render citation labels as numbers for PDF export', async () => {
const { renderAssistantMarkdown } = await loadCitationModule();
const html = renderAssistantMarkdown('Give magnesium for severe exacerbation [1, 2].', sources, { citationLabel: 'number' });