Skip to content

fix: a quote's caption is a figure caption again, and the pin moves with it - #220

Merged
dereuromark merged 1 commit into
mainfrom
fix/revert-quote-attribution-projection
Aug 15, 2026
Merged

fix: a quote's caption is a figure caption again, and the pin moves with it#220
dereuromark merged 1 commit into
mainfrom
fix/revert-quote-attribution-projection

Conversation

@dereuromark

Copy link
Copy Markdown
Contributor

Closes #219.

What

#218 is reverted: a caption on a block quote projects onto carveFigure + carveCaption again, not onto a carveCaption inside the quote. The engine pin moves onto the build that produces that shape.

Why

markup-carve/carve#1213 withdraws PART 9 section 4a, so block_quote.attribution no longer exists and a captioned quote is a figure whose target is the quote.

The HTML Standard's blockquote section:

Attribution for the quotation, if any, must be placed outside the blockquote element.

with <figure> + <figcaption> given as the way to attach it. The clause put the source in the one place the standard names as wrong. Its model argument fails too: figure is already the generic captioned wrapper, since a captioned code block is a figure whose target is the code block.

The property #218 pinned survives its own revert

tests/blockquote-caption-test.js replaces blockquote-attribution-test.js with the same five documents and the same method: mount a real editor, make an UNRELATED edit, and read what the pane would write back. That method is the point of the file, not an artifact of the model it was written against. A load-only assertion cannot see this class of bug, because the whole-document carveSource envelope still holds the source at load time and only the first edit invalidates the fingerprint it is keyed to.

What changed is the shape the probe looks for: a carveCaption beside a blockquote inside a carveFigure, rather than one inside the quote. Four cases from the old file - a quote holding only its caption, a caption mid-quote, several captions joined, an emptied caption - were about a carveCaption living inside a blockquote, which this projection does not produce, so they go with the field.

20 checks pass across the 5 documents, including the negative probes: a quote with no caption, a document with no quote, and an ordinary image caption all report nothing.

Ratchet

tests/mounted-roundtrip-test.js moves 177 -> 173, and the four documents move back: 05-lists-20, 07-blockquote-with-attribution, 55-blockquote-caption-after-a-blank-line and 282-two-blank-lines-detach-a-caption-5 are render-equivalent through a mount again. They stay in the protected list, because the failure mode here is silent content loss on the first edit rather than a visible fallback.

Before merging

The pin is on an unmerged branch. @markup-carve/carve points at carve-js 2bfa5cfe, the head of markup-carve/carve-js#1070, since the revert has to be pinnable before any of this can be measured. Re-pin to the merged sha before this merges.

…ith it

markup-carve/carve#1213 withdraws PART 9 §4a. A caption on a block quote is not
an attribution: the engine emits a `figure` whose target is the quote again, and
`block_quote.attribution` no longer exists.

The HTML Standard's `blockquote` section requires that "attribution for the
quotation, if any, must be placed outside the `blockquote` element" and gives
`<figure>` + `<figcaption>` as the way to attach it, so the clause put the source
in the one place the standard names as wrong. Its model argument fails too:
`figure` is already the generic captioned wrapper, since a captioned code block
is a `figure` whose target is the code block.

So #218 is reverted. The projection it added - `attribution` onto a
`carveCaption` INSIDE the quote - has nothing to read, and the
`carveFigure`/`carveCaption` pair it replaced is correct again. The
`tiptap/schema-map.json` note describing where the field lands goes with it.

THE PROPERTY #218 PINNED SURVIVES ITS OWN REVERT, and that is why the test file
does not simply go away. `tests/blockquote-caption-test.js` replaces
`blockquote-attribution-test.js` with the same five documents and the same
method: mount a real editor, make an UNRELATED edit, and read what the pane would
write back. A load-only assertion cannot see this class of bug, because the
whole-document `carveSource` envelope still holds the source at load time and
only the first edit invalidates the fingerprint it is keyed to. What changed is
the shape the probe looks for - a `carveCaption` beside a `blockquote` inside a
`carveFigure`, rather than one inside the quote - and the four cases about a
caption living inside a quote, which this projection cannot produce, are gone
with the field.

The mounted ratchet moves 177 -> 173, and the four documents move back with it:
05-lists-20, 07-blockquote-with-attribution,
55-blockquote-caption-after-a-blank-line and
282-two-blank-lines-detach-a-caption-5 are render-equivalent through a mount
again. They stay in the protected list, since the failure mode is silent content
loss on the first edit rather than a visible fallback.

THE PIN IS ON AN UNMERGED BRANCH. `@markup-carve/carve` points at
carve-js `2bfa5cfe`, the head of markup-carve/carve-js#1070, because the revert
has to be pinnable before this can be measured at all. It must be re-pinned to
the merged sha before this merges.
@dereuromark
dereuromark marked this pull request as ready for review August 15, 2026 01:43
@dereuromark
dereuromark merged commit 52607c9 into main Aug 15, 2026
4 checks passed
@dereuromark
dereuromark deleted the fix/revert-quote-attribution-projection branch August 15, 2026 01:43
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.

Revert the quote-attribution projection after the engine revert lands

1 participant