Skip to content

fix: keep the padding under the widest list marker - #371

Merged
Azganoth merged 1 commit into
mainfrom
bug/widest-marker-padding
Sep 2, 2026
Merged

fix: keep the padding under the widest list marker#371
Azganoth merged 1 commit into
mainfrom
bug/widest-marker-padding

Conversation

@Azganoth

@Azganoth Azganoth commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

An ordered list item written with a nine-digit marker and four spaces before its content came back with one space.
That is the single marker-and-padding combination leafdownListForm could not read,
and it is a boundary of the padding preservation #317 delivered rather than a class of its own.

LIST_ITEM_HEAD_LENGTH was 14: nine digits, a delimiter, and four spaces,
which is the longest marker CommonMark reads together with the widest run it reads as padding after it.
Reading that run needs one character more than writing it does.
LIST_ITEM_PADDING_PATTERN measures the run against the character that ends it, /^ {1,4}(?=[^\t\n\r ])/u,
because five or more spaces open indented code inside the item and leave the content one space past the marker;
the lookahead is what separates the two.
At the boundary the head stopped on the last space of the run, the lookahead had nothing to look at,
and the padding fell back to the default of one space.
The head now reaches one character past the widest marker and padding together.

Related Issue

Closes #369

Verification

markdownCompatibility.test.ts gains two rows to the group asserting an item's marker padding.
The widest marker carrying the widest padding fails on the pre-change source;
the row one space short of it passes, which is what makes the pair a guard rather than a restatement of the fix.

The extra character can only reach an item whose marker and padding together are exactly the old head length,
and a nine-digit ordered marker is the only marker long enough to get there.
That was measured rather than reasoned, by driving the editor mount used by the plugin tests over the neighbouring cases, none of which moved:

  1. Three spaces under the widest marker; four spaces under the shortest; four spaces under an eight-digit marker; and ten digits, which CommonMark does not read as a marker at all.
  2. The widest marker with its content on the line after it, and with a second block written at the padding column.
  3. Five spaces under either marker, which still read as one space of padding, because the run opens indented code inside the item and CommonMark puts the content one space past the marker there.

Those neighbours are covered by the existing rows in the same group and by corpusRoundTrip.test.ts,
so they are not added again as committed rows; the list above records what the boundary change was checked against.

The frontend checks pass.

Not verified: the five-space rows still round-trip differently, because indented code inside a list item is rewritten as a fenced block.
That is an open class under #251 and is untouched here —
only the padding those items are written at was in question, and it is correct.

Notes

  • No changelog entry.
    The behavior this restores is promised by an entry already sitting in Unreleased, from fix: keep the marker and numbers a list was authored with #355:
    "The spaces between a marker and its content are kept too."
    No released version has the working behavior, so no user met the defect,
    and a second entry would describe a fix to something that never shipped.
    docs/specification.md already states the rule correctly under Serialization And Output and needed no edit.
  • fix: keep the marker a task list item was authored with #370 touches the same two files in disjoint hunks, and the two changes do not interact:
    the task marker is read from the slice between an item's marker and its content,
    while the head length this changes bounds only the marker and padding read.

@Azganoth Azganoth added the Bug Something isn't working label Sep 2, 2026
@Azganoth Azganoth self-assigned this Sep 2, 2026
`LIST_ITEM_HEAD_LENGTH` was the length of the longest marker CommonMark
reads and the widest padding after it, which is one character short of
what reading that padding needs. The run is measured against the
character that ends it rather than against its own length, because a
run of five or more spaces opens indented code inside the item and
leaves the content one space past the marker, and the lookahead
expressing that has nothing to look at when the head stops on the last
space of the run. Only a nine-digit ordered marker followed by four
spaces reaches that boundary; every shorter marker leaves the head with
a content character to spare.
@Azganoth
Azganoth force-pushed the bug/widest-marker-padding branch from a2af30a to 47da15c Compare September 2, 2026 18:26
@Azganoth
Azganoth merged commit 8bc3675 into main Sep 2, 2026
3 checks passed
@Azganoth
Azganoth deleted the bug/widest-marker-padding branch September 2, 2026 23:49
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 nine-digit ordered marker's four-space padding is dropped on save

1 participant