Skip to content

fix(markdown_parser): handle ordered sublist continuation#10349

Open
jfmcdowell wants to merge 2 commits into
biomejs:mainfrom
jfmcdowell:fix/markdown-list-continuation-10347
Open

fix(markdown_parser): handle ordered sublist continuation#10349
jfmcdowell wants to merge 2 commits into
biomejs:mainfrom
jfmcdowell:fix/markdown-list-continuation-10347

Conversation

@jfmcdowell
Copy link
Copy Markdown
Contributor

@jfmcdowell jfmcdowell commented May 12, 2026

Note

I used Codex to help plan, implement, and validate this fix.

Summary

Fixes #10347. Fixes the broader class of Markdown parser list-continuation issues where nested list markers at an ordered item's content column were folded into the child marker prefix, and where non-1 ordered markers incorrectly interrupted paragraph continuation.

Test Plan

Added CST fixtures and content-column-aware fuzz generators covering ordered sublists at the parent content column, quoted variants, and non-1 ordered marker paragraph continuation.

Verified with:

  • just test-crate biome_markdown_parser
  • Differential fuzz against commonmark.js

Docs

N/A

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 12, 2026

⚠️ No Changeset found

Latest commit: 0ff3686

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 May 12, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 12, 2026

Merging this PR will not alter performance

✅ 28 untouched benchmarks
⏩ 228 skipped benchmarks1


Comparing jfmcdowell:fix/markdown-list-continuation-10347 (0ff3686) with main (42190a1)

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 force-pushed the fix/markdown-list-continuation-10347 branch 2 times, most recently from 8981d5d to 5067f94 Compare May 12, 2026 19:17
@jfmcdowell jfmcdowell force-pushed the fix/markdown-list-continuation-10347 branch from 5067f94 to 276d85d Compare May 12, 2026 19:35
@jfmcdowell jfmcdowell marked this pull request as ready for review May 12, 2026 20:59
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Review Change Stack
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: 99690a7b-6e04-42ca-a74b-93a40c312747

📥 Commits

Reviewing files that changed from the base of the PR and between 276d85d and 0ff3686.

📒 Files selected for processing (1)
  • crates/biome_markdown_parser/src/syntax/list.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/biome_markdown_parser/src/syntax/list.rs

Walkthrough

This PR refines the Markdown parser's handling of ordered-list markers to comply with CommonMark §5.2 rules: ordered list markers must start with "1" and be non-empty to interrupt paragraph lazy continuation. The core logic moves from at_block_interrupt into a new can_ordered_marker_interrupt_paragraph predicate that enforces these constraints and handles indented sibling/parent boundary cases. List-item continuation paths now detect nested markers before emitting indentation, introduce force_paragraph_continuation to prevent unwanted marker interruption, and emit MD_CONTINUATION_INDENT nodes at exact required column widths. Test fixtures and corpus generators exercise ordered sublists at content-column boundaries and within blockquotes.

Possibly related PRs

  • biomejs/biome#9776: Modifies list continuation logic and indent emission in syntax/list.rs — directly related.
  • biomejs/biome#9717: Adjusts nested-list indentation and ordered-marker detection — closely related.
  • biomejs/biome#10170: Changes block-interrupt checks during list continuation — related to this PR's interrupt predicate refactor.

Suggested reviewers

  • dyc3
  • ematipico
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main fix: handling ordered sublist continuation in the markdown parser, which directly addresses the changeset's core objective.
Description check ✅ Passed The description adequately explains the fix's purpose, references the linked issue #10347, describes the test coverage, and notes verification methods—all relevant to the changeset.
Linked Issues check ✅ Passed The changeset fully addresses #10347's requirements: it corrects ordered sublist continuation handling at the content column and prevents non-1 ordered markers from interrupting paragraph continuation.
Out of Scope Changes check ✅ Passed All changes remain focused on fixing ordered-list continuation logic and adding relevant test fixtures; no extraneous modifications are present.

✏️ 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/syntax/list.rs (1)

2626-2674: ⚡ Quick win

Consider adding a comment for the force_paragraph_continuation logic.

The condition at lines 2640–2647 is subtle and implements a key CommonMark §5.2 rule: ordered markers that don't start with 1 cannot interrupt paragraph continuation. A brief comment explaining this would help future maintainers.

📝 Suggested comment
+            // CommonMark §5.2: ordered markers that do not start with "1"
+            // cannot interrupt a paragraph, even when nested at content column.
             let force_paragraph_continuation = state.last_block_was_paragraph
                 && !prev_was_blank
                 && line_starts_with_ordered_marker_after_whitespace(p)
                 && !nested_ordered_marker_starts_with_one(p);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/biome_markdown_parser/src/syntax/list.rs` around lines 2626 - 2674,
Add a brief explanatory comment above the force_paragraph_continuation boolean
that states this implements CommonMark §5.2: ordered list markers that do not
start with `1` must not interrupt an ongoing paragraph even when they appear
nested or at an indent where at_order_list_item fails to recognise them; mention
the roles of line_starts_with_ordered_marker_after_whitespace and
nested_ordered_marker_starts_with_one in the check and that the branch clears
starts_nested_ordered / starts_nested_ordered_textual to force paragraph
continuation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/biome_markdown_parser/src/syntax/list.rs`:
- Around line 2626-2674: Add a brief explanatory comment above the
force_paragraph_continuation boolean that states this implements CommonMark
§5.2: ordered list markers that do not start with `1` must not interrupt an
ongoing paragraph even when they appear nested or at an indent where
at_order_list_item fails to recognise them; mention the roles of
line_starts_with_ordered_marker_after_whitespace and
nested_ordered_marker_starts_with_one in the check and that the branch clears
starts_nested_ordered / starts_nested_ordered_textual to force paragraph
continuation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 28caf81a-639a-4375-bb5c-a64061075cdb

📥 Commits

Reviewing files that changed from the base of the PR and between b7f0d02 and 276d85d.

⛔ Files ignored due to path filters (20)
  • crates/biome_markdown_parser/tests/md_test_suite/ok/block_quote_ordered_sublist_after_list_item.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/lazy_continuation_at_marker_indent.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/link_definition_indented_continuation.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/list_continuation_edge_cases.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/list_indentation.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/list_tightness.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/multiline_list.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_bullet_indent_tokens.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_lazy_continuation_loose_item.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_lazy_continuation_same_marker_trailing.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_lazy_continuation_trailing_paragraph.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_list_blank_line_siblings.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_list_double_blank.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_list_double_blank_siblings.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_list_interrupt_after_newline.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_list_lazy_continuation_before_fence.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_list_lazy_continuation_before_link_reference.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/nested_list_triple_blank_siblings.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/ordered_marker_non_one_no_interrupt.md.snap is excluded by !**/*.snap and included by **
  • crates/biome_markdown_parser/tests/md_test_suite/ok/ordered_sublist_at_content_column.md.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (5)
  • crates/biome_markdown_parser/src/syntax/list.rs
  • crates/biome_markdown_parser/src/syntax/mod.rs
  • crates/biome_markdown_parser/tests/fuzz_generate_corpus.cjs
  • crates/biome_markdown_parser/tests/md_test_suite/ok/ordered_marker_non_one_no_interrupt.md
  • crates/biome_markdown_parser/tests/md_test_suite/ok/ordered_sublist_at_content_column.md

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.

📝 [md] Continuation line not detected

1 participant