Closes#1618 (reported by @Zixim) and corrects #1463's previous fix.
Bug: YAML, JSON, and diff/patch fenced code blocks render flattened to a
single line. Reporter noted the bug persisted v0.50.279 -> v0.50.291 ->
v0.50.292 despite PR #1516's CSS-only "fix".
Root cause: PR #484 (v0.50.237) added a JSON/YAML tree-viewer that routes
those languages through <div class="code-tree-wrap">...<pre class="tree-raw-view">
instead of bare <pre>. Same release added the diff/patch coloring path
that emits <pre class="diff-block">. The _pre_stash regex at
static/ui.js:1914 matched only literal <pre> with no attributes:
<pre>[\s\S]*?<\/pre>
Both new shapes failed to match, fell through to the paragraph-wrap pass,
and \n characters inside the code blocks got replaced with <br> tags
inside <code>. By the time Prism ran, no newlines remained for the CSS
rule (PR #1516, language-yaml .token { white-space: pre !important }) to
preserve.
Fix: relax the regex to accept any attribute on <pre>:
<pre>[\s\S]*?<\/pre> -> <pre[^>]*>[\s\S]*?<\/pre>
One regex character. Pulls JSON, YAML, and diff/patch blocks into the
stash so paragraph-wrap can't mangle them. Bash, Python, Go, etc. were
never affected because they emit bare <pre>.
Tests: 9 new (2 source-string invariants + 7 behavioural via node-driver
against the actual static/ui.js renderMd()). 6 of the 7 behavioural tests
fail on master and pass with the fix; the 3 sanity checks (yml-alias,
bash, mermaid) pass on both.
Plus widened source-scan window in 3 pre-existing test_745 assertions
from 400 to 1500 chars. The new comment block above the fixed regex
pushed it past the previous scan window. Pure window-narrowness bug,
not a behavior regression.
4245 -> 4254 passing.
* fix(css): add overflow-wrap:anywhere to chat bubbles — prevents long URL overflow (#1080)
* fix(projects): rename now works via dblclick timer guard + right-click color picker (#1078)
* fix(renderer): block-level constructs inside blockquotes now render
Fenced code blocks, headings, horizontal rules, and ordered lists inside
blockquotes now render correctly. Six related bugs documented in
blockquote-rendering-bugs.md were collapsed into one architectural fix
in renderMd().
Bugs fixed (all 6):
1. Fenced code blocks inside blockquotes -- > prefixes leaked into the
<pre> body and the blockquote got fragmented around the rendered
code, sometimes leaving raw <pre>/<div class="pre-header"> as
visible text.
2. Blank > continuation lines fragmented multi-paragraph blockquotes
into separate <blockquote> elements with literal > between them.
3. ## headings inside blockquotes rendered as literal "##" text.
4. Numbered lists inside blockquotes rendered as plain prose.
5. Complex blockquote (mixed headings + code + list + inline code)
collapsed into a monospace blob with raw markdown syntax leaking
everywhere.
6. Horizontal rules (---) inside blockquotes rendered as literal text.
Root cause:
The per-line passes for fenced code, headings, hr, ordered lists all ran
BEFORE the blockquote handler and could not match lines that started
with >, so by the time blockquote stripping ran those constructs had
already been mishandled.
Fix:
A new blockquote pre-pass at the top of renderMd():
- Walks lines fence-aware so > -prefixed lines inside non-blockquote
code fences (e.g. shell prompts in bash code blocks) are not
miscaptured as a blockquote.
- Groups consecutive > -prefixed lines, strips the > prefix, and
recursively calls renderMd() on the stripped content. The recursive
call handles all block-level constructs (fenced code, headings, hr,
ordered/unordered lists, nested blockquotes) using the same pipeline.
- Wraps the rendered HTML in <blockquote> and stashes it with a \x00Q
token. Restored at the very end of renderMd() so no later pass can
mangle the inner HTML.
The old _applyBlockquotes regex-replace is removed entirely along with
its limited inline branches for nested blockquotes and unordered lists.
Behaviour change:
Blockquotes now produce CommonMark-compliant <p> wrapping for text
content (was: bare text directly inside <blockquote>). The visual
output is the same in browsers but the HTML structure is now standard.
Tests:
- 14 new behavioural tests in tests/test_renderer_js_behaviour.py
drive the actual renderMd() via node and lock all 6 bug fixes.
- .local-review/test_blockquote_bugs.js -- node harness covering the
same scenarios, runnable manually for fast iteration.
- 2407/2408 tests pass (1 pre-existing macOS-only failure deselected).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(renderer): entity decode before blockquote pre-pass + CSS margin fix
- Move the >/</& entity-decode to run at the very top of
renderMd(), before the blockquote pre-pass. Previously decode() ran
at line 756 (after the pre-pass at line 697), so LLM output containing
>-encoded blockquotes was never matched by the pre-pass.
- Add .msg-body blockquote p{margin:0} and .preview-md blockquote p{margin:0}
so the new CommonMark-compliant <p> wrapping inside blockquotes doesn't
add extra vertical spacing. Prior shape (bare text) had no default p-margins.
- Add Node-driven tests: TestBlockquoteEntityEncodedInput covers > prefix
and >-encoded fenced code inside blockquotes.
- Add struct test: TestBlockquotePrePassOrdering::test_entity_decode_runs_before_blockquote_pre_pass
locks decode < _bq_stash ordering in ui.js.
Fixes found during Opus independent review of #1083.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs: v0.50.218 release notes, test count 2458, roadmap update
---------
Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>