Repository: raphlinus/pulldown-cmark (rust)

Issue:
[fuzz result] off-by-one indent numbered list item with empty first line
When a numbered list has a blank first line in its item, the line after it is supposed to be indented to match the imaginary space after it.

For examples:

```markdown
1.
      pulldown-cmark thinks this is code, but commonmark.js and commonmark-hs don't.
      The dot in the list marker is at column two, so the child paragraph actually
      starts in column *four* (there's three spaces of indentation built into the list).
```

```markdown
1.
  This is not in the list at all. It's a paragraph after it.
```


<details>

Events from pulldown-cmark:

```rust
"0)\n  (\n" -> [
  Start(List(Some(0)))
    Start(Item)
      Text(Borrowed("("))
    End(Item)
  End(List(true))
]
```

Events from pandoc:

```rust
"0)\n  (\n" -> [
  Start(List(Some(0)))
    Start(Item)
    End(Item)
  End(List(true))
  Start(Paragraph)
    Text(Boxed("("))
  End(Paragraph)
]
```

Events from commonmark.js:

```rust
"0)\n  (\n" -> [
  Start(List(Some(0)))
    Start(Item)
    End(Item)
  End(List(true))
  Start(Paragraph)
    Text(Boxed("("))
  End(Paragraph)
]
```

</details>


Pull request description:
Calculate correct list indent for ordered lists
Fixes #810


Patch:
diff --git a/specs/regression.txt b/specs/regression.txt
index a82dee2..fbc5000 100644
--- a/specs/regression.txt
+++ b/specs/regression.txt
@@ -2129,3 +2129,28 @@ part of the title'
 <p><a href="https://example.com" title="
 part of the title">mylink</a></p>
 ````````````````````````````````
+
+ISSUE 810
+
+```````````````````````````````` example
+1.
+      pulldown-cmark used to think this was code, but commonmark.js and commonmark-hs didn't.
+      The dot in the list marker is at column two, so the child paragraph actually
+      starts in column *three*.
+.
+<ol>
+<li>pulldown-cmark used to think this was code, but commonmark.js and commonmark-hs didn't.
+The dot in the list marker is at column two, so the child paragraph actually
+starts in column <em>three</em>.</li>
+</ol>
+````````````````````````````````
+
+```````````````````````````````` example
+1.
+  This is not in the list at all. It's a paragraph after it.
+.
+<ol>
+<li></li>
+</ol>
+<p>This is not in the list at all. It's a paragraph after it.</p>
+````````````````````````````````
diff --git a/src/scanners.rs b/src/scanners.rs
index 9052d8e..1b8e6c4 100644
--- a/src/scanners.rs
+++ b/src/scanners.rs
@@ -236,7 +236,7 @@ impl<'a> LineStart<'a> {
                     } else if c == b')' || c == b'.' {
                         self.ix = ix;
                         if self.scan_space(1) || self.is_at_eol() {
-                            return self.finish_list_marker(c, val, indent + self.ix - start_ix);
+                            return self.finish_list_marker(c, val, indent + 1 + ix - start_ix);
                         } else {
                             break;
                         }


Test patch:
diff --git a/tests/suite/regression.rs b/tests/suite/regression.rs
index 6da9535..c5c7d1f 100644
--- a/tests/suite/regression.rs
+++ b/tests/suite/regression.rs
@@ -2493,6 +2493,7 @@ baz](https://example.com)</li>
     test_markdown_html(original, expected, false, false, false);
 }
 
+  
 #[test]
 fn regression_test_154() {
     let original = r##"[mylink]
@@ -2507,3 +2508,35 @@ part of the title">mylink</a></p>
 
     test_markdown_html(original, expected, false, false, false);
 }
+  
+#[test]
+fn regression_test_155() {
+    let original = r##"1.
+      pulldown-cmark used to think this was code, but commonmark.js and commonmark-hs didn't.
+      The dot in the list marker is at column two, so the child paragraph actually
+      starts in column *three*.
+"##;
+    let expected = r##"<ol>
+<li>pulldown-cmark used to think this was code, but commonmark.js and commonmark-hs didn't.
+The dot in the list marker is at column two, so the child paragraph actually
+starts in column <em>three</em>.</li>
+</ol>
+"##;
+
+    test_markdown_html(original, expected, false, false, false);
+}
+
+#[test]
+fn regression_test_156() {
+    let original = r##"1.
+  This is not in the list at all. It's a paragraph after it.
+"##;
+    let expected = r##"<ol>
+<li></li>
+</ol>
+<p>This is not in the list at all. It's a paragraph after it.</p>
+
+"##;
+
+    test_markdown_html(original, expected, false, false, false);
+}