Fix fenced code in lists (#521)

This attempts to fix #495 and #485.

Note the test cases which were added at the bottom of the list. The first added test case was passing even before the changes, but the second was not.
This commit is contained in:
Ignas Anikevicius 2019-01-24 10:23:35 +02:00 committed by Vytautas Šaltenis
parent 13768b07fa
commit a477dd1646
2 changed files with 34 additions and 13 deletions

View File

@ -649,14 +649,17 @@ func isFenceLine(data []byte, info *string, oldmarker string, newlineOptional bo
} }
i = skipChar(data, i, ' ') i = skipChar(data, i, ' ')
if i >= len(data) || data[i] != '\n' { if i >= len(data) {
if newlineOptional && i == len(data) { if newlineOptional {
return i, marker return i, marker
} }
return 0, "" return 0, ""
} }
if data[i] == '\n' {
i++ // Take newline into account
}
return i + 1, marker // Take newline into account. return i, marker
} }
// fencedCodeBlock returns the end index if data contains a fenced code block at the beginning, // fencedCodeBlock returns the end index if data contains a fenced code block at the beginning,
@ -1133,6 +1136,15 @@ func (p *parser) listItem(out *bytes.Buffer, data []byte, flags *int) int {
i++ i++
} }
// process the following lines
containsBlankLine := false
sublist := 0
codeBlockMarker := ""
if p.flags&EXTENSION_FENCED_CODE != 0 && i > line {
// determine if codeblock starts on the first line
_, codeBlockMarker = isFenceLine(data[line:i], nil, "", false)
}
// get working buffer // get working buffer
var raw bytes.Buffer var raw bytes.Buffer
@ -1140,11 +1152,6 @@ func (p *parser) listItem(out *bytes.Buffer, data []byte, flags *int) int {
raw.Write(data[line:i]) raw.Write(data[line:i])
line = i line = i
// process the following lines
containsBlankLine := false
sublist := 0
codeBlockMarker := ""
gatherlines: gatherlines:
for line < len(data) { for line < len(data) {
i++ i++
@ -1153,7 +1160,6 @@ gatherlines:
for data[i-1] != '\n' { for data[i-1] != '\n' {
i++ i++
} }
// if it is an empty line, guess that it is part of this item // if it is an empty line, guess that it is part of this item
// and move on to the next line // and move on to the next line
if p.isEmpty(data[line:i]) > 0 { if p.isEmpty(data[line:i]) > 0 {

View File

@ -697,8 +697,8 @@ func TestUnorderedList(t *testing.T) {
"* List\n extra indent, same paragraph\n", "* List\n extra indent, same paragraph\n",
"<ul>\n<li>List\n extra indent, same paragraph</li>\n</ul>\n", "<ul>\n<li>List\n extra indent, same paragraph</li>\n</ul>\n",
"* List\n\n code block\n", "* List\n\n code block\n\n* List continues",
"<ul>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ul>\n", "<ul>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n\n<li><p>List continues</p></li>\n</ul>\n",
"* List\n\n code block with spaces\n", "* List\n\n code block with spaces\n",
"<ul>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ul>\n", "<ul>\n<li><p>List</p>\n\n<pre><code> code block with spaces\n</code></pre></li>\n</ul>\n",
@ -1096,7 +1096,7 @@ func TestFencedCodeBlock(t *testing.T) {
"<p>``` lisp\nno ending</p>\n", "<p>``` lisp\nno ending</p>\n",
"~~~ lisp\nend with language\n~~~ lisp\n", "~~~ lisp\nend with language\n~~~ lisp\n",
"<p>~~~ lisp\nend with language\n~~~ lisp</p>\n", "<pre><code class=\"language-lisp\">end with language\n</code></pre>\n\n<p>lisp</p>\n",
"```\nmismatched begin and end\n~~~\n", "```\nmismatched begin and end\n~~~\n",
"<p>```\nmismatched begin and end\n~~~</p>\n", "<p>```\nmismatched begin and end\n~~~</p>\n",
@ -1139,6 +1139,21 @@ func TestFencedCodeBlock(t *testing.T) {
"```\n[]:()\n[]:)\n[]:(\n[]:x\n[]:testing\n[:testing\n\n[]:\nlinebreak\n[]()\n\n[]:\n[]()\n```", "```\n[]:()\n[]:)\n[]:(\n[]:x\n[]:testing\n[:testing\n\n[]:\nlinebreak\n[]()\n\n[]:\n[]()\n```",
"<pre><code>[]:()\n[]:)\n[]:(\n[]:x\n[]:testing\n[:testing\n\n[]:\nlinebreak\n[]()\n\n[]:\n[]()\n</code></pre>\n", "<pre><code>[]:()\n[]:)\n[]:(\n[]:x\n[]:testing\n[:testing\n\n[]:\nlinebreak\n[]()\n\n[]:\n[]()\n</code></pre>\n",
"- test\n\n```\n codeblock\n ```\ntest\n",
"<ul>\n<li><p>test</p>\n\n<pre><code>codeblock\n</code></pre></li>\n</ul>\n\n<p>test</p>\n",
"- ```\n codeblock\n ```\n\n- test\n",
"<ul>\n<li><pre><code>codeblock\n</code></pre></li>\n\n<li><p>test</p></li>\n</ul>\n",
"- test\n- ```\n codeblock\n ```\n",
"<ul>\n<li>test</li>\n\n<li><pre><code>codeblock\n</code></pre></li>\n</ul>\n",
"- test\n```\ncodeblock\n```\n\n- test\n",
"<ul>\n<li><p>test</p>\n\n<pre><code>codeblock\n</code></pre></li>\n\n<li><p>test</p></li>\n</ul>\n",
"- test\n```go\nfunc foo() bool {\n\treturn true;\n}\n```\n\n- test\n",
"<ul>\n<li><p>test</p>\n\n<pre><code class=\"language-go\">func foo() bool {\n\treturn true;\n}\n</code></pre></li>\n\n<li><p>test</p></li>\n</ul>\n",
} }
doTestsBlock(t, tests, EXTENSION_FENCED_CODE) doTestsBlock(t, tests, EXTENSION_FENCED_CODE)
} }
@ -1557,7 +1572,7 @@ func TestFencedCodeBlock_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
"<p>``` lisp\nno ending</p>\n", "<p>``` lisp\nno ending</p>\n",
"~~~ lisp\nend with language\n~~~ lisp\n", "~~~ lisp\nend with language\n~~~ lisp\n",
"<p>~~~ lisp\nend with language\n~~~ lisp</p>\n", "<pre><code class=\"language-lisp\">end with language\n</code></pre>\n\n<p>lisp</p>\n",
"```\nmismatched begin and end\n~~~\n", "```\nmismatched begin and end\n~~~\n",
"<p>```\nmismatched begin and end\n~~~</p>\n", "<p>```\nmismatched begin and end\n~~~</p>\n",