Opt-in composite figures: a figure div is one figure of ordered panels - #270
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #270 +/- ##
============================================
+ Coverage 92.42% 92.49% +0.07%
- Complexity 3683 3708 +25
============================================
Files 109 110 +1
Lines 10439 10501 +62
============================================
+ Hits 9648 9713 +65
+ Misses 791 788 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Ordering note: #271 fixes the plain-text gap this PR's degradation test currently pins ( |
A bare `::: figure` div becomes one figure made of ordered panels, so a document can spell the subfigure case (Figure 1a, 1b) that a single captioned image cannot. Opt-in only: composite figures are not djot, and without the extension a figure div still renders as a plain div. No parser change is needed. The div and the `^` caption line already parse; the extension rewrites the tree in beforeRender, which every renderer shares, so HTML, Markdown, plain text and ANSI all degrade through the figure, div and caption paths they already have. Rules: - Captioned children (image and blockquote figures) are promoted to panels; a table is wrapped in a panel figure and keeps its own caption element. - Content that is not captionable stays where it was written, inside the panels container, and is not a panel. - A caret paragraph immediately after the closing fence becomes the group caption. Escaping the caret keeps it an ordinary paragraph, which is how an unattachable caption line already behaves. - Groups do not nest: a figure div inside an open group stays a plain div. The four class names are constructor options, so a project mirroring another vocabulary can rename them without a subclass. Numbering is deliberately absent: this engine has no figure numbering to hook into, so the panel letters and the group number that make subfigures useful in prose are left for whenever numbering lands.
8e59185 to
2e1d021
Compare
|
Rebased onto master (b9c8bac). The degradation test asserted the pre-php-collective/djot-php#271 plain-text output ( which is the point of #271. Assertion updated to the fixed output, nothing else changed. Full suite, phpstan and phpcs green on the rebased commit. |
Composite figures, as an opt-in extension.
Upstream djot has no composite figure. The open discussion is jgm/djot#31, where the objection to the
^caption syntax this library already ships (jgm/djot#37) was that it cannot spell a subfigure: "Figure 1a", "Figure 1b", one caption over the whole plate. This adds that, without new syntax and without touching the parser.A bare
::: figurediv becomes one figure of ordered panels:Why no parser change
Both halves already parse:
::: figureis a div with classfigure, and a^line that cannot attach to anything is a paragraph whose first inline isText("^ ..."). SoFigureGroupExtensionimplementsBeforeRenderExtensionInterfaceand rewrites the tree once, before rendering.That is also why there are no renderer changes in this diff.
beforeRenderruns on the singlerender()path, so Markdown, plain text and ANSI degrade for free through theFigure,DivandCaptionarms they already have.Rules
Figurenodes are promoted in place, aTableis wrapped in a panel figure and keeps its own<caption>.\^ ...) leaves an ordinary paragraph. That works because an escaped caret parses asEscapedText, a sibling ofText, not a subclass, so the check is sound rather than accidental.<div class="figure">; there is a test for exactly that.The four class names (
figure,figure-group,figure-panels,figure-panel) are constructor options.Deliberately out of scope
Noted while working, not fixed here
PlainTextRendererhas noFigurearm, so a captioned image already renders asaPanel caption, the alt text glued to the caption. That predates this branch (reproduces on master with a plain captioned image) and the new test pins the current behavior rather than papering over it. Worth its own fix.