fix(desktop): keep inline math spans when CJK prose follows them

escapeCjkProseDollars treated a real closing dollar as the next opener,
so CJK text between two formulas escaped the first equation's closer.

Co-authored-by: Yun. <fangyun1008@gmail.com>
This commit is contained in:
Cursor Agent
2026-09-25 22:51:27 +00:00
committed by brooklyn!
parent b9e2ddde05
commit f77bf679cb
2 changed files with 13 additions and 3 deletions

View File

@@ -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$,所以')

View File

@@ -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
}