Skip to content

fix(web): disable single-dollar inline math in remark-math#805

Open
heavygee wants to merge 1 commit into
tiann:mainfrom
heavygee:fix/markdown-single-dollar-katex
Open

fix(web): disable single-dollar inline math in remark-math#805
heavygee wants to merge 1 commit into
tiann:mainfrom
heavygee:fix/markdown-single-dollar-katex

Conversation

@heavygee
Copy link
Copy Markdown
Collaborator

@heavygee heavygee commented Jun 5, 2026

Summary

Disables single-dollar inline math in remark-math so prose containing currency amounts no longer collapses into KaTeX output.

$$...$$ block math (on its own line) is unchanged.

Fixes #800.

Problem

remark-math is configured with defaults, which means singleDollarTextMath: true. Any pair of $ characters in a paragraph becomes a math span, so messages like:

The plan is $200/mo and the bill is $80 — total $400 saved.

render with everything between the first and last $ collapsed into a single <span class="katex"> block — whitespace stripped, letters reflowed as italic math symbols, apostrophes turned into prime marks. The text is no longer readable as prose.

Currency mentions are common in chat (pricing discussions, plan comparisons, billing), so the false-positive rate is high enough that day-to-day prose has been hitting it.

Approach

Pass singleDollarTextMath: false to remarkMath in web/src/components/assistant-ui/markdown-text.tsx. This is a single source of truth — MarkdownText, Reasoning, and MarkdownRenderer all import the same MARKDOWN_PLUGINS array, so the fix lands in every markdown surface at once.

Block math $$...$$ continues to render. This matches GitHub-flavored markdown semantics, which only treat $$...$$ (or fenced ```math) as math.

Trade-off vs #237

#237 added KaTeX support and explicitly mentioned single-dollar form $ E= mc^2 $ as desired. This PR partially reverses that — single-dollar inline math goes away. Math-heavy users will need to switch to $$E = mc^2$$ on its own line. The trade-off felt worth it because false positives from currency $ are common in chat prose, while inline math is rare; happy to revisit if maintainers prefer a different policy.

Testing

3 new regression tests in web/src/components/assistant-ui/markdown-text.test.ts drive the unified pipeline end-to-end and assert against the rendered HTML:

  • prose with multiple $N amounts → no class="katex", no <math> element, all amounts present as literal text
  • the real-world reported paragraph → renders as plain text
  • $$E = mc^2$$ block math → still produces a KaTeX block
$ bun run test
Test Files  85 passed (85)
     Tests  739 passed (739)

$ bun run typecheck
$ tsc --noEmit

Related

Questions

Open to a different policy if maintainers prefer (e.g. only disable single-dollar when followed by a digit, to keep $ E= mc^2 $ working). Happy to iterate.

Default remark-math configuration treats $...$ as inline LaTeX, which
turns any prose containing two currency amounts (e.g. "save $400 vs the
$200 plan") into a KaTeX block — paragraphs collapse, whitespace is
stripped, the running text is re-rendered as math symbols.

Pass `singleDollarTextMath: false` to remarkMath so single $ is plain
text. Block math `$$...$$` (on its own line) still renders, matching
GitHub-flavored markdown semantics.

Single source of truth: MARKDOWN_PLUGINS is shared by MarkdownText,
Reasoning, and MarkdownRenderer — fix lands in all three surfaces.

Adds 3 regression tests that drive the unified pipeline end-to-end:
prose with multiple "$N" amounts produces no `class="katex"` and no
`<math>` element; `$$...$$` block math still does.

Co-authored-by: Cursor <cursoragent@cursor.com>
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Findings

  • [Minor] New test imports undeclared markdown packages — the added regression test now imports unified, remark-parse, remark-rehype, and hast-util-to-html directly, but none of those packages are declared in web/package.json or the root/package manifests (checked repo manifests). The test currently relies on transitive dependencies from other markdown packages, so a valid dependency update can remove or move them and make bun run test:web fail even though this test still compiles conceptually. Evidence: web/src/components/assistant-ui/markdown-text.test.ts:2
    Suggested fix:
    {
        "devDependencies": {
            "hast-util-to-html": "^9.0.5",
            "remark-parse": "^11.0.0",
            "remark-rehype": "^11.1.2",
            "unified": "^11.0.5"
        }
    }

Summary

  • Review mode: initial
  • One dependency hygiene issue found in the new test. No correctness issue found in the remarkMath option change itself. Residual risk: I could not run the web test locally because bun is not installed in this runner.

Testing

  • Not run (automation): bun command not available in runner.

HAPI Bot

@@ -1,7 +1,11 @@
import { describe, expect, it } from 'vitest'
import { unified } from 'unified'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Minor] This test now imports unified, remark-parse, remark-rehype, and hast-util-to-html directly, but the web package does not declare any of them. That makes bun run test:web depend on transitive dependencies from other markdown packages, so a valid dependency update can break this test without touching it.

Suggested fix:

{
    "devDependencies": {
        "hast-util-to-html": "^9.0.5",
        "remark-parse": "^11.0.0",
        "remark-rehype": "^11.1.2",
        "unified": "^11.0.5"
    }
}

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.

bug(web): currency prose containing two $ signs is rendered as KaTeX math, mangling messages

1 participant