Skip to content

feat!: parse YAML frontmatter natively (drop need for yaml-metadata)#74

Merged
gaige merged 5 commits into
mainfrom
feat/yaml-frontmatter
Jun 28, 2026
Merged

feat!: parse YAML frontmatter natively (drop need for yaml-metadata)#74
gaige merged 5 commits into
mainfrom
feat/yaml-frontmatter

Conversation

@gaige

@gaige gaige commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Summary

Adds native --- YAML frontmatter parsing to the reader, so Pelican sites no longer need pelican-yaml-metadata alongside it.

Why

When both pelican-markdown-it-reader and pelican-yaml-metadata are installed, whichever registers last wins the .md extension. yaml-metadata (needed for --- YAML headers with list-form tags) registered last and rendered bodies with python-markdown, whose fenced_code only recognizes fences at column 0 — so fenced code blocks nested inside lists broke (list numbering restarted; ```bash collapsed into an inline code span).

Because this reader's frontmatter parser was a naive split(":") loop (couldn't handle YAML lists), yaml-metadata was the only workaround. Fixing the parser here removes the conflict at its source.

Changes

  • feat! native YAML frontmatter parsing (PyYAML): maps tags/category/author(s)/date/slug/status/… onto Pelican metadata, renders FORMATTED_FIELDS through markdown-it. Files without a --- header fall back to the legacy key: value parser, so existing content is unaffected.
  • deps: bump all runtime + dev deps; widen to markdown-it-py 4.x / mdit-py-plugins 0.6; raise Python floor to 3.11 (3.9/3.10 EOL/near-EOL; pytest 9 needs ≥3.10). Migrate deprecated dev-dependencies table.
  • ci: test matrix → 3.11–3.14; add top-level least-privilege permissions; update all actions to latest majors and SHA-pin them (incl. privileged publish-context actions).
  • docs: README documents YAML frontmatter and yaml-metadata removal.

Breaking change

The reader now parses --- YAML frontmatter itself and depends on PyYAML. Sites that paired it with pelican-yaml-metadata should remove that plugin; metadata derived from YAML headers may differ. Warrants a major (3.0.0) release.

Testing

New tests cover YAML metadata (incl. list-form + scalar tags), the fenced-code-in-list regression, link placeholders, and the legacy fallback. invoke tests + invoke lint pass locally against the upgraded set (markdown-it-py 4.2, pelican 4.12, pytest 9, black 26, flake8 7, isort 8).

🤖 Generated with Claude Code

gaige and others added 5 commits June 28, 2026 14:37
Previously the reader only understood a naive `key: value` header and
could not parse `---`-delimited YAML frontmatter with list-form values
(e.g. tags). Users worked around that by also installing
pelican-yaml-metadata, but that plugin renders bodies with
python-markdown -- whose fenced_code only recognises fences at column 0,
so fenced code blocks nested in lists broke (the list restarted and the
fence collapsed into an inline code span).

The reader now detects a `---` YAML header, parses it with PyYAML, and
maps it onto Pelican metadata (tags, category, author(s), date, slug,
status, ...), rendering FORMATTED_FIELDS through markdown-it as well.
Files without a YAML fence still use the legacy `key: value` parser, so
existing content is unaffected.

Sites no longer need pelican-yaml-metadata and get correct markdown-it
rendering for the whole document, including fenced code inside lists.

BREAKING CHANGE: the reader now parses `---` YAML frontmatter itself and
depends on PyYAML. Sites that paired it with pelican-yaml-metadata should
remove that plugin; metadata derived from YAML headers may differ.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Update runtime and dev dependencies to current releases and widen the
markdown-it-py / mdit-py-plugins bounds to allow the 4.x / 0.6.x line
(markdown-it-py 4.2, mdit-py-plugins 0.6.1, Pygments 2.19, PyYAML 6,
pelican 4.11+; black 26, flake8 7, isort 8, pytest 9, invoke 3).

Raise the Python floor to >=3.11: 3.9 and 3.10 are EOL/near-EOL, pytest 9
requires >=3.10, and the primary consumer already targets 3.11+. Also
migrate the deprecated [tool.poetry.dev-dependencies] table to
[tool.poetry.group.dev.dependencies].

Tests and pre-commit (black/flake8/isort/pyupgrade) pass against the
upgraded set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop 3.9/3.10 (now below the >=3.11 requirement and EOL/near-EOL) and add
3.14, which is stable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add a top-level `permissions: contents: read` to the build workflow so
  test/lint/build run with a least-privilege token; the publish/release
  jobs keep their own elevated scopes.
- Update all actions to their latest majors and pin them to full commit
  SHAs (with a version comment), including the privileged publish-context
  actions (pypa/gh-action-pypi-publish, sigstore). Dependabot will keep
  the pins current.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gaige gaige merged commit 47420fd into main Jun 28, 2026
16 checks passed
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.

1 participant