Repository navigation
Update Pandoc to 3.13 - #15320
Draft
cderv wants to merge 32 commits into
Draft
Update Pandoc to 3.13#15320cderv wants to merge 32 commits into
cderv wants to merge 32 commits into
Conversation
2 of 5 tasks
Collaborator
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Before the root lockfile was pinned, the bundling step ran deno with cwd src/ and no --lock, so builds refreshed an untracked src/deno.lock in developer trees; that stale artifact was swept into the Pandoc 3.13 update commit. All scripted deno invocations now resolve through the pinned root lockfile, so ignore the path like tests/deno.lock to keep stale copies out of future commits.
Pandoc 3.11 removed a stray block after the TOC frame in default.beamer (jgm/pandoc#11819): a duplicate \setcounter{tocdepth} + \tableofcontents outside the frame followed by an unmatched closing brace. Quarto's wired beamer toc partial carried the same lines. LaTeX tolerates the glitch, so rendered output is unchanged; the port keeps the wired template aligned with the 3.13 reference. Adds a smoke test asserting the generated .tex has no \tableofcontents after the TOC frame's \end{frame}.
check.ts hardcodes the expected dependency versions (the configuration file format isn't loadable there; see the FIXME). bf3137d set PANDOC=3.13 but left this constraint at 3.10.0, so strict checking (the default) flagged the bundled Pandoc as a mismatch.
Pandoc 3.13 replaced its custom terms.item show rule with #set terms(hanging-indent: 1.5em), because the typst writer no longer wraps tight definition-list descriptions in #block (jgm/pandoc#11748). Keeping the old rule on 3.13 forced every description onto the line below its term; the set rule restores Typst's native layout where tight items keep the description on the term's line. Also port the /nowrap modifier on template keywords for parity with upstream default.typst. It is a no-op in Quarto's pipeline, which renders templates with wrap: none. The definition-item-no-break smoke test asserted the old two-line layout; it is replaced by definition-lists.qmd asserting the new geometry for tight and loose items.
…iographies Pandoc 3.12.1 feeds CSL hanging-indent and entry-spacing to the typst template as csl-hanging-indent/csl-entry-spacing and applies them via a show rule on the <refs> label the writer puts on citeproc bibliographies (jgm/pandoc#11926). Quarto's modular typst template lacked the rule, so CSL-mandated hanging indents were silently dropped. Port the block into quarto/definitions.typ (must precede $body$ for the show rule to apply).
Pandoc 3.13's typst writer emits #divider() for HorizontalRule. With Typst 0.15 that resolves to std.divider, a full-width 0.55pt line, silently replacing Quarto's centered 25-75% rule. Define divider() as an alias of the existing horizontalrule so documents keep their look; the name horizontalrule stays because notes.typ and external typst templates call it.
Reverts the divider() alias from f67d9f4b7. Quarto's template no longer shadows divider, so Pandoc 3.13's `#divider()` output resolves to the native std.divider element, matching pandoc's default template with typst >= 0.15 (Quarto bundles Typst 0.15.1, so pandoc's polyfill branch is never taken). Rationale: the centered 25-75% line was inherited from pandoc's old definitions.typst (97a1d3d), not a Quarto design decision. Pinning it would diverge from upstream permanently and shadow the native element, which users can restyle with `#show divider:` rules. Horizontal rules in typst output now render full-width instead of centered half-width; the visual change is tracked for the 1.12 changelog.
User-visible consequence of the Pandoc 3.13 bump: `---` rules in typst output switch from the inherited centered half-width line to Typst 0.15's native full-width divider element. The restyle hint (`#show divider: set line(stroke: 2pt)` in a raw typst block) was verified against the bundled Typst 0.15.1 via SVG output.
Matches the #13928 precedent of filing pandoc behavior-change notes as sub-bullets of the dependency update, and creates the 'Update pandoc to 3.13' Dependencies entry the remaining 3.13 release-note lines (yamlet, mathml, weasyprint) will hang off.
…table hook
Pandoc's common.latex loads the caption package and sets
\captionsetup[table]{skip=6pt} under $if(tables)$ (since 3.10.1), and
removes the footnotehyper/footnote \makesavenoteenv{longtable} block
(3.12): the LaTeX writer now generates footnotes in longtable manually
like floating tables (jgm/pandoc#11857), which also resolves the
endfloat incompatibility that motivated Quarto's #14741 test.
Port both changes into the wired pdf and beamer tables.tex partials.
The beamer branch already loaded caption, and crossref's injected
\@ifpackageloaded guard makes the now-unconditional top-level load a
no-op when crossref runs first, so there is no option-clash risk.
Verified: pdf (scrartcl) and beamer docs with crossref tables compile;
smoke-all 14741/14741-knitr, caption-footnotes, issue-4748, 9593,
crossref tables/latex and render-latex-output tests pass.
Bring the wired styles.html (used only with theme: pandoc) in line with the parity parts of Pandoc 3.13's stock styles: the print block drops backgrounds and the hardcoded 12pt font size, links inherit the text color unless linkcolor is set, and hr/tbody/th borders use currentColor. Rendered output is unchanged on screen when no color variables are set. Pandoc's light-dark()/color-scheme support is not ported. Its color-scheme expression emits "light dark" when no variables are set, which would make OS-preference dark mode the default for every theme: pandoc document, while the Quarto CSS loaded on that path (syntax highlighting, quarto-html) is light-only. The quotecolor and quotebordercolor variables come with that feature and stay out with it.
Pandoc 3.13's styles.html places its @media print block before the a, blockquote, code and pre rules. Media queries add no specificity, so the later screen rules win when printing: a linkcolor survives print, blockquotes stay grey, and monobackgroundcolor keeps its background and padding. Moving the block to the end of the document-css section lets the print resets apply as intended. Pandoc's own template has the same ordering; this is a local divergence until it is fixed upstream. Adds a Playwright test that emulates print media on a theme: pandoc document with linkcolor and monobackgroundcolor set.
Pandoc 3.13 writes horizontal rules as #divider(), which Quarto's Typst template now resolves to Typst 0.15's native divider. With an older compiler set through QUARTO_TYPST, such documents failed with a raw "unknown variable: divider" error instead of Quarto's upgrade message. The check only runs when QUARTO_TYPST is set; the bundled Typst is not validated. The >=0.8 floor dates from 2023 and was not raised by any Typst bump since, although bundled packages already need newer compilers (marginalia and showybox declare 0.12, theorion 0.13). quarto check already compares against the bundled 0.15.1.
The previous commit moved the @media print block to the end of the document-css section, as the upstream issue suggested. Pandoc fixed the issue (jgm/pandoc#12064, 1d639e394) by moving it to the very end of styles.html, after the highlighting and citation CSS and outside document-css. Match that placement so the block is identical to upstream and the next Pandoc sync has no divergence to carry. Differences from the previous placement: the print resets now also apply when document-css is off, and they follow the task-list, highlighting and citation rules too.
The comment above the bibliography path workaround cited jgm/pandoc#11511, a closed issue about punctuation directly after a link. The leading-dot escaping that the workaround avoids is tracked in jgm/pandoc#11761, which is still open. Point the comment at #11761 so the next Pandoc bump checks the right issue.
patch.sh and reveal.patch were added in 2022 to rebuild Quarto's template.revealjs from Pandoc's revealjs.template. Later that year the template was renamed to template.html and reworked for partials, but the patch was never updated: the script still writes template.revealjs, the patch only applies with fuzz, and it lacks changes template.html has gained since. Nothing calls it, and template.html has been synced with revealjs.template by hand ever since, as the update-pandoc checklist describes for every format.
Since Pandoc 3.12 (jgm/pandoc#11845) every docx bookmark name starts with `_`, which hides it from screen readers, and an id Word would reject as a bookmark name is replaced by a SHA-1 hash of the id. Quarto crossref ids all contain `-`, so `fig-elephant` no longer appears in word/document.xml. Compute each expected name the way Pandoc does and assert that the bookmark exists and the cross-reference link points at it, so the test still checks each id rather than only that some target exists.
Pandoc 3.10.1 fixed slide splitting in the pptx writer (jgm/pandoc#11433): a slide holding a bullet list, a table, then another bullet list used to be split across several slides and now stays on one "Title and Content" slide. Quarto had no pptx test containing a table, so the change was unpinned. This is a characterization test of the 3.13 output: it passes with Pandoc 3.13 and fails with Pandoc 3.10 (three slides instead of two).
pptx is tested through smoke-all documents with four verifiers whose slide numbering and argument shapes are easy to get wrong: slide 1 is the title slide, text before the first heading adds a slide, and the regex verifier takes its slide number after the regex list. Layout and slide-count assertions also depend on the bundled Pandoc, so they need a re-check on each Pandoc bump. A path-scoped rule points to the guide from the pptx smoke-all directory.
The runtime-boundary check counts direct standard-library imports in tests against a baseline. The docx crossref test imported assert from testing/asserts, pushing the count over it. tests/asserts.ts re-exports the same assert, so the test now uses it and the baseline stays as is.
Pandoc no longer wraps a definition made of a single plain block in #block[...] (changelog, tight term list improvements), so the inner term renders as "/ Inner term: Inner definition." The old regex pinned the #block[ that Pandoc happened to emit. The new one checks what the test is about: the inner list sits inside the outer term's block. Same dev build with Pandoc 3.10 gives the old output, so this is writer drift, and the compiled PDF still shows the nesting.
Pandoc 3.13 writes a code block whose class is not a known language
without a space after the fence ("```text" instead of "``` text"),
from the fix for jgm/pandoc#11987. That is the only difference; the
same dev build with Pandoc 3.10 matches the old snapshot exactly.
Pandoc 3.13 parses YAML with yamlet, and a duplicate key in a mapping is now an error instead of a warning, so this fixture failed the whole render. The duplicate only showed Quarto's reader keeping the last value as Pandoc did; the fixture's purpose, a ---delimited YAML bibliography still producing Scholar citation tags (#15128), does not need it. Pandoc has no option to restore the old behavior, so the changelog tells users how to fix the error.
The delimited fixture used to carry a duplicate title to show that Quarto's own read of the file (json: true in bibliography.ts) keeps the last value, as Pandoc did. Pandoc 3.13 rejects duplicate keys when the render reads the bibliography, so that path is unreachable and the fixture dropped the duplicate. This document keeps the case covered from the user's side: the render fails with an error naming the file, line and column. With Pandoc 3.10 it renders and the test fails. The bibliography.ts comment claimed Pandoc also keeps the last value; it now says Pandoc rejects the duplicate.
Pandoc stopped wrapping a single-paragraph tight definition in #block and replaced the default template's terms show rule with a hanging indent (jgm/pandoc@1d6f33b897), so the definition now renders on the term's line. The Quarto template already follows this, but the visible layout change had no changelog entry.
Pandoc 3.12 prefixes every docx bookmark name with _ and hashes ids holding characters other than letters, digits and _, so every Quarto crossref id becomes a hashed, hidden bookmark. Internal crossref links keep working; references by id from outside the document do not. Decided 2026-11-10: accept the upstream change rather than rename bookmarks in a docx post-processing step.
Earlier changelogs never bold package names.
cderv
force-pushed
the
chore/deps-v1.12-pandoc
branch
from
November 10, 2026 16:40
e3b1aa1 to
0a3b147
Compare
5 tasks
cderv
added a commit
that referenced
this pull request
Nov 10, 2026
* Add triage-ci-failures skill for red PR checks A dependency bump like Pandoc 3.13 turns a PR red across dozens of bucket x OS jobs, each log several hundred KB. Check-run annotations only name the bucket, and `gh run view --log` silently truncates near 750 KB, so finding which tests failed meant pulling raw logs into context. The script takes a PR number (every failing run on the head commit) or a run id, caches failed-job logs per job id via the jobs/ID/logs endpoint, and prints one row per unique failing test with the OSes it failed on and the verify message. When verify hits a missing output file, the row shows the render error from the OUTPUT tail instead. `##[error]` lines are reported only for jobs with no failing test, since smoke jobs echo each failed bucket there. Jobs whose log shape is not parsed (Playwright, ff-matrix are unverified) are listed with their log path. The skill then has the agent group rows by cause and classify each as dependency output drift or a regression before touching assertions or snapshots. On PR #15320 it reports the 18 failing tests plus the runtime-boundary error in about 6 KB. * Keep diagnostics for more test failure shapes in ci-failures.sh - Capture the assertion message up to the stack trace (max 6 lines). noErrors and noErrorsOrWarnings put the actual errors after a generic first line, which the digest dropped. - Treat "No output created message" and "Path ... doesn't exist" as a failed render, like an OS NotFound, and show the OUTPUT tail. - A FAILED test with no TEST FAILURE block (prereq or teardown-only failure, which test.ts rethrows undecorated) now names the log to grep instead of printing an empty row. - Download logs to a .part file and rename on success, so a failed fetch is retried next run instead of being cached truncated. The PR #15320 digest is unchanged. The new shapes were checked on a log written in the test.ts failure format. * Keep assertion messages across blank lines in ci-failures.sh A Sass failure reaches noErrorsOrWarnings as "Theme file compilation failed:\n\n<diagnostics>" (src/core/dart-sass.ts), and the diagnostics start with "Error:". Stopping the message at a blank line, or at any "Error:" line, dropped the compiler error. The message now ends at the stack trace, recognised as "at" frames or as "<ErrorName>: <first message line>", the line JS stacks begin with. Blank lines are skipped. XPath and layout verifiers append the whole document after "... follows:", so capture ends at that line; the blank line had been doing that job before. The PR #15320 digest only gains the "Path:" line of the NotFound message. * Read the OS label from suffixed smoke job names in ci-failures.sh test-smokes.yml names jobs "Run smoke (<os>)" plus an optional " with timed file" or " - with some extra R packages". Requiring the parenthesis at the end of the name made those rows show the full job name instead of the OS. * Keep CI digest excerpts traceable across OSes A merged test row can contain failures with different causes. Identify the representative excerpt's OS and job and list all contributing logs so those differences can be checked before grouping failures by cause. Clarify that missing output and failures limited to one OS require investigation before assigning a cause. Verified on PR #15320: 18 unique failing tests and the runtime-boundary error, with the render diagnostics preserved in an 8.5 KB digest. Shell syntax and diff checks pass.
Pandoc 3.12+ writes crossref bookmarks under hashed hidden names (jgm/pandoc#11845), in both w:bookmarkStart/@w:name and w:hyperlink/@w:anchor, so smoke-all docx checks naming the raw crossref id returned nothing and failed. ensureDocxXpath and ensureDocxRegexMatches now replace a {{bookmark:<id>}} placeholder with the name Pandoc computes for that id, using the toBookmarkName port moved from smoke/crossref/docx.test.ts into verify.ts. The docs keep readable ids rather than hardcoded hashes that would break on the next naming change. The placeholder cannot collide with shortcodes ({{< >}}), and the expanded name is hex plus an underscore, so it needs no regex escaping.
… ids The ref-hyperlink: false check targeted tbl-foo with link text "Table 1", but this document defines tbl-letters and fig-elephant and sets tbl-prefix to "T.", so it could never match, even after the bookmark placeholder expansion. Assert that no hyperlink anchors either id's bookmark, without a text predicate. Checked by rendering a copy with ref-hyperlink: true: the check now fails on the tbl-letters hyperlink.
The only document.xml differences are writer drift: Pandoc 3.12+ writes the heading bookmark under a hashed hidden name inside the heading paragraph (jgm/pandoc#11845), and drawing/relationship ids are renumbered. The callout content is unchanged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Update the bundled Pandoc from 3.10 to 3.13.
The Pandoc 3.11 to 3.13 changelogs were reviewed for changes reaching Quarto, and each one was checked by rendering with 3.10 and 3.13. Quarto's customized Pandoc templates (HTML styles, LaTeX/Beamer, Typst, revealjs) are synced with upstream.
Template ports
divider(typst: read and writedividerelement for horizontal rules jgm/pandoc#11540), so they are now full-width. A Typst binary set throughQUARTO_TYPSTmust be 0.15 or later. Also ported: thecsl-settingsblock for citeproc bibliographies, and the definition list hanging indent (tight items keep the description on the term line again).footnotehyperlongtable hook removed, and the duplicate TOC fix in the Beamertocpartial.theme: pandoc: the print rework,currentColorborders and links inheriting the text color from Pandoc'sstyles.html. Pandoc 3.13 places the@media printblock before the base rules, so links, blockquotes and code keep their screen styles when printing (HTML default styles:@media printresets for links, blockquotes and code are overridden by later rules jgm/pandoc#12064). The block is moved to the end ofstyles.html, where Pandoc put it when fixing this after 3.13, with a Playwright test.Pandoc 3.13 also adds automatic dark mode to its
styles.html(jgm/pandoc#11831). This is not enabled fortheme: pandoc: the page stays light when the OS prefers dark, and the newfontcolordark,backgroundcolordark,linkcolordark,quotecolor,quotebordercolorvariables (and their*darkvariants) have no effect. Upstream turns dark mode on by default with no variable set, while Quarto's code highlighting and component CSS ontheme: pandocpages are light only, so a straight port would give unreadable code blocks. Supporting it is left for a follow-up.Other user-visible changes from Pandoc
No Quarto change for these, they will be listed in the release notes:
minimal: true,theme: noneortheme: pandoc, math now renders as MathML instead of italic text. Bootstrap HTML is unchanged (MathJax).de Gaullesorts under "d".yes/nobecome strings, as they already were for Quarto in the first block.typst-labelis honored, and spans withlangget#text(lang:).Stacked on this one: #15321 adds support for Pandoc's
--math-methodinquarto render. A second stacked PR will follow for heading ids that change when a Div with an id wraps a heading with--section-divs(TOC links and anchors), related to jgm/pandoc#12070. The full test suite run on CI is still to triage, and the release notes are still to write.Checklist
I have (if applicable):
AI-assisted PR
Note: autonomous AI agents submitting PRs without human oversight are not permitted — see the Code of Conduct.