Preserve crossref divs nested in layout-ncol#234
Merged
Conversation
Quarto cross-references like `@tbl-foo` failed to resolve when the
target div was nested inside a `layout-ncol` block. Two reasons:
1. The layout filter ran at the default (post-quarto) stage, so
Quarto's PanelLayout filter had already consumed the `layout-ncol`
Div before our filter could transform it — the inner crossref Div
was stripped along the way.
2. Even running earlier, `collect_cells` unwrapped *any* Div via
`cells:insert(el.content)`. Quarto's preprocessor turns crossref
divs into custom-AST nodes that look like Divs but carry
`__quarto_custom_type="FloatRefTarget"` markers; unwrapping
destroyed those markers, and the crossref resolver could no longer
find the target.
Fixes:
- `_extension.yml`: register the filter at `pre-quarto` so it
transforms the layout div before Quarto's PanelLayout filter sees it.
- `layout.lua`: only unwrap *bare* Divs (no id, no classes, no
attributes). Divs that carry identity — including FloatRefTarget
custom-AST nodes — are kept whole so the crossref resolver can
still find them.
Also: in 2024-01-24-1.4-release, replace the raw-HTML `@tbl-table`
workaround with a real `::: {#tbl-table}` crossref div, fix the
image path, and convert the second hard-coded link to `@tbl-table`.
Closes #186
✅ Deploy Preview for posit-open-source canceled.
|
Publishing checklist
|
Blog YAML Checks✅ All 1 posts passed. |
Preview linksBlog listing: https://69fd0d26bafbf98566a541d6--posit-open-source.netlify.app/blog/ |
The filter changes in the prior commit fix a real bug — Quarto crossref divs nested inside `layout-ncol` no longer have their FloatRefTarget markers destroyed, so `@tbl-foo` references resolve correctly. But on hugo-md the *target* of a crossref div containing an image still renders as a flat `<img id="..." alt="Label N: caption">` with no visible caption — the caption is baked into the alt text. That's a hugo-md writer limitation, separate from the layout/filter issue, and applies equally to bare crossref divs outside any layout wrapper. So the layout filter fix stands as a real improvement, but it doesn't get this specific post to a better-looking state than the prior raw-HTML workaround. Restore the workaround until we decide how to address the caption issue more broadly.
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.
Summary
pre-quartoso it transformslayout-ncoldivs before Quarto's PanelLayout filter consumes them.collect_cells, only unwrap bare wrapper Divs (no id, no classes, no attributes). Crossref/float divs that the Quarto preprocessor has converted into custom-AST nodes (carrying__quarto_custom_type="FloatRefTarget"markers) are now kept whole so the crossref resolver can still find them.Scope
This PR fixes a real bug:
@tbl-foo/@fig-fooreferences whose target div sits insidelayout-ncolused to render as?@tbl-foo(Quarto's "unresolved" marker) because ourcollect_cellswas destroying the FloatRefTarget marker on the inner Div before the crossref resolver could see it. After this PR, references resolve correctly and the target gets a workingid="..."anchor.It does not close #186. That issue is broader: Quarto's
hugo-mdwriter also flattens crossref targets (image-as-figure, image-as-table) into a bare<img id="..." alt="Label N: caption">block — the caption is baked into thealtattribute and never rendered as a visible<figcaption>. That's a hugo-md writer limitation, independent of layout, and applies equally to bare crossref divs at the top level. We'll address it in a follow-up (likely a small post-processing Lua filter that wraps these flat<img>blocks as proper<figure>+<figcaption>HTML).Test plan
layout-ncolposts (2023-04-26-1.3-release,2024-10-15-conf-workshops-materials,2025-07-24-parameterized-reports-python) —.mdoutputs are byte-identical to before, no regressions.tbl-crossref div nested insidelayout-ncolnow resolves through to a working anchor (used to emit?@tbl-foo).layout-ncol.