Skip to content

fix(math): escape currency dollars so they aren't parsed as LaTeX math#180

Merged
quiet-node merged 2 commits into
mainfrom
worktree-bubbly-meandering-jellyfish
May 18, 2026
Merged

fix(math): escape currency dollars so they aren't parsed as LaTeX math#180
quiet-node merged 2 commits into
mainfrom
worktree-bubbly-meandering-jellyfish

Conversation

@quiet-node
Copy link
Copy Markdown
Owner

Summary

LLM/user text like raise $1M ... reach $1M was parsed by remark-math as one giant inline-math run, rendered by KaTeX in a nowrap serif block that blew the chat window out horizontally.

This adds escapeCurrencyDollars, a deterministic syntax-level pass applied at the single markdown chokepoint (MarkdownRenderer), plus a CSS structural backstop.

Changes

  • src/utils/escapeCurrencyDollars.ts — escapes a $ immediately followed by a digit ($5, $1M, $1,000, $10.50) so remark-math treats it as literal text. Genuine inline math ($E=mc^2$, $\alpha$) and all $$...$$ block math are untouched. Fenced code blocks (``` / ~~~) and inline code spans (any backtick run length) are left byte-for-byte intact. Pure and idempotent.
  • src/components/MarkdownRenderer.tsx — applies the escape to content before Streamdown, protecting every caller (user, assistant, thinking, update notes) uniformly.
  • src/App.css.katex-display horizontal containment so any wide equation (or anything that slips the filter) scrolls inside its own box instead of growing the window. The vertical axis is intentionally left to flow so tall display math (matrices, large integrals, stacked fractions) is never clipped.
  • Tests: full unit coverage of escapeCurrencyDollars (fast paths, currency forms, genuine math, code regions, streaming/unclosed fences) and a MarkdownRenderer regression test for the reported bug.

Documented trade-off

Digit-led inline math like $2x$ is indistinguishable from currency at the syntax level and is rendered as readable literal text rather than typeset. There is no reliable syntactic rule that separates the two; the CSS backstop guarantees layout integrity regardless.

Validation

  • bun run test:all:coverage — 1341 frontend tests pass, coverage gate clean.
  • bun run validate-build — lint + format + typecheck + build, zero warnings/errors.

🤖 Generated with Claude Code

…s math in Markdown

Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
Signed-off-by: Logan Nguyen <lg.131.dev@gmail.com>
@quiet-node quiet-node merged commit 90faee1 into main May 18, 2026
3 checks passed
@quiet-node quiet-node deleted the worktree-bubbly-meandering-jellyfish branch May 18, 2026 01:59
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.

1 participant