Repository: pulldown-cmark/pulldown-cmark (rust)

Issue:
Definition list indented code block parsing inconsistencies
As mentioned in [this test case](https://github.com/pulldown-cmark/pulldown-cmark/blob/b03f2991d31764a42b8c87c9a82011bed7c2079d/pulldown-cmark/specs/definition_lists.txt#L344-L363), an indented code block needs eight spaces of indentation however if the indented code block starts on the next line it's parsed after five spaces.

Running `cargo run -- -e -D` on the following input

```markdown
bar
:       baz
```

produces these events:
```
0..16: Start(DefinitionList)
0..4: Start(DefinitionListTitle)
0..3: Text(Borrowed("bar"))
0..4: End(DefinitionListTitle)
4..16: Start(DefinitionListDefinition)
12..16: Start(CodeBlock(Indented))
12..16: Text(Borrowed("baz\n"))
12..16: End(CodeBlock)
4..16: End(DefinitionListDefinition)
0..16: End(DefinitionList)
EOF
```

And starting the code block on the next line only needs five spaces to parse an indented code block:

```markdown
bar
:
     baz
```

```
0..15: Start(DefinitionList)
0..4: Start(DefinitionListTitle)
0..3: Text(Borrowed("bar"))
0..4: End(DefinitionListTitle)
4..15: Start(DefinitionListDefinition)
11..15: Start(CodeBlock(Indented))
11..15: Text(Borrowed("baz\n"))
11..15: End(CodeBlock)
4..15: End(DefinitionListDefinition)
0..15: End(DefinitionList)
```

Trying to start the code block using eight spaces of indentation on the next line results in extra whitespace being added to the indented code block.

```markdown
bar
:
       baz
```

```
0..17: Start(DefinitionList)
0..4: Start(DefinitionListTitle)
0..3: Text(Borrowed("bar"))
0..4: End(DefinitionListTitle)
4..17: Start(DefinitionListDefinition)
11..17: Start(CodeBlock(Indented))
11..17: Text(Borrowed("  baz\n"))
11..17: End(CodeBlock)
4..17: End(DefinitionListDefinition)
0..17: End(DefinitionList)
```

Pull request:
Make indent calc for definition lists match commonmark-hs closer
Fixes #975


Patch:
diff --git a/pulldown-cmark/specs/definition_lists.txt b/pulldown-cmark/specs/definition_lists.txt
index ae25016..8a8a2bd 100644
--- a/pulldown-cmark/specs/definition_lists.txt
+++ b/pulldown-cmark/specs/definition_lists.txt
@@ -342,9 +342,7 @@ Bloze
 ````````````````````````````````
 
 To use an indented code block inside of a definition,
-you need to have a total of eight spaces of indentation.
-This can be done by having a colon followed by seven spaces,
-or three spaces followed by four.
+you need to have five spaces of indentation after the colon.
 
 ```````````````````````````````` example
 bar
@@ -364,23 +362,74 @@ bar
 .
 <dl>
 <dt>bar</dt>
-<dd><pre><code>baz
-</code></pre></dd>
+<dd>
+<pre><code>  baz
+</code></pre>
+</dd>
 <dt>bar</dt>
-<dd><pre><code>baz
-</code></pre></dd>
+<dd>
+<pre><code> baz
+</code></pre>
+</dd>
 <dt>bar</dt>
-<dd><pre><code>baz
-</code></pre></dd>
+<dd>
+<pre><code>baz
+</code></pre>
+</dd>
 <dt>bar</dt>
-<dd><pre><code>baz
-</code></pre></dd>
+<dd>baz</dd>
 </dl>
 <p>bar
 :   baz</p>
 ````````````````````````````````
 
 
+Because of the way it eats indentation after the colon, the number of
+spaces you need for indented code blocks on subsequent lines depends on
+the indentation of the earlier block.
+
+```````````````````````````````` example
+*orange*
+
+:   orange fruit
+
+        { orange code block }
+
+  > orange block quote
+
+*orange*
+
+:     orange fruit
+
+        { orange code block }
+
+  > orange block quote
+.
+<dl>
+<dt><em>orange</em></dt>
+<dd>
+<p>orange fruit</p>
+<pre><code>{ orange code block }
+</code></pre>
+</dd>
+</dl>
+<blockquote>
+<p>orange block quote</p>
+</blockquote>
+<dl>
+<dt><em>orange</em></dt>
+<dd>
+<pre><code>orange fruit
+
+  { orange code block }
+</code></pre>
+<blockquote>
+<p>orange block quote</p>
+</blockquote>
+</dd>
+</dl>
+````````````````````````````````
+
 Definition titles can't be tables.
 
 ```````````````````````````````` example
diff --git a/pulldown-cmark/src/scanners.rs b/pulldown-cmark/src/scanners.rs
index ec2e5ec..b2fc4c3 100644
--- a/pulldown-cmark/src/scanners.rs
+++ b/pulldown-cmark/src/scanners.rs
@@ -285,8 +285,14 @@ impl<'a> LineStart<'a> {
     ) -> Option<usize> {
         let save = self.clone();
         if self.scan_ch(b':') {
-            let remaining = 4 - (indent + 1);
-            Some(indent + 1 + self.scan_space_upto(remaining))
+            let save = self.clone();
+            if self.scan_space(5) {
+                *self = save;
+                Some(indent + 1 + self.scan_space_upto(1))
+            } else {
+                *self = save;
+                Some(indent + 1 + self.scan_space_upto(5))
+            }
         } else {
             *self = save;
             None


Test patch:
diff --git a/pulldown-cmark/tests/suite/definition_lists.rs b/pulldown-cmark/tests/suite/definition_lists.rs
index 703a480..897e7d8 100644
--- a/pulldown-cmark/tests/suite/definition_lists.rs
+++ b/pulldown-cmark/tests/suite/definition_lists.rs
@@ -380,17 +380,22 @@ bar
 "##;
     let expected = r##"<dl>
 <dt>bar</dt>
-<dd><pre><code>baz
-</code></pre></dd>
+<dd>
+<pre><code>  baz
+</code></pre>
+</dd>
 <dt>bar</dt>
-<dd><pre><code>baz
-</code></pre></dd>
+<dd>
+<pre><code> baz
+</code></pre>
+</dd>
 <dt>bar</dt>
-<dd><pre><code>baz
-</code></pre></dd>
+<dd>
+<pre><code>baz
+</code></pre>
+</dd>
 <dt>bar</dt>
-<dd><pre><code>baz
-</code></pre></dd>
+<dd>baz</dd>
 </dl>
 <p>bar
 :   baz</p>
@@ -401,6 +406,52 @@ bar
 
 #[test]
 fn definition_lists_test_17() {
+    let original = r##"*orange*
+
+:   orange fruit
+
+        { orange code block }
+
+  > orange block quote
+
+*orange*
+
+:     orange fruit
+
+        { orange code block }
+
+  > orange block quote
+"##;
+    let expected = r##"<dl>
+<dt><em>orange</em></dt>
+<dd>
+<p>orange fruit</p>
+<pre><code>{ orange code block }
+</code></pre>
+</dd>
+</dl>
+<blockquote>
+<p>orange block quote</p>
+</blockquote>
+<dl>
+<dt><em>orange</em></dt>
+<dd>
+<pre><code>orange fruit
+
+  { orange code block }
+</code></pre>
+<blockquote>
+<p>orange block quote</p>
+</blockquote>
+</dd>
+</dl>
+"##;
+
+    test_markdown_html(original, expected, false, false, false);
+}
+
+#[test]
+fn definition_lists_test_18() {
     let original = r##"Test|Table
 ----|-----
 : first
@@ -414,7 +465,7 @@ fn definition_lists_test_17() {
 }
 
 #[test]
-fn definition_lists_test_18() {
+fn definition_lists_test_19() {
     let original = r##"first
 : second
 
@@ -435,7 +486,7 @@ Test|Table
 }
 
 #[test]
-fn definition_lists_test_19() {
+fn definition_lists_test_20() {
     let original = r##"My section
 ==========
 : first
@@ -448,7 +499,7 @@ fn definition_lists_test_19() {
 }
 
 #[test]
-fn definition_lists_test_20() {
+fn definition_lists_test_21() {
     let original = r##"first
 : second
 
@@ -468,7 +519,7 @@ My section
 }
 
 #[test]
-fn definition_lists_test_21() {
+fn definition_lists_test_22() {
     let original = r##"## My subsection
 : first
 "##;
@@ -480,7 +531,7 @@ fn definition_lists_test_21() {
 }
 
 #[test]
-fn definition_lists_test_22() {
+fn definition_lists_test_23() {
     let original = r##"first
 : second
 
@@ -499,7 +550,7 @@ fn definition_lists_test_22() {
 }
 
 #[test]
-fn definition_lists_test_23() {
+fn definition_lists_test_24() {
     let original = r##"first\
 : second
 
@@ -518,7 +569,7 @@ third
 }
 
 #[test]
-fn definition_lists_test_24() {
+fn definition_lists_test_25() {
     let original = r##"<div>first</div>
 : second
 
@@ -541,7 +592,7 @@ first
 }
 
 #[test]
-fn definition_lists_test_25() {
+fn definition_lists_test_26() {
     let original = r##"<span>first</span>
 : second
 
@@ -565,7 +616,7 @@ third
 }
 
 #[test]
-fn definition_lists_test_26() {
+fn definition_lists_test_27() {
     let original = r##"level one
 : l1
     level two