CommonMark conformance

Panache’s parser is shared across all flavors (Pandoc, Quarto, RMarkdown, GFM, CommonMark, MultiMarkdown). Each flavor selects a baseline set of extensions through Extensions::for_flavor(). Under Flavor::CommonMark, almost every Pandoc-specific extension is disabled, leaving only constructs that appear in the CommonMark specification.

Conformance to the spec is tracked by running every example in spec.txt through the parser and comparing the rendered HTML against the expected HTML from the spec.

Harness layout

Path Purpose
crates/panache-parser/tests/fixtures/commonmark-spec/spec.txt Vendored CommonMark spec.
crates/panache-parser/tests/commonmark.rs Test runner (commonmark_allowlist, commonmark_full_report).
crates/panache-parser/tests/commonmark/spec_parser.rs Parses spec.txt into example records.
crates/panache-parser/tests/commonmark/html_renderer.rs Test-only CST → HTML renderer (not a public API).
crates/panache-parser/tests/commonmark/allowlist.txt Example numbers currently passing. CI fails on regression.
crates/panache-parser/tests/commonmark/blocked.txt Examples we deliberately do not target yet, with reasons.

The renderer mirrors the byte-equality comparison commonmark-hs uses: the output is normalized via <li>\n<li> and \n</li></li> before comparison.

Baseline

The table and headline above are regenerated from docs/development/commonmark-report.json, which is written by the harness when you run commonmark_full_report. To refresh the page, run that test and re-render the docs.

Workflow

Updating the spec fixture

task update-commonmark-fixtures
# or specify a different ref
./crates/panache-parser/scripts/update-commonmark-spec-fixtures.sh 0.31.2

This clones commonmark/commonmark-spec at the given tag, copies spec.txt into tests/fixtures/commonmark-spec/, and writes a .panache-source record of the upstream commit.

Running the harness

# Regression guard: every allowlisted example must still pass.
cargo test -p panache-parser --test commonmark commonmark_allowlist

# Full report: writes tests/commonmark/report.txt with per-section
# counts and a list of every passing example number. Use this output
# to grow the allowlist after fixing parser/renderer bugs.
cargo test -p panache-parser --test commonmark commonmark_full_report \
    -- --ignored --nocapture

Growing the allowlist

  1. Fix a parser or renderer bug (with a focused test reproducing the bug).
  2. Run commonmark_full_report and inspect report.txt.
  3. Add the newly-passing example numbers to allowlist.txt, ideally grouped under their section header for readability.
  4. Run commonmark_allowlist to confirm the additions pass.

If an example is intentionally not targeted (e.g. a construct we choose not to support under Flavor::CommonMark), add the number to blocked.txt with a comment explaining the reason.

Why an HTML renderer?

The CommonMark spec defines conformance as markdown-input → HTML-output byte-equality. Panache’s primary output is formatted markdown, not HTML, so the conformance harness needs a renderer to bridge the gap. The renderer in tests/commonmark/html_renderer.rs is test code only — it is not part of the public crate surface, and it covers only the constructs spec.txt exercises. If a public --to html mode is wanted later, the renderer can graduate from test-only to a real module; until then it intentionally stays narrow.