Repository navigation
End list items at block lines, keep nested indentation, footnotes in items - #312
Merged
Merged
Conversation
A text continuation line of a list item lost all its leading whitespace
before the item's content was parsed again. A container nested in the item
then could not tell whether the line reached its own content column, so
- - a
- b
turned `- b` into a second item of the inner list, where djot.js keeps it
as paragraph text ("an indented list marker on the line directly after
paragraph text does not begin a sublist"). A line in a footnote inside an
item lost its place in the note the same way.
Continuation lines now lose only the item's content indentation, as fence
and div content already did.
An unindented line after a list item's paragraph was always taken as lazy text, so `- para` followed by `# H` gave one item with the text "para # H". djot.js ends the list there and parses the heading after it, the same rule djot-php already used for block quotes and definition lists: a lazy line only continues a paragraph when it would not start another block. The nestedListsWithoutBlankLine option test used a quote line after a compact sublist. That line now ends the sublist instead of joining its text, so the test checks the sublist and the quote case separately.
The list item tracker read `[^p]: n` as a reference definition, which has
no paragraph to extend, so in
- [^p]: n
lazy
`lazy` ended the list and became a top-level paragraph. djot.js continues
the note's paragraph (note text "n lazy"). The tracker now follows the
note's content like a list marker's.
The note's paragraph is the one that is open, so a line that opens a block
and is not indented past the note's marker closes the note before the item
looks at it: `1. [^n]: para`, ` | a |`, `tail` keeps the table in the item
and `tail` after the list, as before.
A definition body line needed two spaces of indentation; with one it fell out of the list, so `: t`, blank, ` x` put `x` in a paragraph after the list. djot.js keeps it in the definition: the syntax description's list item rule is "followed by one or more lines, indented relative to the list marker", and the `:` marker sits in column 0.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #312 +/- ##
============================================
- Coverage 93.07% 93.06% -0.01%
- Complexity 4721 4729 +8
============================================
Files 118 118
Lines 12631 12635 +4
============================================
+ Hits 11756 11759 +3
- Misses 875 876 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This was referenced Oct 16, 2026
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.
Four list and definition list differences from djot.js
9790d4d, one commit each.Unindented block line after a list item
djot.js ends the list and parses the heading after it. djot-php gave one item with the text
para # H. Same for* * *,> tail,| a |and:::at column 0.The syntax description does not settle this. Block quotes call the prefix optional only on "regular paragraph lines", and jgm/djot#290 states the rule djot.js follows: "If a line would not start any other kind of block (besides a paragraph), and the last open container is a paragraph, then it gets added to that paragraph." jgm/djot#416 asks for that in the doc and jgm/djot#413 proposes the other reading, so this follows djot.js until upstream decides. djot-php already used the rule for block quotes (#309) and definition lists; #309 left the list case open for this reason. The syntax guide gets a short section on it, next to the block quote one.
One existing test changed:
testNestedListsOptionIsSmallerSubsetput a quote line after a compact sublist. That line now ends the sublist instead of joining its text, so the test checks the sublist case and the quote case separately. The quote still does not interrupt the item's paragraph.Continuation lines keep their indentation
djot.js: one inner item with the text
a - b. djot-php:aandbas two inner items. The outer item stripped all leading whitespace from its continuation lines, so the inner list could not see that- bsat after its paragraph text. Doc (List item): "an indented list marker on the line directly after paragraph text does not begin a sublist; it is taken as lazy continuation of the paragraph." Lines now lose only the item's content indentation. This commit is also what keeps the first change from splitting nested items.Footnote in a list item
djot.js: note text
n lazy. djot-php:lazybecame a top-level paragraph, because the list tracker read the note line as a reference definition. Doc: "The contents of the note are parsed as block-level content."Definition body indented by one space
djot.js keeps
xin the definition; djot-php needed two spaces and put it after the list. Doc (List item): "followed by one or more lines, indented relative to the list marker".Measured against djot.js
On the 4853 generated block-family inputs, djot-php differed from djot.js on 1282 before (after #311) and 1077 after: 1246, 1127, 1123 and 1077 after each commit. 220 cases moved to matching and 15 the other way. Most of those 15 come from the one-space body: an attribute line indented by one space at the end of a definition now goes to the
dd, as a two-space one already did ("Definition List Attributes (Extension)"), where djot.js applies it to the block after the list. The rest are a reference URL continued inside a definition and a quote nested in a list nested in a definition.Not in this PR: a term continued on the next line (
: t, thentail) is a separate change to how existing documents render, so it gets its own PR.