Remove the caption-as-alt fallback introduced in the PDF/UA compliance
work (a867c3c, ba75b37). Using captions as alt text is an
accessibility anti-pattern — captions describe a figure's significance
in context while alt text describes what the image looks like.
LaTeX: remove 3 caption-as-alt blocks in latex.lua, and add fig-alt to
alt conversion in pandoc3_figure.lua for Pandoc 3 Figures without
cross-ref labels.
Typst: mark figure images with _quarto_no_caption_alt so that the
caption-as-alt fallback in typst.lua only fires for inline images
(where image.caption IS the standard markdown alt text).
Key insight: In Pandoc 3, {alt="text"} replaces the Image's caption
content rather than populating image.attributes["alt"]. So
image.caption serves double duty as both visible caption and alt text
override. We distinguish the two cases by comparing image.caption to
figure.caption — when they match, the caption was NOT overridden (the
bug case we suppress); when they differ, an explicit {alt="..."} was
provided (which we preserve). This is the same heuristic Pandoc's own
Markdown writer uses when round-tripping Figures.
Explicit fig-alt (Quarto's dedicated attribute) flows through a
completely separate path and always works unambiguously.
Fixes #14107
Summary
Removes the anti-pattern where figure captions are copied into image alt text for PDF/UA compliance. Captions describe a figure's significance in context; alt text describes what the image looks like. Using one as the other is an accessibility anti-pattern that merely silences validators without helping screen reader users.
This was introduced in the Jan 2026 PDF/UA work (commits
a867c3c24andba75b374f) to satisfy PDF/UA validators, which require every<Figure>structure element to have an/Altstring.Fixes #14107
What changed
LaTeX (
latex.lua): Removed 3 caption-as-alt blocks that copiedimage.captionintoimage.attributes["alt"]before clearing the caption for separate rendering.Typst (
pandoc3_figure.lua,floatreftarget.lua,typst.lua): Used a marker attribute (_quarto_no_caption_alt) to prevent the caption-as-alt fallback for figure images, while preserving it for inline images whereimage.captionIS the standard markdown alt text (in running text).The distinction matters because of how Pandoc 3 represents alt text in its AST.
Pandoc 3 AST analysis
In Pandoc 3,
{alt="text"}on an image does not setimage.attributes["alt"]— it replacesimage.captionwith the alt value. The![visible caption]text moves tofigure.caption.long, whileimage.captionbecomes the alt text. This meansimage.captionserves double duty:image.captionIS the alt text (the![...]content is alt by the HTML spec)image.captionis a copy of the visible caption (unless overridden by{alt="..."})To distinguish these cases, we compare
image.captionto the figure's visible caption (figure.caption.longorfloat.caption_long). If they match, no explicit alt was provided — we set_quarto_no_caption_altto suppress the fallback. If they differ,{alt="..."}was used andimage.captionIS the explicit alt text.This is the same heuristic Pandoc's own Markdown writer uses (confirmed via Pandoc source — it compares image alt to figure caption to decide whether to emit
{alt="..."}). Pandoc itself acknowledges the ambiguity: the AST cannot distinguish "caption that happens to match alt" from "no explicit alt provided." The recommended workaround is Quarto'sfig-altattribute, which flows through a separate, unambiguous path.How
fig-altvsaltwork{alt="text"}: Pandoc replacesimage.caption, no separate attribute. Works but ambiguous when caption and alt are intentionally identical.{fig-alt="text"}: Quarto stores asimage.attributes["fig-alt"], propagated explicitly to\includegraphics[alt=...](LaTeX) orimage(alt: "...")(Typst). Always unambiguous. This is the recommended approach.Test plan
caption-not-alt-ua.qmd— verifies caption is NOT copied to\includegraphics[alt=]and that Quarto warns about missing alt texttypst-image-alt-text.qmd— TC1 moved to must-not-match; TC8 added forfig-altua-image-alt-text.qmd— now uses explicitfig-alt