mirror of
https://github.com/cwinfo/matterbridge.git
synced 2025-07-11 21:16:27 +00:00
Update vendor (#1297)
This commit is contained in:
6
vendor/github.com/gomarkdown/markdown/README.md
generated
vendored
6
vendor/github.com/gomarkdown/markdown/README.md
generated
vendored
@ -6,11 +6,7 @@ Package `github.com/gomarkdown/markdown` is a very fast Go library for parsing [
|
||||
|
||||
It's fast and supports common extensions.
|
||||
|
||||
## Installation
|
||||
|
||||
go get -u github.com/gomarkdown/markdown
|
||||
|
||||
API Docs:
|
||||
## API Docs:
|
||||
|
||||
- https://godoc.org/github.com/gomarkdown/markdown : top level package
|
||||
- https://godoc.org/github.com/gomarkdown/markdown/ast : defines abstract syntax tree of parsed markdown document
|
||||
|
11
vendor/github.com/gomarkdown/markdown/ast/node.go
generated
vendored
11
vendor/github.com/gomarkdown/markdown/ast/node.go
generated
vendored
@ -250,11 +250,12 @@ type Del struct {
|
||||
type Link struct {
|
||||
Container
|
||||
|
||||
Destination []byte // Destination is what goes into a href
|
||||
Title []byte // Title is the tooltip thing that goes in a title attribute
|
||||
NoteID int // NoteID contains a serial number of a footnote, zero if it's not a footnote
|
||||
Footnote Node // If it's a footnote, this is a direct link to the footnote Node. Otherwise nil.
|
||||
DeferredID []byte // If a deferred link this holds the original ID.
|
||||
Destination []byte // Destination is what goes into a href
|
||||
Title []byte // Title is the tooltip thing that goes in a title attribute
|
||||
NoteID int // NoteID contains a serial number of a footnote, zero if it's not a footnote
|
||||
Footnote Node // If it's a footnote, this is a direct link to the footnote Node. Otherwise nil.
|
||||
DeferredID []byte // If a deferred link this holds the original ID.
|
||||
AdditionalAttributes []string // Defines additional attributes to use during rendering.
|
||||
}
|
||||
|
||||
// CrossReference is a reference node.
|
||||
|
42
vendor/github.com/gomarkdown/markdown/html/callouts.go
generated
vendored
42
vendor/github.com/gomarkdown/markdown/html/callouts.go
generated
vendored
@ -1,42 +0,0 @@
|
||||
package html
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/gomarkdown/markdown/ast"
|
||||
"github.com/gomarkdown/markdown/parser"
|
||||
)
|
||||
|
||||
// EscapeHTMLCallouts writes html-escaped d to w. It escapes &, <, > and " characters, *but*
|
||||
// expands callouts <<N>> with the callout HTML, i.e. by calling r.callout() with a newly created
|
||||
// ast.Callout node.
|
||||
func (r *Renderer) EscapeHTMLCallouts(w io.Writer, d []byte) {
|
||||
ld := len(d)
|
||||
Parse:
|
||||
for i := 0; i < ld; i++ {
|
||||
for _, comment := range r.opts.Comments {
|
||||
if !bytes.HasPrefix(d[i:], comment) {
|
||||
break
|
||||
}
|
||||
|
||||
lc := len(comment)
|
||||
if i+lc < ld {
|
||||
if id, consumed := parser.IsCallout(d[i+lc:]); consumed > 0 {
|
||||
// We have seen a callout
|
||||
callout := &ast.Callout{ID: id}
|
||||
r.callout(w, callout)
|
||||
i += consumed + lc - 1
|
||||
continue Parse
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
escSeq := Escaper[d[i]]
|
||||
if escSeq != nil {
|
||||
w.Write(escSeq)
|
||||
} else {
|
||||
w.Write([]byte{d[i]})
|
||||
}
|
||||
}
|
||||
}
|
50
vendor/github.com/gomarkdown/markdown/html/esc.go
generated
vendored
50
vendor/github.com/gomarkdown/markdown/html/esc.go
generated
vendored
@ -1,50 +0,0 @@
|
||||
package html
|
||||
|
||||
import (
|
||||
"html"
|
||||
"io"
|
||||
)
|
||||
|
||||
var Escaper = [256][]byte{
|
||||
'&': []byte("&"),
|
||||
'<': []byte("<"),
|
||||
'>': []byte(">"),
|
||||
'"': []byte("""),
|
||||
}
|
||||
|
||||
// EscapeHTML writes html-escaped d to w. It escapes &, <, > and " characters.
|
||||
func EscapeHTML(w io.Writer, d []byte) {
|
||||
var start, end int
|
||||
n := len(d)
|
||||
for end < n {
|
||||
escSeq := Escaper[d[end]]
|
||||
if escSeq != nil {
|
||||
w.Write(d[start:end])
|
||||
w.Write(escSeq)
|
||||
start = end + 1
|
||||
}
|
||||
end++
|
||||
}
|
||||
if start < n && end <= n {
|
||||
w.Write(d[start:end])
|
||||
}
|
||||
}
|
||||
|
||||
func escLink(w io.Writer, text []byte) {
|
||||
unesc := html.UnescapeString(string(text))
|
||||
EscapeHTML(w, []byte(unesc))
|
||||
}
|
||||
|
||||
// Escape writes the text to w, but skips the escape character.
|
||||
func Escape(w io.Writer, text []byte) {
|
||||
esc := false
|
||||
for i := 0; i < len(text); i++ {
|
||||
if text[i] == '\\' {
|
||||
esc = !esc
|
||||
}
|
||||
if esc && text[i] == '\\' {
|
||||
continue
|
||||
}
|
||||
w.Write([]byte{text[i]})
|
||||
}
|
||||
}
|
441
vendor/github.com/gomarkdown/markdown/html/renderer.go
generated
vendored
441
vendor/github.com/gomarkdown/markdown/html/renderer.go
generated
vendored
@ -3,6 +3,7 @@ package html
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html"
|
||||
"io"
|
||||
"regexp"
|
||||
"sort"
|
||||
@ -10,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gomarkdown/markdown/ast"
|
||||
"github.com/gomarkdown/markdown/parser"
|
||||
)
|
||||
|
||||
// Flags control optional behavior of HTML renderer.
|
||||
@ -125,13 +127,60 @@ type Renderer struct {
|
||||
headingIDs map[string]int
|
||||
|
||||
lastOutputLen int
|
||||
disableTags int
|
||||
|
||||
// if > 0, will strip html tags in Out and Outs
|
||||
DisableTags int
|
||||
|
||||
sr *SPRenderer
|
||||
|
||||
documentMatter ast.DocumentMatters // keep track of front/main/back matter.
|
||||
}
|
||||
|
||||
// Escaper defines how to escape HTML special characters
|
||||
var Escaper = [256][]byte{
|
||||
'&': []byte("&"),
|
||||
'<': []byte("<"),
|
||||
'>': []byte(">"),
|
||||
'"': []byte("""),
|
||||
}
|
||||
|
||||
// EscapeHTML writes html-escaped d to w. It escapes &, <, > and " characters.
|
||||
func EscapeHTML(w io.Writer, d []byte) {
|
||||
var start, end int
|
||||
n := len(d)
|
||||
for end < n {
|
||||
escSeq := Escaper[d[end]]
|
||||
if escSeq != nil {
|
||||
w.Write(d[start:end])
|
||||
w.Write(escSeq)
|
||||
start = end + 1
|
||||
}
|
||||
end++
|
||||
}
|
||||
if start < n && end <= n {
|
||||
w.Write(d[start:end])
|
||||
}
|
||||
}
|
||||
|
||||
func escLink(w io.Writer, text []byte) {
|
||||
unesc := html.UnescapeString(string(text))
|
||||
EscapeHTML(w, []byte(unesc))
|
||||
}
|
||||
|
||||
// Escape writes the text to w, but skips the escape character.
|
||||
func Escape(w io.Writer, text []byte) {
|
||||
esc := false
|
||||
for i := 0; i < len(text); i++ {
|
||||
if text[i] == '\\' {
|
||||
esc = !esc
|
||||
}
|
||||
if esc && text[i] == '\\' {
|
||||
continue
|
||||
}
|
||||
w.Write([]byte{text[i]})
|
||||
}
|
||||
}
|
||||
|
||||
// NewRenderer creates and configures an Renderer object, which
|
||||
// satisfies the Renderer interface.
|
||||
func NewRenderer(opts RendererOptions) *Renderer {
|
||||
@ -384,25 +433,28 @@ func skipParagraphTags(para *ast.Paragraph) bool {
|
||||
return tightOrTerm
|
||||
}
|
||||
|
||||
func (r *Renderer) out(w io.Writer, d []byte) {
|
||||
// Out is a helper to write data to writer
|
||||
func (r *Renderer) Out(w io.Writer, d []byte) {
|
||||
r.lastOutputLen = len(d)
|
||||
if r.disableTags > 0 {
|
||||
if r.DisableTags > 0 {
|
||||
d = htmlTagRe.ReplaceAll(d, []byte{})
|
||||
}
|
||||
w.Write(d)
|
||||
}
|
||||
|
||||
func (r *Renderer) outs(w io.Writer, s string) {
|
||||
// Outs is a helper to write data to writer
|
||||
func (r *Renderer) Outs(w io.Writer, s string) {
|
||||
r.lastOutputLen = len(s)
|
||||
if r.disableTags > 0 {
|
||||
if r.DisableTags > 0 {
|
||||
s = htmlTagRe.ReplaceAllString(s, "")
|
||||
}
|
||||
io.WriteString(w, s)
|
||||
}
|
||||
|
||||
func (r *Renderer) cr(w io.Writer) {
|
||||
// CR writes a new line
|
||||
func (r *Renderer) CR(w io.Writer) {
|
||||
if r.lastOutputLen > 0 {
|
||||
r.outs(w, "\n")
|
||||
r.Outs(w, "\n")
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,11 +478,12 @@ func headingCloseTagFromLevel(level int) string {
|
||||
}
|
||||
|
||||
func (r *Renderer) outHRTag(w io.Writer, attrs []string) {
|
||||
hr := tagWithAttributes("<hr", attrs)
|
||||
r.outOneOf(w, r.opts.Flags&UseXHTML == 0, hr, "<hr />")
|
||||
hr := TagWithAttributes("<hr", attrs)
|
||||
r.OutOneOf(w, r.opts.Flags&UseXHTML == 0, hr, "<hr />")
|
||||
}
|
||||
|
||||
func (r *Renderer) text(w io.Writer, text *ast.Text) {
|
||||
// Text writes ast.Text node
|
||||
func (r *Renderer) Text(w io.Writer, text *ast.Text) {
|
||||
if r.opts.Flags&Smartypants != 0 {
|
||||
var tmp bytes.Buffer
|
||||
EscapeHTML(&tmp, text.Literal)
|
||||
@ -445,41 +498,46 @@ func (r *Renderer) text(w io.Writer, text *ast.Text) {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) hardBreak(w io.Writer, node *ast.Hardbreak) {
|
||||
r.outOneOf(w, r.opts.Flags&UseXHTML == 0, "<br>", "<br />")
|
||||
r.cr(w)
|
||||
// HardBreak writes ast.Hardbreak node
|
||||
func (r *Renderer) HardBreak(w io.Writer, node *ast.Hardbreak) {
|
||||
r.OutOneOf(w, r.opts.Flags&UseXHTML == 0, "<br>", "<br />")
|
||||
r.CR(w)
|
||||
}
|
||||
|
||||
func (r *Renderer) nonBlockingSpace(w io.Writer, node *ast.NonBlockingSpace) {
|
||||
r.outs(w, " ")
|
||||
// NonBlockingSpace writes ast.NonBlockingSpace node
|
||||
func (r *Renderer) NonBlockingSpace(w io.Writer, node *ast.NonBlockingSpace) {
|
||||
r.Outs(w, " ")
|
||||
}
|
||||
|
||||
func (r *Renderer) outOneOf(w io.Writer, outFirst bool, first string, second string) {
|
||||
// OutOneOf writes first or second depending on outFirst
|
||||
func (r *Renderer) OutOneOf(w io.Writer, outFirst bool, first string, second string) {
|
||||
if outFirst {
|
||||
r.outs(w, first)
|
||||
r.Outs(w, first)
|
||||
} else {
|
||||
r.outs(w, second)
|
||||
r.Outs(w, second)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) outOneOfCr(w io.Writer, outFirst bool, first string, second string) {
|
||||
// OutOneOfCr writes CR + first or second + CR depending on outFirst
|
||||
func (r *Renderer) OutOneOfCr(w io.Writer, outFirst bool, first string, second string) {
|
||||
if outFirst {
|
||||
r.cr(w)
|
||||
r.outs(w, first)
|
||||
r.CR(w)
|
||||
r.Outs(w, first)
|
||||
} else {
|
||||
r.outs(w, second)
|
||||
r.cr(w)
|
||||
r.Outs(w, second)
|
||||
r.CR(w)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) htmlSpan(w io.Writer, span *ast.HTMLSpan) {
|
||||
// HTMLSpan writes ast.HTMLSpan node
|
||||
func (r *Renderer) HTMLSpan(w io.Writer, span *ast.HTMLSpan) {
|
||||
if r.opts.Flags&SkipHTML == 0 {
|
||||
r.out(w, span.Literal)
|
||||
r.Out(w, span.Literal)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) linkEnter(w io.Writer, link *ast.Link) {
|
||||
var attrs []string
|
||||
attrs := link.AdditionalAttributes
|
||||
dest := link.Destination
|
||||
dest = r.addAbsPrefix(dest)
|
||||
var hrefBuf bytes.Buffer
|
||||
@ -488,7 +546,7 @@ func (r *Renderer) linkEnter(w io.Writer, link *ast.Link) {
|
||||
hrefBuf.WriteByte('"')
|
||||
attrs = append(attrs, hrefBuf.String())
|
||||
if link.NoteID != 0 {
|
||||
r.outs(w, footnoteRef(r.opts.FootnoteAnchorPrefix, link))
|
||||
r.Outs(w, footnoteRef(r.opts.FootnoteAnchorPrefix, link))
|
||||
return
|
||||
}
|
||||
|
||||
@ -505,14 +563,15 @@ func (r *Renderer) linkEnter(w io.Writer, link *ast.Link) {
|
||||
|
||||
func (r *Renderer) linkExit(w io.Writer, link *ast.Link) {
|
||||
if link.NoteID == 0 {
|
||||
r.outs(w, "</a>")
|
||||
r.Outs(w, "</a>")
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) link(w io.Writer, link *ast.Link, entering bool) {
|
||||
// Link writes ast.Link node
|
||||
func (r *Renderer) Link(w io.Writer, link *ast.Link, entering bool) {
|
||||
// mark it but don't link it if it is not a safe link: no smartypants
|
||||
if needSkipLink(r.opts.Flags, link.Destination) {
|
||||
r.outOneOf(w, entering, "<tt>", "</tt>")
|
||||
r.OutOneOf(w, entering, "<tt>", "</tt>")
|
||||
return
|
||||
}
|
||||
|
||||
@ -526,26 +585,35 @@ func (r *Renderer) link(w io.Writer, link *ast.Link, entering bool) {
|
||||
func (r *Renderer) imageEnter(w io.Writer, image *ast.Image) {
|
||||
dest := image.Destination
|
||||
dest = r.addAbsPrefix(dest)
|
||||
if r.disableTags == 0 {
|
||||
if r.DisableTags == 0 {
|
||||
//if options.safe && potentiallyUnsafe(dest) {
|
||||
//out(w, `<img src="" alt="`)
|
||||
//} else {
|
||||
r.outs(w, `<img src="`)
|
||||
r.Outs(w, `<img src="`)
|
||||
escLink(w, dest)
|
||||
r.outs(w, `" alt="`)
|
||||
r.Outs(w, `" alt="`)
|
||||
//}
|
||||
}
|
||||
r.disableTags++
|
||||
r.DisableTags++
|
||||
}
|
||||
|
||||
func (r *Renderer) imageExit(w io.Writer, image *ast.Image) {
|
||||
r.disableTags--
|
||||
if r.disableTags == 0 {
|
||||
r.DisableTags--
|
||||
if r.DisableTags == 0 {
|
||||
if image.Title != nil {
|
||||
r.outs(w, `" title="`)
|
||||
r.Outs(w, `" title="`)
|
||||
EscapeHTML(w, image.Title)
|
||||
}
|
||||
r.outs(w, `" />`)
|
||||
r.Outs(w, `" />`)
|
||||
}
|
||||
}
|
||||
|
||||
// Image writes ast.Image node
|
||||
func (r *Renderer) Image(w io.Writer, node *ast.Image, entering bool) {
|
||||
if entering {
|
||||
r.imageEnter(w, node)
|
||||
} else {
|
||||
r.imageExit(w, node)
|
||||
}
|
||||
}
|
||||
|
||||
@ -556,33 +624,34 @@ func (r *Renderer) paragraphEnter(w io.Writer, para *ast.Paragraph) {
|
||||
if prev != nil {
|
||||
switch prev.(type) {
|
||||
case *ast.HTMLBlock, *ast.List, *ast.Paragraph, *ast.Heading, *ast.CaptionFigure, *ast.CodeBlock, *ast.BlockQuote, *ast.Aside, *ast.HorizontalRule:
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
}
|
||||
|
||||
if prev == nil {
|
||||
_, isParentBlockQuote := para.Parent.(*ast.BlockQuote)
|
||||
if isParentBlockQuote {
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
_, isParentAside := para.Parent.(*ast.Aside)
|
||||
if isParentAside {
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
}
|
||||
|
||||
tag := tagWithAttributes("<p", BlockAttrs(para))
|
||||
r.outs(w, tag)
|
||||
tag := TagWithAttributes("<p", BlockAttrs(para))
|
||||
r.Outs(w, tag)
|
||||
}
|
||||
|
||||
func (r *Renderer) paragraphExit(w io.Writer, para *ast.Paragraph) {
|
||||
r.outs(w, "</p>")
|
||||
r.Outs(w, "</p>")
|
||||
if !(isListItem(para.Parent) && ast.GetNextNode(para) == nil) {
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) paragraph(w io.Writer, para *ast.Paragraph, entering bool) {
|
||||
// Paragraph writes ast.Paragraph node
|
||||
func (r *Renderer) Paragraph(w io.Writer, para *ast.Paragraph, entering bool) {
|
||||
if skipParagraphTags(para) {
|
||||
return
|
||||
}
|
||||
@ -592,27 +661,22 @@ func (r *Renderer) paragraph(w io.Writer, para *ast.Paragraph, entering bool) {
|
||||
r.paragraphExit(w, para)
|
||||
}
|
||||
}
|
||||
func (r *Renderer) image(w io.Writer, node *ast.Image, entering bool) {
|
||||
if entering {
|
||||
r.imageEnter(w, node)
|
||||
} else {
|
||||
r.imageExit(w, node)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) code(w io.Writer, node *ast.Code) {
|
||||
r.outs(w, "<code>")
|
||||
// Code writes ast.Code node
|
||||
func (r *Renderer) Code(w io.Writer, node *ast.Code) {
|
||||
r.Outs(w, "<code>")
|
||||
EscapeHTML(w, node.Literal)
|
||||
r.outs(w, "</code>")
|
||||
r.Outs(w, "</code>")
|
||||
}
|
||||
|
||||
func (r *Renderer) htmlBlock(w io.Writer, node *ast.HTMLBlock) {
|
||||
// HTMLBlock write ast.HTMLBlock node
|
||||
func (r *Renderer) HTMLBlock(w io.Writer, node *ast.HTMLBlock) {
|
||||
if r.opts.Flags&SkipHTML != 0 {
|
||||
return
|
||||
}
|
||||
r.cr(w)
|
||||
r.out(w, node.Literal)
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
r.Out(w, node.Literal)
|
||||
r.CR(w)
|
||||
}
|
||||
|
||||
func (r *Renderer) headingEnter(w io.Writer, nodeData *ast.Heading) {
|
||||
@ -644,18 +708,19 @@ func (r *Renderer) headingEnter(w io.Writer, nodeData *ast.Heading) {
|
||||
attrs = append(attrs, attrID)
|
||||
}
|
||||
attrs = append(attrs, BlockAttrs(nodeData)...)
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
r.outTag(w, headingOpenTagFromLevel(nodeData.Level), attrs)
|
||||
}
|
||||
|
||||
func (r *Renderer) headingExit(w io.Writer, heading *ast.Heading) {
|
||||
r.outs(w, headingCloseTagFromLevel(heading.Level))
|
||||
r.Outs(w, headingCloseTagFromLevel(heading.Level))
|
||||
if !(isListItem(heading.Parent) && ast.GetNextNode(heading) == nil) {
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) heading(w io.Writer, node *ast.Heading, entering bool) {
|
||||
// Heading writes ast.Heading node
|
||||
func (r *Renderer) Heading(w io.Writer, node *ast.Heading, entering bool) {
|
||||
if entering {
|
||||
r.headingEnter(w, node)
|
||||
} else {
|
||||
@ -663,10 +728,11 @@ func (r *Renderer) heading(w io.Writer, node *ast.Heading, entering bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) horizontalRule(w io.Writer, node *ast.HorizontalRule) {
|
||||
r.cr(w)
|
||||
// HorizontalRule writes ast.HorizontalRule node
|
||||
func (r *Renderer) HorizontalRule(w io.Writer, node *ast.HorizontalRule) {
|
||||
r.CR(w)
|
||||
r.outHRTag(w, BlockAttrs(node))
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
|
||||
func (r *Renderer) listEnter(w io.Writer, nodeData *ast.List) {
|
||||
@ -674,17 +740,17 @@ func (r *Renderer) listEnter(w io.Writer, nodeData *ast.List) {
|
||||
var attrs []string
|
||||
|
||||
if nodeData.IsFootnotesList {
|
||||
r.outs(w, "\n<div class=\"footnotes\">\n\n")
|
||||
r.Outs(w, "\n<div class=\"footnotes\">\n\n")
|
||||
if r.opts.Flags&FootnoteNoHRTag == 0 {
|
||||
r.outHRTag(w, nil)
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
}
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
if isListItem(nodeData.Parent) {
|
||||
grand := nodeData.Parent.GetParent()
|
||||
if isListTight(grand) {
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
}
|
||||
|
||||
@ -700,7 +766,7 @@ func (r *Renderer) listEnter(w io.Writer, nodeData *ast.List) {
|
||||
}
|
||||
attrs = append(attrs, BlockAttrs(nodeData)...)
|
||||
r.outTag(w, openTag, attrs)
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
|
||||
func (r *Renderer) listExit(w io.Writer, list *ast.List) {
|
||||
@ -711,7 +777,7 @@ func (r *Renderer) listExit(w io.Writer, list *ast.List) {
|
||||
if list.ListFlags&ast.ListTypeDefinition != 0 {
|
||||
closeTag = "</dl>"
|
||||
}
|
||||
r.outs(w, closeTag)
|
||||
r.Outs(w, closeTag)
|
||||
|
||||
//cr(w)
|
||||
//if node.parent.Type != Item {
|
||||
@ -721,18 +787,19 @@ func (r *Renderer) listExit(w io.Writer, list *ast.List) {
|
||||
switch parent.(type) {
|
||||
case *ast.ListItem:
|
||||
if ast.GetNextNode(list) != nil {
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
case *ast.Document, *ast.BlockQuote, *ast.Aside:
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
|
||||
if list.IsFootnotesList {
|
||||
r.outs(w, "\n</div>\n")
|
||||
r.Outs(w, "\n</div>\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) list(w io.Writer, list *ast.List, entering bool) {
|
||||
// List writes ast.List node
|
||||
func (r *Renderer) List(w io.Writer, list *ast.List, entering bool) {
|
||||
if entering {
|
||||
r.listEnter(w, list)
|
||||
} else {
|
||||
@ -742,11 +809,11 @@ func (r *Renderer) list(w io.Writer, list *ast.List, entering bool) {
|
||||
|
||||
func (r *Renderer) listItemEnter(w io.Writer, listItem *ast.ListItem) {
|
||||
if listItemOpenCR(listItem) {
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
if listItem.RefLink != nil {
|
||||
slug := slugify(listItem.RefLink)
|
||||
r.outs(w, footnoteItem(r.opts.FootnoteAnchorPrefix, slug))
|
||||
r.Outs(w, footnoteItem(r.opts.FootnoteAnchorPrefix, slug))
|
||||
return
|
||||
}
|
||||
|
||||
@ -757,7 +824,7 @@ func (r *Renderer) listItemEnter(w io.Writer, listItem *ast.ListItem) {
|
||||
if listItem.ListFlags&ast.ListTypeTerm != 0 {
|
||||
openTag = "<dt>"
|
||||
}
|
||||
r.outs(w, openTag)
|
||||
r.Outs(w, openTag)
|
||||
}
|
||||
|
||||
func (r *Renderer) listItemExit(w io.Writer, listItem *ast.ListItem) {
|
||||
@ -766,7 +833,7 @@ func (r *Renderer) listItemExit(w io.Writer, listItem *ast.ListItem) {
|
||||
prefix := r.opts.FootnoteAnchorPrefix
|
||||
link := r.opts.FootnoteReturnLinkContents
|
||||
s := footnoteReturnLink(prefix, link, slug)
|
||||
r.outs(w, s)
|
||||
r.Outs(w, s)
|
||||
}
|
||||
|
||||
closeTag := "</li>"
|
||||
@ -776,11 +843,12 @@ func (r *Renderer) listItemExit(w io.Writer, listItem *ast.ListItem) {
|
||||
if listItem.ListFlags&ast.ListTypeTerm != 0 {
|
||||
closeTag = "</dt>"
|
||||
}
|
||||
r.outs(w, closeTag)
|
||||
r.cr(w)
|
||||
r.Outs(w, closeTag)
|
||||
r.CR(w)
|
||||
}
|
||||
|
||||
func (r *Renderer) listItem(w io.Writer, listItem *ast.ListItem, entering bool) {
|
||||
// ListItem writes ast.ListItem node
|
||||
func (r *Renderer) ListItem(w io.Writer, listItem *ast.ListItem, entering bool) {
|
||||
if entering {
|
||||
r.listItemEnter(w, listItem)
|
||||
} else {
|
||||
@ -788,38 +856,74 @@ func (r *Renderer) listItem(w io.Writer, listItem *ast.ListItem, entering bool)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) codeBlock(w io.Writer, codeBlock *ast.CodeBlock) {
|
||||
// EscapeHTMLCallouts writes html-escaped d to w. It escapes &, <, > and " characters, *but*
|
||||
// expands callouts <<N>> with the callout HTML, i.e. by calling r.callout() with a newly created
|
||||
// ast.Callout node.
|
||||
func (r *Renderer) EscapeHTMLCallouts(w io.Writer, d []byte) {
|
||||
ld := len(d)
|
||||
Parse:
|
||||
for i := 0; i < ld; i++ {
|
||||
for _, comment := range r.opts.Comments {
|
||||
if !bytes.HasPrefix(d[i:], comment) {
|
||||
break
|
||||
}
|
||||
|
||||
lc := len(comment)
|
||||
if i+lc < ld {
|
||||
if id, consumed := parser.IsCallout(d[i+lc:]); consumed > 0 {
|
||||
// We have seen a callout
|
||||
callout := &ast.Callout{ID: id}
|
||||
r.Callout(w, callout)
|
||||
i += consumed + lc - 1
|
||||
continue Parse
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
escSeq := Escaper[d[i]]
|
||||
if escSeq != nil {
|
||||
w.Write(escSeq)
|
||||
} else {
|
||||
w.Write([]byte{d[i]})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CodeBlock writes ast.CodeBlock node
|
||||
func (r *Renderer) CodeBlock(w io.Writer, codeBlock *ast.CodeBlock) {
|
||||
var attrs []string
|
||||
// TODO(miek): this can add multiple class= attribute, they should be coalesced into one.
|
||||
// This is probably true for some other elements as well
|
||||
attrs = appendLanguageAttr(attrs, codeBlock.Info)
|
||||
attrs = append(attrs, BlockAttrs(codeBlock)...)
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
|
||||
r.outs(w, "<pre>")
|
||||
code := tagWithAttributes("<code", attrs)
|
||||
r.outs(w, code)
|
||||
r.Outs(w, "<pre>")
|
||||
code := TagWithAttributes("<code", attrs)
|
||||
r.Outs(w, code)
|
||||
if r.opts.Comments != nil {
|
||||
r.EscapeHTMLCallouts(w, codeBlock.Literal)
|
||||
} else {
|
||||
EscapeHTML(w, codeBlock.Literal)
|
||||
}
|
||||
r.outs(w, "</code>")
|
||||
r.outs(w, "</pre>")
|
||||
r.Outs(w, "</code>")
|
||||
r.Outs(w, "</pre>")
|
||||
if !isListItem(codeBlock.Parent) {
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) caption(w io.Writer, caption *ast.Caption, entering bool) {
|
||||
// Caption writes ast.Caption node
|
||||
func (r *Renderer) Caption(w io.Writer, caption *ast.Caption, entering bool) {
|
||||
if entering {
|
||||
r.outs(w, "<figcaption>")
|
||||
r.Outs(w, "<figcaption>")
|
||||
return
|
||||
}
|
||||
r.outs(w, "</figcaption>")
|
||||
r.Outs(w, "</figcaption>")
|
||||
}
|
||||
|
||||
func (r *Renderer) captionFigure(w io.Writer, figure *ast.CaptionFigure, entering bool) {
|
||||
// CaptionFigure writes ast.CaptionFigure node
|
||||
func (r *Renderer) CaptionFigure(w io.Writer, figure *ast.CaptionFigure, entering bool) {
|
||||
// TODO(miek): copy more generic ways of mmark over to here.
|
||||
fig := "<figure"
|
||||
if figure.HeadingID != "" {
|
||||
@ -827,13 +931,14 @@ func (r *Renderer) captionFigure(w io.Writer, figure *ast.CaptionFigure, enterin
|
||||
} else {
|
||||
fig += ">"
|
||||
}
|
||||
r.outOneOf(w, entering, fig, "\n</figure>\n")
|
||||
r.OutOneOf(w, entering, fig, "\n</figure>\n")
|
||||
}
|
||||
|
||||
func (r *Renderer) tableCell(w io.Writer, tableCell *ast.TableCell, entering bool) {
|
||||
// TableCell writes ast.TableCell node
|
||||
func (r *Renderer) TableCell(w io.Writer, tableCell *ast.TableCell, entering bool) {
|
||||
if !entering {
|
||||
r.outOneOf(w, tableCell.IsHeader, "</th>", "</td>")
|
||||
r.cr(w)
|
||||
r.OutOneOf(w, tableCell.IsHeader, "</th>", "</td>")
|
||||
r.CR(w)
|
||||
return
|
||||
}
|
||||
|
||||
@ -848,44 +953,47 @@ func (r *Renderer) tableCell(w io.Writer, tableCell *ast.TableCell, entering boo
|
||||
attrs = append(attrs, fmt.Sprintf(`align="%s"`, align))
|
||||
}
|
||||
if ast.GetPrevNode(tableCell) == nil {
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
r.outTag(w, openTag, attrs)
|
||||
}
|
||||
|
||||
func (r *Renderer) tableBody(w io.Writer, node *ast.TableBody, entering bool) {
|
||||
// TableBody writes ast.TableBody node
|
||||
func (r *Renderer) TableBody(w io.Writer, node *ast.TableBody, entering bool) {
|
||||
if entering {
|
||||
r.cr(w)
|
||||
r.outs(w, "<tbody>")
|
||||
r.CR(w)
|
||||
r.Outs(w, "<tbody>")
|
||||
// XXX: this is to adhere to a rather silly test. Should fix test.
|
||||
if ast.GetFirstChild(node) == nil {
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
}
|
||||
} else {
|
||||
r.outs(w, "</tbody>")
|
||||
r.cr(w)
|
||||
r.Outs(w, "</tbody>")
|
||||
r.CR(w)
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) matter(w io.Writer, node *ast.DocumentMatter, entering bool) {
|
||||
// DocumentMatter writes ast.DocumentMatter
|
||||
func (r *Renderer) DocumentMatter(w io.Writer, node *ast.DocumentMatter, entering bool) {
|
||||
if !entering {
|
||||
return
|
||||
}
|
||||
if r.documentMatter != ast.DocumentMatterNone {
|
||||
r.outs(w, "</section>\n")
|
||||
r.Outs(w, "</section>\n")
|
||||
}
|
||||
switch node.Matter {
|
||||
case ast.DocumentMatterFront:
|
||||
r.outs(w, `<section data-matter="front">`)
|
||||
r.Outs(w, `<section data-matter="front">`)
|
||||
case ast.DocumentMatterMain:
|
||||
r.outs(w, `<section data-matter="main">`)
|
||||
r.Outs(w, `<section data-matter="main">`)
|
||||
case ast.DocumentMatterBack:
|
||||
r.outs(w, `<section data-matter="back">`)
|
||||
r.Outs(w, `<section data-matter="back">`)
|
||||
}
|
||||
r.documentMatter = node.Matter
|
||||
}
|
||||
|
||||
func (r *Renderer) citation(w io.Writer, node *ast.Citation) {
|
||||
// Citation writes ast.Citation node
|
||||
func (r *Renderer) Citation(w io.Writer, node *ast.Citation) {
|
||||
for i, c := range node.Destination {
|
||||
attr := []string{`class="none"`}
|
||||
switch node.Type[i] {
|
||||
@ -897,23 +1005,25 @@ func (r *Renderer) citation(w io.Writer, node *ast.Citation) {
|
||||
attr[0] = `class="suppressed"`
|
||||
}
|
||||
r.outTag(w, "<cite", attr)
|
||||
r.outs(w, fmt.Sprintf(`<a href="#%s">`+r.opts.CitationFormatString+`</a>`, c, c))
|
||||
r.outs(w, "</cite>")
|
||||
r.Outs(w, fmt.Sprintf(`<a href="#%s">`+r.opts.CitationFormatString+`</a>`, c, c))
|
||||
r.Outs(w, "</cite>")
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Renderer) callout(w io.Writer, node *ast.Callout) {
|
||||
// Callout writes ast.Callout node
|
||||
func (r *Renderer) Callout(w io.Writer, node *ast.Callout) {
|
||||
attr := []string{`class="callout"`}
|
||||
r.outTag(w, "<span", attr)
|
||||
r.out(w, node.ID)
|
||||
r.outs(w, "</span>")
|
||||
r.Out(w, node.ID)
|
||||
r.Outs(w, "</span>")
|
||||
}
|
||||
|
||||
func (r *Renderer) index(w io.Writer, node *ast.Index) {
|
||||
// Index writes ast.Index node
|
||||
func (r *Renderer) Index(w io.Writer, node *ast.Index) {
|
||||
// there is no in-text representation.
|
||||
attr := []string{`class="index"`, fmt.Sprintf(`id="%s"`, node.ID)}
|
||||
r.outTag(w, "<span", attr)
|
||||
r.outs(w, "</span>")
|
||||
r.Outs(w, "</span>")
|
||||
}
|
||||
|
||||
// RenderNode renders a markdown node to HTML
|
||||
@ -926,102 +1036,102 @@ func (r *Renderer) RenderNode(w io.Writer, node ast.Node, entering bool) ast.Wal
|
||||
}
|
||||
switch node := node.(type) {
|
||||
case *ast.Text:
|
||||
r.text(w, node)
|
||||
r.Text(w, node)
|
||||
case *ast.Softbreak:
|
||||
r.cr(w)
|
||||
r.CR(w)
|
||||
// TODO: make it configurable via out(renderer.softbreak)
|
||||
case *ast.Hardbreak:
|
||||
r.hardBreak(w, node)
|
||||
r.HardBreak(w, node)
|
||||
case *ast.NonBlockingSpace:
|
||||
r.nonBlockingSpace(w, node)
|
||||
r.NonBlockingSpace(w, node)
|
||||
case *ast.Emph:
|
||||
r.outOneOf(w, entering, "<em>", "</em>")
|
||||
r.OutOneOf(w, entering, "<em>", "</em>")
|
||||
case *ast.Strong:
|
||||
r.outOneOf(w, entering, "<strong>", "</strong>")
|
||||
r.OutOneOf(w, entering, "<strong>", "</strong>")
|
||||
case *ast.Del:
|
||||
r.outOneOf(w, entering, "<del>", "</del>")
|
||||
r.OutOneOf(w, entering, "<del>", "</del>")
|
||||
case *ast.BlockQuote:
|
||||
tag := tagWithAttributes("<blockquote", BlockAttrs(node))
|
||||
r.outOneOfCr(w, entering, tag, "</blockquote>")
|
||||
tag := TagWithAttributes("<blockquote", BlockAttrs(node))
|
||||
r.OutOneOfCr(w, entering, tag, "</blockquote>")
|
||||
case *ast.Aside:
|
||||
tag := tagWithAttributes("<aside", BlockAttrs(node))
|
||||
r.outOneOfCr(w, entering, tag, "</aside>")
|
||||
tag := TagWithAttributes("<aside", BlockAttrs(node))
|
||||
r.OutOneOfCr(w, entering, tag, "</aside>")
|
||||
case *ast.Link:
|
||||
r.link(w, node, entering)
|
||||
r.Link(w, node, entering)
|
||||
case *ast.CrossReference:
|
||||
link := &ast.Link{Destination: append([]byte("#"), node.Destination...)}
|
||||
r.link(w, link, entering)
|
||||
r.Link(w, link, entering)
|
||||
case *ast.Citation:
|
||||
r.citation(w, node)
|
||||
r.Citation(w, node)
|
||||
case *ast.Image:
|
||||
if r.opts.Flags&SkipImages != 0 {
|
||||
return ast.SkipChildren
|
||||
}
|
||||
r.image(w, node, entering)
|
||||
r.Image(w, node, entering)
|
||||
case *ast.Code:
|
||||
r.code(w, node)
|
||||
r.Code(w, node)
|
||||
case *ast.CodeBlock:
|
||||
r.codeBlock(w, node)
|
||||
r.CodeBlock(w, node)
|
||||
case *ast.Caption:
|
||||
r.caption(w, node, entering)
|
||||
r.Caption(w, node, entering)
|
||||
case *ast.CaptionFigure:
|
||||
r.captionFigure(w, node, entering)
|
||||
r.CaptionFigure(w, node, entering)
|
||||
case *ast.Document:
|
||||
// do nothing
|
||||
case *ast.Paragraph:
|
||||
r.paragraph(w, node, entering)
|
||||
r.Paragraph(w, node, entering)
|
||||
case *ast.HTMLSpan:
|
||||
r.htmlSpan(w, node)
|
||||
r.HTMLSpan(w, node)
|
||||
case *ast.HTMLBlock:
|
||||
r.htmlBlock(w, node)
|
||||
r.HTMLBlock(w, node)
|
||||
case *ast.Heading:
|
||||
r.heading(w, node, entering)
|
||||
r.Heading(w, node, entering)
|
||||
case *ast.HorizontalRule:
|
||||
r.horizontalRule(w, node)
|
||||
r.HorizontalRule(w, node)
|
||||
case *ast.List:
|
||||
r.list(w, node, entering)
|
||||
r.List(w, node, entering)
|
||||
case *ast.ListItem:
|
||||
r.listItem(w, node, entering)
|
||||
r.ListItem(w, node, entering)
|
||||
case *ast.Table:
|
||||
tag := tagWithAttributes("<table", BlockAttrs(node))
|
||||
r.outOneOfCr(w, entering, tag, "</table>")
|
||||
tag := TagWithAttributes("<table", BlockAttrs(node))
|
||||
r.OutOneOfCr(w, entering, tag, "</table>")
|
||||
case *ast.TableCell:
|
||||
r.tableCell(w, node, entering)
|
||||
r.TableCell(w, node, entering)
|
||||
case *ast.TableHeader:
|
||||
r.outOneOfCr(w, entering, "<thead>", "</thead>")
|
||||
r.OutOneOfCr(w, entering, "<thead>", "</thead>")
|
||||
case *ast.TableBody:
|
||||
r.tableBody(w, node, entering)
|
||||
r.TableBody(w, node, entering)
|
||||
case *ast.TableRow:
|
||||
r.outOneOfCr(w, entering, "<tr>", "</tr>")
|
||||
r.OutOneOfCr(w, entering, "<tr>", "</tr>")
|
||||
case *ast.TableFooter:
|
||||
r.outOneOfCr(w, entering, "<tfoot>", "</tfoot>")
|
||||
r.OutOneOfCr(w, entering, "<tfoot>", "</tfoot>")
|
||||
case *ast.Math:
|
||||
r.outOneOf(w, true, `<span class="math inline">\(`, `\)</span>`)
|
||||
r.OutOneOf(w, true, `<span class="math inline">\(`, `\)</span>`)
|
||||
EscapeHTML(w, node.Literal)
|
||||
r.outOneOf(w, false, `<span class="math inline">\(`, `\)</span>`)
|
||||
r.OutOneOf(w, false, `<span class="math inline">\(`, `\)</span>`)
|
||||
case *ast.MathBlock:
|
||||
r.outOneOf(w, entering, `<p><span class="math display">\[`, `\]</span></p>`)
|
||||
r.OutOneOf(w, entering, `<p><span class="math display">\[`, `\]</span></p>`)
|
||||
if entering {
|
||||
EscapeHTML(w, node.Literal)
|
||||
}
|
||||
case *ast.DocumentMatter:
|
||||
r.matter(w, node, entering)
|
||||
r.DocumentMatter(w, node, entering)
|
||||
case *ast.Callout:
|
||||
r.callout(w, node)
|
||||
r.Callout(w, node)
|
||||
case *ast.Index:
|
||||
r.index(w, node)
|
||||
r.Index(w, node)
|
||||
case *ast.Subscript:
|
||||
r.outOneOf(w, true, "<sub>", "</sub>")
|
||||
r.OutOneOf(w, true, "<sub>", "</sub>")
|
||||
if entering {
|
||||
Escape(w, node.Literal)
|
||||
}
|
||||
r.outOneOf(w, false, "<sub>", "</sub>")
|
||||
r.OutOneOf(w, false, "<sub>", "</sub>")
|
||||
case *ast.Superscript:
|
||||
r.outOneOf(w, true, "<sup>", "</sup>")
|
||||
r.OutOneOf(w, true, "<sup>", "</sup>")
|
||||
if entering {
|
||||
Escape(w, node.Literal)
|
||||
}
|
||||
r.outOneOf(w, false, "<sup>", "</sup>")
|
||||
r.OutOneOf(w, false, "<sup>", "</sup>")
|
||||
case *ast.Footnotes:
|
||||
// nothing by default; just output the list.
|
||||
default:
|
||||
@ -1041,7 +1151,7 @@ func (r *Renderer) RenderHeader(w io.Writer, ast ast.Node) {
|
||||
// RenderFooter writes HTML document footer.
|
||||
func (r *Renderer) RenderFooter(w io.Writer, _ ast.Node) {
|
||||
if r.documentMatter != ast.DocumentMatterNone {
|
||||
r.outs(w, "</section>\n")
|
||||
r.Outs(w, "</section>\n")
|
||||
}
|
||||
|
||||
if r.opts.Flags&CompletePage == 0 {
|
||||
@ -1315,7 +1425,8 @@ func BlockAttrs(node ast.Node) []string {
|
||||
return s
|
||||
}
|
||||
|
||||
func tagWithAttributes(name string, attrs []string) string {
|
||||
// TagWithAttributes creates a HTML tag with a given name and attributes
|
||||
func TagWithAttributes(name string, attrs []string) string {
|
||||
s := name
|
||||
if len(attrs) > 0 {
|
||||
s += " " + strings.Join(attrs, " ")
|
||||
|
20
vendor/github.com/gomarkdown/markdown/parser/block.go
generated
vendored
20
vendor/github.com/gomarkdown/markdown/parser/block.go
generated
vendored
@ -1074,10 +1074,14 @@ func isBackslashEscaped(data []byte, i int) bool {
|
||||
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
|
||||
@ -1097,10 +1101,18 @@ func (p *Parser) tableHeader(data []byte) (size int, columns []ast.CellAlignFlag
|
||||
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
|
||||
i++
|
||||
if i >= len(data) {
|
||||
return
|
||||
}
|
||||
@ -1175,8 +1187,10 @@ func (p *Parser) tableHeader(data []byte) (size int, columns []ast.CellAlignFlag
|
||||
|
||||
table = &ast.Table{}
|
||||
p.addBlock(table)
|
||||
p.addBlock(&ast.TableHeader{})
|
||||
p.tableRow(header, columns, true)
|
||||
if header != nil {
|
||||
p.addBlock(&ast.TableHeader{})
|
||||
p.tableRow(header, columns, true)
|
||||
}
|
||||
size = skipCharN(data, i, '\n', 1)
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user