Bad Interaction Between Laziness Rule and Ordered Lists

I believe I have found an issue with the specification. In particular, the laziness rule for list items, combined with the details about when lists can interrupt paragraphs, together imply an undesirable treatment of ordered lists that would break common usage. To show this, first, here is an unambiguous motivating example:

1. Before the end of the paragraph, I invite you to
   consider a very large number. For example,
   45000000. Are you thinking about it?

Despite 45000000. being a well-formed list item marker in isolation, it does not interrupt the paragraph to start a list, because the item number isn’t 1. Therefore, this line satisfies the specification’s definition of paragraph continuation text. However, this creates an issue when combined with the laziness rule for list items, which reads as follows:

Laziness. If a string of lines Ls constitute a list item with contents Bs, then the result of deleting some or all of the indentation from one or more lines in which the next character other than a space or tab after the indentation is paragraph continuation text is a list item with the same contents and attributes. The unindented lines are called lazy continuation lines.

Taking this rule as written, the following would be an equivalent way to write our original example:

1. Before the end of the paragraph, I invite you to
consider a very large number. For example,
45000000. Are you thinking about it?

However, I’m not aware of any implementations of the written behavior. Everyone seems to interpret 45000000. as an item marker for the second element of the list (dingus link). This is surely the correct decision, for otherwise a list like

1. item 1
2. item 2

would be mistakenly interpreted as a list of one item, equivalent to

1. item 1
   2. item 2

It seems the spec needs to be changed so that ordered list item markers interrupt paragraphs in more situations than are currently specified. There is a similar issue affecting unordered list item markers that start with a blank line. Like ordered markers with numbers other than 1, these cannot interrupt a paragraph, so they interact with the laziness rule in the same bad way.

A mitigation would involve explicitly disqualifying certain types of list item beginnings from being counted as lazy continuation lines. We could use language such as, “paragraphs are interrupted by ordered list item markers which could be interpreted to start a subsequent item in an enclosing list; this takes precedence over identifying lazy continuation lines.” This is not so bad to implement, as classifying such list items merely requires walking through the stack of open list item blocks and determining if the next line could start one of their siblings.

On the other hand, commonmark.js is more permissive in terms of when it allows ordered list items to interrupt nested paragraphs. For example, the following example creates two ordered lists, one after the other, interpreting the 2) as a list item marker rather than as paragraph continuation text (dingus link):

1. item
2) continue paragraph or start new list? commonmark.js does the latter
2 Likes

It seems to me that the best way to fix this is to amend the laziness rules to agree with the behavior in the reference implementation. Here is a suitable laziness rule for list items:

Laziness. Let L be a line within a list item such that the first character of L, other than any leading spaces or tabs, is paragraph continuation text. Then some or all of the indentation at the beginning of L may be deleted without changing the contents or attributes of the enclosing list item, unless the resulting line could otherwise be interpreted as the beginning of a list item.

The bolded part at the end is the correction. Without that, this rule would be equivalent to the one stated in section 5.2 of the current version of the specification, 0.31.2.

The laziness rule for block quotes could likewise be updated to read

Laziness. Let L be a line within a block quote such that the first character of L, after the initial block quote marker and any spaces or tabs, is paragraph continuation text. Then the initial block quote marker of L may be deleted without changing the contents or attributes of the enclosing block quote, unless the resulting line could otherwise be interpreted as the beginning of a list item.

Paragraph continuation text is text that will be parsed as part of the content of a paragraph, but does not occur at the beginning of the paragraph.

(The definition of paragraph continuation text is also part of the laziness rule for block quotes in the current version of the spec. I have made the editorial choice to put it in its own paragraph.)

To the best of my knowledge, the rewritten rules match the behavior exhibited by commonmark.js, without requiring changes anywhere else in the spec. This essentially gives list item markers parsing priority over lazy continuation lines, even for markers that wouldn’t normally break a paragraph. At any rate, these are the rules I plan to follow in my own implementation.

EDIT: slight change to wording in proposed rules.