Skip to content

Keep heading id on sections Pandoc 3.13 merges with a wrapper div - #15344

Merged
cderv merged 2 commits into
mainfrom
fix/pandoc-3.13-section-ids
Nov 12, 2026
Merged

cderv merged 2 commits into
mainfrom
fix/pandoc-3.13-section-ids

Conversation

@cderv

@cderv cderv commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Pandoc 3.10.1 and later (jgm/pandoc#11745) merge a Div with an id that starts with a heading into a single section. The section takes the Div's id and the heading keeps its own. Quarto's crossrefs still target the heading id, so ids start to disagree once the bundled Pandoc moves to 3.13 (#15320).

For ::: {#sec-other} wrapping ## Second {#sec-second} in HTML:

  • the TOC link and the anchor link (data-anchor-id) point at #sec-other, while @sec-second points at #sec-second
  • website search results use #sec-other too

Other formats are worse. Revealjs strips the slide heading id, and beamer, DocBook, ConTeXt and AsciiDoc no longer write the heading id at all (jgm/pandoc#12070), so a crossref to such a heading has no target.

Fix

A finalize filter (quarto-finalize/section-ids.lua) swaps the two ids exactly where Pandoc merges. The section keeps the heading id, so TOC, anchors, search and crossrefs agree again, and the wrapper id stays addressable on the heading. The wrapper's classes stay on the section, which is the 3.13 behavior.

The condition follows Pandoc's own makeSections walk: Div nesting only, with sections split by a later heading of the same or higher level. It runs for HTML, EPUB, revealjs, beamer, DocBook, ConTeXt and AsciiDoc. LaTeX, Typst and docx already write both ids, and a swap there would move the crossref label off the heading. Divs with class cell, column, columns or fragment are left alone. An explicit .section wrapper in HTML keeps Pandoc's new result, since that is the case upstream merges on purpose.

Alternative considered: accept Pandoc's ids and align Quarto to the wrapper id. That touches the anchor postprocessor, TOC links, the search index and the xref preview script, and still ends with different ids on the section than in 3.10.

Dashboards are unaffected by the filter. A characterization test pins that wrapped rows and cards are not nested inside other cards on 3.13.

Third layer of a stack: #15320 (Pandoc 3.13 bump) <- #15321 <- this PR. The new changelog line sits under the pandoc 3.13 entry from #15320.

Checklist

I have (if applicable):

  • referenced the GitHub issue this PR closes
  • updated the appropriate changelog in the PR
  • ensured the present test suite passes
  • added new tests
  • created a separate documentation PR in Quarto's website repo and linked it to this PR
AI-assisted PR
  • AI tool used: Claude Code
  • Codebase grounding: local clone
  • Human review: I have reviewed, tested, and verified the AI-generated content before submitting.

Note: autonomous AI agents submitting PRs without human oversight are not permitted — see the Code of Conduct.

@cderv
cderv added this pull request to stack #15322 November 12, 2026 11:12
@posit-snyk-bot

posit-snyk-bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Collaborator

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cderv cderv changed the title fix/pandoc 3.13 section ids Keep heading id on sections Pandoc 3.13 merges with a wrapper div Nov 12, 2026
@cderv
cderv force-pushed the fix/pandoc-3.13-section-ids branch from a8148ee to 80d021c Compare November 12, 2026 11:49
@cderv
cderv marked this pull request as ready for review November 12, 2026 14:06
@cderv
cderv force-pushed the fix/pandoc-3.13-section-ids branch from 80d021c to ab48d75 Compare November 12, 2026 17:00
Base automatically changed from fix/html-math-method to main November 12, 2026 17:03
…r div

Pandoc 3.10.1+ merges a Div with an id that starts with a heading into
the heading's section and gives the section the Div's id (jgm/pandoc#11745).
In HTML the TOC, anchor links, search and the crossref preview then use
the wrapper id while crossrefs use the heading id. Beamer, DocBook,
ConTeXt and AsciiDoc drop the heading id entirely (jgm/pandoc#12070), and
revealjs strips slide heading ids, so crossrefs to such headings dangle.

A finalize filter swaps the two ids exactly where Pandoc merges, keeping
the single section and its classes. It follows makeSections' own walk
(Div nesting only, sections split by nested headings) and runs only for
the formats where the merge changes ids: LaTeX, Typst and docx already
write both ids, and a swap there moves the crossref label off the heading.
@cderv
cderv force-pushed the fix/pandoc-3.13-section-ids branch from ab48d75 to 2849f97 Compare November 12, 2026 17:03
@cderv
cderv merged commit e92eb44 into main Nov 12, 2026
10 of 52 checks passed
@cderv
cderv deleted the fix/pandoc-3.13-section-ids branch November 12, 2026 17:04
cderv added a commit that referenced this pull request Nov 12, 2026
Regroup the Pandoc 3.13 entries in the 1.12 changelog the way earlier
Pandoc updates were recorded (see news/changelog-1.9.md). The update
line under Dependencies now lists only the Pandoc changes that alter
existing documents with no Quarto change. Quarto's own template and
style ports move under the format they affect, the section id change
goes under All Formats, and --math-method support goes under Commands.

See #15320, #15321 and #15344, which added the entries.
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.

2 participants