summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/gomarkdown/markdown
diff options
context:
space:
mode:
authorWim <wim@42.be>2021-10-17 00:47:22 +0200
committerGitHub <noreply@github.com>2021-10-17 00:47:22 +0200
commit4dd8bae5c91fa4aef09d865d8fef1acd84f90925 (patch)
treeffad9b242daccaf8c86d1c1fbd59032302bd3be9 /vendor/github.com/gomarkdown/markdown
parent7ae45c42e712bd0e66c101f3f714c05aa1dc2104 (diff)
downloadmatterbridge-msglm-4dd8bae5c91fa4aef09d865d8fef1acd84f90925.tar.gz
matterbridge-msglm-4dd8bae5c91fa4aef09d865d8fef1acd84f90925.tar.bz2
matterbridge-msglm-4dd8bae5c91fa4aef09d865d8fef1acd84f90925.zip
Update dependencies (#1610)
* Update dependencies * Update module to go 1.17
Diffstat (limited to 'vendor/github.com/gomarkdown/markdown')
-rw-r--r--vendor/github.com/gomarkdown/markdown/.gitpod7
-rw-r--r--vendor/github.com/gomarkdown/markdown/README.md23
-rw-r--r--vendor/github.com/gomarkdown/markdown/ast/attribute.go10
-rw-r--r--vendor/github.com/gomarkdown/markdown/ast/node.go9
-rw-r--r--vendor/github.com/gomarkdown/markdown/go.mod5
-rw-r--r--vendor/github.com/gomarkdown/markdown/go.sum1
-rw-r--r--vendor/github.com/gomarkdown/markdown/html/renderer.go41
-rw-r--r--vendor/github.com/gomarkdown/markdown/markdown.go26
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/block.go332
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/block_table.go311
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/inline.go2
-rw-r--r--vendor/github.com/gomarkdown/markdown/parser/parser.go24
-rw-r--r--vendor/github.com/gomarkdown/markdown/tracking-perf.md189
13 files changed, 428 insertions, 552 deletions
diff --git a/vendor/github.com/gomarkdown/markdown/.gitpod b/vendor/github.com/gomarkdown/markdown/.gitpod
deleted file mode 100644
index ad5feff6..00000000
--- a/vendor/github.com/gomarkdown/markdown/.gitpod
+++ /dev/null
@@ -1,7 +0,0 @@
-checkoutLocation: "src/github.com/gomarkdown/markdown"
-workspaceLocation: "."
-tasks:
- - command: >
- cd /workspace/src/github.com/gomarkdown/markdown &&
- go get -v ./... &&
- go test -c
diff --git a/vendor/github.com/gomarkdown/markdown/README.md b/vendor/github.com/gomarkdown/markdown/README.md
index a40c7a94..7efc1919 100644
--- a/vendor/github.com/gomarkdown/markdown/README.md
+++ b/vendor/github.com/gomarkdown/markdown/README.md
@@ -25,6 +25,7 @@ Some tools using this package:
- https://github.com/romanyx/mdopen : view markdown files in the default browser
- https://github.com/ystyle/sqlmanager : a library for manager sql with markdown like beetsql
- https://gitlab.com/kendellfab/fazer : library for making templates
+- https://github.com/blmayer/tasker : a simple task list web app
## Usage
@@ -130,6 +131,12 @@ maybeUnsafeHTML := markdown.ToHTML(md, nil, nil)
html := bluemonday.UGCPolicy().SanitizeBytes(maybeUnsafeHTML)
```
+## Windows / Mac newlines
+
+The library only supports Unix newlines. If you have markdown text with possibly
+Windows / Mac newlines, normalize newlines before caling this librar using
+`d = markdown.NormalizeNewlines(d)`
+
## mdtohtml command-line tool
https://github.com/gomarkdown/mdtohtml is a command-line markdown to html
@@ -259,10 +266,10 @@ implements the following extensions:
should be crossed out.
- **Hard line breaks**. With this extension enabled newlines in the input
- translate into line breaks in the output. This extension is off by default.
+ translates into line breaks in the output. This extension is off by default.
-- **Non blocking space**. With this extension enabled spaces preceeded by an backslash n the input
- translate non-blocking spaces in the output. This extension is off by default.
+- **Non blocking space**. With this extension enabled spaces preceeded by a backslash
+ in the input translates non-blocking spaces in the output. This extension is off by default.
- **Smart quotes**. Smartypants-style punctuation substitution is
supported, turning normal double- and single-quote marks into
@@ -281,9 +288,9 @@ implements the following extensions:
<sup>4</sup>&frasl;<sub>5</sub>.
- **MathJaX Support** is an additional feature which is supported by
- many markdown editor. It translate inline math equation quoted by `$`
- and display math block quoted by `$$` into MathJax compatible format.
- hyphen `_` won't break LaTeX render within a math element any more.
+ many markdown editor. It translates inline math equations quoted by `$`
+ and displays math blocks quoted by `$$` into MathJax compatible format.
+ Hyphens (`_`) won't break LaTeX render within a math element any more.
```
$$
@@ -299,13 +306,13 @@ implements the following extensions:
$$
```
-- **Ordered list start number**. With this extension enabled an ordered list will start with the
+- **Ordered list start number**. With this extension enabled an ordered list will start with
the number that was used to start it.
- **Super and subscript**. With this extension enabled sequences between ^ will indicate
superscript and ~ will become a subscript. For example: H~2~O is a liquid, 2^10^ is 1024.
-- **Block level attributes**, allow setting attributes (ID, classes and key/value pairs) on block
+- **Block level attributes** allow setting attributes (ID, classes and key/value pairs) on block
level elements. The attribute must be enclosed with braces and be put on a line before the
element.
diff --git a/vendor/github.com/gomarkdown/markdown/ast/attribute.go b/vendor/github.com/gomarkdown/markdown/ast/attribute.go
deleted file mode 100644
index 002c6a2e..00000000
--- a/vendor/github.com/gomarkdown/markdown/ast/attribute.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package ast
-
-// An attribute can be attached to block elements. They are specified as
-// {#id .classs key="value"} where quotes for values are mandatory, multiple
-// key/value pairs are separated by whitespace.
-type Attribute struct {
- ID []byte
- Classes [][]byte
- Attrs map[string][]byte
-}
diff --git a/vendor/github.com/gomarkdown/markdown/ast/node.go b/vendor/github.com/gomarkdown/markdown/ast/node.go
index 7881f6e7..0d7175c5 100644
--- a/vendor/github.com/gomarkdown/markdown/ast/node.go
+++ b/vendor/github.com/gomarkdown/markdown/ast/node.go
@@ -1,5 +1,14 @@
package ast
+// An attribute can be attached to block elements. They are specified as
+// {#id .classs key="value"} where quotes for values are mandatory, multiple
+// key/value pairs are separated by whitespace.
+type Attribute struct {
+ ID []byte
+ Classes [][]byte
+ Attrs map[string][]byte
+}
+
// ListType contains bitwise or'ed flags for list and list item objects.
type ListType int
diff --git a/vendor/github.com/gomarkdown/markdown/go.mod b/vendor/github.com/gomarkdown/markdown/go.mod
deleted file mode 100644
index 899e3237..00000000
--- a/vendor/github.com/gomarkdown/markdown/go.mod
+++ /dev/null
@@ -1,5 +0,0 @@
-module github.com/gomarkdown/markdown
-
-go 1.12
-
-require golang.org/dl v0.0.0-20190829154251-82a15e2f2ead // indirect
diff --git a/vendor/github.com/gomarkdown/markdown/go.sum b/vendor/github.com/gomarkdown/markdown/go.sum
deleted file mode 100644
index 1406b01f..00000000
--- a/vendor/github.com/gomarkdown/markdown/go.sum
+++ /dev/null
@@ -1 +0,0 @@
-golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
diff --git a/vendor/github.com/gomarkdown/markdown/html/renderer.go b/vendor/github.com/gomarkdown/markdown/html/renderer.go
index 1b466876..68868573 100644
--- a/vendor/github.com/gomarkdown/markdown/html/renderer.go
+++ b/vendor/github.com/gomarkdown/markdown/html/renderer.go
@@ -304,25 +304,6 @@ func isRelativeLink(link []byte) (yes bool) {
return false
}
-func (r *Renderer) ensureUniqueHeadingID(id string) string {
- for count, found := r.headingIDs[id]; found; count, found = r.headingIDs[id] {
- tmp := fmt.Sprintf("%s-%d", id, count+1)
-
- if _, tmpFound := r.headingIDs[tmp]; !tmpFound {
- r.headingIDs[id] = count + 1
- id = tmp
- } else {
- id = id + "-1"
- }
- }
-
- if _, found := r.headingIDs[id]; !found {
- r.headingIDs[id] = 0
- }
-
- return id
-}
-
func (r *Renderer) addAbsPrefix(link []byte) []byte {
if r.opts.AbsolutePrefix != "" && isRelativeLink(link) && link[0] != '.' {
newDest := r.opts.AbsolutePrefix
@@ -701,8 +682,28 @@ func (r *Renderer) headingEnter(w io.Writer, nodeData *ast.Heading) {
if class != "" {
attrs = []string{`class="` + class + `"`}
}
+
+ ensureUniqueHeadingID := func(id string) string {
+ for count, found := r.headingIDs[id]; found; count, found = r.headingIDs[id] {
+ tmp := fmt.Sprintf("%s-%d", id, count+1)
+
+ if _, tmpFound := r.headingIDs[tmp]; !tmpFound {
+ r.headingIDs[id] = count + 1
+ id = tmp
+ } else {
+ id = id + "-1"
+ }
+ }
+
+ if _, found := r.headingIDs[id]; !found {
+ r.headingIDs[id] = 0
+ }
+
+ return id
+ }
+
if nodeData.HeadingID != "" {
- id := r.ensureUniqueHeadingID(nodeData.HeadingID)
+ id := ensureUniqueHeadingID(nodeData.HeadingID)
if r.opts.HeadingIDPrefix != "" {
id = r.opts.HeadingIDPrefix + id
}
diff --git a/vendor/github.com/gomarkdown/markdown/markdown.go b/vendor/github.com/gomarkdown/markdown/markdown.go
index fd5c1cfb..537eb27b 100644
--- a/vendor/github.com/gomarkdown/markdown/markdown.go
+++ b/vendor/github.com/gomarkdown/markdown/markdown.go
@@ -83,3 +83,29 @@ func ToHTML(markdown []byte, p *parser.Parser, renderer Renderer) []byte {
}
return Render(doc, renderer)
}
+
+// NormalizeNewlines converts Windows and Mac newlines to Unix newlines
+// The parser only supports Unix newlines. If your mardown content
+// might contain Windows or Mac newlines, use this function to convert to Unix newlines
+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]
+}
diff --git a/vendor/github.com/gomarkdown/markdown/parser/block.go b/vendor/github.com/gomarkdown/markdown/parser/block.go
index 95438174..7d7e9f9c 100644
--- a/vendor/github.com/gomarkdown/markdown/parser/block.go
+++ b/vendor/github.com/gomarkdown/markdown/parser/block.go
@@ -74,9 +74,9 @@ var (
}
)
-// sanitizeAnchorName returns a sanitized anchor name for the given text.
+// sanitizeHeadingID returns a sanitized anchor name for the given text.
// Taken from https://github.com/shurcooL/sanitized_anchor_name/blob/master/main.go#L14:1
-func sanitizeAnchorName(text string) string {
+func sanitizeHeadingID(text string) string {
var anchorName []rune
var futureDash = false
for _, r := range text {
@@ -91,6 +91,9 @@ func sanitizeAnchorName(text string) string {
futureDash = true
}
}
+ if len(anchorName) == 0 {
+ return "empty"
+ }
return string(anchorName)
}
@@ -278,12 +281,6 @@ func (p *Parser) block(data []byte) {
}
}
- // table:
- //
- // Name | Age | Phone
- // ------|-----|---------
- // Bob | 31 | 555-1234
- // Alice | 27 | 555-4321
if p.extensions&Tables != 0 {
if i := p.table(data); i > 0 {
data = data[i:]
@@ -422,13 +419,14 @@ func (p *Parser) prefixHeading(data []byte) int {
end--
}
if end > i {
- if id == "" && p.extensions&AutoHeadingIDs != 0 {
- id = sanitizeAnchorName(string(data[i:end]))
- }
block := &ast.Heading{
HeadingID: id,
Level: level,
}
+ if id == "" && p.extensions&AutoHeadingIDs != 0 {
+ block.HeadingID = sanitizeHeadingID(string(data[i:end]))
+ p.allHeadingsWithAutoID = append(p.allHeadingsWithAutoID, block)
+ }
block.Content = data[i:end]
p.addBlock(block)
}
@@ -492,14 +490,15 @@ func (p *Parser) prefixSpecialHeading(data []byte) int {
end--
}
if end > i {
- if id == "" && p.extensions&AutoHeadingIDs != 0 {
- id = sanitizeAnchorName(string(data[i:end]))
- }
block := &ast.Heading{
HeadingID: id,
IsSpecial: true,
Level: 1, // always level 1.
}
+ if id == "" && p.extensions&AutoHeadingIDs != 0 {
+ block.HeadingID = sanitizeHeadingID(string(data[i:end]))
+ p.allHeadingsWithAutoID = append(p.allHeadingsWithAutoID, block)
+ }
block.Literal = data[i:end]
block.Content = data[i:end]
p.addBlock(block)
@@ -647,7 +646,7 @@ func (p *Parser) html(data []byte, doRender bool) int {
if doRender {
// trim newlines
end := backChar(data, i, '\n')
- htmlBLock := &ast.HTMLBlock{ast.Leaf{Content: data[:end]}}
+ htmlBLock := &ast.HTMLBlock{Leaf: ast.Leaf{Content: data[:end]}}
p.addBlock(htmlBLock)
finalizeHTMLBlock(htmlBLock)
}
@@ -669,7 +668,7 @@ func (p *Parser) htmlComment(data []byte, doRender bool) int {
if doRender {
// trim trailing newlines
end := backChar(data, size, '\n')
- htmlBLock := &ast.HTMLBlock{ast.Leaf{Content: data[:end]}}
+ htmlBLock := &ast.HTMLBlock{Leaf: ast.Leaf{Content: data[:end]}}
p.addBlock(htmlBLock)
finalizeHTMLBlock(htmlBLock)
}
@@ -701,7 +700,7 @@ func (p *Parser) htmlHr(data []byte, doRender bool) int {
if doRender {
// trim newlines
end := backChar(data, size, '\n')
- htmlBlock := &ast.HTMLBlock{ast.Leaf{Content: data[:end]}}
+ htmlBlock := &ast.HTMLBlock{Leaf: ast.Leaf{Content: data[:end]}}
p.addBlock(htmlBlock)
finalizeHTMLBlock(htmlBlock)
}
@@ -1005,294 +1004,6 @@ func finalizeCodeBlock(code *ast.CodeBlock) {
code.Content = nil
}
-func (p *Parser) table(data []byte) int {
- i, columns, table := p.tableHeader(data)
- if i == 0 {
- return 0
- }
-
- p.addBlock(&ast.TableBody{})
-
- for i < len(data) {
- pipes, rowStart := 0, i
- for ; i < len(data) && data[i] != '\n'; i++ {
- if data[i] == '|' {
- pipes++
- }
- }
-
- if pipes == 0 {
- i = rowStart
- break
- }
-
- // include the newline in data sent to tableRow
- i = skipCharN(data, i, '\n', 1)
-
- if p.tableFooter(data[rowStart:i]) {
- continue
- }
-
- p.tableRow(data[rowStart:i], columns, false)
- }
- if captionContent, id, consumed := p.caption(data[i:], []byte("Table: ")); consumed > 0 {
- caption := &ast.Caption{}
- p.Inline(caption, captionContent)
-
- // Some switcheroo to re-insert the parsed table as a child of the captionfigure.
- figure := &ast.CaptionFigure{}
- figure.HeadingID = id
- table2 := &ast.Table{}
- // Retain any block level attributes.
- table2.AsContainer().Attribute = table.AsContainer().Attribute
- children := table.GetChildren()
- ast.RemoveFromTree(table)
-
- table2.SetChildren(children)
- ast.AppendChild(figure, table2)
- ast.AppendChild(figure, caption)
-
- p.addChild(figure)
- p.finalize(figure)
-
- i += consumed
- }
-
- return i
-}
-
-// check if the specified position is preceded by an odd number of backslashes
-func isBackslashEscaped(data []byte, i int) bool {
- backslashes := 0
- for i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\' {
- backslashes++
- }
- return backslashes&1 == 1
-}
-
-// tableHeaders parses the header. If recognized it will also add a table.
-func (p *Parser) tableHeader(data []byte) (size int, columns []ast.CellAlignFlags, table ast.Node) {
- i := 0
- colCount := 1
- headerIsUnderline := true
- for i = 0; i < len(data) && data[i] != '\n'; i++ {
- if data[i] == '|' && !isBackslashEscaped(data, i) {
- colCount++
- }
- if data[i] != '-' && data[i] != ' ' && data[i] != ':' && data[i] != '|' {
- headerIsUnderline = false
- }
- }
-
- // doesn't look like a table header
- if colCount == 1 {
- return
- }
-
- // include the newline in the data sent to tableRow
- j := skipCharN(data, i, '\n', 1)
- header := data[:j]
-
- // column count ignores pipes at beginning or end of line
- if data[0] == '|' {
- colCount--
- }
- if i > 2 && data[i-1] == '|' && !isBackslashEscaped(data, i-1) {
- colCount--
- }
-
- // if the header looks like a underline, then we omit the header
- // and parse the first line again as underline
- if headerIsUnderline {
- header = nil
- i = 0
- } else {
- i++ // move past newline
- }
-
- columns = make([]ast.CellAlignFlags, colCount)
-
- // move on to the header underline
- if i >= len(data) {
- return
- }
-
- if data[i] == '|' && !isBackslashEscaped(data, i) {
- i++
- }
- i = skipChar(data, i, ' ')
-
- // each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3
- // and trailing | optional on last column
- col := 0
- n := len(data)
- for i < n && data[i] != '\n' {
- dashes := 0
-
- if data[i] == ':' {
- i++
- columns[col] |= ast.TableAlignmentLeft
- dashes++
- }
- for i < n && data[i] == '-' {
- i++
- dashes++
- }
- if i < n && data[i] == ':' {
- i++
- columns[col] |= ast.TableAlignmentRight
- dashes++
- }
- for i < n && data[i] == ' ' {
- i++
- }
- if i == n {
- return
- }
- // end of column test is messy
- switch {
- case dashes < 3:
- // not a valid column
- return
-
- case data[i] == '|' && !isBackslashEscaped(data, i):
- // marker found, now skip past trailing whitespace
- col++
- i++
- for i < n && data[i] == ' ' {
- i++
- }
-
- // trailing junk found after last column
- if col >= colCount && i < len(data) && data[i] != '\n' {
- return
- }
-
- case (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount:
- // something else found where marker was required
- return
-
- case data[i] == '\n':
- // marker is optional for the last column
- col++
-
- default:
- // trailing junk found after last column
- return
- }
- }
- if col != colCount {
- return
- }
-
- table = &ast.Table{}
- p.addBlock(table)
- if header != nil {
- p.addBlock(&ast.TableHeader{})
- p.tableRow(header, columns, true)
- }
- size = skipCharN(data, i, '\n', 1)
- return
-}
-
-func (p *Parser) tableRow(data []byte, columns []ast.CellAlignFlags, header bool) {
- p.addBlock(&ast.TableRow{})
- i, col := 0, 0
-
- if data[i] == '|' && !isBackslashEscaped(data, i) {
- i++
- }
-
- n := len(data)
- colspans := 0 // keep track of total colspan in this row.
- for col = 0; col < len(columns) && i < n; col++ {
- colspan := 0
- for i < n && data[i] == ' ' {
- i++
- }
-
- cellStart := i
-
- for i < n && (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\n' {
- i++
- }
-
- cellEnd := i
-
- // skip the end-of-cell marker, possibly taking us past end of buffer
- // each _extra_ | means a colspan
- for i < len(data) && data[i] == '|' && !isBackslashEscaped(data, i) {
- i++
- colspan++
- }
- // only colspan > 1 make sense.
- if colspan < 2 {
- colspan = 0
- }
-
- for cellEnd > cellStart && cellEnd-1 < n && data[cellEnd-1] == ' ' {
- cellEnd--
- }
-
- block := &ast.TableCell{
- IsHeader: header,
- Align: columns[col],
- ColSpan: colspan,
- }
- block.Content = data[cellStart:cellEnd]
- if cellStart == cellEnd && colspans > 0 {
- // an empty cell that we should ignore, it exists because of colspan
- colspans--
- } else {
- p.addBlock(block)
- }
-
- if colspan > 0 {
- colspans += colspan - 1
- }
- }
-
- // pad it out with empty columns to get the right number
- for ; col < len(columns); col++ {
- block := &ast.TableCell{
- IsHeader: header,
- Align: columns[col],
- }
- p.addBlock(block)
- }
-
- // silently ignore rows with too many cells
-}
-
-// tableFooter parses the (optional) table footer.
-func (p *Parser) tableFooter(data []byte) bool {
- colCount := 1
- i := 0
- n := len(data)
- for i < 3 && i < n && data[i] == ' ' { // ignore up to 3 spaces
- i++
- }
- for ; i < n && data[i] != '\n'; i++ {
- if data[i] == '|' && !isBackslashEscaped(data, i) {
- colCount++
- continue
- }
- // remaining data must be the = character
- if data[i] != '=' {
- return false
- }
- }
-
- // doesn't look like a table footer
- if colCount == 1 {
- return false
- }
-
- p.addBlock(&ast.TableFooter{})
-
- return true
-}
-
// returns blockquote prefix length
func (p *Parser) quotePrefix(data []byte) int {
i := 0
@@ -1887,15 +1598,14 @@ func (p *Parser) paragraph(data []byte) int {
eol--
}
- id := ""
+ block := &ast.Heading{
+ Level: level,
+ }
if p.extensions&AutoHeadingIDs != 0 {
- id = sanitizeAnchorName(string(data[prev:eol]))
+ block.HeadingID = sanitizeHeadingID(string(data[prev:eol]))
+ p.allHeadingsWithAutoID = append(p.allHeadingsWithAutoID, block)
}
- block := &ast.Heading{
- Level: level,
- HeadingID: id,
- }
block.Content = data[prev:eol]
p.addBlock(block)
diff --git a/vendor/github.com/gomarkdown/markdown/parser/block_table.go b/vendor/github.com/gomarkdown/markdown/parser/block_table.go
new file mode 100644
index 00000000..f6c06dff
--- /dev/null
+++ b/vendor/github.com/gomarkdown/markdown/parser/block_table.go
@@ -0,0 +1,311 @@
+package parser
+
+import "github.com/gomarkdown/markdown/ast"
+
+// check if the specified position is preceded by an odd number of backslashes
+func isBackslashEscaped(data []byte, i int) bool {
+ backslashes := 0
+ for i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\' {
+ backslashes++
+ }
+ return backslashes&1 == 1
+}
+
+func (p *Parser) tableRow(data []byte, columns []ast.CellAlignFlags, header bool) {
+ p.addBlock(&ast.TableRow{})
+ col := 0
+
+ i := skipChar(data, 0, '|')
+
+ n := len(data)
+ colspans := 0 // keep track of total colspan in this row.
+ for col = 0; col < len(columns) && i < n; col++ {
+ colspan := 0
+ i = skipChar(data, i, ' ')
+
+ cellStart := i
+
+ for i < n && (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\n' {
+ i++
+ }
+
+ cellEnd := i
+
+ // skip the end-of-cell marker, possibly taking us past end of buffer
+ // each _extra_ | means a colspan
+ for i < len(data) && data[i] == '|' && !isBackslashEscaped(data, i) {
+ i++
+ colspan++
+ }
+ // only colspan > 1 make sense.
+ if colspan < 2 {
+ colspan = 0
+ }
+
+ for cellEnd > cellStart && cellEnd-1 < n && data[cellEnd-1] == ' ' {
+ cellEnd--
+ }
+
+ block := &ast.TableCell{
+ IsHeader: header,
+ Align: columns[col],
+ ColSpan: colspan,
+ }
+ block.Content = data[cellStart:cellEnd]
+ if cellStart == cellEnd && colspans > 0 {
+ // an empty cell that we should ignore, it exists because of colspan
+ colspans--
+ } else {
+ p.addBlock(block)
+ }
+
+ if colspan > 0 {
+ colspans += colspan - 1
+ }
+ }
+
+ // pad it out with empty columns to get the right number
+ for ; col < len(columns); col++ {
+ block := &ast.TableCell{
+ IsHeader: header,
+ Align: columns[col],
+ }
+ p.addBlock(block)
+ }
+
+ // silently ignore rows with too many cells
+}
+
+// tableFooter parses the (optional) table footer.
+func (p *Parser) tableFooter(data []byte) bool {
+ colCount := 1
+
+ // ignore up to 3 spaces
+ n := len(data)
+ i := skipCharN(data, 0, ' ', 3)
+ for ; i < n && data[i] != '\n'; i++ {
+ if data[i] == '|' && !isBackslashEscaped(data, i) {
+ colCount++
+ continue
+ }
+ // remaining data must be the = character
+ if data[i] != '=' {
+ return false
+ }
+ }
+
+ // doesn't look like a table footer
+ if colCount == 1 {
+ return false
+ }
+
+ p.addBlock(&ast.TableFooter{})
+
+ return true
+}
+
+// tableHeaders parses the header. If recognized it will also add a table.
+func (p *Parser) tableHeader(data []byte) (size int, columns []ast.CellAlignFlags, table ast.Node) {
+ i := 0
+ colCount := 1
+ headerIsUnderline := true
+ headerIsWithEmptyFields := true
+ for i = 0; i < len(data) && data[i] != '\n'; i++ {
+ if data[i] == '|' && !isBackslashEscaped(data, i) {
+ colCount++
+ }
+ if data[i] != '-' && data[i] != ' ' && data[i] != ':' && data[i] != '|' {
+ headerIsUnderline = false
+ }
+ if data[i] != ' ' && data[i] != '|' {
+ headerIsWithEmptyFields = false
+ }
+ }
+
+ // doesn't look like a table header
+ if colCount == 1 {
+ return
+ }
+
+ // include the newline in the data sent to tableRow
+ j := skipCharN(data, i, '\n', 1)
+ header := data[:j]
+
+ // column count ignores pipes at beginning or end of line
+ if data[0] == '|' {
+ colCount--
+ }
+ {
+ tmp := header
+ // remove whitespace from the end
+ for len(tmp) > 0 {
+ lastIdx := len(tmp) - 1
+ if tmp[lastIdx] == '\n' || tmp[lastIdx] == ' ' {
+ tmp = tmp[:lastIdx]
+ } else {
+ break
+ }
+ }
+ n := len(tmp)
+ if n > 2 && tmp[n-1] == '|' && !isBackslashEscaped(tmp, n-1) {
+ colCount--
+ }
+ }
+
+ // if the header looks like a underline, then we omit the header
+ // and parse the first line again as underline
+ if headerIsUnderline && !headerIsWithEmptyFields {
+ header = nil
+ i = 0
+ } else {
+ i++ // move past newline
+ }
+
+ columns = make([]ast.CellAlignFlags, colCount)
+
+ // move on to the header underline
+ if i >= len(data) {
+ return
+ }
+
+ if data[i] == '|' && !isBackslashEscaped(data, i) {
+ i++
+ }
+ i = skipChar(data, i, ' ')
+
+ // each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3
+ // and trailing | optional on last column
+ col := 0
+ n := len(data)
+ for i < n && data[i] != '\n' {
+ dashes := 0
+
+ if data[i] == ':' {
+ i++
+ columns[col] |= ast.TableAlignmentLeft
+ dashes++
+ }
+ for i < n && data[i] == '-' {
+ i++
+ dashes++
+ }
+ if i < n && data[i] == ':' {
+ i++
+ columns[col] |= ast.TableAlignmentRight
+ dashes++
+ }
+ for i < n && data[i] == ' ' {
+ i++
+ }
+ if i == n {
+ return
+ }
+ // end of column test is messy
+ switch {
+ case dashes < 3:
+ // not a valid column
+ return
+
+ case data[i] == '|' && !isBackslashEscaped(data, i):
+ // marker found, now skip past trailing whitespace
+ col++
+ i++
+ for i < n && data[i] == ' ' {
+ i++
+ }
+
+ // trailing junk found after last column
+ if col >= colCount && i < len(data) && data[i] != '\n' {
+ return
+ }
+
+ case (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount:
+ // something else found where marker was required
+ return
+
+ case data[i] == '\n':
+ // marker is optional for the last column
+ col++
+
+ default:
+ // trailing junk found after last column
+ return
+ }
+ }
+ if col != colCount {
+ return
+ }
+
+ table = &ast.Table{}
+ p.addBlock(table)
+ if header != nil {
+ p.addBlock(&ast.TableHeader{})
+ p.tableRow(header, columns, true)
+ }
+ size = skipCharN(data, i, '\n', 1)
+ return
+}
+
+/*
+Table:
+
+Name | Age | Phone
+------|-----|---------
+Bob | 31 | 555-1234
+Alice | 27 | 555-4321
+*/
+func (p *Parser) table(data []byte) int {
+ i, columns, table := p.tableHeader(data)
+ if i == 0 {
+ return 0
+ }
+
+ p.addBlock(&ast.TableBody{})
+
+ for i < len(data) {
+ pipes, rowStart := 0, i
+ for ; i < len(data) && data[i] != '\n'; i++ {
+ if data[i] == '|' {
+ pipes++
+ }
+ }
+
+ if pipes == 0 {
+ i = rowStart
+ break
+ }
+
+ // include the newline in data sent to tableRow
+ i = skipCharN(data, i, '\n', 1)
+
+ if p.tableFooter(data[rowStart:i]) {
+ continue
+ }
+
+ p.tableRow(data[rowStart:i], columns, false)
+ }
+ if captionContent, id, consumed := p.caption(data[i:], []byte("Table: ")); consumed > 0 {
+ caption := &ast.Caption{}
+ p.Inline(caption, captionContent)
+
+ // Some switcheroo to re-insert the parsed table as a child of the captionfigure.
+ figure := &ast.CaptionFigure{}
+ figure.HeadingID = id
+ table2 := &ast.Table{}
+ // Retain any block level attributes.
+ table2.AsContainer().Attribute = table.AsContainer().Attribute
+ children := table.GetChildren()
+ ast.RemoveFromTree(table)
+
+ table2.SetChildren(children)
+ ast.AppendChild(figure, table2)
+ ast.AppendChild(figure, caption)
+
+ p.addChild(figure)
+ p.finalize(figure)
+
+ i += consumed
+ }
+
+ return i
+}
diff --git a/vendor/github.com/gomarkdown/markdown/parser/inline.go b/vendor/github.com/gomarkdown/markdown/parser/inline.go
index 9bb5b30b..bc30326d 100644
--- a/vendor/github.com/gomarkdown/markdown/parser/inline.go
+++ b/vendor/github.com/gomarkdown/markdown/parser/inline.go
@@ -1293,7 +1293,7 @@ func math(p *Parser, data []byte, offset int) (int, ast.Node) {
}
func newTextNode(d []byte) *ast.Text {
- return &ast.Text{ast.Leaf{Literal: d}}
+ return &ast.Text{Leaf: ast.Leaf{Literal: d}}
}
func normalizeURI(s []byte) []byte {
diff --git a/vendor/github.com/gomarkdown/markdown/parser/parser.go b/vendor/github.com/gomarkdown/markdown/parser/parser.go
index c7302dfd..7712a29f 100644
--- a/vendor/github.com/gomarkdown/markdown/parser/parser.go
+++ b/vendor/github.com/gomarkdown/markdown/parser/parser.go
@@ -6,6 +6,7 @@ package parser
import (
"bytes"
"fmt"
+ "strconv"
"strings"
"unicode/utf8"
@@ -113,6 +114,10 @@ type Parser struct {
attr *ast.Attribute
includeStack *incStack
+
+ // collect headings where we auto-generated id so that we can
+ // ensure they are unique at the end
+ allHeadingsWithAutoID []*ast.Heading
}
// New creates a markdown parser with CommonExtensions.
@@ -282,6 +287,25 @@ func (p *Parser) Parse(input []byte) ast.Node {
if p.Opts.Flags&SkipFootnoteList == 0 {
p.parseRefsToAST()
}
+
+ // ensure HeadingIDs generated with AutoHeadingIDs are unique
+ // this is delayed here (as opposed to done when we create the id)
+ // so that we can preserve more original ids when there are conflicts
+ taken := map[string]bool{}
+ for _, h := range p.allHeadingsWithAutoID {
+ id := h.HeadingID
+ if id == "" {
+ continue
+ }
+ n := 0
+ for taken[id] {
+ n++
+ id = h.HeadingID + "-" + strconv.Itoa(n)
+ }
+ h.HeadingID = id
+ taken[id] = true
+ }
+
return p.Doc
}
diff --git a/vendor/github.com/gomarkdown/markdown/tracking-perf.md b/vendor/github.com/gomarkdown/markdown/tracking-perf.md
deleted file mode 100644
index 40b95183..00000000
--- a/vendor/github.com/gomarkdown/markdown/tracking-perf.md
+++ /dev/null
@@ -1,189 +0,0 @@
-## Tracking perf changes
-
-Initial performance:
-```
-goos: darwin
-goarch: amd64
-pkg: github.com/gomarkdown/markdown
-BenchmarkEscapeHTML-8 2000000 823 ns/op 0 B/op 0 allocs/op
-BenchmarkSmartDoubleQuotes-8 300000 5033 ns/op 9872 B/op 56 allocs/op
-BenchmarkReferenceAmps-8 100000 19538 ns/op 26776 B/op 150 allocs/op
-BenchmarkReferenceAutoLinks-8 100000 17574 ns/op 24544 B/op 132 allocs/op
-BenchmarkReferenceBackslashEscapes-8 30000 50977 ns/op 76752 B/op 243 allocs/op
-BenchmarkReferenceBlockquotesWithCodeBlocks-8 200000 8546 ns/op 12864 B/op 65 allocs/op
-BenchmarkReferenceCodeBlocks-8 200000 9000 ns/op 14912 B/op 70 allocs/op
-BenchmarkReferenceCodeSpans-8 200000 8856 ns/op 14992 B/op 69 allocs/op
-BenchmarkReferenceHardWrappedPara-8 200000 6599 ns/op 11312 B/op 57 allocs/op
-BenchmarkReferenceHorizontalRules-8 100000 15483 ns/op 23536 B/op 98 allocs/op
-BenchmarkReferenceInlineHTMLAdvances-8 200000 6839 ns/op 12150 B/op 62 allocs/op
-BenchmarkReferenceInlineHTMLSimple-8 100000 19940 ns/op 28488 B/op 117 allocs/op
-BenchmarkReferenceInlineHTMLComments-8 200000 7455 ns/op 13440 B/op 64 allocs/op
-BenchmarkReferenceLinksInline-8 100000 16425 ns/op 23664 B/op 147 allocs/op
-BenchmarkReferenceLinksReference-8 30000 54895 ns/op 66464 B/op 416 allocs/op
-BenchmarkReferenceLinksShortcut-8 100000 17647 ns/op 23776 B/op 158 allocs/op
-BenchmarkReferenceLiterQuotesInTitles-8 200000 9367 ns/op 14832 B/op 95 allocs/op
-BenchmarkReferenceMarkdownBasics-8 10000 129772 ns/op 130848 B/op 378 allocs/op
-BenchmarkReferenceMarkdownSyntax-8 3000 502365 ns/op 461411 B/op 1411 allocs/op
-BenchmarkReferenceNestedBlockquotes-8 200000 7028 ns/op 12688 B/op 64 allocs/op
-BenchmarkReferenceOrderedAndUnorderedLists-8 20000 79686 ns/op 107520 B/op 374 allocs/op
-BenchmarkReferenceStrongAndEm-8 200000 10020 ns/op 17792 B/op 78 allocs/op
-BenchmarkReferenceTabs-8 200000 12025 ns/op 18224 B/op 81 allocs/op
-BenchmarkReferenceTidyness-8 200000 8985 ns/op 14432 B/op 71 allocs/op
-PASS
-ok github.com/gomarkdown/markdown 45.375s
-```
-
-After switching to using interface{} for Node.Data:
-```
-BenchmarkEscapeHTML-8 2000000 929 ns/op 0 B/op 0 allocs/op
-BenchmarkSmartDoubleQuotes-8 300000 5126 ns/op 9248 B/op 56 allocs/op
-BenchmarkReferenceAmps-8 100000 19927 ns/op 17880 B/op 154 allocs/op
-BenchmarkReferenceAutoLinks-8 100000 20732 ns/op 17360 B/op 141 allocs/op
-BenchmarkReferenceBackslashEscapes-8 30000 50267 ns/op 38128 B/op 244 allocs/op
-BenchmarkReferenceBlockquotesWithCodeBlocks-8 200000 8988 ns/op 10912 B/op 67 allocs/op
-BenchmarkReferenceCodeBlocks-8 200000 8611 ns/op 12256 B/op 74 allocs/op
-BenchmarkReferenceCodeSpans-8 200000 8256 ns/op 11248 B/op 69 allocs/op
-BenchmarkReferenceHardWrappedPara-8 200000 6739 ns/op 9856 B/op 57 allocs/op
-BenchmarkReferenceHorizontalRules-8 100000 15503 ns/op 15600 B/op 104 allocs/op
-BenchmarkReferenceInlineHTMLAdvances-8 200000 6874 ns/op 10278 B/op 62 allocs/op
-BenchmarkReferenceInlineHTMLSimple-8 100000 22271 ns/op 18552 B/op 121 allocs/op
-BenchmarkReferenceInlineHTMLComments-8 200000 8315 ns/op 10736 B/op 64 allocs/op
-BenchmarkReferenceLinksInline-8 100000 16155 ns/op 16912 B/op 152 allocs/op
-BenchmarkReferenceLinksReference-8 30000 52387 ns/op 38192 B/op 445 allocs/op
-BenchmarkReferenceLinksShortcut-8 100000 17111 ns/op 16592 B/op 167 allocs/op
-BenchmarkReferenceLiterQuotesInTitles-8 200000 9164 ns/op 12048 B/op 97 allocs/op
-BenchmarkReferenceMarkdownBasics-8 10000 129262 ns/op 87264 B/op 416 allocs/op
-BenchmarkReferenceMarkdownSyntax-8 3000 496873 ns/op 293906 B/op 1559 allocs/op
-BenchmarkReferenceNestedBlockquotes-8 200000 6854 ns/op 10192 B/op 64 allocs/op
-BenchmarkReferenceOrderedAndUnorderedLists-8 20000 79633 ns/op 55024 B/op 447 allocs/op
-BenchmarkReferenceStrongAndEm-8 200000 9637 ns/op 12176 B/op 78 allocs/op
-BenchmarkReferenceTabs-8 100000 12164 ns/op 13776 B/op 87 allocs/op
-BenchmarkReferenceTidyness-8 200000 8677 ns/op 11296 B/op 75 allocs/op
-```
-
-Not necessarily faster, but uses less bytes per op (but sometimes more allocs).
-
-After tweaking the API:
-```
-$ ./s/run-bench.sh
-
-go test -bench=. -test.benchmem
-goos: darwin
-goarch: amd64
-pkg: github.com/gomarkdown/markdown
-BenchmarkEscapeHTML-8 2000000 834 ns/op 0 B/op 0 allocs/op
-BenchmarkSmartDoubleQuotes-8 300000 3486 ns/op 6160 B/op 27 allocs/op
-BenchmarkReferenceAmps-8 100000 18158 ns/op 14792 B/op 125 allocs/op
-BenchmarkReferenceAutoLinks-8 100000 16824 ns/op 14272 B/op 112 allocs/op
-BenchmarkReferenceBackslashEscapes-8 30000 44066 ns/op 35040 B/op 215 allocs/op
-BenchmarkReferenceBlockquotesWithCodeBlocks-8 200000 6868 ns/op 7824 B/op 38 allocs/op
-BenchmarkReferenceCodeBlocks-8 200000 7157 ns/op 9168 B/op 45 allocs/op
-BenchmarkReferenceCodeSpans-8 200000 6663 ns/op 8160 B/op 40 allocs/op
-BenchmarkReferenceHardWrappedPara-8 300000 4821 ns/op 6768 B/op 28 allocs/op
-BenchmarkReferenceHorizontalRules-8 100000 13033 ns/op 12512 B/op 75 allocs/op
-BenchmarkReferenceInlineHTMLAdvances-8 300000 4998 ns/op 7190 B/op 33 allocs/op
-BenchmarkReferenceInlineHTMLSimple-8 100000 17696 ns/op 15464 B/op 92 allocs/op
-BenchmarkReferenceInlineHTMLComments-8 300000 5506 ns/op 7648 B/op 35 allocs/op
-BenchmarkReferenceLinksInline-8 100000 14450 ns/op 13824 B/op 123 allocs/op
-BenchmarkReferenceLinksReference-8 30000 52561 ns/op 35104 B/op 416 allocs/op
-BenchmarkReferenceLinksShortcut-8 100000 15616 ns/op 13504 B/op 138 allocs/op
-BenchmarkReferenceLiterQuotesInTitles-8 200000 7772 ns/op 8960 B/op 68 allocs/op
-BenchmarkReferenceMarkdownBasics-8 10000 121436 ns/op 84176 B/op 387 allocs/op
-BenchmarkReferenceMarkdownSyntax-8 3000 487404 ns/op 290818 B/op 1530 allocs/op
-BenchmarkReferenceNestedBlockquotes-8 300000 5098 ns/op 7104 B/op 35 allocs/op
-BenchmarkReferenceOrderedAndUnorderedLists-8 20000 74422 ns/op 51936 B/op 418 allocs/op
-BenchmarkReferenceStrongAndEm-8 200000 7888 ns/op 9088 B/op 49 allocs/op
-BenchmarkReferenceTabs-8 200000 10061 ns/op 10688 B/op 58 allocs/op
-BenchmarkReferenceTidyness-8 200000 7152 ns/op 8208 B/op 46 allocs/op
-ok github.com/gomarkdown/markdown 40.809s
-```
-
-After refactoring Renderer:
-```
-BenchmarkEscapeHTML-8 2000000 883 ns/op 0 B/op 0 allocs/op
-BenchmarkSmartDoubleQuotes-8 300000 3717 ns/op 6208 B/op 29 allocs/op
-BenchmarkReferenceAmps-8 100000 19135 ns/op 14680 B/op 123 allocs/op
-BenchmarkReferenceAutoLinks-8 100000 17142 ns/op 14176 B/op 110 allocs/op
-BenchmarkReferenceBackslashEscapes-8 30000 54616 ns/op 35088 B/op 217 allocs/op
-BenchmarkReferenceBlockquotesWithCodeBlocks-8 200000 7993 ns/op 7872 B/op 40 allocs/op
-BenchmarkReferenceCodeBlocks-8 200000 8285 ns/op 9216 B/op 47 allocs/op
-BenchmarkReferenceCodeSpans-8 200000 7684 ns/op 8208 B/op 42 allocs/op
-BenchmarkReferenceHardWrappedPara-8 200000 5595 ns/op 6816 B/op 30 allocs/op
-BenchmarkReferenceHorizontalRules-8 100000 16444 ns/op 12560 B/op 77 allocs/op
-BenchmarkReferenceInlineHTMLAdvances-8 200000 5415 ns/op 7238 B/op 35 allocs/op
-BenchmarkReferenceInlineHTMLSimple-8 100000 19867 ns/op 15512 B/op 94 allocs/op
-BenchmarkReferenceInlineHTMLComments-8 200000 6026 ns/op 7696 B/op 37 allocs/op
-BenchmarkReferenceLinksInline-8 100000 14864 ns/op 13664 B/op 120 allocs/op
-BenchmarkReferenceLinksReference-8 30000 52479 ns/op 34816 B/op 401 allocs/op
-BenchmarkReferenceLinksShortcut-8 100000 15812 ns/op 13472 B/op 135 allocs/op
-BenchmarkReferenceLiterQuotesInTitles-8 200000 7767 ns/op 8880 B/op 68 allocs/op
-BenchmarkReferenceMarkdownBasics-8 10000 131065 ns/op 84048 B/op 386 allocs/op
-BenchmarkReferenceMarkdownSyntax-8 2000 515604 ns/op 289953 B/op 1501 allocs/op
-BenchmarkReferenceNestedBlockquotes-8 200000 5655 ns/op 7152 B/op 37 allocs/op
-BenchmarkReferenceOrderedAndUnorderedLists-8 20000 84188 ns/op 51984 B/op 420 allocs/op
-BenchmarkReferenceStrongAndEm-8 200000 8664 ns/op 9136 B/op 51 allocs/op
-BenchmarkReferenceTabs-8 100000 11110 ns/op 10736 B/op 60 allocs/op
-BenchmarkReferenceTidyness-8 200000 7628 ns/op 8256 B/op 48 allocs/op
-ok github.com/gomarkdown/markdown 40.841s
-```
-
-After Node refactor to have Children array:
-```
-BenchmarkEscapeHTML-8 2000000 901 ns/op 0 B/op 0 allocs/op
-BenchmarkSmartDoubleQuotes-8 300000 3905 ns/op 6224 B/op 31 allocs/op
-BenchmarkReferenceAmps-8 100000 22216 ns/op 15560 B/op 157 allocs/op
-BenchmarkReferenceAutoLinks-8 100000 20335 ns/op 14824 B/op 146 allocs/op
-BenchmarkReferenceBackslashEscapes-8 20000 69174 ns/op 37392 B/op 316 allocs/op
-BenchmarkReferenceBlockquotesWithCodeBlocks-8 200000 8443 ns/op 7968 B/op 48 allocs/op
-BenchmarkReferenceCodeBlocks-8 200000 9250 ns/op 9392 B/op 58 allocs/op
-BenchmarkReferenceCodeSpans-8 200000 8515 ns/op 8432 B/op 54 allocs/op
-BenchmarkReferenceHardWrappedPara-8 200000 5738 ns/op 6856 B/op 34 allocs/op
-BenchmarkReferenceHorizontalRules-8 100000 20864 ns/op 13648 B/op 93 allocs/op
-BenchmarkReferenceInlineHTMLAdvances-8 200000 6187 ns/op 7310 B/op 40 allocs/op
-BenchmarkReferenceInlineHTMLSimple-8 50000 23793 ns/op 16128 B/op 114 allocs/op
-BenchmarkReferenceInlineHTMLComments-8 200000 7060 ns/op 7840 B/op 44 allocs/op
-BenchmarkReferenceLinksInline-8 100000 18432 ns/op 14496 B/op 153 allocs/op
-BenchmarkReferenceLinksReference-8 20000 67666 ns/op 37136 B/op 502 allocs/op
-BenchmarkReferenceLinksShortcut-8 100000 19324 ns/op 13984 B/op 162 allocs/op
-BenchmarkReferenceLiterQuotesInTitles-8 200000 8998 ns/op 9320 B/op 83 allocs/op
-BenchmarkReferenceMarkdownBasics-8 10000 160908 ns/op 88152 B/op 518 allocs/op
-BenchmarkReferenceMarkdownSyntax-8 2000 707160 ns/op 303801 B/op 2044 allocs/op
-BenchmarkReferenceNestedBlockquotes-8 200000 6740 ns/op 7248 B/op 45 allocs/op
-BenchmarkReferenceOrderedAndUnorderedLists-8 10000 115808 ns/op 55052 B/op 626 allocs/op
-BenchmarkReferenceStrongAndEm-8 100000 10540 ns/op 9416 B/op 72 allocs/op
-BenchmarkReferenceTabs-8 100000 13171 ns/op 10968 B/op 77 allocs/op
-BenchmarkReferenceTidyness-8 200000 8903 ns/op 8404 B/op 62 allocs/op
-PASS
-ok github.com/gomarkdown/markdown 43.477s
-```
-It's slower (but opens up possibilities for further improvements).
-
-After refactoring to make ast.Node a top-level thing.
-```
-BenchmarkEscapeHTML-8 2000000 829 ns/op 0 B/op 0 allocs/op
-BenchmarkSmartDoubleQuotes-8 300000 3998 ns/op 6192 B/op 31 allocs/op
-BenchmarkReferenceAmps-8 50000 27389 ns/op 15480 B/op 153 allocs/op
-BenchmarkReferenceAutoLinks-8 50000 23106 ns/op 14656 B/op 137 allocs/op
-BenchmarkReferenceBackslashEscapes-8 10000 112435 ns/op 36696 B/op 315 allocs/op
-BenchmarkReferenceBlockquotesWithCodeBlocks-8 200000 9227 ns/op 7856 B/op 46 allocs/op
-BenchmarkReferenceCodeBlocks-8 200000 10469 ns/op 9248 B/op 54 allocs/op
-BenchmarkReferenceCodeSpans-8 200000 10522 ns/op 8368 B/op 54 allocs/op
-BenchmarkReferenceHardWrappedPara-8 200000 6354 ns/op 6784 B/op 34 allocs/op
-BenchmarkReferenceHorizontalRules-8 50000 32393 ns/op 13952 B/op 87 allocs/op
-BenchmarkReferenceInlineHTMLAdvances-8 200000 6894 ns/op 7238 B/op 40 allocs/op
-BenchmarkReferenceInlineHTMLSimple-8 50000 32942 ns/op 15864 B/op 110 allocs/op
-BenchmarkReferenceInlineHTMLComments-8 200000 8181 ns/op 7776 B/op 44 allocs/op
-BenchmarkReferenceLinksInline-8 100000 21679 ns/op 14400 B/op 148 allocs/op
-BenchmarkReferenceLinksReference-8 20000 83928 ns/op 36688 B/op 473 allocs/op
-BenchmarkReferenceLinksShortcut-8 100000 22053 ns/op 13872 B/op 153 allocs/op
-BenchmarkReferenceLiterQuotesInTitles-8 100000 10784 ns/op 9296 B/op 81 allocs/op
-BenchmarkReferenceMarkdownBasics-8 5000 237097 ns/op 87760 B/op 480 allocs/op
-BenchmarkReferenceMarkdownSyntax-8 1000 1465402 ns/op 300769 B/op 1896 allocs/op
-BenchmarkReferenceNestedBlockquotes-8 200000 7461 ns/op 7152 B/op 45 allocs/op
-BenchmarkReferenceOrderedAndUnorderedLists-8 5000 212256 ns/op 53724 B/op 553 allocs/op
-BenchmarkReferenceStrongAndEm-8 100000 13018 ns/op 9264 B/op 72 allocs/op
-BenchmarkReferenceTabs-8 100000 15005 ns/op 10752 B/op 71 allocs/op
-BenchmarkReferenceTidyness-8 200000 10308 ns/op 8292 B/op 58 allocs/op
-PASS
-ok github.com/gomarkdown/markdown 42.176s
-```