Number a Carve composite figure as one unit - #4
Closed
dereuromark wants to merge 4 commits into
Closed
Conversation
A bare `::: figure` container is one figure of ordered panels (Carve PART 9
section 4c): the group is one numbering unit and only the group produces a
list-of-figures entry. Two of the three layers that have to know about it now
do.
pandoc-carve maps `figure_group` to a Pandoc `Figure` whose direct `Figure` and
`Table` children are the panels, and its lockfile pins a carve-js commit that
carries the node, so the shape reaches this adapter. Measured on
examples/composite-figure.crv:
```
Figure id="fig-mixed" cls=["columns-2"]
Table
Figure
CodeBlock
```
Resilient's pandocast renderer turns every one of those into its own captioned
float. Left alone the two panels each take a figure number and file a
list-of-figures entry, the group is numbered 3, and the caption Carve already
resolved still reads "Figure 1:". The two numbering schemes disagree.
carve/figuregroup.lua walks the parsed tree and marks the direct captioned
children of a captioned figure `unnumbered` and `notoc`. Resilient's
`markdown:internal:captioned-figure` and `markdown:internal:captioned-table`
commands already read both classes, so nothing new has to be taught to the
renderer. Doing this on the SILE AST rather than on the Pandoc JSON is
deliberate: `Renderer:Table` discards the Pandoc attributes of a table
outright, so a class put on a table panel earlier would never arrive.
Only direct children are panels. A captioned figure sitting inside group
content, in a `::: note` or in the generic div a nested bare `::: figure`
degrades to, keeps its own number, which is what corpus documents
318-composite-figures-9 and -11 pin.
The Dockerfile pinned pandoc-carve at 60e219a, which predates that mapping, so
the container test could not have exercised a group at all. It now pins
af285cc.
What this does NOT do: place the group as a float, or act on the `columns-N`
hint. Resilient's captioned elements are not floats and nothing below this
adapter turns a `columns-N` class into a column arrangement, so panels stack in
the text flow. Writing that here would mean owning a renderer. The README says
so in place.
A table panel files its entry in the list of TABLES, at toclevel 6, not in the list of figures. Counting level-5 entries therefore said nothing about it: the example passed the check whether or not the captioned-table branch of carve/figuregroup.lua did anything. Assert that the example files no list-of-tables entry either. Without the suppression the run files one, and the panel takes table number 1.
Only the direct figure and table children of a bare `::: figure` container are its panels. A captioned figure inside group content, in a `::: note` or in the generic div a nested bare `::: figure` degrades to, is not a panel and keeps a number of its own, which corpus documents 318-composite-figures-9 and -11 pin. Nothing here tested that. Rewriting carve/figuregroup.lua to mark every captioned DESCENDANT of a captioned figure rather than its direct children left both the unit test and the end-to-end run green, because the only figure the first example nests inside a container is a sibling of the group, not part of it. The rule the module is built on was free to be wrong. examples/composite-figure-nested.crv puts a captioned listing inside a `::: note` inside a group, which pandoc-carve maps to a Figure holding a Div holding a Figure. test/toccheck.lua grows a mode for it: two list-of-figures entries, one for the group and one for the listing. Under the descendant rewrite the listing is suppressed and only one entry is left. The check asserts no numbers, deliberately. Resilient numbers every captioned figure, Carve numbers only the captions carrying a placeholder, so the two counters agree only in a document where every caption carries one, and this example is not that document.
The nested example is now part of the test run, and the reason its check asserts entries rather than numbers is a property of the pipeline worth stating where a reader will look for it: Resilient numbers every captioned figure it typesets, Carve numbers only the captions carrying a placeholder, so the two counters agree only in a document where every caption carries one.
Contributor
Author
|
Superseded: PR #1 replaced the pandoc-carve pipeline with the native exchange-AST renderer this branch predates, and #5 landed composite figures on that renderer (one numbered unit, panels as unnumbered captioned children, engine pin bumped). The numbering insight from this branch's figuregroup transform is covered by #5's direct-children discrimination test. |
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.
This is a draft and is not meant to be merged yet. It lands ahead of the
dependency that would complete it, so it is staged and visible rather than
merged. Please do not mark it ready or merge it without the decision below.
Closes nothing. #2 stays open.
Where the three gates stand
#2 and the docs section this replaces named three layers that had to move
before anything here could be real. Two of them have.
An engine carrying
figure_group- cleared, through a git pin. Thenewest published build of the carve-js engine on npm is
0.1.3and doesnot have the node, but pandoc-carve's lockfile no longer resolves a
published version: it pins a carve-js commit that does. Parsing
tests/corpus/318-composite-figures.crvthrough that pin yields afigure_groupnode with twofigurechildren.A pandoc-carve mapping - cleared. Map figure_group to pandoc's subfigure model, both directions pandoc-carve#70 maps
figure_groupin both directions. A bare::: figureopener becomes aPandoc
Figurewhose directFigureandTablechildren are the panelsand whose other content stays in place. An opener carrying a quoted title
stays a
Div. Measured on this PR'sexamples/composite-figure.crv:Crossrefs come through the same way.
See </#fig-x> and </#fig-x-a>.arrives as two links already reading
Figure 1andFigure 1a, resolvedupstream, with no adapter code involved.
Resilient placing the group as a float - still open, and partly
unreachable.
classes/resilient/book.luasays of its captioned elements,in a comment above them, that despite the similar naming to LaTeX these are
not floats. There is no float mechanism in resilient 4.2.0 to place a
composite figure into, and nothing below this adapter turns a
columns-Nclass into a column arrangement. What resilient does have is numbering, and
that half is reachable.
What this lands
carve/figuregroup.luamakes a composite figure one numbering unit, which iswhat Carve PART 9 section 4c asks for and what the paged-output contract in
#2 lists as one line item: one list-of-figures entry per group.
Resilient's
pandocastrenders every nestedFigureandTableas its owncaptioned float. Left alone, the two-panel example gives its listing panel a
figure number and a list-of-figures entry of its own, gives its table panel a
table number and a list-of-tables entry, and leaves the group numbered
Figure 2while the caption Carve already resolved still readsFigure 1:. The module walks the parsed tree and marks the directcaptioned children of a captioned figure
unnumberedandnotoc, two classesmarkdown:internal:captioned-figureandmarkdown:internal:captioned-tablealready read. The group then takes exactly one number, that number agrees with
the one Carve wrote into the caption, and the list of figures gains one entry
per group.
Two details are worth flagging for review:
deliberate.
Renderer:Tableinpandocastdiscards a table's Pandocattributes outright (
function Renderer:Table (_, caption, ...)), so a classput on a table panel any earlier would never arrive.
a
::: noteor in the generic div a nested bare::: figuredegrades to,keeps its own number. That is what corpus documents
318-composite-figures-9and-11pin.Dockerfilepinned pandoc-carve at60e219a, which predates the mapping inmarkup-carve/pandoc-carve#70. The container could not have exercised a group at
all. It now pins
af285cc.What this deliberately does not do
into. A composite figure sits in the text flow where it was written, which is
the degradation floor Render composite figures as grouped floats #2 names: vertical stack in source order.
columns-N. The class arrives on the group and no layerbelow acts on it. Making two panels sit side by side means emitting layout
commands, which means this adapter owning a renderer, and it deliberately
does not. Left as it is rather than written against a shape nothing produces.
before the text reaches SILE and Resilient prepends its own
Figure N., so acaption written
^ Figure #: ...renders its label twice. That is notspecific to composite figures. A single captioned image does the same, and
fixing it is a separate decision about which layer owns figure numbers.
What the tests pin, and what they do not
test/figuregroup.luais a pure-Lua unit test over the shapepandocastactually produces, read off a parsed tree rather than imagined.
test/toccheck.luareads back the list entries a SILE run writes and checksthem, so the numbering is asserted through the real renderer rather than
through a model of it.
The control is the titled opener, which must stay a generic container. It does
discriminate: markup-carve/pandoc-carve#70 makes the bare and titled spellings
produce different Pandoc nodes, so the same panel content under a title keeps
numbering on its own, and the check fails if that stops being true. This is
worth stating explicitly because in a pipeline whose upstream lacked section 4c
the two spellings render identically and that control would pass while testing
nothing.
The first example did NOT pin the direct-children rule, and it took a mutation
to notice. Rewriting the module to mark every captioned DESCENDANT rather than
the direct children left the whole suite green, because the only nested figure
in that example is a sibling of the group rather than part of it.
examples/composite-figure-nested.crvwas added for exactly that case, and themutation now fails both the unit test and the end-to-end check.
One thing is knowingly unpinned. The nested example's check asserts entries,
not numbers, because Resilient numbers every captioned figure it typesets while
Carve numbers only the captions that carry a placeholder. The two counters
agree only in a document where every caption carries one. The README says so,
and so does the comment on the check.
To take this out of draft
A reviewer would need to decide two things.
reachable. If a composite figure numbering as one unit but stacking
vertically is an acceptable intermediate state, this is complete as it
stands and only needs the pin question below settled.
pandoc-carvea consumer is expected to have. Both gate 1 and gate 2are cleared through unpublished commits: pandoc-carve is not on npm, and its
own engine dependency is a git pin rather than a release. The
Dockerfilepin and the README requirement line say
af285ccfor now. If this reposhould instead wait for a published carve-js engine release carrying
figure_groupand a published pandoc-carve on top of it, that is the reasonto hold the draft.