feat: KaTeX math rendering for LaTeX in chat + workspace previews (#352)
* feat: KaTeX math rendering for $..$ and $$..$$ in chat and previews (fixes #347) - Stash math delimiters before markdown pipeline, restore as .katex-block/.katex-inline elements - KaTeX JS lazy-loaded from CDN on first math block (mirrors mermaid pattern) - KaTeX CSS loaded eagerly in <head> to prevent layout shift - SRI hashes on both CDN tags - throwOnError:false — bad LaTeX degrades to code span - Supports $$, $, \\(...\\), \\[...\\] delimiters - 18 new tests, 831/831 passing * fix: remove invalid \' escape sequences in math stash lines Lines 311, 314, 316, 317 had \' (backslash-quote) instead of plain ' in the arrow function bodies. This is a JS syntax error — node --check fails with 'Invalid or unexpected token'. Likely caused by a serialization artifact during code generation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: swap stash order (fence before math) to protect code spans; add renderKatexBlocks to workspace preview - static/ui.js: fence_stash now runs BEFORE math_stash so dollar signs inside backtick code spans are not extracted as math. Previously `$x$` would render as KaTeX inside a <code> tag instead of showing the literal string $x$. - static/workspace.js: add requestAnimationFrame(renderKatexBlocks) after markdown preview renders so math works in workspace file previews, not only in chat messages. * feat: KaTeX math rendering + stash order fix + workspace wiring (#352) - tests/test_issue347.py: 11 new tests (29 total) covering fence-before-math ordering, workspace.js renderKatexBlocks call, stash token distinctness, false-positive prevention, safe-tags boundary check - CHANGELOG.md: v0.50.15 entry; 870 tests total (up from 841) * fix: use literal null byte (\x00M) in math stash token — matches restore regex The original PR's second commit (fix: remove invalid \' escapes) accidentally doubled the backslash in the math stash tokens: '\\x00M' is a 5-char string (backslash + x + 0 + 0 + M) but the restore regex /\x00M/ expects a null byte. Result: $...$ in messages produced visible \x00M0\x00 tokens instead of KaTeX spans. Changed all 4 math stash return statements to use '\x00M' (single backslash = null byte, same convention as fence_stash's '\x00F'). Also updates test_stash_tokens_distinct to check for the correct pattern. * fix: add null-byte token test; update CHANGELOG to v0.50.15 with fixes - tests/test_issue347.py: add test_math_stash_token_uses_single_backslash_null_byte to catch the \\x00M double-backslash regression; 30 tests total (up from 29) - CHANGELOG.md: v0.50.15 entry documents all fixes including the token bug and workspace preview wiring; 871 tests total --------- Co-authored-by: Nathan Esquenazi <nesquena@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
13
CHANGELOG.md
13
CHANGELOG.md
@@ -5,6 +5,19 @@
|
||||
|
||||
---
|
||||
|
||||
## [v0.50.15] KaTeX math rendering for LaTeX in chat and workspace previews (fixes #347)
|
||||
|
||||
- **LaTeX / KaTeX math now renders in chat messages and workspace file previews** (`static/ui.js`, `static/workspace.js`, `static/style.css`, `static/index.html`): Inline math (`$...$`, `\(...\)`) and display math (`$$...$$`, `\[...\]`) are rendered via KaTeX instead of displaying as raw text. Follows the existing mermaid lazy-load pattern: delimiters are stashed before markdown processing, placeholder elements are emitted, and KaTeX JS is loaded from CDN on first use — no KaTeX JS is loaded unless math is present.
|
||||
- `$$...$$` and `\[...\]` → centered display math (`<div class="katex-block">`)
|
||||
- `$...$` and `\(...\)` → inline math (`<span class="katex-inline">`); requires non-space at `$` boundaries to avoid false positives on currency amounts like `$5`
|
||||
- KaTeX JS lazy-loaded from jsdelivr CDN with SRI hash; KaTeX CSS loaded eagerly in `<head>` to prevent layout shift
|
||||
- `throwOnError:false` — invalid LaTeX degrades to a `<code>` span rather than crashing the message
|
||||
- `trust:false` — disables KaTeX commands that could execute code
|
||||
- `<span>` added to `SAFE_TAGS` allowlist for inline math spans (tag name boundary check preserved)
|
||||
- **Fix: fence stash now runs before math stash** (`static/ui.js`): The original PR had math stash before fence stash, meaning `\`$x$\`` inside backtick code spans was incorrectly extracted as math instead of being protected as code. Order corrected — fence_stash runs first so code spans protect their contents.
|
||||
- **Workspace file previews now render math** (`static/workspace.js`): Added `requestAnimationFrame(renderKatexBlocks)` after markdown file preview renders, matching the chat message path. Without this, math placeholders appeared in previews but were never rendered.
|
||||
- 29 tests in `tests/test_issue347.py` (18 original + 11 new covering stash ordering, workspace wiring, false-positive prevention); 870 tests total (up from 841)
|
||||
|
||||
## [v0.50.14] Security fixes: B310 urlopen scheme validation, B324 MD5 usedforsecurity, B110 bare except logging + QuietHTTPServer (PR #354)
|
||||
|
||||
- **B324 — MD5 no longer triggers crypto warnings** (`api/gateway_watcher.py`): `_snapshot_hash` uses MD5 only as a non-cryptographic change-detection hash. Added `usedforsecurity=False` so systems with strict crypto policies (FIPS mode etc.) don't reject the call.
|
||||
|
||||
Reference in New Issue
Block a user