diff --git a/block_test.go b/block_test.go index 5ea69f55..9f0d4513 100644 --- a/block_test.go +++ b/block_test.go @@ -179,6 +179,12 @@ func TestCodeInList(t *testing.T) { doTestsParam(t, tests, TestParams{extensions: exts}) } +func TestBug346(t *testing.T) { + tests := readTestFile2(t, "bug346.tests") + exts := parser.CommonExtensions + doTestsParam(t, tests, TestParams{extensions: exts}) +} + func TestLists(t *testing.T) { tests := readTestFile2(t, "Lists.tests") exts := parser.CommonExtensions diff --git a/parser/block.go b/parser/block.go index 12404909..e0b99604 100644 --- a/parser/block.go +++ b/parser/block.go @@ -1409,6 +1409,9 @@ func (p *Parser) listItem(data []byte, flags *ast.ListType) int { // process the following lines containsBlankLine := false sublist := 0 + // track fenced code blocks inside list items so that lines within + // the fence are gathered verbatim (not misinterpreted as list items) + fenceMarker := "" gatherlines: for line < len(data) { @@ -1442,6 +1445,39 @@ gatherlines: chunk := data[line+indentIndex : i] + // track fenced code blocks inside list items; + // only track fences that are indented (part of the list item content), + // a fence at indent 0 ends the list (handled below) + if !isDefinitionList && p.extensions&FencedCode != 0 { + if fenceMarker != "" { + if indent == 0 { + // non-indented line while inside a fence means we + // left the list item content -- abandon the fence + fenceMarker = "" + } else { + // inside a fence: check for closing fence + _, marker := isFenceLine(chunk, nil, fenceMarker) + if marker != "" { + fenceMarker = "" + } + // gather the line verbatim, skip structure detection + if containsBlankLine { + containsBlankLine = false + raw.WriteByte('\n') + } + raw.Write(chunk) + line = i + continue + } + } else if indent > 0 { + // not inside a fence: check for opening fence (indented only) + _, marker := isFenceLine(chunk, nil, "") + if marker != "" { + fenceMarker = marker + } + } + } + // If there is a fence line (marking starting of a code block) // without indent do not process it as part of the list. // diff --git a/testdata/bug346.tests b/testdata/bug346.tests new file mode 100644 index 00000000..0b54067b --- /dev/null +++ b/testdata/bug346.tests @@ -0,0 +1,86 @@ +- test1 + + ``` + - test + ``` +- test2 + + ``` + - test + ``` +- test3 + + ``` + - test + ``` ++++ +
test1
+ +- test
+test2
+ + - test
+test3
+ + - test
+item
+ +1. not a list
+item
+ +# not a heading
+item
+ +- dash in tilde fence
+item1
+ +``` +- should be code
item2