Skip to content

Commit

Permalink
#248 - 13
Browse files Browse the repository at this point in the history
  • Loading branch information
yuin committed Oct 21, 2021
1 parent 15ea976 commit 7557842
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 25 deletions.
25 changes: 25 additions & 0 deletions _test/extra.txt
Original file line number Diff line number Diff line change
Expand Up @@ -614,3 +614,28 @@ a</p>
b</li>
</ul>
//= = = = = = = = = = = = = = = = = = = = = = = =//


49: A list item that is indented up to 3 spaces after an empty list item
//- - - - - - - - -//
1.

1. b

-

- b
//- - - - - - - - -//
<ol>
<li></li>
<li>
<p>b</p>
</li>
</ol>
<ul>
<li></li>
<li>
<p>b</p>
</li>
</ul>
//= = = = = = = = = = = = = = = = = = = = = = = =//
55 changes: 38 additions & 17 deletions parser/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ const (
orderedList
)

var skipListParserKey = NewContextKey()
var emptyListItemWithBlankLines = NewContextKey()
var listItemFlagValue interface{} = true

// Same as
// `^(([ ]*)([\-\*\+]))(\s+.*)?\n?$`.FindSubmatchIndex or
// `^(([ ]*)(\d{1,9}[\.\)]))(\s+.*)?\n?$`.FindSubmatchIndex
Expand Down Expand Up @@ -123,8 +127,8 @@ func (b *listParser) Trigger() []byte {

func (b *listParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) {
last := pc.LastOpenedBlock().Node
if _, lok := last.(*ast.List); lok || pc.Get(skipListParser) != nil {
pc.Set(skipListParser, nil)
if _, lok := last.(*ast.List); lok || pc.Get(skipListParserKey) != nil {
pc.Set(skipListParserKey, nil)
return nil, NoChildren
}
line, _ := reader.PeekLine()
Expand Down Expand Up @@ -154,24 +158,18 @@ func (b *listParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.
if start > -1 {
node.Start = start
}
pc.Set(emptyListItemWithBlankLines, nil)
return node, HasChildren
}

func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) State {
list := node.(*ast.List)
line, _ := reader.PeekLine()
startsWithBlankLines := util.IsBlank(line)
if startsWithBlankLines {
if node.LastChild().ChildCount() != 0 {
return Continue | HasChildren
}
for {
reader.AdvanceLine()
line, _ = reader.PeekLine()
if !util.IsBlank(line) {
break
}
if util.IsBlank(line) {
if node.LastChild().ChildCount() == 0 {
pc.Set(emptyListItemWithBlankLines, listItemFlagValue)
}
return Continue | HasChildren
}

// "offset" means a width that bar indicates.
Expand All @@ -182,10 +180,23 @@ func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) Sta
// - a
// - b <--- current line
// it maybe a new child of the list.
//
// Empty list items can have multiple blanklines
//
// - <--- 1st item is an empty thus "offset" is unknown
//
//
// - <--- current line
//
// -> 1 list with 2 blank items
//
// So if the last item is an empty, it maybe a new child of the list.
//
offset := lastOffset(node)
lastIsEmpty := node.LastChild().ChildCount() == 0
indent, _ := util.IndentWidth(line, reader.LineOffset())

if indent < offset {
if indent < offset || lastIsEmpty {
if indent < 4 {
match, typ := matchesListItem(line, false) // may have a leading spaces more than 3
if typ != notList && match[1]-offset < 4 {
Expand All @@ -207,13 +218,23 @@ func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) Sta
return Close
}
}

return Continue | HasChildren
}
}
return Close
if !lastIsEmpty {
return Close
}
}
if startsWithBlankLines {

// Non empty items can not exist next to an empty list item
// with blank lines. So we need to close the current list
//
// -
//
// foo
//
// -> 1 list with 1 blank items and 1 paragraph
if pc.Get(emptyListItemWithBlankLines) != nil {
return Close
}
return Continue | HasChildren
Expand Down
19 changes: 11 additions & 8 deletions parser/list_item.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ func NewListItemParser() BlockParser {
return defaultListItemParser
}

var skipListParser = NewContextKey()
var skipListParserValue interface{} = true

func (b *listItemParser) Trigger() []byte {
return []byte{'-', '+', '*', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
}
Expand All @@ -38,6 +35,9 @@ func (b *listItemParser) Open(parent ast.Node, reader text.Reader, pc Context) (
if match[1]-offset > 3 {
return nil, NoChildren
}

pc.Set(emptyListItemWithBlankLines, nil)

itemOffset := calcListOffset(line, match)
node := ast.NewListItem(match[3] + itemOffset)
if match[4] < 0 || util.IsBlank(line[match[4]:match[5]]) {
Expand All @@ -54,19 +54,22 @@ func (b *listItemParser) Continue(node ast.Node, reader text.Reader, pc Context)
line, _ := reader.PeekLine()
if util.IsBlank(line) {
reader.Advance(len(line) - 1)

return Continue | HasChildren
}

indent, _ := util.IndentWidth(line, reader.LineOffset())
offset := lastOffset(node.Parent())
if indent < offset && indent < 4 {
isEmpty := node.ChildCount() == 0
indent, _ := util.IndentWidth(line, reader.LineOffset())
if (isEmpty || indent < offset) && indent < 4 {
_, typ := matchesListItem(line, true)
// new list item found
if typ != notList {
pc.Set(skipListParser, skipListParserValue)
pc.Set(skipListParserKey, listItemFlagValue)
return Close
}
if !isEmpty {
return Close
}
return Close
}
pos, padding := util.IndentPosition(line, reader.LineOffset(), offset)
reader.AdvanceAndSetPadding(pos, padding)
Expand Down

0 comments on commit 7557842

Please sign in to comment.