fix(markdown_parser): parse tab-indented siblings#10333
Conversation
|
| Name | Type |
|---|---|
| @biomejs/biome | Patch |
| @biomejs/cli-win32-x64 | Patch |
| @biomejs/cli-win32-arm64 | Patch |
| @biomejs/cli-darwin-x64 | Patch |
| @biomejs/cli-darwin-arm64 | Patch |
| @biomejs/cli-linux-x64 | Patch |
| @biomejs/cli-linux-arm64 | Patch |
| @biomejs/cli-linux-x64-musl | Patch |
| @biomejs/cli-linux-arm64-musl | Patch |
| @biomejs/wasm-web | Patch |
| @biomejs/wasm-bundler | Patch |
| @biomejs/wasm-nodejs | Patch |
| @biomejs/backend-jsonrpc | Patch |
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
Merging this PR will not alter performance
Comparing Footnotes
|
7ac3e11 to
04e4d1e
Compare
04e4d1e to
fc057de
Compare
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (3)
WalkthroughThis PR fixes incorrect parsing of nested Markdown lists with tab indentation (issue Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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. Comment |
|
I will submit a follow up PR to address findings related to this class of problem found by the differential fuzzer |
Inside a list item, a sibling ordered marker at column <= the item's marker_indent must end the current paragraph (CommonMark §5.2). break_for_list_interrupt_after_inline_newline only ran the marker lookahead when the leading whitespace contained a tab, so a non-tab sibling ordered marker was missed whenever the parent's post-marker space widened required_indent past the sibling's column. Reproducer (biomejs#10374): 1. first 2. second 1. third 2. fourth Inner item `1. third` has marker_indent=4, required_indent=9. The next line at indent 4 is a sibling, but `indent < required_indent` and no tab in the leading whitespace, so the break check returned false and `2. fourth` plus its leading 4 spaces were swallowed as MD_TEXTUAL_LITERALs inside the first inner item's paragraph. The non-tab path now runs a narrow token lookahead that only flags non-1 ordered markers — parse_inline_item_list's textual_looks_like_list_marker already terminates on bullets and on `1.`/`1)`, so widening to all marker shapes regressed synthetic/nested-lists by ~10% without buying additional correctness. The tab path keeps the original token-aware lookahead (biomejs#10333). Verified: - cargo test -p biome_markdown_parser (all 256 tests pass) - cargo test -p biome_markdown_formatter (all 839 tests pass) - cargo bench synthetic/nested-lists: cached +5%, uncached noise
Inside a list item, a sibling ordered marker at column <= the item's marker_indent must end the current paragraph (CommonMark §5.2). break_for_list_interrupt_after_inline_newline only ran the marker lookahead when the leading whitespace contained a tab, so a non-tab sibling ordered marker was missed whenever the parent's post-marker space widened required_indent past the sibling's column. Reproducer (biomejs#10374): 1. first 2. second 1. third 2. fourth Inner item `1. third` has marker_indent=4, required_indent=9. The next line at indent 4 is a sibling, but `indent < required_indent` and no tab in the leading whitespace, so the break check returned false and `2. fourth` plus its leading 4 spaces were swallowed as MD_TEXTUAL_LITERALs inside the first inner item's paragraph. The non-tab path now runs a narrow token lookahead that only flags non-1 ordered markers — parse_inline_item_list's textual_looks_like_list_marker already terminates on bullets and on `1.`/`1)`, so widening to all marker shapes regressed synthetic/nested-lists by ~10% without buying additional correctness. The tab path keeps the original token-aware lookahead (biomejs#10333). Verified: - cargo test -p biome_markdown_parser (all 256 tests pass) - cargo test -p biome_markdown_formatter (all 839 tests pass) - cargo bench synthetic/nested-lists: cached +5%, uncached noise
Note
I used Claude Code to plan and implement this fix.
Summary
Fixes #10295
The markdown parser now treats tab-indented sibling list markers below the current item continuation indent as list-interrupting blocks. This preserves the nested list CST shape expected by the formatter.
Fixes a whitespace issue in
.changeset/bright-dragons-clean.mdto make the CI happy.No changeset: this is an internal markdown parser conformance fix.
Test Plan
just test-crate biome_markdown_parserjust test-crate biome_markdown_formatterjust test-markdown-conformanceDocs
N/A