diff --git a/apps/desktop/src/components/assistant-ui/markdown-text.test.ts b/apps/desktop/src/components/assistant-ui/markdown-text.test.ts index b7c29620f5..2d67bf17c4 100644 --- a/apps/desktop/src/components/assistant-ui/markdown-text.test.ts +++ b/apps/desktop/src/components/assistant-ui/markdown-text.test.ts @@ -574,6 +574,12 @@ describe('preprocessMarkdown', () => { expect(output).not.toContain('\\$x^2') }) + it('keeps every real inline math span when CJK prose separates them (#123163)', () => { + expect(preprocessMarkdown('$E = mc^2$ 代入 $x$ 求解')).toBe('$E = mc^2$ 代入 $x$ 求解') + expect(preprocessMarkdown('$a$ 与 $b$ 之间的说明')).toBe('$a$ 与 $b$ 之间的说明') + expect(preprocessMarkdown('$a$ 甲 $b$ 乙 $c$ 丙')).toBe('$a$ 甲 $b$ 乙 $c$ 丙') + }) + it('leaves real inline math adjacent to CJK untouched (#103546)', () => { const output = preprocessMarkdown('其中 $\\alpha = 1$,所以') diff --git a/apps/desktop/src/lib/markdown-preprocess.ts b/apps/desktop/src/lib/markdown-preprocess.ts index 87efb8ebb9..b1f5caf63a 100644 --- a/apps/desktop/src/lib/markdown-preprocess.ts +++ b/apps/desktop/src/lib/markdown-preprocess.ts @@ -658,9 +658,12 @@ const CJK_RE = /[\u3000-\u303f\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufa * Escaping only the OPENING `$` is enough: the closing `$` loses its partner * and renders literally. Real math is untouched — its body carries no CJK — * and `$$` display runs are skipped by the same `$$`-run guard the currency - * escape uses. The one accepted tradeoff: genuine inline math whose body - * names a CJK variable (`$x = 变量$`) renders as literal prose. Losing one - * equation is far cheaper than corrupting a sentence's copy-out. + * escape uses. A non-CJK span is consumed through its closer: otherwise that + * closer is scanned as the next opener, and CJK prose between two formulas + * makes the escape land on the first equation's real closing `$`. The one + * accepted tradeoff: genuine inline math whose body names a CJK variable + * (`$x = 变量$`) renders as literal prose. Losing one equation is far cheaper + * than corrupting a sentence's copy-out. */ function escapeCjkProseDollars(text: string): string { let out = '' @@ -680,6 +683,7 @@ function escapeCjkProseDollars(text: string): string { const body = text.slice(cursor + 1, closingIndex) if (!CJK_RE.test(body)) { + cursor = closingIndex continue }