Odd List behaviour?

Here’s a markdown puzzle for everyone… It’s an extended version of Example 213 in the spec.

What would be the expected result of the following sample?

1. zero
 1. one
  1. two
   1. three
    1. four
     1. five
      1. six
       1. seven
        1. eight
         1. nine
          1. ten

and would you expect the following to render differently?

100. zero
 1. one
  1. two
   1. three
    1. four
     1. five
      1. six
       1. seven
        1. eight
         1. nine
          1. ten

Here are the dingus links so you can test if you were right :smile:

Sample 1

Sample 2

The behaviour seems odd to me, and the result is complete different in commonmark.js compared to others like markdown.pl and GFM. But I am having trouble working out whether that is due to a bug in commonmark.js, or whether I am just not understanding the spec properly.

Based on the text above examples 197 and 213, I would have expected Sample 1 to be rendered

 1. zero
 2. one
 3. two
 4. three
 5. four
 6. five
 7. six
 8. seven
 9. eight
10. nine
11. ten

since none of the lines is indented enough to become a sublist. The “four” line is being treated as a continuation. But I am not sure why that is the case.

So, is this a bug, or a spec issue, or BKAC issue?


1 Like

Looks like a bug with 4[space] causing the problem

If you read the spec on lists, you’ll see why this gives you the
behavior it does with the reference implementations.

Block-level content inside list items (including other lists) need to be
indented past the list marker. In this case the marker is two
characters wide, so you need at least two spaces indent (not just one)
to get a sublist. For bullet lists, the marker is one space wide, so
one space indent suffices.

I have read the list section numerous times. It has so far been the hardest part of the spec to follow.

In any case Example 213 states:

List items need not be indented to the same level. The following list items will be treated as items at the same list level, since none is indented enough to belong to the previous list item:

But if that’s the case, why is my example any different from Example 213? None of these are indented enough to belong to the previous list item either.

Which part of the spec is coming into effect to override this behaviour?

Sorry, I replied before properly appreciating your point. This is indeed puzzling! I’ll need to look into this more when I get some time; most likely it’s a bug in the implementations.

Here’s another simple case:

10000. ok
    1. ok

which yields

<ol start="10000">
1. ok</li>

Another case:

   10. hi
    11. there
<ol start="10">
11. there</li>

@lu_zero is right that the trigger is a four-space indent.

OK, I see what is going on here. In lib/blocks.js, around lines 384-399, the parser assumes that if a line is indented 4 or more spaces but it’s not a code block (because it would be interrupting a paragraph), then it’s a lazy paragraph continuation. That assumption is wrong, because it might be a list item.

I pushed a workaround for CommonMark-py to see if that was the problem and seems working up to a point.

I’ve fixed this in both cmark and commonmark.js, and added a test case in the spec.

1 Like

Thanks @jgm ! I’ll have a look to try to keep the pure-python implementation in sync soon.

I do think the new behavior is more intuitive, but I’m still struggling to understand the spec. I looked at the implementation, and see it’s based on whether a line can be lazily continued, but I’m not yet 100% convinced this is the correct formulation. For one, making the list loose brings you back to interpreting the inner indents as a code block. Simple test case:

-    a

   -    b

      -    c

So I definitely don’t feel that the spec language precisely specifies what an implementation should do at this point.

(Incidentally, my implementation is now open-source and it’s possible to play with it: pulldown-cmark. This case is currently the only test that’s failing)

I’d consider the list item as blockquote so if

>     code
> notcode

Is acceptable so should be

-     This is a code snippet
- This is not

Or not?

What landed in 0.20 looks fine to me. pulldown-cmark 0.0.3 passes all spec tests.