fix: keep the Markdown an image description was written with - #347
Merged
Conversation
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
An image description holds inline content and the parser keeps only the text it spells, so
opened asAlt with emphasisand saved that way, and](leaf.svg)lost the inner image's destination from the file on the first save with nothing in the document able to recover it.The image node now carries the description's source beside the alt text the parser derived, on the pattern an authored destination and a title marker already use. The source is recovered in the pass that walks the tree against the file it was read from, and reaches the file as it stands rather than through the label escaping that would turn its markers into characters. The alt text is unchanged, so the rendered image is still named by the text its description spells.
Holding the description as document content was the alternative, and nothing delivers it: the mdast image node carries no children to build inline content from, and the node view's whole editing surface is a raw Markdown input, so a description rich in the schema would still be edited as text. That trade and its consequences are recorded in
docs/decisions.md.Two things follow from the same place:
mdast-util-to-markdownkeeps those forms only while the description it writes still matches the label, which a flattened description does not, so![*em*]needed the description back before it could stay a shortcut.A description is carried only where it says more than the alt text does. Escapes and character references are differences the alt text answers for on its own, so a description spelling only those is left exactly as it was.
The source is read from the file slice, and a code span binds more tightly than the brackets around a description, so the reading is confirmed against the destination or the reference label the node holds and declined where they disagree. A description whose brackets a code span interrupts is left to its text rather than written from a reading that ended early.
Related Issue
Closes #259
Verification
imageDescription.test.tsis new. Each row opens a source, saves it, and reopens the result, asserting the saved bytes, the node attributes, and that the document the reopened file gives back is the document that was saved. The document assertion is the one that matters here: a flattened description converges perfectly, so the corpus guard is green on this defect either way, which is the trap#251records. The rows cover emphasis with inline code, strong with strikethrough, a link, a title, an image in a link label, the three reference forms, a nested image, a description holding only escapes, and a description a code span interrupts. The nested-image row asserts the outer node keepsOuter inneras its alt text while carryingOuter as its description.imageView.test.tsgains two rows: editing the destination through the raw image Markdown keeps the description the file holds, and editing the description writes it as text, sosaves as.sourceProjectionImageLink.test.tsgains one: a link label holding a described image projects that image's authored source and restores the identical document when the caret leaves it.imageMarkdown.test.tscovers the input's serialize and parse for a description holding a nested image, and for a shortcut reference whose description spells its label.Measured by driving the editor mount across ten image forms before and after the change, comparing the saved bytes and the document each time. The five flattening rows move to byte identity: emphasis with inline code, strong with strikethrough, a link in a description, a nested image, and a reference image. Nothing else in the set moves — an escaped description, a bracketed one, an entity one, a linked image, and a titled image are all written exactly as before.
pnpm check:frontendpasses. The backend is untouched, sopnpm check:backendwas not run.Not verified: the manual pass over
corpus/in the running application, which covers rendering, interaction, and navigator behavior beyond the automated round-trip.Notes
A character reference in a description still decodes on save, so
is still written. Carrying the source only where it says more than the alt text is what keeps that difference with#262, which owns it, rather than fixing it as collateral here.A copy through the DOM carries no authored attributes, so an image pasted from outside the editing session falls back to the text its description spells, exactly as an edited description does. That is the fallback the authored destination and title marker already take.
corpus/commonmark/links-and-images.mdis unchanged. Both forms the issue names were already in it, underInline and reference image formsandLinked and nested images, and both now round-trip byte-identically.