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
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Change Log

## Unreleased

- 🐛 FIX: front matter closed by `...` is parsed correctly

The YAML document-end marker was tested against the previous line rather than
the current one, because `start`/`maximum` were only moved onto the current
line after the test. Two things followed: a block whose last line was `...` was
dropped entirely, so the front matter leaked into the document as visible text,
and where it did parse, the marker itself was included in the token content.

```python
MarkdownIt().use(front_matter_plugin).render("---\ntitle: a\n...\n")
# before: '<hr />\n<p>title: a\n...</p>\n'
# after: ''
```

## 0.7.0 - 2026-07-19

- ✨ NEW: Add section reference plugin (`section_ref`) (#144)
Expand Down
11 changes: 8 additions & 3 deletions mdit_py_plugins/front_matter/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,17 @@ def _front_matter_rule(
# unclosed block should be autoclosed by end of document.
return False

if state.src[start:maximum] == "...":
break

start = state.bMarks[nextLine] + state.tShift[nextLine]
maximum = state.eMarks[nextLine]

if state.src[start:maximum] == "...":
# The YAML document-end marker closes the block on this line, so it must
# be consumed here: checking it before start/maximum are moved onto the
# current line tests the previous one, which both missed a `...` that
# ends the document and leaked the marker into the extracted content.
auto_closed = True
break

if start < maximum and state.sCount[nextLine] < state.blkIndent:
# non-empty line with negative indent should stop the list:
# - ```
Expand Down
24 changes: 24 additions & 0 deletions tests/test_front_matter.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,30 @@ def test_token():
]


@pytest.mark.parametrize("closer", ["---", "..."])
def test_token_content_excludes_the_closer(closer):
"""The closing marker must not be left inside the extracted content.

``...`` is the YAML document-end marker and is exercised by the fixture file,
so it has to be consumed like the dashed form rather than kept in the block.
"""
md = MarkdownIt("commonmark").use(front_matter_plugin)
tokens = md.parse(f"---\na: 1\n{closer}")
assert [token.type for token in tokens] == ["front_matter"]
assert tokens[0].content == "a: 1"


def test_dots_closer_on_the_last_line():
"""A block closed by ``...`` on the final line is still front matter.

``test_all`` cannot see this: the front_matter token is hidden, so only the
rendered output is asserted, and a block that is dropped rather than closed
renders as visible text instead of disappearing.
"""
md = MarkdownIt("commonmark").use(front_matter_plugin)
assert md.render("---\na: 1\n...\n") == md.render("---\na: 1\n---\n") == ""


def test_short_source():
md = MarkdownIt("commonmark").use(front_matter_plugin)

Expand Down