Skip to content

fix: keep the form a reference definition was authored with - #376

Merged
Azganoth merged 1 commit into
mainfrom
bug/definition-form
Sep 3, 2026
Merged

fix: keep the form a reference definition was authored with#376
Azganoth merged 1 commit into
mainfrom
bug/definition-form

Conversation

@Azganoth

@Azganoth Azganoth commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Summary

A reference definition is now written back in the form it was authored in. #260 kept the definition rather than inlining it and deleting it, but it was still written in the serializer's own form: angle brackets around the destination were dropped, and a title written on its own continuation line was folded onto the destination's line.

Three attributes carry what a definition's label, destination, title, and title marker did not already answer for: the form the destination was written in, and the two whitespace runs CommonMark lets a definition spend a line ending in. leafdownReferenceLink stamps all three onto the mdast definition beside the title marker it already stamped, read off the slice the node was built from, and the definition node carries them as attributes.

serializeMarkdownDefinition writes the line itself rather than steering defaultHandlers.definition. That handler makes four choices — the label, the destination's form, the title's marker, and the whitespace between them — and the document now owns three of them. What is left is escaping, which every run still reaches the file through, under the construct name the default handler enters for it, so what a destination or a title gives up a backslash for is unchanged. Writing the title's marker directly also retires the trailing parameter withAuthoredTitle carried for definitions alone, which existed only to locate that marker in the default handler's output.

The recorded runs are read past the columns the definition's container owns, named by the definition's own starting column. A container writes its prefix back around every line the serializer makes, so a run recorded through that prefix is added to it: a definition in a list item whose title stands on the next line would gain the item's indentation on the first save and gain it again on the next. Reading past the prefix instead leaves the blockquote, nested blockquote, and list item forms byte-identical, and leaves a prefix the column count does not describe unreadable, which is the default one-line form rather than a guess.

The recorded form only ever adds the brackets. A destination that cannot be read back bare — an empty one, and one holding whitespace or a control character — is written between them whatever the file recorded, which a bare destination reaches through a character reference the parse decodes into it.

.leafdown-definition renders with white-space: pre-wrap, because the block shows the source the file is written with and that source can now hold a line ending and the indentation under it.

Related Issue

Closes #325

Verification

markdownCompatibility.test.ts gains a Definition form group.

Twenty rows assert the written bytes and the reopened document together, because a destination written in a form the next read does not answer for costs the destination rather than the form. They cover both destination forms, a destination the bare form cannot spell and one it could, both brackets escaped inside an angle destination, a colon followed by no whitespace at all, a title separated by a space, by a tab, and by three spaces, a title and a destination each on a line of their own, both runs spending their line ending at once, and the same layouts inside a blockquote, a nested blockquote, and a list item.

Three more tests cover the bracket a recorded form cannot withhold, a two-line definition rendered as both of its lines, and a layout read past a prefix another class moves — a lazy continuation and a blockquote marker written without its space — each asserted across a second save.

corpusRoundTrip.test.ts is unchanged and still passes. corpus/commonmark/blocks.md loses both differences this issue names, measured by saving the file once and comparing it to itself, which is the fourth Done when item.

Not verified: the application was not run. The rendered block's text content is asserted, so what rests on the stylesheet alone is that pre-wrap shows the line ending and indentation that text content already holds.

Notes

@Azganoth Azganoth added the Bug Something isn't working label Sep 3, 2026
@Azganoth Azganoth self-assigned this Sep 3, 2026
@Azganoth
Azganoth enabled auto-merge (squash) September 3, 2026 04:59
@Azganoth
Azganoth merged commit bae82e0 into main Sep 3, 2026
3 checks passed
@Azganoth
Azganoth deleted the bug/definition-form branch September 3, 2026 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A reference definition's destination form and line layout are rewritten on save

1 participant