summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/gomarkdown/markdown/parser
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/gomarkdown/markdown/parser')
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/aside.go10
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/block.go134
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/block_table.go18
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/caption.go8
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/figures.go8
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/matter.go4
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/parser.go59
7 files changed, 147 insertions, 94 deletions
diff --git a/vendor/github.com/gomarkdown/markdown/parser/aside.go b/vendor/github.com/gomarkdown/markdown/parser/aside.go
index 96e25fe0..9d02ed04 100644
--- a/vendor/github.com/gomarkdown/markdown/parser/aside.go
+++ b/vendor/github.com/gomarkdown/markdown/parser/aside.go
@@ -25,13 +25,13 @@ func (p *Parser) asidePrefix(data []byte) int {
// aside ends with at least one blank line
// followed by something without a aside prefix
func (p *Parser) terminateAside(data []byte, beg, end int) bool {
- if p.isEmpty(data[beg:]) <= 0 {
+ if IsEmpty(data[beg:]) <= 0 {
return false
}
if end >= len(data) {
return true
}
- return p.asidePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0
+ return p.asidePrefix(data[end:]) == 0 && IsEmpty(data[end:]) == 0
}
// parse a aside fragment
@@ -66,8 +66,8 @@ func (p *Parser) aside(data []byte) int {
beg = end
}
- block := p.addBlock(&ast.Aside{})
- p.block(raw.Bytes())
- p.finalize(block)
+ block := p.AddBlock(&ast.Aside{})
+ p.Block(raw.Bytes())
+ p.Finalize(block)
return end
}
diff --git a/vendor/github.com/gomarkdown/markdown/parser/block.go b/vendor/github.com/gomarkdown/markdown/parser/block.go
index 490871c7..028ae758 100644
--- a/vendor/github.com/gomarkdown/markdown/parser/block.go
+++ b/vendor/github.com/gomarkdown/markdown/parser/block.go
@@ -103,10 +103,10 @@ func sanitizeHeadingID(text string) string {
return string(anchorName)
}
-// Parse block-level data.
+// Parse Block-level data.
// Note: this function and many that it calls assume that
// the input buffer ends with a newline.
-func (p *Parser) block(data []byte) {
+func (p *Parser) Block(data []byte) {
// this is called recursively: enforce a maximum depth
if p.nesting >= p.maxNesting {
return
@@ -142,7 +142,7 @@ func (p *Parser) block(data []byte) {
}
}
p.includeStack.Push(path)
- p.block(included)
+ p.Block(included)
p.includeStack.Pop()
data = data[consumed:]
continue
@@ -156,10 +156,10 @@ func (p *Parser) block(data []byte) {
data = data[consumed:]
if node != nil {
- p.addBlock(node)
+ p.AddBlock(node)
if blockdata != nil {
- p.block(blockdata)
- p.finalize(node)
+ p.Block(blockdata)
+ p.Finalize(node)
}
}
continue
@@ -213,7 +213,7 @@ func (p *Parser) block(data []byte) {
}
// blank lines. note: returns the # of bytes to skip
- if i := p.isEmpty(data); i > 0 {
+ if i := IsEmpty(data); i > 0 {
data = data[i:]
continue
}
@@ -255,11 +255,11 @@ func (p *Parser) block(data []byte) {
// ******
// or
// ______
- if p.isHRule(data) {
+ if isHRule(data) {
i := skipUntilChar(data, 0, '\n')
hr := ast.HorizontalRule{}
hr.Literal = bytes.Trim(data[:i], " \n")
- p.addBlock(&hr)
+ p.AddBlock(&hr)
data = data[i:]
continue
}
@@ -377,7 +377,7 @@ func (p *Parser) block(data []byte) {
p.nesting--
}
-func (p *Parser) addBlock(n ast.Node) ast.Node {
+func (p *Parser) AddBlock(n ast.Node) ast.Node {
p.closeUnmatchedBlocks()
if p.attr != nil {
@@ -448,7 +448,7 @@ func (p *Parser) prefixHeading(data []byte) int {
p.allHeadingsWithAutoID = append(p.allHeadingsWithAutoID, block)
}
block.Content = data[i:end]
- p.addBlock(block)
+ p.AddBlock(block)
}
return skip
}
@@ -521,7 +521,7 @@ func (p *Parser) prefixSpecialHeading(data []byte) int {
}
block.Literal = data[i:end]
block.Content = data[i:end]
- p.addBlock(block)
+ p.AddBlock(block)
}
return skip
}
@@ -572,7 +572,7 @@ func (p *Parser) titleBlock(data []byte, doRender bool) int {
IsTitleblock: true,
}
block.Content = data
- p.addBlock(block)
+ p.AddBlock(block)
return consumed
}
@@ -617,14 +617,14 @@ func (p *Parser) html(data []byte, doRender bool) int {
}
// see if it is the only thing on the line
- if skip := p.isEmpty(data[j:]); skip > 0 {
+ if skip := IsEmpty(data[j:]); skip > 0 {
// see if it is followed by a blank line/eof
j += skip
if j >= len(data) {
found = true
i = j
} else {
- if skip := p.isEmpty(data[j:]); skip > 0 {
+ if skip := IsEmpty(data[j:]); skip > 0 {
j += skip
found = true
i = j
@@ -667,7 +667,7 @@ func (p *Parser) html(data []byte, doRender bool) int {
// trim newlines
end := backChar(data, i, '\n')
htmlBLock := &ast.HTMLBlock{Leaf: ast.Leaf{Content: data[:end]}}
- p.addBlock(htmlBLock)
+ p.AddBlock(htmlBLock)
finalizeHTMLBlock(htmlBLock)
}
@@ -683,13 +683,13 @@ func finalizeHTMLBlock(block *ast.HTMLBlock) {
func (p *Parser) htmlComment(data []byte, doRender bool) int {
i := p.inlineHTMLComment(data)
// needs to end with a blank line
- if j := p.isEmpty(data[i:]); j > 0 {
+ if j := IsEmpty(data[i:]); j > 0 {
size := i + j
if doRender {
// trim trailing newlines
end := backChar(data, size, '\n')
htmlBLock := &ast.HTMLBlock{Leaf: ast.Leaf{Content: data[:end]}}
- p.addBlock(htmlBLock)
+ p.AddBlock(htmlBLock)
finalizeHTMLBlock(htmlBLock)
}
return size
@@ -715,13 +715,13 @@ func (p *Parser) htmlHr(data []byte, doRender bool) int {
}
if i < len(data) && data[i] == '>' {
i++
- if j := p.isEmpty(data[i:]); j > 0 {
+ if j := IsEmpty(data[i:]); j > 0 {
size := i + j
if doRender {
// trim newlines
end := backChar(data, size, '\n')
htmlBlock := &ast.HTMLBlock{Leaf: ast.Leaf{Content: data[:end]}}
- p.addBlock(htmlBlock)
+ p.AddBlock(htmlBlock)
finalizeHTMLBlock(htmlBlock)
}
return size
@@ -753,7 +753,7 @@ func (p *Parser) htmlFindEnd(tag string, data []byte) int {
// check that the rest of the line is blank
skip := 0
- if skip = p.isEmpty(data[i:]); skip == 0 {
+ if skip = IsEmpty(data[i:]); skip == 0 {
return 0
}
i += skip
@@ -766,7 +766,7 @@ func (p *Parser) htmlFindEnd(tag string, data []byte) int {
if p.extensions&LaxHTMLBlocks != 0 {
return i
}
- if skip = p.isEmpty(data[i:]); skip == 0 {
+ if skip = IsEmpty(data[i:]); skip == 0 {
// following line must be blank
return 0
}
@@ -774,7 +774,7 @@ func (p *Parser) htmlFindEnd(tag string, data []byte) int {
return i + skip
}
-func (*Parser) isEmpty(data []byte) int {
+func IsEmpty(data []byte) int {
// it is okay to call isEmpty on an empty buffer
if len(data) == 0 {
return 0
@@ -790,7 +790,7 @@ func (*Parser) isEmpty(data []byte) int {
return i
}
-func (*Parser) isHRule(data []byte) bool {
+func isHRule(data []byte) bool {
i := 0
// skip up to three spaces
@@ -976,7 +976,7 @@ func (p *Parser) fencedCodeBlock(data []byte, doRender bool) int {
codeBlock.Content = work.Bytes() // TODO: get rid of temp buffer
if p.extensions&Mmark == 0 {
- p.addBlock(codeBlock)
+ p.AddBlock(codeBlock)
finalizeCodeBlock(codeBlock)
return beg
}
@@ -988,12 +988,12 @@ func (p *Parser) fencedCodeBlock(data []byte, doRender bool) int {
figure.HeadingID = id
p.Inline(caption, captionContent)
- p.addBlock(figure)
+ p.AddBlock(figure)
codeBlock.AsLeaf().Attribute = figure.AsContainer().Attribute
p.addChild(codeBlock)
finalizeCodeBlock(codeBlock)
p.addChild(caption)
- p.finalize(figure)
+ p.Finalize(figure)
beg += consumed
@@ -1001,7 +1001,7 @@ func (p *Parser) fencedCodeBlock(data []byte, doRender bool) int {
}
// Still here, normal block
- p.addBlock(codeBlock)
+ p.AddBlock(codeBlock)
finalizeCodeBlock(codeBlock)
}
@@ -1055,13 +1055,13 @@ func (p *Parser) quotePrefix(data []byte) int {
// blockquote ends with at least one blank line
// followed by something without a blockquote prefix
func (p *Parser) terminateBlockquote(data []byte, beg, end int) bool {
- if p.isEmpty(data[beg:]) <= 0 {
+ if IsEmpty(data[beg:]) <= 0 {
return false
}
if end >= len(data) {
return true
}
- return p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0
+ return p.quotePrefix(data[end:]) == 0 && IsEmpty(data[end:]) == 0
}
// parse a blockquote fragment
@@ -1096,9 +1096,9 @@ func (p *Parser) quote(data []byte) int {
}
if p.extensions&Mmark == 0 {
- block := p.addBlock(&ast.BlockQuote{})
- p.block(raw.Bytes())
- p.finalize(block)
+ block := p.AddBlock(&ast.BlockQuote{})
+ p.Block(raw.Bytes())
+ p.Finalize(block)
return end
}
@@ -1108,24 +1108,24 @@ func (p *Parser) quote(data []byte) int {
figure.HeadingID = id
p.Inline(caption, captionContent)
- p.addBlock(figure) // this discard any attributes
+ p.AddBlock(figure) // this discard any attributes
block := &ast.BlockQuote{}
block.AsContainer().Attribute = figure.AsContainer().Attribute
p.addChild(block)
- p.block(raw.Bytes())
- p.finalize(block)
+ p.Block(raw.Bytes())
+ p.Finalize(block)
p.addChild(caption)
- p.finalize(figure)
+ p.Finalize(figure)
end += consumed
return end
}
- block := p.addBlock(&ast.BlockQuote{})
- p.block(raw.Bytes())
- p.finalize(block)
+ block := p.AddBlock(&ast.BlockQuote{})
+ p.Block(raw.Bytes())
+ p.Finalize(block)
return end
}
@@ -1152,7 +1152,7 @@ func (p *Parser) code(data []byte) int {
i = skipUntilChar(data, i, '\n')
i = skipCharN(data, i, '\n', 1)
- blankline := p.isEmpty(data[beg:i]) > 0
+ blankline := IsEmpty(data[beg:i]) > 0
if pre := p.codePrefix(data[beg:i]); pre > 0 {
beg += pre
} else if !blankline {
@@ -1185,7 +1185,7 @@ func (p *Parser) code(data []byte) int {
}
// TODO: get rid of temp buffer
codeBlock.Content = work.Bytes()
- p.addBlock(codeBlock)
+ p.AddBlock(codeBlock)
finalizeCodeBlock(codeBlock)
return i
@@ -1237,10 +1237,29 @@ func (p *Parser) dliPrefix(data []byte) int {
if data[0] != ':' || !(data[1] == ' ' || data[1] == '\t') {
return 0
}
+ // TODO: this is a no-op (data[0] is ':' so not ' ').
+ // Maybe the intent was to eat spaces before ':' ?
+ // either way, no change in tests
i := skipChar(data, 0, ' ')
return i + 2
}
+// TODO: maybe it was meant to be like below
+// either way, no change in tests
+/*
+func (p *Parser) dliPrefix(data []byte) int {
+ i := skipChar(data, 0, ' ')
+ if i+len(data) < 2 {
+ return 0
+ }
+ // need a ':' followed by a space or a tab
+ if data[i] != ':' || !(data[i+1] == ' ' || data[i+1] == '\t') {
+ return 0
+ }
+ return i + 2
+}
+*/
+
// parse ordered or unordered list block
func (p *Parser) list(data []byte, flags ast.ListType, start int, delim byte) int {
i := 0
@@ -1251,7 +1270,7 @@ func (p *Parser) list(data []byte, flags ast.ListType, start int, delim byte) in
Start: start,
Delimiter: delim,
}
- block := p.addBlock(list)
+ block := p.AddBlock(list)
for i < len(data) {
skip := p.listItem(data[i:], &flags)
@@ -1398,7 +1417,7 @@ gatherlines:
// if it is an empty line, guess that it is part of this item
// and move on to the next line
- if p.isEmpty(data[line:i]) > 0 {
+ if IsEmpty(data[line:i]) > 0 {
containsBlankLine = true
line = i
continue
@@ -1432,7 +1451,7 @@ gatherlines:
// evaluate how this line fits in
switch {
// is this a nested list item?
- case (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) || p.oliPrefix(chunk) > 0 || p.dliPrefix(chunk) > 0:
+ case (p.uliPrefix(chunk) > 0 && !isHRule(chunk)) || p.oliPrefix(chunk) > 0 || p.dliPrefix(chunk) > 0:
// if indent is 4 or more spaces on unordered or ordered lists
// we need to add leadingWhiteSpaces + 1 spaces in the beginning of the chunk
@@ -1484,10 +1503,7 @@ gatherlines:
case containsBlankLine && indent < 4:
if *flags&ast.ListTypeDefinition != 0 && i < len(data)-1 {
// is the next item still a part of this list?
- next := i
- for next < len(data) && data[next] != '\n' {
- next++
- }
+ next := skipUntilChar(data, i, '\n')
for next < len(data)-1 && data[next] == '\n' {
next++
}
@@ -1526,16 +1542,16 @@ gatherlines:
BulletChar: bulletChar,
Delimiter: delimiter,
}
- p.addBlock(listItem)
+ p.AddBlock(listItem)
// render the contents of the list item
if *flags&ast.ListItemContainsBlock != 0 && *flags&ast.ListTypeTerm == 0 {
// intermediate render of block item, except for definition term
if sublist > 0 {
- p.block(rawBytes[:sublist])
- p.block(rawBytes[sublist:])
+ p.Block(rawBytes[:sublist])
+ p.Block(rawBytes[sublist:])
} else {
- p.block(rawBytes)
+ p.Block(rawBytes)
}
} else {
// intermediate render of inline item
@@ -1547,7 +1563,7 @@ gatherlines:
}
p.addChild(para)
if sublist > 0 {
- p.block(rawBytes[sublist:])
+ p.Block(rawBytes[sublist:])
}
}
return line
@@ -1574,7 +1590,7 @@ func (p *Parser) renderParagraph(data []byte) {
}
para := &ast.Paragraph{}
para.Content = data[beg:end]
- p.addBlock(para)
+ p.AddBlock(para)
}
// blockMath handle block surround with $$
@@ -1596,7 +1612,7 @@ func (p *Parser) blockMath(data []byte) int {
// render the display math
mathBlock := &ast.MathBlock{}
mathBlock.Literal = data[2:end]
- p.addBlock(mathBlock)
+ p.AddBlock(mathBlock)
return end + 2
}
@@ -1626,7 +1642,7 @@ func (p *Parser) paragraph(data []byte) int {
}
// did we find a blank line marking the end of the paragraph?
- if n := p.isEmpty(current); n > 0 {
+ if n := IsEmpty(current); n > 0 {
// did this blank line followed by a definition list item?
if p.extensions&DefinitionLists != 0 {
if i < len(data)-1 && data[i+1] == ':' {
@@ -1663,7 +1679,7 @@ func (p *Parser) paragraph(data []byte) int {
}
block.Content = data[prev:eol]
- p.addBlock(block)
+ p.AddBlock(block)
// find the end of the underline
return skipUntilChar(data, i, '\n')
@@ -1680,7 +1696,7 @@ func (p *Parser) paragraph(data []byte) int {
}
// if there's a prefixed heading or a horizontal rule after this, paragraph is over
- if p.isPrefixHeading(current) || p.isPrefixSpecialHeading(current) || p.isHRule(current) {
+ if p.isPrefixHeading(current) || p.isPrefixSpecialHeading(current) || isHRule(current) {
p.renderParagraph(data[:i])
return i
}
diff --git a/vendor/github.com/gomarkdown/markdown/parser/block_table.go b/vendor/github.com/gomarkdown/markdown/parser/block_table.go
index 0bf4f4ad..fa8efdf2 100644
--- a/vendor/github.com/gomarkdown/markdown/parser/block_table.go
+++ b/vendor/github.com/gomarkdown/markdown/parser/block_table.go
@@ -12,7 +12,7 @@ func isBackslashEscaped(data []byte, i int) bool {
}
func (p *Parser) tableRow(data []byte, columns []ast.CellAlignFlags, header bool) {
- p.addBlock(&ast.TableRow{})
+ p.AddBlock(&ast.TableRow{})
col := 0
i := skipChar(data, 0, '|')
@@ -61,7 +61,7 @@ func (p *Parser) tableRow(data []byte, columns []ast.CellAlignFlags, header bool
// an empty cell that we should ignore, it exists because of colspan
colspans--
} else {
- p.addBlock(block)
+ p.AddBlock(block)
}
if colspan > 0 {
@@ -75,7 +75,7 @@ func (p *Parser) tableRow(data []byte, columns []ast.CellAlignFlags, header bool
IsHeader: header,
Align: columns[col],
}
- p.addBlock(block)
+ p.AddBlock(block)
}
// silently ignore rows with too many cells
@@ -109,7 +109,7 @@ func (p *Parser) tableFooter(data []byte) bool {
return false
}
- p.addBlock(&ast.TableFooter{})
+ p.AddBlock(&ast.TableFooter{})
return true
}
@@ -217,7 +217,7 @@ func (p *Parser) tableHeader(data []byte, doRender bool) (size int, columns []as
}
// end of column test is messy
switch {
- case dashes < 3:
+ case dashes < 1:
// not a valid column
return
@@ -253,9 +253,9 @@ func (p *Parser) tableHeader(data []byte, doRender bool) (size int, columns []as
if doRender {
table = &ast.Table{}
- p.addBlock(table)
+ p.AddBlock(table)
if header != nil {
- p.addBlock(&ast.TableHeader{})
+ p.AddBlock(&ast.TableHeader{})
p.tableRow(header, columns, true)
}
}
@@ -277,7 +277,7 @@ func (p *Parser) table(data []byte) int {
return 0
}
- p.addBlock(&ast.TableBody{})
+ p.AddBlock(&ast.TableBody{})
for i < len(data) {
pipes, rowStart := 0, i
@@ -319,7 +319,7 @@ func (p *Parser) table(data []byte) int {
ast.AppendChild(figure, caption)
p.addChild(figure)
- p.finalize(figure)
+ p.Finalize(figure)
i += consumed
}
diff --git a/vendor/github.com/gomarkdown/markdown/parser/caption.go b/vendor/github.com/gomarkdown/markdown/parser/caption.go
index fe31711a..08794504 100644
--- a/vendor/github.com/gomarkdown/markdown/parser/caption.go
+++ b/vendor/github.com/gomarkdown/markdown/parser/caption.go
@@ -11,7 +11,7 @@ func (p *Parser) caption(data, caption []byte) ([]byte, string, int) {
}
j := len(caption)
data = data[j:]
- end := p.linesUntilEmpty(data)
+ end := LinesUntilEmpty(data)
data = data[:end]
@@ -23,8 +23,8 @@ func (p *Parser) caption(data, caption []byte) ([]byte, string, int) {
return data, "", end + j
}
-// linesUntilEmpty scans lines up to the first empty line.
-func (p *Parser) linesUntilEmpty(data []byte) int {
+// LinesUntilEmpty scans lines up to the first empty line.
+func LinesUntilEmpty(data []byte) int {
line, i := 0, 0
for line < len(data) {
@@ -35,7 +35,7 @@ func (p *Parser) linesUntilEmpty(data []byte) int {
i++
}
- if p.isEmpty(data[line:i]) == 0 {
+ if IsEmpty(data[line:i]) == 0 {
line = i
continue
}
diff --git a/vendor/github.com/gomarkdown/markdown/parser/figures.go b/vendor/github.com/gomarkdown/markdown/parser/figures.go
index 6615449c..0566c16e 100644
--- a/vendor/github.com/gomarkdown/markdown/parser/figures.go
+++ b/vendor/github.com/gomarkdown/markdown/parser/figures.go
@@ -98,10 +98,10 @@ func (p *Parser) figureBlock(data []byte, doRender bool) int {
}
figure := &ast.CaptionFigure{}
- p.addBlock(figure)
- p.block(raw.Bytes())
+ p.AddBlock(figure)
+ p.Block(raw.Bytes())
- defer p.finalize(figure)
+ defer p.Finalize(figure)
if captionContent, id, consumed := p.caption(data[beg:], []byte("Figure: ")); consumed > 0 {
caption := &ast.Caption{}
@@ -113,7 +113,5 @@ func (p *Parser) figureBlock(data []byte, doRender bool) int {
beg += consumed
}
-
- p.finalize(figure)
return beg
}
diff --git a/vendor/github.com/gomarkdown/markdown/parser/matter.go b/vendor/github.com/gomarkdown/markdown/parser/matter.go
index 92686357..df284237 100644
--- a/vendor/github.com/gomarkdown/markdown/parser/matter.go
+++ b/vendor/github.com/gomarkdown/markdown/parser/matter.go
@@ -29,8 +29,8 @@ func (p *Parser) documentMatter(data []byte) int {
return 0
}
node := &ast.DocumentMatter{Matter: matter}
- p.addBlock(node)
- p.finalize(node)
+ p.AddBlock(node)
+ p.Finalize(node)
return consumed
}
diff --git a/vendor/github.com/gomarkdown/markdown/parser/parser.go b/vendor/github.com/gomarkdown/markdown/parser/parser.go
index 07444cd8..91123e1b 100644
--- a/vendor/github.com/gomarkdown/markdown/parser/parser.go
+++ b/vendor/github.com/gomarkdown/markdown/parser/parser.go
@@ -42,7 +42,7 @@ const (
SuperSubscript // Super- and subscript support: 2^10^, H~2~O.
EmptyLinesBreakList // 2 empty lines break out of list
Includes // Support including other files.
- Mmark // Support Mmark syntax, see https://mmark.nl/syntax
+ Mmark // Support Mmark syntax, see https://mmark.miek.nl/post/syntax/
CommonExtensions Extensions = NoIntraEmphasis | Tables | FencedCode |
Autolink | Strikethrough | SpaceHeadings | HeadingIDs |
@@ -206,13 +206,13 @@ func (p *Parser) isFootnote(ref *reference) bool {
return ok
}
-func (p *Parser) finalize(block ast.Node) {
+func (p *Parser) Finalize(block ast.Node) {
p.tip = block.GetParent()
}
func (p *Parser) addChild(node ast.Node) ast.Node {
for !canNodeContain(p.tip, node) {
- p.finalize(p.tip)
+ p.Finalize(p.tip)
}
ast.AppendChild(p.tip, node)
p.tip = node
@@ -239,6 +239,18 @@ func canNodeContain(n ast.Node, v ast.Node) bool {
_, ok := v.(*ast.TableCell)
return ok
}
+ // for nodes implemented outside of ast package, allow them
+ // to implement this logic via CanContain interface
+ if o, ok := n.(ast.CanContain); ok {
+ return o.CanContain(v)
+ }
+ // for container nodes outside of ast package default to true
+ // because false is a bad default
+ typ := fmt.Sprintf("%T", n)
+ customNode := !strings.HasPrefix(typ, "*ast.")
+ if customNode {
+ return n.AsLeaf() == nil
+ }
return false
}
@@ -248,7 +260,7 @@ func (p *Parser) closeUnmatchedBlocks() {
}
for p.oldTip != p.lastMatchedContainer {
parent := p.oldTip.GetParent()
- p.finalize(p.oldTip)
+ p.Finalize(p.oldTip)
p.oldTip = parent
}
p.allClosed = true
@@ -273,10 +285,14 @@ type Reference struct {
// You can then convert AST to html using html.Renderer, to some other format
// using a custom renderer or transform the tree.
func (p *Parser) Parse(input []byte) ast.Node {
- p.block(input)
+ // the code only works with Unix CR newlines so to make life easy for
+ // callers normalize newlines
+ input = NormalizeNewlines(input)
+
+ p.Block(input)
// Walk the tree and finish up some of unfinished blocks
for p.tip != nil {
- p.finalize(p.tip)
+ p.Finalize(p.tip)
}
// Walk the tree again and process inline markdown in each block
ast.WalkFunc(p.Doc, func(node ast.Node, entering bool) ast.WalkStatus {
@@ -322,8 +338,8 @@ func (p *Parser) parseRefsToAST() {
IsFootnotesList: true,
ListFlags: ast.ListTypeOrdered,
}
- p.addBlock(&ast.Footnotes{})
- block := p.addBlock(list)
+ p.AddBlock(&ast.Footnotes{})
+ block := p.AddBlock(list)
flags := ast.ListItemBeginningOfList
// Note: this loop is intentionally explicit, not range-form. This is
// because the body of the loop will append nested footnotes to p.notes and
@@ -338,7 +354,7 @@ func (p *Parser) parseRefsToAST() {
listItem.RefLink = ref.link
if ref.hasBlock {
flags |= ast.ListItemContainsBlock
- p.block(ref.title)
+ p.Block(ref.title)
} else {
p.Inline(block, ref.title)
}
@@ -660,7 +676,7 @@ gatherLines:
// if it is an empty line, guess that it is part of this item
// and move on to the next line
- if p.isEmpty(data[blockEnd:i]) > 0 {
+ if IsEmpty(data[blockEnd:i]) > 0 {
containsBlankLine = true
blockEnd = i
continue
@@ -883,3 +899,26 @@ func isListItem(d ast.Node) bool {
_, ok := d.(*ast.ListItem)
return ok
}
+
+func NormalizeNewlines(d []byte) []byte {
+ wi := 0
+ n := len(d)
+ for i := 0; i < n; i++ {
+ c := d[i]
+ // 13 is CR
+ if c != 13 {
+ d[wi] = c
+ wi++
+ continue
+ }
+ // replace CR (mac / win) with LF (unix)
+ d[wi] = 10
+ wi++
+ if i < n-1 && d[i+1] == 10 {
+ // this was CRLF, so skip the LF
+ i++
+ }
+
+ }
+ return d[:wi]
+}