PR #1854 added a math stash to _renderUserFencedBlocks so backslash LaTeX
delimiters (\[..\], \(..\)) survive esc() and reach the KaTeX renderer in
user bubbles. The stash ran BEFORE the existing code-fence stash, so a
user-typed code block containing LaTeX-like syntax was extracted as
KaTeX and rendered as math inside <pre><code>:
```
\[ a + b \] is wrong
```
→ <pre><code><div class="katex-block"> a + b </div> is wrong</code></pre>
renderMd() (assistant path) handles this correctly by running fence_stash
before math_stash. The user-bubble path got the order inverted. Fix:
stash code fences first, then run the math regexes on the
outside-of-fence text only. Both top-level math and code-fenced literals
now render correctly:
- "math: \[ x + y \]" → KaTeX block
- "```\n\[ a + b \]\n```" → literal <pre><code>\[ a + b \]</code></pre>
Adds two regression tests:
- test_user_code_block_with_latex_syntax_renders_as_literal_code
(fails pre-fix, asserts no KaTeX wrappers inside <pre><code>)
- test_user_bubble_top_level_latex_still_renders_after_fence_reorder
(sibling guard against over-correcting and disabling math entirely)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>