Skip to content

fix(ui): render $..$ and same-line $$..$$ math - #51989

Closed
wulart wants to merge 3935 commits into
anomalyco:devfrom
wulart:feat/markdown-dollar-math
Closed

wulart wants to merge 3935 commits into
anomalyco:devfrom
wulart:feat/markdown-dollar-math

Conversation

@wulart

@wulart wulart commented Sep 29, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #51725 (same gap reported in #39170, #38030, #34407, #49486)

Type of change

  • Bug fix

What does this PR do?

#34850 dropped $...$ inline math in favor of \(...\), fixing the currency false positives of the old unguarded matcher — but chat output overwhelmingly uses $...$ for inline and single-line $$...$$ for display math, which now renders as raw source (#51725 et al).

This reopens the delimiter question with the piece that was missing when #34850 was decided: guards on the dollar matcher. The old matcher ((?<!\$)\$(?!\$)...) had none, so costs $5 and $10 matched as math. This one requires:

  • opening $ not followed by whitespace
  • closing $ not preceded by whitespace
  • closing $ not followed by a digit
  • no $ or newline inside the content

so costs $5 and $10, from $1,000 to $2,000, and an unclosed $ (mid-stream output) all stay plain text.

Implementation stays inside the existing katex extension (marked-parser.tsx, +32/−8): the inline tokenizer falls back to $...$ when \(...\) doesn't match ($$...$$ inside a paragraph renders in display mode); the block regex accepts single-line and same-line $$...$$ alongside the existing newline-delimited form; start hints now report the earliest $ (inline) and \n$$ (block) so marked can split paragraphs around display math glued to preceding text. \(...\) and $$\n...\n$$ handling is untouched; no new dependencies.

#48329 covers this ground plus \[...\] with a larger rewrite — this is deliberately the minimal version scoped to the reported issues. Happy to extend the guard set if reviewers see cases it misses.

How did you verify your code works?

11 new cases in packages/ui/src/context/marked-parser.test.ts: single-dollar inline, symbol-heavy inline, CJK in \text{}, single-line block, block glued to text, in-paragraph $$, money amounts, unclosed delimiters, invalid latex, dollars literal inside code, plain markdown unaffected. All recognition cases fail on unmodified dev first; the money/unclosed/code-literal cases pass there since they assert non-rendering.

  • bun test in packages/ui — 38 pass (incl. marked-regression.test.ts)
  • bun test in packages/session-ui — 83 pass (the parser's consumer)
  • tsgo --noEmit clean

Screenshots / recordings

Rendering fix — the new tests show the before/after directly (<p>$x^2$</p> becomes <span class="katex">…); happy to attach a rendered screenshot on request.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

vimtor and others added 30 commits September 22, 2026 10:10
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

rekram1-node and others added 7 commits September 29, 2026 00:45
The katex extension only recognized \(...\) inline math and block math
requiring newlines right after the opening $$ and before the closing $$.
Most LLM chat output uses $..$ for inline math and single-line $$..$$
for display math, so those formulas currently render as raw source.

Extend the existing extension rather than adding a new one:

- inline: try $..$ after \(...\) fails, with display mode for $$..$$
- block: accept single-line and same-line $$..$$ alongside the existing
  newline-delimited form
- start hints: report the earliest $ for inline math and \n$$ for block
  math so marked can split paragraphs around glued display math

Currency guards keep money amounts as plain text: the opening $ must
not be followed by whitespace, the closing $ must not be preceded by
whitespace nor followed by a digit, and the content cannot contain $
or newlines ("costs $5 and $10", "$1,000 to $2,000" stay literal).
Unclosed delimiters are left as text; invalid latex renders as an
inline error via the existing throwOnError:false path.

Co-Authored-By: Claude Code <[email protected]>
@wulart
wulart force-pushed the feat/markdown-dollar-math branch from bcd31a7 to ad24d62 Compare September 29, 2026 12:51
@wulart wulart closed this Sep 29, 2026
@wulart

wulart commented Sep 29, 2026

Copy link
Copy Markdown
Author

Retargeting to the v2 line where merges are landing — superseded by #52087. The gap exists identically on v2 (its katex extension also only matches (...)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chat: LaTeX math ($...$) is not rendered in messages