feat: render LaTeX math in chat markdown (THU-606)#999
Conversation
Generalize the LaTeX/math rendering prototyped on the OUP demo branch into a standard chat markdown feature, with no demo-specific coupling. - Wire remark-math + rehype-katex into the shared MemoizedMarkdown renderer and ship the KaTeX stylesheet on the chat critical path. - Add normalizeDisplayMath: promote a whole-line `$$…$$` equation to fenced display math, since models routinely emit standalone equations on one line. Inline `$…$`, mid-sentence `$$…$$`, and already-fenced blocks are untouched. - Add katex, rehype-katex, remark-math deps. - Cover inline/display/mixed/lone-dollar cases in memoized-markdown.test.tsx. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Semgrep Security ScanNo security issues found. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit b7eb372. Configure here.
|
|
||
| const parseMarkdownIntoBlocks = (markdown: string): string[] => { | ||
| const tokens = marked.lexer(markdown) | ||
| const tokens = marked.lexer(normalizeDisplayMath(markdown)) |
There was a problem hiding this comment.
Math rewrite mutates fenced code
Medium Severity
normalizeDisplayMath runs on the full markdown string before marked.lexer splits blocks, so any fenced or indented code line that is only $$…$$ gets rewritten with extra newlines inside the code text. Chat messages that include such examples show altered source, not the literal line the model sent.
Reviewed by Cursor Bugbot for commit b7eb372. Configure here.
|
Preview environment deployed 🚀
Stack: Auto-destroys on PR close/merge. Login via the bundled Keycloak realm — |
PR Metrics
Updated Thu, 18 Jun 2026 17:53:22 GMT · run #1946 |


What
Generalizes the LaTeX/math rendering prototyped on the OUP demo branch into a standard chat-markdown feature — no demo-specific coupling.
remark-math+rehype-katexinto the sharedMemoizedMarkdownrenderer and ships the KaTeX stylesheet on the chat critical path.normalizeDisplayMath: promotes a whole-line$$…$$equation to fenced display math (models routinely emit standalone equations on one line). Inline$…$, mid-sentence$$…$$, and already-fenced blocks are left untouched.katex,rehype-katex,remark-mathdeps.Test
memoized-markdown.test.tsx: inline, display, mixed-with-GFM, single-line-amid-prose, and lone-dollar cases. 5/5 pass; typecheck clean.Closes THU-606
🤖 Generated with Claude Code
Note
Low Risk
UI-only markdown rendering change with targeted preprocessing; no auth, API, or data-path changes.
Overview
Chat markdown now renders LaTeX via
remark-mathandrehype-katex, with KaTeX CSS loaded alongsideMemoizedMarkdown. GFM still runs first; math plugins are shared on every block.A
normalizeDisplayMathpass runs beforemarkedsplits content: whole lines that are only$$…$$get rewritten to fenced display math so single-line model equations center correctly. Inline$…$, currency-like lone$, and mid-sentence$$are unchanged.Adds
katex,rehype-katex, andremark-mathplusmemoized-markdown.test.tsxcovering inline/display, GFM mix, single-line display amid prose, and plain$5text.Reviewed by Cursor Bugbot for commit b7eb372. Bugbot is set up for automated code reviews on this repo. Configure here.