Skip to content

fix(markdown_parser): trim trailing newline in tight lists inside blockquotes#9976

Open
jfmcdowell wants to merge 2 commits intobiomejs:mainfrom
jfmcdowell:fix/md-quoted-list-tight-newline
Open

fix(markdown_parser): trim trailing newline in tight lists inside blockquotes#9976
jfmcdowell wants to merge 2 commits intobiomejs:mainfrom
jfmcdowell:fix/md-quoted-list-tight-newline

Conversation

@jfmcdowell
Copy link
Copy Markdown
Contributor

@jfmcdowell jfmcdowell commented Apr 14, 2026

Note

This PR was created with AI assistance (Claude Code).

Summary

Fixes spurious trailing \n inside the first <li> of tight lists nested in blockquotes. > - a\n> - b rendered <li>a\n</li> instead of <li>a</li>.

Root cause: MdQuotePrefix blocks leaked into list item content, causing last_is_paragraph to evaluate false and skip trailing newline trimming. Introduces is_transparent_block() to skip structural-only blocks (MdNewline, MdContinuationIndent, MdQuotePrefix) when determining paragraph boundaries for tightness.

Test Plan

  • just test-crate biome_markdown_parser
  • just test-markdown-conformance

Docs

N/A

…ckquotes

MdQuotePrefix blocks leaked into list item content, causing
last_is_paragraph to evaluate false and skip trailing newline
trimming on the first <li> of tight lists nested in blockquotes.
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 14, 2026

⚠️ No Changeset found

Latest commit: 4acaa14

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions bot added A-Parser Area: parser L-Markdown Language: Markdown labels Apr 14, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Apr 14, 2026

Merging this PR will not alter performance

✅ 28 untouched benchmarks
⏩ 228 skipped benchmarks1


Comparing jfmcdowell:fix/md-quoted-list-tight-newline (4acaa14) with main (eaa7d3a)

Open in CodSpeed

Footnotes

  1. 228 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@jfmcdowell jfmcdowell marked this pull request as ready for review April 14, 2026 12:50
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 14, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fa130c87-b21e-4e17-8205-89e8ca70eb7a

📥 Commits

Reviewing files that changed from the base of the PR and between c0ad4e2 and 4acaa14.

📒 Files selected for processing (1)
  • crates/biome_markdown_parser/src/to_html.rs

Walkthrough

The PR updates Markdown-to-HTML list tightness and trimming logic: it introduces is_transparent_block to treat newline/continuation-indent leaf blocks and quote-prefix markers as transparent when locating first/last paragraph-like blocks inside list items. is_empty_content now returns true when all blocks are transparent. Tests were added to verify tight bullet/ordered lists nested in blockquotes (including a 3-item bullet case) and a control case for a tight list outside a blockquote.

Possibly related PRs

Suggested reviewers

  • ematipico
  • dyc3
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main fix: handling trailing newlines in tight lists nested inside blockquotes, which directly matches the changeset's core problem and solution.
Description check ✅ Passed The description clearly explains the bug (spurious trailing newline in list items), root cause (MdQuotePrefix leaking into content), and solution (is_transparent_block helper), all of which align with the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/biome_markdown_parser/src/to_html.rs (1)

1776-1787: Consider making transparency the single source of truth.

Now that is_transparent_block exists, it may be worth routing is_empty_content/is_newline_block through it to avoid helper drift later.

Possible tidy-up
 fn is_newline_block(block: &AnyMdBlock) -> bool {
-    matches!(
-        block,
-        AnyMdBlock::AnyMdLeafBlock(
-            AnyMdLeafBlock::MdNewline(_) | AnyMdLeafBlock::MdContinuationIndent(_),
-        )
-    )
+    is_transparent_block(block)
 }
 
 /// Check if blocks are effectively empty (empty or only newlines).
 fn is_empty_content(blocks: &[AnyMdBlock]) -> bool {
-    blocks.is_empty() || blocks.iter().all(is_newline_block)
+    blocks.is_empty() || blocks.iter().all(is_transparent_block)
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_markdown_parser/src/to_html.rs` around lines 1776 - 1787,
is_transparent_block should be the single source of truth for blocks that render
no content; update callers and helper predicates (e.g., is_empty_content,
is_newline_block) to delegate to is_transparent_block instead of re-implementing
the same checks. Find usages of is_empty_content and is_newline_block and
replace their internal logic with a call to is_transparent_block(&block) (or
have them return is_transparent_block result), keeping any additional semantics
only when strictly necessary and adding small adapters that call
is_transparent_block to preserve existing API shapes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/biome_markdown_parser/src/to_html.rs`:
- Around line 1776-1787: is_transparent_block should be the single source of
truth for blocks that render no content; update callers and helper predicates
(e.g., is_empty_content, is_newline_block) to delegate to is_transparent_block
instead of re-implementing the same checks. Find usages of is_empty_content and
is_newline_block and replace their internal logic with a call to
is_transparent_block(&block) (or have them return is_transparent_block result),
keeping any additional semantics only when strictly necessary and adding small
adapters that call is_transparent_block to preserve existing API shapes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2d52d4ba-6540-4615-b76f-39719cb9fe31

📥 Commits

Reviewing files that changed from the base of the PR and between eaa7d3a and c0ad4e2.

📒 Files selected for processing (1)
  • crates/biome_markdown_parser/src/to_html.rs

@jfmcdowell
Copy link
Copy Markdown
Contributor Author

@codersbbitai: I addressed your nit comment in 4acaa14. However it surfaced an unrelated to our change snapshot failure in the latest CI run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Parser Area: parser L-Markdown Language: Markdown

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant