Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* ✨ Add `--enable-tables` to the CLI for file, standard input and interactive parsing in [#422](https://github.com/executablebooks/markdown-it-py/pull/422)
* πŸ› Fix CLI interactive mode joining input lines with an extra newline, which split every line into its own paragraph and broke hard line breaks, in [#172](https://github.com/executablebooks/markdown-it-py/issues/172)
* πŸ› Fix trimming and splitting with the Python whitespace set instead of the CommonMark one, which dropped U+001C–U+001F and U+0085 from paragraphs, headings, table cells and fence info strings and let distinct reference labels resolve each other, in [#418](https://github.com/executablebooks/markdown-it-py/pull/418), thanks to [@Nexory](https://github.com/Nexory)
* πŸ› Fix HTML blocks on under-indented lines being absorbed as lazy continuations of a list item's paragraph: a line that starts an HTML block outside the item's content indent now ends the list, like cmark and commonmark.js, in [#442](https://github.com/executablebooks/markdown-it-py/pull/442)
* πŸ“š Document the Python renderer constructor contract.
* πŸ”§ Drop the optional dependency on the `commonmark` package and its benchmark, since the upstream package is unmaintained, in [#401](https://github.com/executablebooks/markdown-it-py/pull/401)

Expand Down
10 changes: 10 additions & 0 deletions markdown_it/rules_block/html_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@
]


def html_block_starts(state: StateBlock, line: int) -> bool:
"""Whether `line` begins an HTML block of any type (issue #434)."""
pos = state.bMarks[line] + state.tShift[line]
maximum = state.eMarks[line]
if pos >= maximum or state.src[pos] != "<":
return False
lineText = state.src[pos:maximum]
return any(sequence[0].search(lineText) for sequence in HTML_SEQUENCES)


def html_block(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool:
LOGGER.debug(
"entering html_block: %s, %s, %s, %s", state, startLine, endLine, silent
Expand Down
11 changes: 11 additions & 0 deletions markdown_it/rules_block/paragraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging

from ..common.utils import mdTrim
from .html_block import html_block_starts
from .state_block import StateBlock

LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -36,6 +37,16 @@ def paragraph(state: StateBlock, startLine: int, endLine: int, silent: bool) ->
nextLine += 1
continue

# An HTML block start on a line under-indented for the current
# container is not a lazy continuation: like cmark, end the paragraph
# here so the line can open a block in an outer container (issue
# #434). At the same container level a type-7 sequence still does not
# interrupt the paragraph, which the terminator rules below handle.
if state.sCount[nextLine] < state.blkIndent and html_block_starts(
state, nextLine
):
break

# Some tags can terminate paragraph without empty line.
terminate = False
for terminatorRule in terminatorRules:
Expand Down
32 changes: 32 additions & 0 deletions tests/test_html_block_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Regression tests for HTML blocks interacting with list items (#434)."""

from markdown_it import MarkdownIt


def test_html_block_under_indented_closes_list() -> None:
"""A type-7 HTML block at outer indentation ends the list, like cmark."""
md = MarkdownIt("commonmark", {"html": True})
assert md.render("## Opts\n\n- a\n<br>\n## Next\n") == (
"<h2>Opts</h2>\n<ul>\n<li>a</li>\n</ul>\n<br>\n## Next\n"
)


def test_html_block_at_item_indent_is_lazy_continuation() -> None:
"""At the item's content indent, type 7 cannot interrupt the paragraph."""
md = MarkdownIt("commonmark", {"html": True})
assert md.render("- a\n <br>\n") == "<ul>\n<li>a\n<br></li>\n</ul>\n"


def test_html_block_cannot_interrupt_top_level_paragraph() -> None:
md = MarkdownIt("commonmark", {"html": True})
assert md.render("para\n<br>\n") == "<p>para\n<br></p>\n"


def test_plain_text_is_still_lazy_continuation() -> None:
md = MarkdownIt("commonmark", {"html": True})
assert md.render("- a\nb\n") == "<ul>\n<li>a\nb</li>\n</ul>\n"


def test_type_6_html_block_closes_list() -> None:
md = MarkdownIt("commonmark", {"html": True})
assert md.render("- a\n<div>\n") == "<ul>\n<li>a</li>\n</ul>\n<div>\n"