Run 2026-10-04 · pandoc 3.11
One dated reading of the grid: which pandoc
produced these numbers, what moved since the baseline, and how much of the movement
a reader would actually notice. Every figure is read from results/;
nothing on this page is typed by hand.
Deltas
A cell moved when its verdict changed between two runs. The direction is not a
matter of taste: every lane declares an order over its verdicts in
src/verdicts.py, and a cell that drops rank is a regression. Thresholds
live in thresholds.json and the exit code of make delta is
the gate, so a regression stops a build rather than scrolling past in a diffstat.
pandoc 3.11 of 2026-10-04T10:56:21Z against pandoc 3.11 of 2026-09-30T22:08:13Z, profile pin.
Every cell held its verdict.
Severity
Counting probes treats a dropped footnote body and a dropped column width as one
event each. They are not. Each probe is classified by what is missing from the page
when it does not survive: content means text or a referent
is gone with nothing left saying so, structure means every
character survived but the document's shape did not, and
presentation means styling or a measurement is gone
while the words and the shape are intact. The rubric, and the calls that are arguable,
are in src/severity.py.
The weighted score below forgives the canonical verdict, because the question it asks is whether the content came home, not whether the writer restyled it on the way. The three per-class columns are the point: two formats reach the same percentage by losing very different things.
| format | expressed/66 | round‑trip/66 | exact/66 | canon./66 | meta/10 | semantic | content/12 | structure/27 | presentation/27 |
|---|---|---|---|---|---|---|---|---|---|
| native | - | ||||||||
| markdown | |||||||||
| html | |||||||||
| commonmark_x | |||||||||
| muse | |||||||||
| epub | |||||||||
| rst | |||||||||
| djot | - | ||||||||
| latex | |||||||||
| markdown_mmd | |||||||||
| docx | |||||||||
| mediawiki | |||||||||
| docbook | |||||||||
| gfm | |||||||||
| odt | |||||||||
| markdown_github | |||||||||
| markdown_phpextra | |||||||||
| org | |||||||||
| textile | |||||||||
| asciidoc | - | ||||||||
| ipynb | |||||||||
| typst | - | - | |||||||
| dokuwiki | |||||||||
| jats | - | ||||||||
| commonmark | - | ||||||||
| man | |||||||||
| markdown_strict | - | ||||||||
| jira | |||||||||
| rtf | |||||||||
| fb2 | - | ||||||||
| haddock | |||||||||
| t2t | - | ||||||||
| pptx | |||||||||
| opml | - |
Carve
Every lane above starts from a pandoc AST, which answers how much of a pandoc document a format can hold. It cannot answer the question a Carve author has, because the pandoc AST has no node for an admonition, a task list, a highlight or an editorial mark, so those never appear in the probe set at all.
This lane starts from Carve instead: 42 source files, one construct each,
written out through the
pandoc-carve bridge and read
straight back, and again through each of 13 export formats. exact is character for character,
equivalent is a formatter restyling, respelled means the source is
spelled differently and renders identically (a [^1] reference footnote
coming back as an inline one), and lossy means a reader would see the
difference. The three left-hand verdicts preserve rendered content; source-only
information such as comments can still be lost and reported in warnings.
42 Carve fixtures · renderer @markup-carve/carve 0.1.9 (revision 04845b7fc316) · pandoc 3.11 · bridge revision c3d85783623c
| conversion path | exact | equivalent | respelled | lossy | unparsable | err | came back readable/42 |
|---|---|---|---|---|---|---|---|
| bridge | - | - | |||||
| bridge-preserve | - | - | |||||
| markdown | - | - | - | ||||
| gfm | - | - | - | ||||
| commonmark_x | - | - | - | ||||
| djot | - | - | - | ||||
| html | - | - | - | ||||
| latex | - | - | |||||
| typst | - | - | |||||
| docx | - | - | |||||
| odt | - | - | - | ||||
| rst | - | - | - | ||||
| org | - | - | - | ||||
| jats | - | - | |||||
| epub | - | - | - |
These verdicts compare rendered content. A dropped comment can count as respelled because it renders to nothing; warnings record that source loss. Each format row covers writing, reading, bridge conversion, and Carve source serialization. An error may occur at any of those steps; the failure details identify the step.
bridge-preserve enables roundtrip: true metadata on the direct bridge path. Export-format rows use the default bridge options.
Table-span and table-rowspan test continuation cells; table-ragged tests a short row that Pandoc pads with an empty cell.
Preservation-mode warnings: table-ragged.
Carve round-trip measurement: 2026-09-30T22:12:39Z; bridge revision c3d85783623c2498370941e09d757b68b34fb839.
The default bridge lane changes 7 of them: comment (respelled), footnote (respelled), frontmatter (equivalent), ordered-list (respelled), quote-container (respelled), table-align (respelled), table-ragged (lossy).
jats/raw-html: pandoc export/import: Command failed: pandoc -f jats -t json
Invalid XML:
Missing root element
latex/table-span: pandocToCarve: renderCarve cannot spell table_row: a table row whose every cell is blank has no Carve source spellingtypst/heading: pandoc export/import: Command failed: pandoc -f typst -t json
(line 1, column 1):
unexpected Elt {eltName = Identifier "heading", eltPos = Just (line 1, column 1), eltFields = fromList [(Identifier "body",VContent (fromList [Elt {eltName = Identifier "document", eltPos = Just (line 1, column 1), eltFields = fromList [(Identifier "body",VContent (fromList [Elt {eltName = Identifier "text", eltPos = Just (line 1, column 1), eltFields = fromList [(Identifier "body",VContent (fromList [Txt "A second-level heading"]))]}])),(Identifier "level",VInteger 2)]}]))]}
typst/table: pandocToCarve: Cannot read properties of undefined (reading 'flatMap')typst/table-align: pandocToCarve: Cannot read properties of undefined (reading 'flatMap')typst/table-ragged: pandocToCarve: Cannot read properties of undefined (reading 'flatMap')typst/table-rowspan: pandocToCarve: Cannot read properties of undefined (reading 'flatMap')typst/table-span: pandocToCarve: Cannot read properties of undefined (reading 'flatMap')The bridge says out loud what it dropped on comment, table-ragged.
History
One line per recorded run, appended by src/delta.py --record. Medians
rather than means: a handful of formats cannot be measured on a runner without a TeX
engine, and a mean would report the machine instead of pandoc.
| date | pandoc | expressed | exact | meta | semantic | regressions | status |
|---|---|---|---|---|---|---|---|
| 2026-09-30T22:08:13Z | 3.11 | 47.5 | 22.0 | 2.0 | 37.6 | 0 | ok |
| 2026-09-30T00:53:45Z | 3.11 | 47.5 | 22.0 | 2.0 | 37.6 | 0 | ok |
| 2026-09-30T00:53:45Z | 3.11 | 47.5 | 22.0 | 2.0 | 37.6 | 0 | ok |
| 2026-09-08T22:04:55Z | 3.11 | 47.5 | 22.0 | 2.0 | 37.6 | 0 | ok |
| 2026-09-07T12:16:16Z | 3.10.2 | 47.0 | 22.0 | 2.0 | 37.6 | 0 | ok |
Gate
Two profiles, because the two comparisons are not the same question. Against the pinned pandoc nothing may move without someone deciding it should. Against pandoc's nightly, upstream restyles writers routinely, so presentation-class movement is expected and content-class movement is not.
| profile | max regressions | per lane | per class | max weight | what it is for |
|---|---|---|---|---|---|
| pin | 0 | - | - | 0 | the repo's own results against the pinned pandoc: nothing may move without a human deciding it should |
| nightly | 12 | exact 12, matrix 6, meta 2, roundtrip 6 | content 0, structure 4 | 24 | the watch on pandoc's nightly build: upstream restyles writers all the time, so presentation may move; content may not |
exempt: pdf on the matrix lane - the pdf writer needs an external TeX engine, so this row measures whether the runner has one