From 34eef6ec6b9b38409cf931d070146fbc90523ce1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 1 Sep 2026 18:51:39 +0200 Subject: [PATCH] Keep prose citations inline --- public/js/assistant/citations.js | 2 -- test/assistant-citations.test.js | 19 ++++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/public/js/assistant/citations.js b/public/js/assistant/citations.js index 0d0b8d2..bc9cfd0 100644 --- a/public/js/assistant/citations.js +++ b/public/js/assistant/citations.js @@ -96,10 +96,8 @@ function formatCitationCluster(nums) { export function normalizeMarkdownText(text) { return stripOrphanMarkdownMarkers(normalizeTableSourceCitationCells(String(text || '') .replace(/\r\n/g, '\n') - .replace(/(\[(?:\d+\s*,\s*)*\d+\])\s*[-–—]\s*/g, '$1\n- ') .replace(/([.!?])\s*[-–—]\s+(\*\*)?/g, '$1\n- $2') .replace(/(:)\s*[-–—]\s+(\*\*)?/g, '$1\n- $2') - .replace(/(\[(?:\d+\s*,\s*)*\d+\]\.)\s+(\d+\.\s+[A-Z][A-Za-z][^\n]{0,80})/g, '$1\n$2') .replace(/([.!?])\s+(\d+\.\s+[A-Z][A-Za-z][^\n]{0,80})/g, '$1\n$2') .replace(/([^\n])\s+(#{1,4}\s+)/g, '$1\n\n$2') .replace(/(#{1,4}\s+[^\n]+?)\s+(-\s+)/g, '$1\n\n$2') diff --git a/test/assistant-citations.test.js b/test/assistant-citations.test.js index 76f0cea..6a5d58b 100644 --- a/test/assistant-citations.test.js +++ b/test/assistant-citations.test.js @@ -105,12 +105,11 @@ test('normalizes old saved assistant answer formatting', async () => { assert.match(html, /Key Differences/); }); -test('repairs smashed admission bullet list after citations', async () => { +test('does not turn citation-delimited prose into a list', async () => { const { renderAssistantMarkdown } = await loadCitationModule(); - const html = renderAssistantMarkdown('Admission is indicated for: Apnoea [1, 2]- **Persistent oxygen saturation <90%** [1, 2]- **Severe respiratory distress** [1]', sources); - assert.match(html, /
  • Persistent oxygen saturation <90%<\/strong>/); - assert.match(html, /
  • Severe respiratory distress<\/strong>/); - assert.doesNotMatch(html, /\]-/); + const html = renderAssistantMarkdown('Admission is indicated for: Apnoea [1, 2]- **Persistent oxygen saturation <90%** [1, 2].', sources); + assert.match(html, /<\/a>- Persistent oxygen saturation <90%<\/strong>/); + assert.doesNotMatch(html, /
      /); }); test('keeps citations inline before clinical terms', async () => { @@ -120,13 +119,11 @@ test('keeps citations inline before clinical terms', async () => { assert.doesNotMatch(html, /<\/a>
      \s*and dehydration/); }); -test('repairs smashed head injury red flag bullets after citation clusters', async () => { +test('keeps citation-delimited clinical prose inline', async () => { const { renderAssistantMarkdown } = await loadCitationModule(); - const html = renderAssistantMarkdown('CT is indicated for: [1, 2, 3]- Focal neurologic deficits [1]- Signs of skull fracture [2]- Recurrent vomiting [3]', sources); - assert.match(html, /
    • Focal neurologic deficits/); - assert.match(html, /
    • Signs of skull fracture/); - assert.match(html, /
    • Recurrent vomiting/); - assert.doesNotMatch(html, /\]-/); + const html = renderAssistantMarkdown('CT is indicated for: [1, 2, 3]- Focal neurologic deficits [1].', sources); + assert.match(html, /<\/a>- Focal neurologic deficits/); + assert.doesNotMatch(html, /
      |
        /); }); test('preserves code block contents without creating citation links inside code', async () => {