Skip to content

feat(mobile-web): render math formulas with katex in chat markdown - #3321

Merged
bobleer merged 7 commits into
GCWing:mainfrom
BingCHuanJ:feat/mobile-web-math
Oct 19, 2026
Merged

bobleer merged 7 commits into
GCWing:mainfrom
BingCHuanJ:feat/mobile-web-math

Conversation

@BingCHuanJ

@BingCHuanJ BingCHuanJ commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds KaTeX math rendering support (remark-math and rehype-katex) to chat markdown messages in mobile-web. It supports inline ($...$, \(...\)) and block ($$...$$, \[...\]) LaTeX formulas with mobile-responsive horizontal scrolling.

Type and Areas

Type: Feature

Areas: mobile web

Motivation / Impact

Currently, LaTeX math formulas sent in remote control chats are displayed as raw text (e.g., $\alpha$ or $$\sum_{i=1}^n x_i$$), making technical discussions and math responses hard to read on mobile devices.

This PR adds:

  • TeX formula rendering using katex, remark-math, and rehype-katex.
  • Delimiter normalization (\(...\) -> inline math, \[...\] -> display math) with code-fence and inline-code protection.
  • Responsive styling for .katex-display with horizontal scrolling and max-width bounds to prevent layout overflow on narrow mobile screens.

Review updates

  • KaTeX stays off the chat chunk. The math plugins and styles live in MarkdownMathContent.tsx, which ChatMarkdown imports on demand. The chat chunk stays near its pre-PR size; the ~280 kB KaTeX chunk is only fetched for messages that may contain math.
  • Currency and shell text stay literal. remark-math runs with singleDollarTextMath: false, and only recognized formulas are widened to the $$...$$ form it still parses. This keeps $5 and $10, $HOME, ${VAR}, and Windows paths as text even when the same message also contains formulas, and it prevents a \(...\) conversion from pairing with an earlier currency dollar.
  • Display math respects its container. $$...$$/\[...\] become a block only when they own a top-level line; inside lists, tables, and blockquotes they stay inline so the surrounding container is not torn apart.
  • Delimiter logic is testable. Activation and normalization moved to the pure chatMarkdownMath.ts, with coverage for escaped delimiters, blockquoted/indented code fences, multi-backtick code, code-fence $$/$& payloads, currency, shell variables, and Windows paths.
  • Dependency cleanup. Removed the redundant @types/katex devDependency; katex ships its own type definitions.

Verification

  • pnpm --dir src/mobile-web run type-check: passed with zero type errors.
  • pnpm --dir src/mobile-web run test:ui-components: passed (18/18, including lazy-load contracts, currency/shell gating, container-aware display math, and code isolation).
  • pnpm --dir src/mobile-web run test:host-queue: passed (17/17, including real-browser KaTeX DOM, mixed currency/formula text, and code-fence preservation).
  • pnpm --dir src/mobile-web run test:session-stream-browser: passed.
  • pnpm --dir src/mobile-web run build: emits a separate MarkdownMathContent JS/CSS chunk.
  • pnpm run check:repo-hygiene: passed.

Reviewer Notes

  • Uses katex/dist/katex.min.css bundled with font handling compatible with mobile assets; the CSS is emitted with the lazy math chunk.
  • Formula display blocks (.katex-display) are constrained to viewport bounds with -webkit-overflow-scrolling: touch for smooth touch scrolling.
  • A bare single-dollar identifier longer than two characters ($abc$) is treated as text, not math, to avoid swallowing shell variables. Formulas should use TeX markers ($x^2$, $\alpha$) or two-character identifiers ($x$, $n$).
  • $$content with content on the opening line and the closing fence on a later line is left untouched; standard $$ fences and single-line $$...$$ are supported.

Checklist

  • This PR is focused and does not include secrets, temporary prompts, generated scratch files, or unrelated artifacts.
  • Relevant verification is recorded above, or skipped checks are explained.
  • User-facing strings, docs, and locales are updated where applicable.

@GCWing
GCWing requested a review from bobleer October 19, 2026 01:22
Keep the KaTeX runtime out of the chat chunk by resolving the math renderer
on demand, and only activate math when the message can contain formulas so
currency-only dollar pairs keep rendering as text. Move the delimiter
normalization into a pure module so both helpers are unit-testable, and drop
the redundant @types/katex package because katex ships its own types.
Disable remark-math single-dollar parsing and widen only recognized inline
formulas to the double-dollar form remark-math still parses. This keeps
currency, shell variables, brace expansions, and Windows paths literal even
when the same message contains formulas, while \( ... \) no longer pairs with
a preceding currency dollar. Display delimiters stay block only on a top-level
line and remain inline inside lists, tables, and blockquotes, and blockquoted
or list-indented code fences are protected. Extend the unit and browser tests
to cover the mixed text cases.
Move the KaTeX display containment rules to the chat page so thinking previews
and background-receipt prompts get the same scrolling, theme the parse-error
text, and log a failed math chunk load while keeping the base renderer.
@bobleer
bobleer merged commit 4fdb5b7 into GCWing:main Oct 19, 2026
14 checks passed
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.

2 participants