Skip to content

🐛 HTML block start outside a list item closes the list - #442

Open
inchang-ing wants to merge 1 commit into
executablebooks:masterfrom
inchang-ing:fix/html-block-closes-list
Open

inchang-ing wants to merge 1 commit into
executablebooks:masterfrom
inchang-ing:fix/html-block-closes-list

Conversation

@inchang-ing

@inchang-ing inchang-ing commented Sep 28, 2026 •

Copy link
Copy Markdown

Fixes #434

Problem

A line that starts an HTML block (any type) on a line under-indented for the list item's content was consumed as a lazy continuation of the item's paragraph:

## Opts

- a
<br>
## Next

rendered as <li>a\n<br></li> in markdown-it-py (and in the JS original), while cmark and commonmark.js close the list and open the HTML block at the outer level — because such a line can neither be item content nor a lazy continuation of it (it starts a new block). Flipping the type-7 "can terminate paragraph" flag is not a fix: it would let <br> interrupt a top-level paragraph, where all implementations agree it must not.

Change

  • html_block.py: new html_block_starts(state, line) helper — detects whether a line begins an HTML block of any type (same sequence table as the rule).
  • paragraph.py: while scanning continuation lines, end the paragraph when the next line starts an HTML block and is under-indented for the current container (sCount < blkIndent). The list rule then sees the line, finds no item marker, and closes the list, so the line is offered to the outer containers — reproducing cmark's container walk. At the same container level a type-7 sequence still does not interrupt the paragraph (the terminator rules are unchanged), and plain text at outer indentation remains a lazy continuation.
  • CHANGELOG.md: entry under Unreleased, per the contributing guidance in AGENTS.md.

Verification

  • The issue's minimal input now renders exactly the cmark output: <h2>Opts</h2><ul><li>a</li></ul><br>\n## Next (the type-7 block swallows ## Next up to a blank line, as cmark does).
  • Five cases are pinned in tests/test_html_block_list.py: the issue's input; HTML block at the item's content indent stays a lazy continuation; a top-level paragraph still continues through <br>; plain text at outer indentation is still a lazy continuation; a type-6 block (<div>) still closes the list as before.
  • Full suite with CI's dependency set (.[testing,linkify]): 1037 passed, 0 failed; pristine master in the same environment: 1032 passed — the delta is exactly the 5 new tests, so zero regressions (CommonMark spec tests included).
  • Reverting the two source files while keeping the tests makes test_html_block_under_indented_closes_list fail, so the tests do pin the fix.
  • ruff check / ruff format clean on touched files; mypy --strict clean (the tests build MarkdownIt locally instead of via a fixture, matching the example pattern in AGENTS.md — the pre-commit mypy environment does not have pytest installed, and an untyped decorator is not allowed under the repo's strict settings).

Note

The JS markdown-it behaves the same way as this library currently does, so this change intentionally diverges from upstream JS toward the cmark/commonmark.js behavior documented in the issue; happy to align on whatever the maintainers decide.

Disclosure

This PR was prepared with AI assistance (ZCode/GLM, orchestrated via WorkBuddy).

…lebooks#442)

A line that starts an HTML block on an under-indented line was consumed
as a lazy continuation of the item's paragraph, because the type-7
sequence is flagged as unable to terminate a paragraph. cmark and
commonmark.js instead end the list: the line cannot be item content,
and a block start is not a lazy continuation.

End the paragraph when the next line starts an HTML block while being
under-indented for the current container, so the list closes and the
line is offered to the outer containers. At the same container level a
type-7 sequence still cannot interrupt the paragraph, and plain text
remains a lazy continuation, so the behaviors all implementations agree
on are unchanged.

Fixes executablebooks#434
@inchang-ing

Copy link
Copy Markdown
Author

Hi maintainers, gentle ping on #442 — fix(block): HTML block start outside a list item closes the list. It's a small, self-contained fix with passing tests. Would appreciate a review when you have a moment. Thanks for maintaining executablebooks/markdown-it-py!

@inchang-ing
inchang-ing force-pushed the fix/html-block-closes-list branch from 597b896 to df3fc1f Compare October 16, 2026 08:33
@inchang-ing inchang-ing changed the title fix(block): HTML block start outside a list item closes the list 🐛 HTML block start outside a list item closes the list Oct 16, 2026
@inchang-ing

Copy link
Copy Markdown
Author

Addressed the pre-commit.ci mypy failure and tidied the PR up:

  • mypy fix: tests/test_html_block_list.py used a @pytest.fixture, which the pre-commit mypy hook rejects — that hook's environment installs only mdurl/typing-extensions (no pytest), and the repo's strict mypy settings keep disallow_untyped_decorators enabled for tests.*, so Untyped decorator makes function "md" untyped. The tests now build MarkdownIt locally, matching the example test pattern in AGENTS.md and the rest of the suite (no other test file uses a fixture).
  • CHANGELOG.md: added an entry under Unreleased, per the pull request requirements in AGENTS.md.
  • Squashed the branch into a single commit on top of current master (the previous head also contained a pre-commit.ci autofix commit), and retitled to the EMOJI + description format the repo uses.

Verified locally with the same dependency set as CI (.[testing,linkify]): 1037 passed / 0 failed (pristine master: 1032 passed, i.e. the delta is exactly the 5 new tests), ruff check + ruff format clean, mypy --strict clean on the touched files.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTML block (type 7) glued to a list item is treated as lazy continuation; cmark and commonmark.js close the list

1 participant