gomarkdown / markdown

markdown parser and HTML renderer for Go
Other
1.37k stars 172 forks source link

Unordered list - nesting problem #216

Closed DenisDuev closed 2 years ago

DenisDuev commented 2 years ago

Hi folks,

When I define unorder list with 3 levels of nesting it is displayed only in 2 levels. Babelmark

For example:

- [level-1-a](#l1)
  - [level-2-a](#level-2-a)
  - [level-2-b](#level-2-b)
  - [level-2-c](#level-2-c)
- [level-1-b](#level-1)
  - [level-2-a](#level-2)
    - [level-3-a](#level-3-a)
    - [level-3-b](#level-3-a)
    - [level-3-c](#level-3-c)
  - [level-2-b](#level-2)
  - [level-2-c](#level-2)

In GitHub:

How it is rendered:

image

<ul>
  <li><a href="#l1">level-1-a</a><br>

    <ul>
      <li><a href="#level-2-a">level-2-a</a><br>
      </li>
      <li><a href="#level-2-b">level-2-b</a><br>
      </li>
      <li><a href="#level-2-c">level-2-c</a><br>
      </li>
    </ul>
  </li>
  <li><a href="#level-1">level-1-b</a><br>

    <ul>
      <li><a href="#level-2">level-2-a</a><br>
      </li>
      <li><a href="#level-3-a">level-3-a</a><br>
      </li>
      <li><a href="#level-3-a">level-3-b</a><br>
      </li>
      <li><a href="#level-3-c">level-3-c</a><br>
      </li>
      <li><a href="#level-2">level-2-b</a><br>
      </li>
      <li><a href="#level-2">level-2-c</a><br>
      </li>
    </ul>
  </li>
</ul>
kjk commented 2 years ago

If you use 3 spaces for indent, it'll work as expected.

See https://www.codeeval.dev/edit?gistid=ca065f34cd03d9f8734f7fb1d147d58d

Arguably it's strange that 2 spaces are accepted for first indent abut second needs 3 spaces. 3 parsers in BabelMark has the same issue.

It should probably work with 2 spaces as well.

miekg commented 2 years ago

I think it's this code in parser/block.go that goes awry:

        // calculate the indentation
        indent := 0
        indentIndex := 0
        if data[line] == '\t' {
            indentIndex++
            indent += 4
        } else {
            for indent < 4 && line+indent < i && data[line+indent] == ' ' {
                indent++
                indentIndex++
            }
        }

the else part, indent <4 is enforcing the 3 spaces rule and this is only happening when we're already in the list explaining why it only manifests here. So any indentation is gone when we look at it in the switch below, and thus that listitem is considered to be part of the current list

miekg commented 2 years ago

at least that's what I'm thinking, I would look there, but it's tricky code.

I won't spend cycles on this one, so you should propose a PR, or otherwise we should probably close with 'wont-fix'