summaryrefslogtreecommitdiff
path: root/vendor/github.com/yuin/goldmark/extension
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/yuin/goldmark/extension')
-rw-r--r--vendor/github.com/yuin/goldmark/extension/ast/definition_list.go83
-rw-r--r--vendor/github.com/yuin/goldmark/extension/ast/footnote.go138
-rw-r--r--vendor/github.com/yuin/goldmark/extension/ast/strikethrough.go29
-rw-r--r--vendor/github.com/yuin/goldmark/extension/ast/table.go158
-rw-r--r--vendor/github.com/yuin/goldmark/extension/ast/tasklist.go35
-rw-r--r--vendor/github.com/yuin/goldmark/extension/cjk.go72
-rw-r--r--vendor/github.com/yuin/goldmark/extension/definition_list.go274
-rw-r--r--vendor/github.com/yuin/goldmark/extension/footnote.go691
-rw-r--r--vendor/github.com/yuin/goldmark/extension/gfm.go18
-rw-r--r--vendor/github.com/yuin/goldmark/extension/linkify.go322
-rw-r--r--vendor/github.com/yuin/goldmark/extension/package.go2
-rw-r--r--vendor/github.com/yuin/goldmark/extension/strikethrough.go118
-rw-r--r--vendor/github.com/yuin/goldmark/extension/table.go555
-rw-r--r--vendor/github.com/yuin/goldmark/extension/tasklist.go120
-rw-r--r--vendor/github.com/yuin/goldmark/extension/typographer.go348
15 files changed, 0 insertions, 2963 deletions
diff --git a/vendor/github.com/yuin/goldmark/extension/ast/definition_list.go b/vendor/github.com/yuin/goldmark/extension/ast/definition_list.go
deleted file mode 100644
index 1beffb3aa..000000000
--- a/vendor/github.com/yuin/goldmark/extension/ast/definition_list.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package ast
-
-import (
- gast "github.com/yuin/goldmark/ast"
-)
-
-// A DefinitionList struct represents a definition list of Markdown
-// (PHPMarkdownExtra) text.
-type DefinitionList struct {
- gast.BaseBlock
- Offset int
- TemporaryParagraph *gast.Paragraph
-}
-
-// Dump implements Node.Dump.
-func (n *DefinitionList) Dump(source []byte, level int) {
- gast.DumpHelper(n, source, level, nil, nil)
-}
-
-// KindDefinitionList is a NodeKind of the DefinitionList node.
-var KindDefinitionList = gast.NewNodeKind("DefinitionList")
-
-// Kind implements Node.Kind.
-func (n *DefinitionList) Kind() gast.NodeKind {
- return KindDefinitionList
-}
-
-// NewDefinitionList returns a new DefinitionList node.
-func NewDefinitionList(offset int, para *gast.Paragraph) *DefinitionList {
- return &DefinitionList{
- Offset: offset,
- TemporaryParagraph: para,
- }
-}
-
-// A DefinitionTerm struct represents a definition list term of Markdown
-// (PHPMarkdownExtra) text.
-type DefinitionTerm struct {
- gast.BaseBlock
-}
-
-// Dump implements Node.Dump.
-func (n *DefinitionTerm) Dump(source []byte, level int) {
- gast.DumpHelper(n, source, level, nil, nil)
-}
-
-// KindDefinitionTerm is a NodeKind of the DefinitionTerm node.
-var KindDefinitionTerm = gast.NewNodeKind("DefinitionTerm")
-
-// Kind implements Node.Kind.
-func (n *DefinitionTerm) Kind() gast.NodeKind {
- return KindDefinitionTerm
-}
-
-// NewDefinitionTerm returns a new DefinitionTerm node.
-func NewDefinitionTerm() *DefinitionTerm {
- return &DefinitionTerm{}
-}
-
-// A DefinitionDescription struct represents a definition list description of Markdown
-// (PHPMarkdownExtra) text.
-type DefinitionDescription struct {
- gast.BaseBlock
- IsTight bool
-}
-
-// Dump implements Node.Dump.
-func (n *DefinitionDescription) Dump(source []byte, level int) {
- gast.DumpHelper(n, source, level, nil, nil)
-}
-
-// KindDefinitionDescription is a NodeKind of the DefinitionDescription node.
-var KindDefinitionDescription = gast.NewNodeKind("DefinitionDescription")
-
-// Kind implements Node.Kind.
-func (n *DefinitionDescription) Kind() gast.NodeKind {
- return KindDefinitionDescription
-}
-
-// NewDefinitionDescription returns a new DefinitionDescription node.
-func NewDefinitionDescription() *DefinitionDescription {
- return &DefinitionDescription{}
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/ast/footnote.go b/vendor/github.com/yuin/goldmark/extension/ast/footnote.go
deleted file mode 100644
index b24eafe67..000000000
--- a/vendor/github.com/yuin/goldmark/extension/ast/footnote.go
+++ /dev/null
@@ -1,138 +0,0 @@
-package ast
-
-import (
- "fmt"
-
- gast "github.com/yuin/goldmark/ast"
-)
-
-// A FootnoteLink struct represents a link to a footnote of Markdown
-// (PHP Markdown Extra) text.
-type FootnoteLink struct {
- gast.BaseInline
- Index int
- RefCount int
- RefIndex int
-}
-
-// Dump implements Node.Dump.
-func (n *FootnoteLink) Dump(source []byte, level int) {
- m := map[string]string{}
- m["Index"] = fmt.Sprintf("%v", n.Index)
- m["RefCount"] = fmt.Sprintf("%v", n.RefCount)
- m["RefIndex"] = fmt.Sprintf("%v", n.RefIndex)
- gast.DumpHelper(n, source, level, m, nil)
-}
-
-// KindFootnoteLink is a NodeKind of the FootnoteLink node.
-var KindFootnoteLink = gast.NewNodeKind("FootnoteLink")
-
-// Kind implements Node.Kind.
-func (n *FootnoteLink) Kind() gast.NodeKind {
- return KindFootnoteLink
-}
-
-// NewFootnoteLink returns a new FootnoteLink node.
-func NewFootnoteLink(index int) *FootnoteLink {
- return &FootnoteLink{
- Index: index,
- RefCount: 0,
- RefIndex: 0,
- }
-}
-
-// A FootnoteBacklink struct represents a link to a footnote of Markdown
-// (PHP Markdown Extra) text.
-type FootnoteBacklink struct {
- gast.BaseInline
- Index int
- RefCount int
- RefIndex int
-}
-
-// Dump implements Node.Dump.
-func (n *FootnoteBacklink) Dump(source []byte, level int) {
- m := map[string]string{}
- m["Index"] = fmt.Sprintf("%v", n.Index)
- m["RefCount"] = fmt.Sprintf("%v", n.RefCount)
- m["RefIndex"] = fmt.Sprintf("%v", n.RefIndex)
- gast.DumpHelper(n, source, level, m, nil)
-}
-
-// KindFootnoteBacklink is a NodeKind of the FootnoteBacklink node.
-var KindFootnoteBacklink = gast.NewNodeKind("FootnoteBacklink")
-
-// Kind implements Node.Kind.
-func (n *FootnoteBacklink) Kind() gast.NodeKind {
- return KindFootnoteBacklink
-}
-
-// NewFootnoteBacklink returns a new FootnoteBacklink node.
-func NewFootnoteBacklink(index int) *FootnoteBacklink {
- return &FootnoteBacklink{
- Index: index,
- RefCount: 0,
- RefIndex: 0,
- }
-}
-
-// A Footnote struct represents a footnote of Markdown
-// (PHP Markdown Extra) text.
-type Footnote struct {
- gast.BaseBlock
- Ref []byte
- Index int
-}
-
-// Dump implements Node.Dump.
-func (n *Footnote) Dump(source []byte, level int) {
- m := map[string]string{}
- m["Index"] = fmt.Sprintf("%v", n.Index)
- m["Ref"] = string(n.Ref)
- gast.DumpHelper(n, source, level, m, nil)
-}
-
-// KindFootnote is a NodeKind of the Footnote node.
-var KindFootnote = gast.NewNodeKind("Footnote")
-
-// Kind implements Node.Kind.
-func (n *Footnote) Kind() gast.NodeKind {
- return KindFootnote
-}
-
-// NewFootnote returns a new Footnote node.
-func NewFootnote(ref []byte) *Footnote {
- return &Footnote{
- Ref: ref,
- Index: -1,
- }
-}
-
-// A FootnoteList struct represents footnotes of Markdown
-// (PHP Markdown Extra) text.
-type FootnoteList struct {
- gast.BaseBlock
- Count int
-}
-
-// Dump implements Node.Dump.
-func (n *FootnoteList) Dump(source []byte, level int) {
- m := map[string]string{}
- m["Count"] = fmt.Sprintf("%v", n.Count)
- gast.DumpHelper(n, source, level, m, nil)
-}
-
-// KindFootnoteList is a NodeKind of the FootnoteList node.
-var KindFootnoteList = gast.NewNodeKind("FootnoteList")
-
-// Kind implements Node.Kind.
-func (n *FootnoteList) Kind() gast.NodeKind {
- return KindFootnoteList
-}
-
-// NewFootnoteList returns a new FootnoteList node.
-func NewFootnoteList() *FootnoteList {
- return &FootnoteList{
- Count: 0,
- }
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/ast/strikethrough.go b/vendor/github.com/yuin/goldmark/extension/ast/strikethrough.go
deleted file mode 100644
index a9216b72e..000000000
--- a/vendor/github.com/yuin/goldmark/extension/ast/strikethrough.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Package ast defines AST nodes that represents extension's elements
-package ast
-
-import (
- gast "github.com/yuin/goldmark/ast"
-)
-
-// A Strikethrough struct represents a strikethrough of GFM text.
-type Strikethrough struct {
- gast.BaseInline
-}
-
-// Dump implements Node.Dump.
-func (n *Strikethrough) Dump(source []byte, level int) {
- gast.DumpHelper(n, source, level, nil, nil)
-}
-
-// KindStrikethrough is a NodeKind of the Strikethrough node.
-var KindStrikethrough = gast.NewNodeKind("Strikethrough")
-
-// Kind implements Node.Kind.
-func (n *Strikethrough) Kind() gast.NodeKind {
- return KindStrikethrough
-}
-
-// NewStrikethrough returns a new Strikethrough node.
-func NewStrikethrough() *Strikethrough {
- return &Strikethrough{}
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/ast/table.go b/vendor/github.com/yuin/goldmark/extension/ast/table.go
deleted file mode 100644
index 4142e33c7..000000000
--- a/vendor/github.com/yuin/goldmark/extension/ast/table.go
+++ /dev/null
@@ -1,158 +0,0 @@
-package ast
-
-import (
- "fmt"
- "strings"
-
- gast "github.com/yuin/goldmark/ast"
-)
-
-// Alignment is a text alignment of table cells.
-type Alignment int
-
-const (
- // AlignLeft indicates text should be left justified.
- AlignLeft Alignment = iota + 1
-
- // AlignRight indicates text should be right justified.
- AlignRight
-
- // AlignCenter indicates text should be centered.
- AlignCenter
-
- // AlignNone indicates text should be aligned by default manner.
- AlignNone
-)
-
-func (a Alignment) String() string {
- switch a {
- case AlignLeft:
- return "left"
- case AlignRight:
- return "right"
- case AlignCenter:
- return "center"
- case AlignNone:
- return "none"
- }
- return ""
-}
-
-// A Table struct represents a table of Markdown(GFM) text.
-type Table struct {
- gast.BaseBlock
-
- // Alignments returns alignments of the columns.
- Alignments []Alignment
-}
-
-// Dump implements Node.Dump.
-func (n *Table) Dump(source []byte, level int) {
- gast.DumpHelper(n, source, level, nil, func(level int) {
- indent := strings.Repeat(" ", level)
- fmt.Printf("%sAlignments {\n", indent)
- for i, alignment := range n.Alignments {
- indent2 := strings.Repeat(" ", level+1)
- fmt.Printf("%s%s", indent2, alignment.String())
- if i != len(n.Alignments)-1 {
- fmt.Println("")
- }
- }
- fmt.Printf("\n%s}\n", indent)
- })
-}
-
-// KindTable is a NodeKind of the Table node.
-var KindTable = gast.NewNodeKind("Table")
-
-// Kind implements Node.Kind.
-func (n *Table) Kind() gast.NodeKind {
- return KindTable
-}
-
-// NewTable returns a new Table node.
-func NewTable() *Table {
- return &Table{
- Alignments: []Alignment{},
- }
-}
-
-// A TableRow struct represents a table row of Markdown(GFM) text.
-type TableRow struct {
- gast.BaseBlock
- Alignments []Alignment
-}
-
-// Dump implements Node.Dump.
-func (n *TableRow) Dump(source []byte, level int) {
- gast.DumpHelper(n, source, level, nil, nil)
-}
-
-// KindTableRow is a NodeKind of the TableRow node.
-var KindTableRow = gast.NewNodeKind("TableRow")
-
-// Kind implements Node.Kind.
-func (n *TableRow) Kind() gast.NodeKind {
- return KindTableRow
-}
-
-// NewTableRow returns a new TableRow node.
-func NewTableRow(alignments []Alignment) *TableRow {
- return &TableRow{Alignments: alignments}
-}
-
-// A TableHeader struct represents a table header of Markdown(GFM) text.
-type TableHeader struct {
- gast.BaseBlock
- Alignments []Alignment
-}
-
-// KindTableHeader is a NodeKind of the TableHeader node.
-var KindTableHeader = gast.NewNodeKind("TableHeader")
-
-// Kind implements Node.Kind.
-func (n *TableHeader) Kind() gast.NodeKind {
- return KindTableHeader
-}
-
-// Dump implements Node.Dump.
-func (n *TableHeader) Dump(source []byte, level int) {
- gast.DumpHelper(n, source, level, nil, nil)
-}
-
-// NewTableHeader returns a new TableHeader node.
-func NewTableHeader(row *TableRow) *TableHeader {
- n := &TableHeader{}
- for c := row.FirstChild(); c != nil; {
- next := c.NextSibling()
- n.AppendChild(n, c)
- c = next
- }
- return n
-}
-
-// A TableCell struct represents a table cell of a Markdown(GFM) text.
-type TableCell struct {
- gast.BaseBlock
- Alignment Alignment
-}
-
-// Dump implements Node.Dump.
-func (n *TableCell) Dump(source []byte, level int) {
- gast.DumpHelper(n, source, level, nil, nil)
-}
-
-// KindTableCell is a NodeKind of the TableCell node.
-var KindTableCell = gast.NewNodeKind("TableCell")
-
-// Kind implements Node.Kind.
-func (n *TableCell) Kind() gast.NodeKind {
- return KindTableCell
-}
-
-// NewTableCell returns a new TableCell node.
-func NewTableCell() *TableCell {
- return &TableCell{
- Alignment: AlignNone,
- }
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/ast/tasklist.go b/vendor/github.com/yuin/goldmark/extension/ast/tasklist.go
deleted file mode 100644
index 670cc1495..000000000
--- a/vendor/github.com/yuin/goldmark/extension/ast/tasklist.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package ast
-
-import (
- "fmt"
- gast "github.com/yuin/goldmark/ast"
-)
-
-// A TaskCheckBox struct represents a checkbox of a task list.
-type TaskCheckBox struct {
- gast.BaseInline
- IsChecked bool
-}
-
-// Dump implements Node.Dump.
-func (n *TaskCheckBox) Dump(source []byte, level int) {
- m := map[string]string{
- "Checked": fmt.Sprintf("%v", n.IsChecked),
- }
- gast.DumpHelper(n, source, level, m, nil)
-}
-
-// KindTaskCheckBox is a NodeKind of the TaskCheckBox node.
-var KindTaskCheckBox = gast.NewNodeKind("TaskCheckBox")
-
-// Kind implements Node.Kind.
-func (n *TaskCheckBox) Kind() gast.NodeKind {
- return KindTaskCheckBox
-}
-
-// NewTaskCheckBox returns a new TaskCheckBox node.
-func NewTaskCheckBox(checked bool) *TaskCheckBox {
- return &TaskCheckBox{
- IsChecked: checked,
- }
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/cjk.go b/vendor/github.com/yuin/goldmark/extension/cjk.go
deleted file mode 100644
index a3238c20c..000000000
--- a/vendor/github.com/yuin/goldmark/extension/cjk.go
+++ /dev/null
@@ -1,72 +0,0 @@
-package extension
-
-import (
- "github.com/yuin/goldmark"
- "github.com/yuin/goldmark/parser"
- "github.com/yuin/goldmark/renderer/html"
-)
-
-// A CJKOption sets options for CJK support mostly for HTML based renderers.
-type CJKOption func(*cjk)
-
-// A EastAsianLineBreaks is a style of east asian line breaks.
-type EastAsianLineBreaks int
-
-const (
- //EastAsianLineBreaksNone renders line breaks as it is.
- EastAsianLineBreaksNone EastAsianLineBreaks = iota
- // EastAsianLineBreaksSimple is a style where soft line breaks are ignored
- // if both sides of the break are east asian wide characters.
- EastAsianLineBreaksSimple
- // EastAsianLineBreaksCSS3Draft is a style where soft line breaks are ignored
- // even if only one side of the break is an east asian wide character.
- EastAsianLineBreaksCSS3Draft
-)
-
-// WithEastAsianLineBreaks is a functional option that indicates whether softline breaks
-// between east asian wide characters should be ignored.
-// style defauts to [EastAsianLineBreaksSimple] .
-func WithEastAsianLineBreaks(style ...EastAsianLineBreaks) CJKOption {
- return func(c *cjk) {
- if len(style) == 0 {
- c.EastAsianLineBreaks = EastAsianLineBreaksSimple
- return
- }
- c.EastAsianLineBreaks = style[0]
- }
-}
-
-// WithEscapedSpace is a functional option that indicates that a '\' escaped half-space(0x20) should not be rendered.
-func WithEscapedSpace() CJKOption {
- return func(c *cjk) {
- c.EscapedSpace = true
- }
-}
-
-type cjk struct {
- EastAsianLineBreaks EastAsianLineBreaks
- EscapedSpace bool
-}
-
-// CJK is a goldmark extension that provides functionalities for CJK languages.
-var CJK = NewCJK(WithEastAsianLineBreaks(), WithEscapedSpace())
-
-// NewCJK returns a new extension with given options.
-func NewCJK(opts ...CJKOption) goldmark.Extender {
- e := &cjk{
- EastAsianLineBreaks: EastAsianLineBreaksNone,
- }
- for _, opt := range opts {
- opt(e)
- }
- return e
-}
-
-func (e *cjk) Extend(m goldmark.Markdown) {
- m.Renderer().AddOptions(html.WithEastAsianLineBreaks(
- html.EastAsianLineBreaks(e.EastAsianLineBreaks)))
- if e.EscapedSpace {
- m.Renderer().AddOptions(html.WithWriter(html.NewWriter(html.WithEscapedSpace())))
- m.Parser().AddOptions(parser.WithEscapedSpace())
- }
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/definition_list.go b/vendor/github.com/yuin/goldmark/extension/definition_list.go
deleted file mode 100644
index 3e64dcf7f..000000000
--- a/vendor/github.com/yuin/goldmark/extension/definition_list.go
+++ /dev/null
@@ -1,274 +0,0 @@
-package extension
-
-import (
- "github.com/yuin/goldmark"
- gast "github.com/yuin/goldmark/ast"
- "github.com/yuin/goldmark/extension/ast"
- "github.com/yuin/goldmark/parser"
- "github.com/yuin/goldmark/renderer"
- "github.com/yuin/goldmark/renderer/html"
- "github.com/yuin/goldmark/text"
- "github.com/yuin/goldmark/util"
-)
-
-type definitionListParser struct {
-}
-
-var defaultDefinitionListParser = &definitionListParser{}
-
-// NewDefinitionListParser return a new parser.BlockParser that
-// can parse PHP Markdown Extra Definition lists.
-func NewDefinitionListParser() parser.BlockParser {
- return defaultDefinitionListParser
-}
-
-func (b *definitionListParser) Trigger() []byte {
- return []byte{':'}
-}
-
-func (b *definitionListParser) Open(parent gast.Node, reader text.Reader, pc parser.Context) (gast.Node, parser.State) {
- if _, ok := parent.(*ast.DefinitionList); ok {
- return nil, parser.NoChildren
- }
- line, _ := reader.PeekLine()
- pos := pc.BlockOffset()
- indent := pc.BlockIndent()
- if pos < 0 || line[pos] != ':' || indent != 0 {
- return nil, parser.NoChildren
- }
-
- last := parent.LastChild()
- // need 1 or more spaces after ':'
- w, _ := util.IndentWidth(line[pos+1:], pos+1)
- if w < 1 {
- return nil, parser.NoChildren
- }
- if w >= 8 { // starts with indented code
- w = 5
- }
- w += pos + 1 /* 1 = ':' */
-
- para, lastIsParagraph := last.(*gast.Paragraph)
- var list *ast.DefinitionList
- status := parser.HasChildren
- var ok bool
- if lastIsParagraph {
- list, ok = last.PreviousSibling().(*ast.DefinitionList)
- if ok { // is not first item
- list.Offset = w
- list.TemporaryParagraph = para
- } else { // is first item
- list = ast.NewDefinitionList(w, para)
- status |= parser.RequireParagraph
- }
- } else if list, ok = last.(*ast.DefinitionList); ok { // multiple description
- list.Offset = w
- list.TemporaryParagraph = nil
- } else {
- return nil, parser.NoChildren
- }
-
- return list, status
-}
-
-func (b *definitionListParser) Continue(node gast.Node, reader text.Reader, pc parser.Context) parser.State {
- line, _ := reader.PeekLine()
- if util.IsBlank(line) {
- return parser.Continue | parser.HasChildren
- }
- list, _ := node.(*ast.DefinitionList)
- w, _ := util.IndentWidth(line, reader.LineOffset())
- if w < list.Offset {
- return parser.Close
- }
- pos, padding := util.IndentPosition(line, reader.LineOffset(), list.Offset)
- reader.AdvanceAndSetPadding(pos, padding)
- return parser.Continue | parser.HasChildren
-}
-
-func (b *definitionListParser) Close(node gast.Node, reader text.Reader, pc parser.Context) {
- // nothing to do
-}
-
-func (b *definitionListParser) CanInterruptParagraph() bool {
- return true
-}
-
-func (b *definitionListParser) CanAcceptIndentedLine() bool {
- return false
-}
-
-type definitionDescriptionParser struct {
-}
-
-var defaultDefinitionDescriptionParser = &definitionDescriptionParser{}
-
-// NewDefinitionDescriptionParser return a new parser.BlockParser that
-// can parse definition description starts with ':'.
-func NewDefinitionDescriptionParser() parser.BlockParser {
- return defaultDefinitionDescriptionParser
-}
-
-func (b *definitionDescriptionParser) Trigger() []byte {
- return []byte{':'}
-}
-
-func (b *definitionDescriptionParser) Open(
- parent gast.Node, reader text.Reader, pc parser.Context) (gast.Node, parser.State) {
- line, _ := reader.PeekLine()
- pos := pc.BlockOffset()
- indent := pc.BlockIndent()
- if pos < 0 || line[pos] != ':' || indent != 0 {
- return nil, parser.NoChildren
- }
- list, _ := parent.(*ast.DefinitionList)
- if list == nil {
- return nil, parser.NoChildren
- }
- para := list.TemporaryParagraph
- list.TemporaryParagraph = nil
- if para != nil {
- lines := para.Lines()
- l := lines.Len()
- for i := 0; i < l; i++ {
- term := ast.NewDefinitionTerm()
- segment := lines.At(i)
- term.Lines().Append(segment.TrimRightSpace(reader.Source()))
- list.AppendChild(list, term)
- }
- para.Parent().RemoveChild(para.Parent(), para)
- }
- cpos, padding := util.IndentPosition(line[pos+1:], pos+1, list.Offset-pos-1)
- reader.AdvanceAndSetPadding(cpos+1, padding)
-
- return ast.NewDefinitionDescription(), parser.HasChildren
-}
-
-func (b *definitionDescriptionParser) Continue(node gast.Node, reader text.Reader, pc parser.Context) parser.State {
- // definitionListParser detects end of the description.
- // so this method will never be called.
- return parser.Continue | parser.HasChildren
-}
-
-func (b *definitionDescriptionParser) Close(node gast.Node, reader text.Reader, pc parser.Context) {
- desc := node.(*ast.DefinitionDescription)
- desc.IsTight = !desc.HasBlankPreviousLines()
- if desc.IsTight {
- for gc := desc.FirstChild(); gc != nil; gc = gc.NextSibling() {
- paragraph, ok := gc.(*gast.Paragraph)
- if ok {
- textBlock := gast.NewTextBlock()
- textBlock.SetLines(paragraph.Lines())
- desc.ReplaceChild(desc, paragraph, textBlock)
- }
- }
- }
-}
-
-func (b *definitionDescriptionParser) CanInterruptParagraph() bool {
- return true
-}
-
-func (b *definitionDescriptionParser) CanAcceptIndentedLine() bool {
- return false
-}
-
-// DefinitionListHTMLRenderer is a renderer.NodeRenderer implementation that
-// renders DefinitionList nodes.
-type DefinitionListHTMLRenderer struct {
- html.Config
-}
-
-// NewDefinitionListHTMLRenderer returns a new DefinitionListHTMLRenderer.
-func NewDefinitionListHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
- r := &DefinitionListHTMLRenderer{
- Config: html.NewConfig(),
- }
- for _, opt := range opts {
- opt.SetHTMLOption(&r.Config)
- }
- return r
-}
-
-// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs.
-func (r *DefinitionListHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
- reg.Register(ast.KindDefinitionList, r.renderDefinitionList)
- reg.Register(ast.KindDefinitionTerm, r.renderDefinitionTerm)
- reg.Register(ast.KindDefinitionDescription, r.renderDefinitionDescription)
-}
-
-// DefinitionListAttributeFilter defines attribute names which dl elements can have.
-var DefinitionListAttributeFilter = html.GlobalAttributeFilter
-
-func (r *DefinitionListHTMLRenderer) renderDefinitionList(
- w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) {
- if entering {
- if n.Attributes() != nil {
- _, _ = w.WriteString("<dl")
- html.RenderAttributes(w, n, DefinitionListAttributeFilter)
- _, _ = w.WriteString(">\n")
- } else {
- _, _ = w.WriteString("<dl>\n")
- }
- } else {
- _, _ = w.WriteString("</dl>\n")
- }
- return gast.WalkContinue, nil
-}
-
-// DefinitionTermAttributeFilter defines attribute names which dd elements can have.
-var DefinitionTermAttributeFilter = html.GlobalAttributeFilter
-
-func (r *DefinitionListHTMLRenderer) renderDefinitionTerm(
- w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) {
- if entering {
- if n.Attributes() != nil {
- _, _ = w.WriteString("<dt")
- html.RenderAttributes(w, n, DefinitionTermAttributeFilter)
- _ = w.WriteByte('>')
- } else {
- _, _ = w.WriteString("<dt>")
- }
- } else {
- _, _ = w.WriteString("</dt>\n")
- }
- return gast.WalkContinue, nil
-}
-
-// DefinitionDescriptionAttributeFilter defines attribute names which dd elements can have.
-var DefinitionDescriptionAttributeFilter = html.GlobalAttributeFilter
-
-func (r *DefinitionListHTMLRenderer) renderDefinitionDescription(
- w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
- if entering {
- n := node.(*ast.DefinitionDescription)
- _, _ = w.WriteString("<dd")
- if n.Attributes() != nil {
- html.RenderAttributes(w, n, DefinitionDescriptionAttributeFilter)
- }
- if n.IsTight {
- _, _ = w.WriteString(">")
- } else {
- _, _ = w.WriteString(">\n")
- }
- } else {
- _, _ = w.WriteString("</dd>\n")
- }
- return gast.WalkContinue, nil
-}
-
-type definitionList struct {
-}
-
-// DefinitionList is an extension that allow you to use PHP Markdown Extra Definition lists.
-var DefinitionList = &definitionList{}
-
-func (e *definitionList) Extend(m goldmark.Markdown) {
- m.Parser().AddOptions(parser.WithBlockParsers(
- util.Prioritized(NewDefinitionListParser(), 101),
- util.Prioritized(NewDefinitionDescriptionParser(), 102),
- ))
- m.Renderer().AddOptions(renderer.WithNodeRenderers(
- util.Prioritized(NewDefinitionListHTMLRenderer(), 500),
- ))
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/footnote.go b/vendor/github.com/yuin/goldmark/extension/footnote.go
deleted file mode 100644
index 2e225269c..000000000
--- a/vendor/github.com/yuin/goldmark/extension/footnote.go
+++ /dev/null
@@ -1,691 +0,0 @@
-package extension
-
-import (
- "bytes"
- "fmt"
- "strconv"
-
- "github.com/yuin/goldmark"
- gast "github.com/yuin/goldmark/ast"
- "github.com/yuin/goldmark/extension/ast"
- "github.com/yuin/goldmark/parser"
- "github.com/yuin/goldmark/renderer"
- "github.com/yuin/goldmark/renderer/html"
- "github.com/yuin/goldmark/text"
- "github.com/yuin/goldmark/util"
-)
-
-var footnoteListKey = parser.NewContextKey()
-var footnoteLinkListKey = parser.NewContextKey()
-
-type footnoteBlockParser struct {
-}
-
-var defaultFootnoteBlockParser = &footnoteBlockParser{}
-
-// NewFootnoteBlockParser returns a new parser.BlockParser that can parse
-// footnotes of the Markdown(PHP Markdown Extra) text.
-func NewFootnoteBlockParser() parser.BlockParser {
- return defaultFootnoteBlockParser
-}
-
-func (b *footnoteBlockParser) Trigger() []byte {
- return []byte{'['}
-}
-
-func (b *footnoteBlockParser) Open(parent gast.Node, reader text.Reader, pc parser.Context) (gast.Node, parser.State) {
- line, segment := reader.PeekLine()
- pos := pc.BlockOffset()
- if pos < 0 || line[pos] != '[' {
- return nil, parser.NoChildren
- }
- pos++
- if pos > len(line)-1 || line[pos] != '^' {
- return nil, parser.NoChildren
- }
- open := pos + 1
- var closes int
- closure := util.FindClosure(line[pos+1:], '[', ']', false, false) //nolint:staticcheck
- closes = pos + 1 + closure
- next := closes + 1
- if closure > -1 {
- if next >= len(line) || line[next] != ':' {
- return nil, parser.NoChildren
- }
- } else {
- return nil, parser.NoChildren
- }
- padding := segment.Padding
- label := reader.Value(text.NewSegment(segment.Start+open-padding, segment.Start+closes-padding))
- if util.IsBlank(label) {
- return nil, parser.NoChildren
- }
- item := ast.NewFootnote(label)
-
- pos = next + 1 - padding
- if pos >= len(line) {
- reader.Advance(pos)
- return item, parser.NoChildren
- }
- reader.AdvanceAndSetPadding(pos, padding)
- return item, parser.HasChildren
-}
-
-func (b *footnoteBlockParser) Continue(node gast.Node, reader text.Reader, pc parser.Context) parser.State {
- line, _ := reader.PeekLine()
- if util.IsBlank(line) {
- return parser.Continue | parser.HasChildren
- }
- childpos, padding := util.IndentPosition(line, reader.LineOffset(), 4)
- if childpos < 0 {
- return parser.Close
- }
- reader.AdvanceAndSetPadding(childpos, padding)
- return parser.Continue | parser.HasChildren
-}
-
-func (b *footnoteBlockParser) Close(node gast.Node, reader text.Reader, pc parser.Context) {
- var list *ast.FootnoteList
- if tlist := pc.Get(footnoteListKey); tlist != nil {
- list = tlist.(*ast.FootnoteList)
- } else {
- list = ast.NewFootnoteList()
- pc.Set(footnoteListKey, list)
- node.Parent().InsertBefore(node.Parent(), node, list)
- }
- node.Parent().RemoveChild(node.Parent(), node)
- list.AppendChild(list, node)
-}
-
-func (b *footnoteBlockParser) CanInterruptParagraph() bool {
- return true
-}
-
-func (b *footnoteBlockParser) CanAcceptIndentedLine() bool {
- return false
-}
-
-type footnoteParser struct {
-}
-
-var defaultFootnoteParser = &footnoteParser{}
-
-// NewFootnoteParser returns a new parser.InlineParser that can parse
-// footnote links of the Markdown(PHP Markdown Extra) text.
-func NewFootnoteParser() parser.InlineParser {
- return defaultFootnoteParser
-}
-
-func (s *footnoteParser) Trigger() []byte {
- // footnote syntax probably conflict with the image syntax.
- // So we need trigger this parser with '!'.
- return []byte{'!', '['}
-}
-
-func (s *footnoteParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node {
- line, segment := block.PeekLine()
- pos := 1
- if len(line) > 0 && line[0] == '!' {
- pos++
- }
- if pos >= len(line) || line[pos] != '^' {
- return nil
- }
- pos++
- if pos >= len(line) {
- return nil
- }
- open := pos
- closure := util.FindClosure(line[pos:], '[', ']', false, false) //nolint:staticcheck
- if closure < 0 {
- return nil
- }
- closes := pos + closure
- value := block.Value(text.NewSegment(segment.Start+open, segment.Start+closes))
- block.Advance(closes + 1)
-
- var list *ast.FootnoteList
- if tlist := pc.Get(footnoteListKey); tlist != nil {
- list = tlist.(*ast.FootnoteList)
- }
- if list == nil {
- return nil
- }
- index := 0
- for def := list.FirstChild(); def != nil; def = def.NextSibling() {
- d := def.(*ast.Footnote)
- if bytes.Equal(d.Ref, value) {
- if d.Index < 0 {
- list.Count++
- d.Index = list.Count
- }
- index = d.Index
- break
- }
- }
- if index == 0 {
- return nil
- }
-
- fnlink := ast.NewFootnoteLink(index)
- var fnlist []*ast.FootnoteLink
- if tmp := pc.Get(footnoteLinkListKey); tmp != nil {
- fnlist = tmp.([]*ast.FootnoteLink)
- } else {
- fnlist = []*ast.FootnoteLink{}
- pc.Set(footnoteLinkListKey, fnlist)
- }
- pc.Set(footnoteLinkListKey, append(fnlist, fnlink))
- if line[0] == '!' {
- parent.AppendChild(parent, gast.NewTextSegment(text.NewSegment(segment.Start, segment.Start+1)))
- }
-
- return fnlink
-}
-
-type footnoteASTTransformer struct {
-}
-
-var defaultFootnoteASTTransformer = &footnoteASTTransformer{}
-
-// NewFootnoteASTTransformer returns a new parser.ASTTransformer that
-// insert a footnote list to the last of the document.
-func NewFootnoteASTTransformer() parser.ASTTransformer {
- return defaultFootnoteASTTransformer
-}
-
-func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) {
- var list *ast.FootnoteList
- var fnlist []*ast.FootnoteLink
- if tmp := pc.Get(footnoteListKey); tmp != nil {
- list = tmp.(*ast.FootnoteList)
- }
- if tmp := pc.Get(footnoteLinkListKey); tmp != nil {
- fnlist = tmp.([]*ast.FootnoteLink)
- }
-
- pc.Set(footnoteListKey, nil)
- pc.Set(footnoteLinkListKey, nil)
-
- if list == nil {
- return
- }
-
- counter := map[int]int{}
- if fnlist != nil {
- for _, fnlink := range fnlist {
- if fnlink.Index >= 0 {
- counter[fnlink.Index]++
- }
- }
- refCounter := map[int]int{}
- for _, fnlink := range fnlist {
- fnlink.RefCount = counter[fnlink.Index]
- if _, ok := refCounter[fnlink.Index]; !ok {
- refCounter[fnlink.Index] = 0
- }
- fnlink.RefIndex = refCounter[fnlink.Index]
- refCounter[fnlink.Index]++
- }
- }
- for footnote := list.FirstChild(); footnote != nil; {
- var container gast.Node = footnote
- next := footnote.NextSibling()
- if fc := container.LastChild(); fc != nil && gast.IsParagraph(fc) {
- container = fc
- }
- fn := footnote.(*ast.Footnote)
- index := fn.Index
- if index < 0 {
- list.RemoveChild(list, footnote)
- } else {
- refCount := counter[index]
- backLink := ast.NewFootnoteBacklink(index)
- backLink.RefCount = refCount
- backLink.RefIndex = 0
- container.AppendChild(container, backLink)
- if refCount > 1 {
- for i := 1; i < refCount; i++ {
- backLink := ast.NewFootnoteBacklink(index)
- backLink.RefCount = refCount
- backLink.RefIndex = i
- container.AppendChild(container, backLink)
- }
- }
- }
- footnote = next
- }
- list.SortChildren(func(n1, n2 gast.Node) int {
- if n1.(*ast.Footnote).Index < n2.(*ast.Footnote).Index {
- return -1
- }
- return 1
- })
- if list.Count <= 0 {
- list.Parent().RemoveChild(list.Parent(), list)
- return
- }
-
- node.AppendChild(node, list)
-}
-
-// FootnoteConfig holds configuration values for the footnote extension.
-//
-// Link* and Backlink* configurations have some variables:
-// Occurrences of “^^” in the string will be replaced by the
-// corresponding footnote number in the HTML output.
-// Occurrences of “%%” will be replaced by a number for the
-// reference (footnotes can have multiple references).
-type FootnoteConfig struct {
- html.Config
-
- // IDPrefix is a prefix for the id attributes generated by footnotes.
- IDPrefix []byte
-
- // IDPrefix is a function that determines the id attribute for given Node.
- IDPrefixFunction func(gast.Node) []byte
-
- // LinkTitle is an optional title attribute for footnote links.
- LinkTitle []byte
-
- // BacklinkTitle is an optional title attribute for footnote backlinks.
- BacklinkTitle []byte
-
- // LinkClass is a class for footnote links.
- LinkClass []byte
-
- // BacklinkClass is a class for footnote backlinks.
- BacklinkClass []byte
-
- // BacklinkHTML is an HTML content for footnote backlinks.
- BacklinkHTML []byte
-}
-
-// FootnoteOption interface is a functional option interface for the extension.
-type FootnoteOption interface {
- renderer.Option
- // SetFootnoteOption sets given option to the extension.
- SetFootnoteOption(*FootnoteConfig)
-}
-
-// NewFootnoteConfig returns a new Config with defaults.
-func NewFootnoteConfig() FootnoteConfig {
- return FootnoteConfig{
- Config: html.NewConfig(),
- LinkTitle: []byte(""),
- BacklinkTitle: []byte(""),
- LinkClass: []byte("footnote-ref"),
- BacklinkClass: []byte("footnote-backref"),
- BacklinkHTML: []byte("&#x21a9;&#xfe0e;"),
- }
-}
-
-// SetOption implements renderer.SetOptioner.
-func (c *FootnoteConfig) SetOption(name renderer.OptionName, value interface{}) {
- switch name {
- case optFootnoteIDPrefixFunction:
- c.IDPrefixFunction = value.(func(gast.Node) []byte)
- case optFootnoteIDPrefix:
- c.IDPrefix = value.([]byte)
- case optFootnoteLinkTitle:
- c.LinkTitle = value.([]byte)
- case optFootnoteBacklinkTitle:
- c.BacklinkTitle = value.([]byte)
- case optFootnoteLinkClass:
- c.LinkClass = value.([]byte)
- case optFootnoteBacklinkClass:
- c.BacklinkClass = value.([]byte)
- case optFootnoteBacklinkHTML:
- c.BacklinkHTML = value.([]byte)
- default:
- c.Config.SetOption(name, value)
- }
-}
-
-type withFootnoteHTMLOptions struct {
- value []html.Option
-}
-
-func (o *withFootnoteHTMLOptions) SetConfig(c *renderer.Config) {
- if o.value != nil {
- for _, v := range o.value {
- v.(renderer.Option).SetConfig(c)
- }
- }
-}
-
-func (o *withFootnoteHTMLOptions) SetFootnoteOption(c *FootnoteConfig) {
- if o.value != nil {
- for _, v := range o.value {
- v.SetHTMLOption(&c.Config)
- }
- }
-}
-
-// WithFootnoteHTMLOptions is functional option that wraps goldmark HTMLRenderer options.
-func WithFootnoteHTMLOptions(opts ...html.Option) FootnoteOption {
- return &withFootnoteHTMLOptions{opts}
-}
-
-const optFootnoteIDPrefix renderer.OptionName = "FootnoteIDPrefix"
-
-type withFootnoteIDPrefix struct {
- value []byte
-}
-
-func (o *withFootnoteIDPrefix) SetConfig(c *renderer.Config) {
- c.Options[optFootnoteIDPrefix] = o.value
-}
-
-func (o *withFootnoteIDPrefix) SetFootnoteOption(c *FootnoteConfig) {
- c.IDPrefix = o.value
-}
-
-// WithFootnoteIDPrefix is a functional option that is a prefix for the id attributes generated by footnotes.
-func WithFootnoteIDPrefix[T []byte | string](a T) FootnoteOption {
- return &withFootnoteIDPrefix{[]byte(a)}
-}
-
-const optFootnoteIDPrefixFunction renderer.OptionName = "FootnoteIDPrefixFunction"
-
-type withFootnoteIDPrefixFunction struct {
- value func(gast.Node) []byte
-}
-
-func (o *withFootnoteIDPrefixFunction) SetConfig(c *renderer.Config) {
- c.Options[optFootnoteIDPrefixFunction] = o.value
-}
-
-func (o *withFootnoteIDPrefixFunction) SetFootnoteOption(c *FootnoteConfig) {
- c.IDPrefixFunction = o.value
-}
-
-// WithFootnoteIDPrefixFunction is a functional option that is a prefix for the id attributes generated by footnotes.
-func WithFootnoteIDPrefixFunction(a func(gast.Node) []byte) FootnoteOption {
- return &withFootnoteIDPrefixFunction{a}
-}
-
-const optFootnoteLinkTitle renderer.OptionName = "FootnoteLinkTitle"
-
-type withFootnoteLinkTitle struct {
- value []byte
-}
-
-func (o *withFootnoteLinkTitle) SetConfig(c *renderer.Config) {
- c.Options[optFootnoteLinkTitle] = o.value
-}
-
-func (o *withFootnoteLinkTitle) SetFootnoteOption(c *FootnoteConfig) {
- c.LinkTitle = o.value
-}
-
-// WithFootnoteLinkTitle is a functional option that is an optional title attribute for footnote links.
-func WithFootnoteLinkTitle[T []byte | string](a T) FootnoteOption {
- return &withFootnoteLinkTitle{[]byte(a)}
-}
-
-const optFootnoteBacklinkTitle renderer.OptionName = "FootnoteBacklinkTitle"
-
-type withFootnoteBacklinkTitle struct {
- value []byte
-}
-
-func (o *withFootnoteBacklinkTitle) SetConfig(c *renderer.Config) {
- c.Options[optFootnoteBacklinkTitle] = o.value
-}
-
-func (o *withFootnoteBacklinkTitle) SetFootnoteOption(c *FootnoteConfig) {
- c.BacklinkTitle = o.value
-}
-
-// WithFootnoteBacklinkTitle is a functional option that is an optional title attribute for footnote backlinks.
-func WithFootnoteBacklinkTitle[T []byte | string](a T) FootnoteOption {
- return &withFootnoteBacklinkTitle{[]byte(a)}
-}
-
-const optFootnoteLinkClass renderer.OptionName = "FootnoteLinkClass"
-
-type withFootnoteLinkClass struct {
- value []byte
-}
-
-func (o *withFootnoteLinkClass) SetConfig(c *renderer.Config) {
- c.Options[optFootnoteLinkClass] = o.value
-}
-
-func (o *withFootnoteLinkClass) SetFootnoteOption(c *FootnoteConfig) {
- c.LinkClass = o.value
-}
-
-// WithFootnoteLinkClass is a functional option that is a class for footnote links.
-func WithFootnoteLinkClass[T []byte | string](a T) FootnoteOption {
- return &withFootnoteLinkClass{[]byte(a)}
-}
-
-const optFootnoteBacklinkClass renderer.OptionName = "FootnoteBacklinkClass"
-
-type withFootnoteBacklinkClass struct {
- value []byte
-}
-
-func (o *withFootnoteBacklinkClass) SetConfig(c *renderer.Config) {
- c.Options[optFootnoteBacklinkClass] = o.value
-}
-
-func (o *withFootnoteBacklinkClass) SetFootnoteOption(c *FootnoteConfig) {
- c.BacklinkClass = o.value
-}
-
-// WithFootnoteBacklinkClass is a functional option that is a class for footnote backlinks.
-func WithFootnoteBacklinkClass[T []byte | string](a T) FootnoteOption {
- return &withFootnoteBacklinkClass{[]byte(a)}
-}
-
-const optFootnoteBacklinkHTML renderer.OptionName = "FootnoteBacklinkHTML"
-
-type withFootnoteBacklinkHTML struct {
- value []byte
-}
-
-func (o *withFootnoteBacklinkHTML) SetConfig(c *renderer.Config) {
- c.Options[optFootnoteBacklinkHTML] = o.value
-}
-
-func (o *withFootnoteBacklinkHTML) SetFootnoteOption(c *FootnoteConfig) {
- c.BacklinkHTML = o.value
-}
-
-// WithFootnoteBacklinkHTML is an HTML content for footnote backlinks.
-func WithFootnoteBacklinkHTML[T []byte | string](a T) FootnoteOption {
- return &withFootnoteBacklinkHTML{[]byte(a)}
-}
-
-// FootnoteHTMLRenderer is a renderer.NodeRenderer implementation that
-// renders FootnoteLink nodes.
-type FootnoteHTMLRenderer struct {
- FootnoteConfig
-}
-
-// NewFootnoteHTMLRenderer returns a new FootnoteHTMLRenderer.
-func NewFootnoteHTMLRenderer(opts ...FootnoteOption) renderer.NodeRenderer {
- r := &FootnoteHTMLRenderer{
- FootnoteConfig: NewFootnoteConfig(),
- }
- for _, opt := range opts {
- opt.SetFootnoteOption(&r.FootnoteConfig)
- }
- return r
-}
-
-// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs.
-func (r *FootnoteHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
- reg.Register(ast.KindFootnoteLink, r.renderFootnoteLink)
- reg.Register(ast.KindFootnoteBacklink, r.renderFootnoteBacklink)
- reg.Register(ast.KindFootnote, r.renderFootnote)
- reg.Register(ast.KindFootnoteList, r.renderFootnoteList)
-}
-
-func (r *FootnoteHTMLRenderer) renderFootnoteLink(
- w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
- if entering {
- n := node.(*ast.FootnoteLink)
- is := strconv.Itoa(n.Index)
- _, _ = w.WriteString(`<sup id="`)
- _, _ = w.Write(r.idPrefix(node))
- _, _ = w.WriteString(`fnref`)
- if n.RefIndex > 0 {
- _, _ = w.WriteString(fmt.Sprintf("%v", n.RefIndex))
- }
- _ = w.WriteByte(':')
- _, _ = w.WriteString(is)
- _, _ = w.WriteString(`"><a href="#`)
- _, _ = w.Write(r.idPrefix(node))
- _, _ = w.WriteString(`fn:`)
- _, _ = w.WriteString(is)
- _, _ = w.WriteString(`" class="`)
- _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.LinkClass,
- n.Index, n.RefCount))
- if len(r.FootnoteConfig.LinkTitle) > 0 {
- _, _ = w.WriteString(`" title="`)
- _, _ = w.Write(util.EscapeHTML(applyFootnoteTemplate(r.FootnoteConfig.LinkTitle, n.Index, n.RefCount)))
- }
- _, _ = w.WriteString(`" role="doc-noteref">`)
-
- _, _ = w.WriteString(is)
- _, _ = w.WriteString(`</a></sup>`)
- }
- return gast.WalkContinue, nil
-}
-
-func (r *FootnoteHTMLRenderer) renderFootnoteBacklink(
- w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
- if entering {
- n := node.(*ast.FootnoteBacklink)
- is := strconv.Itoa(n.Index)
- _, _ = w.WriteString(`&#160;<a href="#`)
- _, _ = w.Write(r.idPrefix(node))
- _, _ = w.WriteString(`fnref`)
- if n.RefIndex > 0 {
- _, _ = w.WriteString(fmt.Sprintf("%v", n.RefIndex))
- }
- _ = w.WriteByte(':')
- _, _ = w.WriteString(is)
- _, _ = w.WriteString(`" class="`)
- _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkClass, n.Index, n.RefCount))
- if len(r.FootnoteConfig.BacklinkTitle) > 0 {
- _, _ = w.WriteString(`" title="`)
- _, _ = w.Write(util.EscapeHTML(applyFootnoteTemplate(r.FootnoteConfig.BacklinkTitle, n.Index, n.RefCount)))
- }
- _, _ = w.WriteString(`" role="doc-backlink">`)
- _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkHTML, n.Index, n.RefCount))
- _, _ = w.WriteString(`</a>`)
- }
- return gast.WalkContinue, nil
-}
-
-func (r *FootnoteHTMLRenderer) renderFootnote(
- w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
- n := node.(*ast.Footnote)
- is := strconv.Itoa(n.Index)
- if entering {
- _, _ = w.WriteString(`<li id="`)
- _, _ = w.Write(r.idPrefix(node))
- _, _ = w.WriteString(`fn:`)
- _, _ = w.WriteString(is)
- _, _ = w.WriteString(`"`)
- if node.Attributes() != nil {
- html.RenderAttributes(w, node, html.ListItemAttributeFilter)
- }
- _, _ = w.WriteString(">\n")
- } else {
- _, _ = w.WriteString("</li>\n")
- }
- return gast.WalkContinue, nil
-}
-
-func (r *FootnoteHTMLRenderer) renderFootnoteList(
- w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
- if entering {
- _, _ = w.WriteString(`<div class="footnotes" role="doc-endnotes"`)
- if node.Attributes() != nil {
- html.RenderAttributes(w, node, html.GlobalAttributeFilter)
- }
- _ = w.WriteByte('>')
- if r.Config.XHTML {
- _, _ = w.WriteString("\n<hr />\n")
- } else {
- _, _ = w.WriteString("\n<hr>\n")
- }
- _, _ = w.WriteString("<ol>\n")
- } else {
- _, _ = w.WriteString("</ol>\n")
- _, _ = w.WriteString("</div>\n")
- }
- return gast.WalkContinue, nil
-}
-
-func (r *FootnoteHTMLRenderer) idPrefix(node gast.Node) []byte {
- if r.FootnoteConfig.IDPrefix != nil {
- return r.FootnoteConfig.IDPrefix
- }
- if r.FootnoteConfig.IDPrefixFunction != nil {
- return r.FootnoteConfig.IDPrefixFunction(node)
- }
- return []byte("")
-}
-
-func applyFootnoteTemplate(b []byte, index, refCount int) []byte {
- fast := true
- for i, c := range b {
- if i != 0 {
- if b[i-1] == '^' && c == '^' {
- fast = false
- break
- }
- if b[i-1] == '%' && c == '%' {
- fast = false
- break
- }
- }
- }
- if fast {
- return b
- }
- is := []byte(strconv.Itoa(index))
- rs := []byte(strconv.Itoa(refCount))
- ret := bytes.Replace(b, []byte("^^"), is, -1)
- return bytes.Replace(ret, []byte("%%"), rs, -1)
-}
-
-type footnote struct {
- options []FootnoteOption
-}
-
-// Footnote is an extension that allow you to use PHP Markdown Extra Footnotes.
-var Footnote = &footnote{
- options: []FootnoteOption{},
-}
-
-// NewFootnote returns a new extension with given options.
-func NewFootnote(opts ...FootnoteOption) goldmark.Extender {
- return &footnote{
- options: opts,
- }
-}
-
-func (e *footnote) Extend(m goldmark.Markdown) {
- m.Parser().AddOptions(
- parser.WithBlockParsers(
- util.Prioritized(NewFootnoteBlockParser(), 999),
- ),
- parser.WithInlineParsers(
- util.Prioritized(NewFootnoteParser(), 101),
- ),
- parser.WithASTTransformers(
- util.Prioritized(NewFootnoteASTTransformer(), 999),
- ),
- )
- m.Renderer().AddOptions(renderer.WithNodeRenderers(
- util.Prioritized(NewFootnoteHTMLRenderer(e.options...), 500),
- ))
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/gfm.go b/vendor/github.com/yuin/goldmark/extension/gfm.go
deleted file mode 100644
index a570fbdb3..000000000
--- a/vendor/github.com/yuin/goldmark/extension/gfm.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package extension
-
-import (
- "github.com/yuin/goldmark"
-)
-
-type gfm struct {
-}
-
-// GFM is an extension that provides Github Flavored markdown functionalities.
-var GFM = &gfm{}
-
-func (e *gfm) Extend(m goldmark.Markdown) {
- Linkify.Extend(m)
- Table.Extend(m)
- Strikethrough.Extend(m)
- TaskList.Extend(m)
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/linkify.go b/vendor/github.com/yuin/goldmark/extension/linkify.go
deleted file mode 100644
index ad88933ac..000000000
--- a/vendor/github.com/yuin/goldmark/extension/linkify.go
+++ /dev/null
@@ -1,322 +0,0 @@
-package extension
-
-import (
- "bytes"
- "regexp"
-
- "github.com/yuin/goldmark"
- "github.com/yuin/goldmark/ast"
- "github.com/yuin/goldmark/parser"
- "github.com/yuin/goldmark/text"
- "github.com/yuin/goldmark/util"
-)
-
-var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]+(?:[/#?][-a-zA-Z0-9@:%_\+.~#!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) //nolint:golint,lll
-
-var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp)://[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]+(?::\d+)?(?:[/#?][-a-zA-Z0-9@:%_+.~#$!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) //nolint:golint,lll
-
-// An LinkifyConfig struct is a data structure that holds configuration of the
-// Linkify extension.
-type LinkifyConfig struct {
- AllowedProtocols [][]byte
- URLRegexp *regexp.Regexp
- WWWRegexp *regexp.Regexp
- EmailRegexp *regexp.Regexp
-}
-
-const (
- optLinkifyAllowedProtocols parser.OptionName = "LinkifyAllowedProtocols"
- optLinkifyURLRegexp parser.OptionName = "LinkifyURLRegexp"
- optLinkifyWWWRegexp parser.OptionName = "LinkifyWWWRegexp"
- optLinkifyEmailRegexp parser.OptionName = "LinkifyEmailRegexp"
-)
-
-// SetOption implements SetOptioner.
-func (c *LinkifyConfig) SetOption(name parser.OptionName, value interface{}) {
- switch name {
- case optLinkifyAllowedProtocols:
- c.AllowedProtocols = value.([][]byte)
- case optLinkifyURLRegexp:
- c.URLRegexp = value.(*regexp.Regexp)
- case optLinkifyWWWRegexp:
- c.WWWRegexp = value.(*regexp.Regexp)
- case optLinkifyEmailRegexp:
- c.EmailRegexp = value.(*regexp.Regexp)
- }
-}
-
-// A LinkifyOption interface sets options for the LinkifyOption.
-type LinkifyOption interface {
- parser.Option
- SetLinkifyOption(*LinkifyConfig)
-}
-
-type withLinkifyAllowedProtocols struct {
- value [][]byte
-}
-
-func (o *withLinkifyAllowedProtocols) SetParserOption(c *parser.Config) {
- c.Options[optLinkifyAllowedProtocols] = o.value
-}
-
-func (o *withLinkifyAllowedProtocols) SetLinkifyOption(p *LinkifyConfig) {
- p.AllowedProtocols = o.value
-}
-
-// WithLinkifyAllowedProtocols is a functional option that specify allowed
-// protocols in autolinks. Each protocol must end with ':' like
-// 'http:' .
-func WithLinkifyAllowedProtocols[T []byte | string](value []T) LinkifyOption {
- opt := &withLinkifyAllowedProtocols{}
- for _, v := range value {
- opt.value = append(opt.value, []byte(v))
- }
- return opt
-}
-
-type withLinkifyURLRegexp struct {
- value *regexp.Regexp
-}
-
-func (o *withLinkifyURLRegexp) SetParserOption(c *parser.Config) {
- c.Options[optLinkifyURLRegexp] = o.value
-}
-
-func (o *withLinkifyURLRegexp) SetLinkifyOption(p *LinkifyConfig) {
- p.URLRegexp = o.value
-}
-
-// WithLinkifyURLRegexp is a functional option that specify
-// a pattern of the URL including a protocol.
-func WithLinkifyURLRegexp(value *regexp.Regexp) LinkifyOption {
- return &withLinkifyURLRegexp{
- value: value,
- }
-}
-
-type withLinkifyWWWRegexp struct {
- value *regexp.Regexp
-}
-
-func (o *withLinkifyWWWRegexp) SetParserOption(c *parser.Config) {
- c.Options[optLinkifyWWWRegexp] = o.value
-}
-
-func (o *withLinkifyWWWRegexp) SetLinkifyOption(p *LinkifyConfig) {
- p.WWWRegexp = o.value
-}
-
-// WithLinkifyWWWRegexp is a functional option that specify
-// a pattern of the URL without a protocol.
-// This pattern must start with 'www.' .
-func WithLinkifyWWWRegexp(value *regexp.Regexp) LinkifyOption {
- return &withLinkifyWWWRegexp{
- value: value,
- }
-}
-
-type withLinkifyEmailRegexp struct {
- value *regexp.Regexp
-}
-
-func (o *withLinkifyEmailRegexp) SetParserOption(c *parser.Config) {
- c.Options[optLinkifyEmailRegexp] = o.value
-}
-
-func (o *withLinkifyEmailRegexp) SetLinkifyOption(p *LinkifyConfig) {
- p.EmailRegexp = o.value
-}
-
-// WithLinkifyEmailRegexp is a functional otpion that specify
-// a pattern of the email address.
-func WithLinkifyEmailRegexp(value *regexp.Regexp) LinkifyOption {
- return &withLinkifyEmailRegexp{
- value: value,
- }
-}
-
-type linkifyParser struct {
- LinkifyConfig
-}
-
-// NewLinkifyParser return a new InlineParser can parse
-// text that seems like a URL.
-func NewLinkifyParser(opts ...LinkifyOption) parser.InlineParser {
- p := &linkifyParser{
- LinkifyConfig: LinkifyConfig{
- AllowedProtocols: nil,
- URLRegexp: urlRegexp,
- WWWRegexp: wwwURLRegxp,
- },
- }
- for _, o := range opts {
- o.SetLinkifyOption(&p.LinkifyConfig)
- }
- return p
-}
-
-func (s *linkifyParser) Trigger() []byte {
- // ' ' indicates any white spaces and a line head
- return []byte{' ', '*', '_', '~', '('}
-}
-
-var (
- protoHTTP = []byte("http:")
- protoHTTPS = []byte("https:")
- protoFTP = []byte("ftp:")
- domainWWW = []byte("www.")
-)
-
-func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node {
- if pc.IsInLinkLabel() {
- return nil
- }
- line, segment := block.PeekLine()
- consumes := 0
- start := segment.Start
- c := line[0]
- // advance if current position is not a line head.
- if c == ' ' || c == '*' || c == '_' || c == '~' || c == '(' {
- consumes++
- start++
- line = line[1:]
- }
-
- var m []int
- var protocol []byte
- var typ ast.AutoLinkType = ast.AutoLinkURL
- if s.LinkifyConfig.AllowedProtocols == nil {
- if bytes.HasPrefix(line, protoHTTP) || bytes.HasPrefix(line, protoHTTPS) || bytes.HasPrefix(line, protoFTP) {
- m = s.LinkifyConfig.URLRegexp.FindSubmatchIndex(line)
- }
- } else {
- for _, prefix := range s.LinkifyConfig.AllowedProtocols {
- if bytes.HasPrefix(line, prefix) {
- m = s.LinkifyConfig.URLRegexp.FindSubmatchIndex(line)
- break
- }
- }
- }
- if m == nil && bytes.HasPrefix(line, domainWWW) {
- m = s.LinkifyConfig.WWWRegexp.FindSubmatchIndex(line)
- protocol = []byte("http")
- }
- if m != nil && m[0] != 0 {
- m = nil
- }
- if m != nil && m[0] == 0 {
- lastChar := line[m[1]-1]
- if lastChar == '.' {
- m[1]--
- } else if lastChar == ')' {
- closing := 0
- for i := m[1] - 1; i >= m[0]; i-- {
- if line[i] == ')' {
- closing++
- } else if line[i] == '(' {
- closing--
- }
- }
- if closing > 0 {
- m[1] -= closing
- }
- } else if lastChar == ';' {
- i := m[1] - 2
- for ; i >= m[0]; i-- {
- if util.IsAlphaNumeric(line[i]) {
- continue
- }
- break
- }
- if i != m[1]-2 {
- if line[i] == '&' {
- m[1] -= m[1] - i
- }
- }
- }
- }
- if m == nil {
- if len(line) > 0 && util.IsPunct(line[0]) {
- return nil
- }
- typ = ast.AutoLinkEmail
- stop := -1
- if s.LinkifyConfig.EmailRegexp == nil {
- stop = util.FindEmailIndex(line)
- } else {
- m := s.LinkifyConfig.EmailRegexp.FindSubmatchIndex(line)
- if m != nil && m[0] == 0 {
- stop = m[1]
- }
- }
- if stop < 0 {
- return nil
- }
- at := bytes.IndexByte(line, '@')
- m = []int{0, stop, at, stop - 1}
- if m == nil || bytes.IndexByte(line[m[2]:m[3]], '.') < 0 {
- return nil
- }
- lastChar := line[m[1]-1]
- if lastChar == '.' {
- m[1]--
- }
- if m[1] < len(line) {
- nextChar := line[m[1]]
- if nextChar == '-' || nextChar == '_' {
- return nil
- }
- }
- }
- if m == nil {
- return nil
- }
- if consumes != 0 {
- s := segment.WithStop(segment.Start + 1)
- ast.MergeOrAppendTextSegment(parent, s)
- }
- i := m[1] - 1
- for ; i > 0; i-- {
- c := line[i]
- switch c {
- case '?', '!', '.', ',', ':', '*', '_', '~':
- default:
- goto endfor
- }
- }
-endfor:
- i++
- consumes += i
- block.Advance(consumes)
- n := ast.NewTextSegment(text.NewSegment(start, start+i))
- link := ast.NewAutoLink(typ, n)
- link.Protocol = protocol
- return link
-}
-
-func (s *linkifyParser) CloseBlock(parent ast.Node, pc parser.Context) {
- // nothing to do
-}
-
-type linkify struct {
- options []LinkifyOption
-}
-
-// Linkify is an extension that allow you to parse text that seems like a URL.
-var Linkify = &linkify{}
-
-// NewLinkify creates a new [goldmark.Extender] that
-// allow you to parse text that seems like a URL.
-func NewLinkify(opts ...LinkifyOption) goldmark.Extender {
- return &linkify{
- options: opts,
- }
-}
-
-func (e *linkify) Extend(m goldmark.Markdown) {
- m.Parser().AddOptions(
- parser.WithInlineParsers(
- util.Prioritized(NewLinkifyParser(e.options...), 999),
- ),
- )
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/package.go b/vendor/github.com/yuin/goldmark/extension/package.go
deleted file mode 100644
index 2ec1d1eb2..000000000
--- a/vendor/github.com/yuin/goldmark/extension/package.go
+++ /dev/null
@@ -1,2 +0,0 @@
-// Package extension is a collection of builtin extensions.
-package extension
diff --git a/vendor/github.com/yuin/goldmark/extension/strikethrough.go b/vendor/github.com/yuin/goldmark/extension/strikethrough.go
deleted file mode 100644
index 9fc0becfd..000000000
--- a/vendor/github.com/yuin/goldmark/extension/strikethrough.go
+++ /dev/null
@@ -1,118 +0,0 @@
-package extension
-
-import (
- "github.com/yuin/goldmark"
- gast "github.com/yuin/goldmark/ast"
- "github.com/yuin/goldmark/extension/ast"
- "github.com/yuin/goldmark/parser"
- "github.com/yuin/goldmark/renderer"
- "github.com/yuin/goldmark/renderer/html"
- "github.com/yuin/goldmark/text"
- "github.com/yuin/goldmark/util"
-)
-
-type strikethroughDelimiterProcessor struct {
-}
-
-func (p *strikethroughDelimiterProcessor) IsDelimiter(b byte) bool {
- return b == '~'
-}
-
-func (p *strikethroughDelimiterProcessor) CanOpenCloser(opener, closer *parser.Delimiter) bool {
- return opener.Char == closer.Char
-}
-
-func (p *strikethroughDelimiterProcessor) OnMatch(consumes int) gast.Node {
- return ast.NewStrikethrough()
-}
-
-var defaultStrikethroughDelimiterProcessor = &strikethroughDelimiterProcessor{}
-
-type strikethroughParser struct {
-}
-
-var defaultStrikethroughParser = &strikethroughParser{}
-
-// NewStrikethroughParser return a new InlineParser that parses
-// strikethrough expressions.
-func NewStrikethroughParser() parser.InlineParser {
- return defaultStrikethroughParser
-}
-
-func (s *strikethroughParser) Trigger() []byte {
- return []byte{'~'}
-}
-
-func (s *strikethroughParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node {
- before := block.PrecendingCharacter()
- line, segment := block.PeekLine()
- node := parser.ScanDelimiter(line, before, 1, defaultStrikethroughDelimiterProcessor)
- if node == nil || node.OriginalLength > 2 || before == '~' {
- return nil
- }
-
- node.Segment = segment.WithStop(segment.Start + node.OriginalLength)
- block.Advance(node.OriginalLength)
- pc.PushDelimiter(node)
- return node
-}
-
-func (s *strikethroughParser) CloseBlock(parent gast.Node, pc parser.Context) {
- // nothing to do
-}
-
-// StrikethroughHTMLRenderer is a renderer.NodeRenderer implementation that
-// renders Strikethrough nodes.
-type StrikethroughHTMLRenderer struct {
- html.Config
-}
-
-// NewStrikethroughHTMLRenderer returns a new StrikethroughHTMLRenderer.
-func NewStrikethroughHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
- r := &StrikethroughHTMLRenderer{
- Config: html.NewConfig(),
- }
- for _, opt := range opts {
- opt.SetHTMLOption(&r.Config)
- }
- return r
-}
-
-// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs.
-func (r *StrikethroughHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
- reg.Register(ast.KindStrikethrough, r.renderStrikethrough)
-}
-
-// StrikethroughAttributeFilter defines attribute names which dd elements can have.
-var StrikethroughAttributeFilter = html.GlobalAttributeFilter
-
-func (r *StrikethroughHTMLRenderer) renderStrikethrough(
- w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) {
- if entering {
- if n.Attributes() != nil {
- _, _ = w.WriteString("<del")
- html.RenderAttributes(w, n, StrikethroughAttributeFilter)
- _ = w.WriteByte('>')
- } else {
- _, _ = w.WriteString("<del>")
- }
- } else {
- _, _ = w.WriteString("</del>")
- }
- return gast.WalkContinue, nil
-}
-
-type strikethrough struct {
-}
-
-// Strikethrough is an extension that allow you to use strikethrough expression like '~~text~~' .
-var Strikethrough = &strikethrough{}
-
-func (e *strikethrough) Extend(m goldmark.Markdown) {
- m.Parser().AddOptions(parser.WithInlineParsers(
- util.Prioritized(NewStrikethroughParser(), 500),
- ))
- m.Renderer().AddOptions(renderer.WithNodeRenderers(
- util.Prioritized(NewStrikethroughHTMLRenderer(), 500),
- ))
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/table.go b/vendor/github.com/yuin/goldmark/extension/table.go
deleted file mode 100644
index ee782a2c5..000000000
--- a/vendor/github.com/yuin/goldmark/extension/table.go
+++ /dev/null
@@ -1,555 +0,0 @@
-package extension
-
-import (
- "bytes"
- "fmt"
- "regexp"
-
- "github.com/yuin/goldmark"
- gast "github.com/yuin/goldmark/ast"
- "github.com/yuin/goldmark/extension/ast"
- "github.com/yuin/goldmark/parser"
- "github.com/yuin/goldmark/renderer"
- "github.com/yuin/goldmark/renderer/html"
- "github.com/yuin/goldmark/text"
- "github.com/yuin/goldmark/util"
-)
-
-var escapedPipeCellListKey = parser.NewContextKey()
-
-type escapedPipeCell struct {
- Cell *ast.TableCell
- Pos []int
- Transformed bool
-}
-
-// TableCellAlignMethod indicates how are table cells aligned in HTML format.
-type TableCellAlignMethod int
-
-const (
- // TableCellAlignDefault renders alignments by default method.
- // With XHTML, alignments are rendered as an align attribute.
- // With HTML5, alignments are rendered as a style attribute.
- TableCellAlignDefault TableCellAlignMethod = iota
-
- // TableCellAlignAttribute renders alignments as an align attribute.
- TableCellAlignAttribute
-
- // TableCellAlignStyle renders alignments as a style attribute.
- TableCellAlignStyle
-
- // TableCellAlignNone does not care about alignments.
- // If you using classes or other styles, you can add these attributes
- // in an ASTTransformer.
- TableCellAlignNone
-)
-
-// TableConfig struct holds options for the extension.
-type TableConfig struct {
- html.Config
-
- // TableCellAlignMethod indicates how are table celss aligned.
- TableCellAlignMethod TableCellAlignMethod
-}
-
-// TableOption interface is a functional option interface for the extension.
-type TableOption interface {
- renderer.Option
- // SetTableOption sets given option to the extension.
- SetTableOption(*TableConfig)
-}
-
-// NewTableConfig returns a new Config with defaults.
-func NewTableConfig() TableConfig {
- return TableConfig{
- Config: html.NewConfig(),
- TableCellAlignMethod: TableCellAlignDefault,
- }
-}
-
-// SetOption implements renderer.SetOptioner.
-func (c *TableConfig) SetOption(name renderer.OptionName, value interface{}) {
- switch name {
- case optTableCellAlignMethod:
- c.TableCellAlignMethod = value.(TableCellAlignMethod)
- default:
- c.Config.SetOption(name, value)
- }
-}
-
-type withTableHTMLOptions struct {
- value []html.Option
-}
-
-func (o *withTableHTMLOptions) SetConfig(c *renderer.Config) {
- if o.value != nil {
- for _, v := range o.value {
- v.(renderer.Option).SetConfig(c)
- }
- }
-}
-
-func (o *withTableHTMLOptions) SetTableOption(c *TableConfig) {
- if o.value != nil {
- for _, v := range o.value {
- v.SetHTMLOption(&c.Config)
- }
- }
-}
-
-// WithTableHTMLOptions is functional option that wraps goldmark HTMLRenderer options.
-func WithTableHTMLOptions(opts ...html.Option) TableOption {
- return &withTableHTMLOptions{opts}
-}
-
-const optTableCellAlignMethod renderer.OptionName = "TableTableCellAlignMethod"
-
-type withTableCellAlignMethod struct {
- value TableCellAlignMethod
-}
-
-func (o *withTableCellAlignMethod) SetConfig(c *renderer.Config) {
- c.Options[optTableCellAlignMethod] = o.value
-}
-
-func (o *withTableCellAlignMethod) SetTableOption(c *TableConfig) {
- c.TableCellAlignMethod = o.value
-}
-
-// WithTableCellAlignMethod is a functional option that indicates how are table cells aligned in HTML format.
-func WithTableCellAlignMethod(a TableCellAlignMethod) TableOption {
- return &withTableCellAlignMethod{a}
-}
-
-func isTableDelim(bs []byte) bool {
- if w, _ := util.IndentWidth(bs, 0); w > 3 {
- return false
- }
- for _, b := range bs {
- if !(util.IsSpace(b) || b == '-' || b == '|' || b == ':') {
- return false
- }
- }
- return true
-}
-
-var tableDelimLeft = regexp.MustCompile(`^\s*\:\-+\s*$`)
-var tableDelimRight = regexp.MustCompile(`^\s*\-+\:\s*$`)
-var tableDelimCenter = regexp.MustCompile(`^\s*\:\-+\:\s*$`)
-var tableDelimNone = regexp.MustCompile(`^\s*\-+\s*$`)
-
-type tableParagraphTransformer struct {
-}
-
-var defaultTableParagraphTransformer = &tableParagraphTransformer{}
-
-// NewTableParagraphTransformer returns a new ParagraphTransformer
-// that can transform paragraphs into tables.
-func NewTableParagraphTransformer() parser.ParagraphTransformer {
- return defaultTableParagraphTransformer
-}
-
-func (b *tableParagraphTransformer) Transform(node *gast.Paragraph, reader text.Reader, pc parser.Context) {
- lines := node.Lines()
- if lines.Len() < 2 {
- return
- }
- for i := 1; i < lines.Len(); i++ {
- alignments := b.parseDelimiter(lines.At(i), reader)
- if alignments == nil {
- continue
- }
- header := b.parseRow(lines.At(i-1), alignments, true, reader, pc)
- if header == nil || len(alignments) != header.ChildCount() {
- return
- }
- table := ast.NewTable()
- table.Alignments = alignments
- table.AppendChild(table, ast.NewTableHeader(header))
- for j := i + 1; j < lines.Len(); j++ {
- table.AppendChild(table, b.parseRow(lines.At(j), alignments, false, reader, pc))
- }
- node.Lines().SetSliced(0, i-1)
- node.Parent().InsertAfter(node.Parent(), node, table)
- if node.Lines().Len() == 0 {
- node.Parent().RemoveChild(node.Parent(), node)
- } else {
- last := node.Lines().At(i - 2)
- last.Stop = last.Stop - 1 // trim last newline(\n)
- node.Lines().Set(i-2, last)
- }
- }
-}
-
-func (b *tableParagraphTransformer) parseRow(segment text.Segment,
- alignments []ast.Alignment, isHeader bool, reader text.Reader, pc parser.Context) *ast.TableRow {
- source := reader.Source()
- segment = segment.TrimLeftSpace(source)
- segment = segment.TrimRightSpace(source)
- line := segment.Value(source)
- pos := 0
- limit := len(line)
- row := ast.NewTableRow(alignments)
- if len(line) > 0 && line[pos] == '|' {
- pos++
- }
- if len(line) > 0 && line[limit-1] == '|' {
- limit--
- }
- i := 0
- for ; pos < limit; i++ {
- alignment := ast.AlignNone
- if i >= len(alignments) {
- if !isHeader {
- return row
- }
- } else {
- alignment = alignments[i]
- }
-
- var escapedCell *escapedPipeCell
- node := ast.NewTableCell()
- node.Alignment = alignment
- hasBacktick := false
- closure := pos
- for ; closure < limit; closure++ {
- if line[closure] == '`' {
- hasBacktick = true
- }
- if line[closure] == '|' {
- if closure == 0 || line[closure-1] != '\\' {
- break
- } else if hasBacktick {
- if escapedCell == nil {
- escapedCell = &escapedPipeCell{node, []int{}, false}
- escapedList := pc.ComputeIfAbsent(escapedPipeCellListKey,
- func() interface{} {
- return []*escapedPipeCell{}
- }).([]*escapedPipeCell)
- escapedList = append(escapedList, escapedCell)
- pc.Set(escapedPipeCellListKey, escapedList)
- }
- escapedCell.Pos = append(escapedCell.Pos, segment.Start+closure-1)
- }
- }
- }
- seg := text.NewSegment(segment.Start+pos, segment.Start+closure)
- seg = seg.TrimLeftSpace(source)
- seg = seg.TrimRightSpace(source)
- node.Lines().Append(seg)
- row.AppendChild(row, node)
- pos = closure + 1
- }
- for ; i < len(alignments); i++ {
- row.AppendChild(row, ast.NewTableCell())
- }
- return row
-}
-
-func (b *tableParagraphTransformer) parseDelimiter(segment text.Segment, reader text.Reader) []ast.Alignment {
-
- line := segment.Value(reader.Source())
- if !isTableDelim(line) {
- return nil
- }
- cols := bytes.Split(line, []byte{'|'})
- if util.IsBlank(cols[0]) {
- cols = cols[1:]
- }
- if len(cols) > 0 && util.IsBlank(cols[len(cols)-1]) {
- cols = cols[:len(cols)-1]
- }
-
- var alignments []ast.Alignment
- for _, col := range cols {
- if tableDelimLeft.Match(col) {
- alignments = append(alignments, ast.AlignLeft)
- } else if tableDelimRight.Match(col) {
- alignments = append(alignments, ast.AlignRight)
- } else if tableDelimCenter.Match(col) {
- alignments = append(alignments, ast.AlignCenter)
- } else if tableDelimNone.Match(col) {
- alignments = append(alignments, ast.AlignNone)
- } else {
- return nil
- }
- }
- return alignments
-}
-
-type tableASTTransformer struct {
-}
-
-var defaultTableASTTransformer = &tableASTTransformer{}
-
-// NewTableASTTransformer returns a parser.ASTTransformer for tables.
-func NewTableASTTransformer() parser.ASTTransformer {
- return defaultTableASTTransformer
-}
-
-func (a *tableASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) {
- lst := pc.Get(escapedPipeCellListKey)
- if lst == nil {
- return
- }
- pc.Set(escapedPipeCellListKey, nil)
- for _, v := range lst.([]*escapedPipeCell) {
- if v.Transformed {
- continue
- }
- _ = gast.Walk(v.Cell, func(n gast.Node, entering bool) (gast.WalkStatus, error) {
- if !entering || n.Kind() != gast.KindCodeSpan {
- return gast.WalkContinue, nil
- }
-
- for c := n.FirstChild(); c != nil; {
- next := c.NextSibling()
- if c.Kind() != gast.KindText {
- c = next
- continue
- }
- parent := c.Parent()
- ts := &c.(*gast.Text).Segment
- n := c
- for _, v := range lst.([]*escapedPipeCell) {
- for _, pos := range v.Pos {
- if ts.Start <= pos && pos < ts.Stop {
- segment := n.(*gast.Text).Segment
- n1 := gast.NewRawTextSegment(segment.WithStop(pos))
- n2 := gast.NewRawTextSegment(segment.WithStart(pos + 1))
- parent.InsertAfter(parent, n, n1)
- parent.InsertAfter(parent, n1, n2)
- parent.RemoveChild(parent, n)
- n = n2
- v.Transformed = true
- }
- }
- }
- c = next
- }
- return gast.WalkContinue, nil
- })
- }
-}
-
-// TableHTMLRenderer is a renderer.NodeRenderer implementation that
-// renders Table nodes.
-type TableHTMLRenderer struct {
- TableConfig
-}
-
-// NewTableHTMLRenderer returns a new TableHTMLRenderer.
-func NewTableHTMLRenderer(opts ...TableOption) renderer.NodeRenderer {
- r := &TableHTMLRenderer{
- TableConfig: NewTableConfig(),
- }
- for _, opt := range opts {
- opt.SetTableOption(&r.TableConfig)
- }
- return r
-}
-
-// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs.
-func (r *TableHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
- reg.Register(ast.KindTable, r.renderTable)
- reg.Register(ast.KindTableHeader, r.renderTableHeader)
- reg.Register(ast.KindTableRow, r.renderTableRow)
- reg.Register(ast.KindTableCell, r.renderTableCell)
-}
-
-// TableAttributeFilter defines attribute names which table elements can have.
-//
-// - align: Deprecated
-// - bgcolor: Deprecated
-// - border: Deprecated
-// - cellpadding: Deprecated
-// - cellspacing: Deprecated
-// - frame: Deprecated
-// - rules: Deprecated
-// - summary: Deprecated
-// - width: Deprecated.
-var TableAttributeFilter = html.GlobalAttributeFilter.ExtendString(`align,bgcolor,border,cellpadding,cellspacing,frame,rules,summary,width`) // nolint: lll
-
-func (r *TableHTMLRenderer) renderTable(
- w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) {
- if entering {
- _, _ = w.WriteString("<table")
- if n.Attributes() != nil {
- html.RenderAttributes(w, n, TableAttributeFilter)
- }
- _, _ = w.WriteString(">\n")
- } else {
- _, _ = w.WriteString("</table>\n")
- }
- return gast.WalkContinue, nil
-}
-
-// TableHeaderAttributeFilter defines attribute names which <thead> elements can have.
-//
-// - align: Deprecated since HTML4, Obsolete since HTML5
-// - bgcolor: Not Standardized
-// - char: Deprecated since HTML4, Obsolete since HTML5
-// - charoff: Deprecated since HTML4, Obsolete since HTML5
-// - valign: Deprecated since HTML4, Obsolete since HTML5.
-var TableHeaderAttributeFilter = html.GlobalAttributeFilter.ExtendString(`align,bgcolor,char,charoff,valign`)
-
-func (r *TableHTMLRenderer) renderTableHeader(
- w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) {
- if entering {
- _, _ = w.WriteString("<thead")
- if n.Attributes() != nil {
- html.RenderAttributes(w, n, TableHeaderAttributeFilter)
- }
- _, _ = w.WriteString(">\n")
- _, _ = w.WriteString("<tr>\n") // Header <tr> has no separate handle
- } else {
- _, _ = w.WriteString("</tr>\n")
- _, _ = w.WriteString("</thead>\n")
- if n.NextSibling() != nil {
- _, _ = w.WriteString("<tbody>\n")
- }
- }
- return gast.WalkContinue, nil
-}
-
-// TableRowAttributeFilter defines attribute names which <tr> elements can have.
-//
-// - align: Obsolete since HTML5
-// - bgcolor: Obsolete since HTML5
-// - char: Obsolete since HTML5
-// - charoff: Obsolete since HTML5
-// - valign: Obsolete since HTML5.
-var TableRowAttributeFilter = html.GlobalAttributeFilter.ExtendString(`align,bgcolor,char,charoff,valign`)
-
-func (r *TableHTMLRenderer) renderTableRow(
- w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) {
- if entering {
- _, _ = w.WriteString("<tr")
- if n.Attributes() != nil {
- html.RenderAttributes(w, n, TableRowAttributeFilter)
- }
- _, _ = w.WriteString(">\n")
- } else {
- _, _ = w.WriteString("</tr>\n")
- if n.Parent().LastChild() == n {
- _, _ = w.WriteString("</tbody>\n")
- }
- }
- return gast.WalkContinue, nil
-}
-
-// TableThCellAttributeFilter defines attribute names which table <th> cells can have.
-//
-// - abbr: [OK] Contains a short abbreviated description of the cell's content [NOT OK in <td>]
-// - align: Obsolete since HTML5
-// - axis: Obsolete since HTML5
-// - bgcolor: Not Standardized
-// - char: Obsolete since HTML5
-// - charoff: Obsolete since HTML5
-// - colspan: [OK] Number of columns that the cell is to span
-// - headers: [OK] This attribute contains a list of space-separated strings,
-// each corresponding to the id attribute of the <th> elements that apply to this element
-// - height: Deprecated since HTML4. Obsolete since HTML5
-// - rowspan: [OK] Number of rows that the cell is to span
-// - scope: [OK] This enumerated attribute defines the cells that the header
-// (defined in the <th>) element relates to [NOT OK in <td>]
-// - valign: Obsolete since HTML5
-// - width: Deprecated since HTML4. Obsolete since HTML5.
-var TableThCellAttributeFilter = html.GlobalAttributeFilter.ExtendString(`abbr,align,axis,bgcolor,char,charoff,colspan,headers,height,rowspan,scope,valign,width`) // nolint:lll
-
-// TableTdCellAttributeFilter defines attribute names which table <td> cells can have.
-//
-// - abbr: Obsolete since HTML5. [OK in <th>]
-// - align: Obsolete since HTML5
-// - axis: Obsolete since HTML5
-// - bgcolor: Not Standardized
-// - char: Obsolete since HTML5
-// - charoff: Obsolete since HTML5
-// - colspan: [OK] Number of columns that the cell is to span
-// - headers: [OK] This attribute contains a list of space-separated strings, each corresponding
-// to the id attribute of the <th> elements that apply to this element
-// - height: Deprecated since HTML4. Obsolete since HTML5
-// - rowspan: [OK] Number of rows that the cell is to span
-// - scope: Obsolete since HTML5. [OK in <th>]
-// - valign: Obsolete since HTML5
-// - width: Deprecated since HTML4. Obsolete since HTML5.
-var TableTdCellAttributeFilter = html.GlobalAttributeFilter.ExtendString(`abbr,align,axis,bgcolor,char,charoff,colspan,headers,height,rowspan,scope,valign,width`) // nolint: lll
-
-func (r *TableHTMLRenderer) renderTableCell(
- w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
- n := node.(*ast.TableCell)
- tag := "td"
- if n.Parent().Kind() == ast.KindTableHeader {
- tag = "th"
- }
- if entering {
- _, _ = fmt.Fprintf(w, "<%s", tag)
- if n.Alignment != ast.AlignNone {
- amethod := r.TableConfig.TableCellAlignMethod
- if amethod == TableCellAlignDefault {
- if r.Config.XHTML {
- amethod = TableCellAlignAttribute
- } else {
- amethod = TableCellAlignStyle
- }
- }
- switch amethod {
- case TableCellAlignAttribute:
- if _, ok := n.AttributeString("align"); !ok { // Skip align render if overridden
- _, _ = fmt.Fprintf(w, ` align="%s"`, n.Alignment.String())
- }
- case TableCellAlignStyle:
- v, ok := n.AttributeString("style")
- var cob util.CopyOnWriteBuffer
- if ok {
- cob = util.NewCopyOnWriteBuffer(v.([]byte))
- cob.AppendByte(';')
- }
- style := fmt.Sprintf("text-align:%s", n.Alignment.String())
- cob.AppendString(style)
- n.SetAttributeString("style", cob.Bytes())
- }
- }
- if n.Attributes() != nil {
- if tag == "td" {
- html.RenderAttributes(w, n, TableTdCellAttributeFilter) // <td>
- } else {
- html.RenderAttributes(w, n, TableThCellAttributeFilter) // <th>
- }
- }
- _ = w.WriteByte('>')
- } else {
- _, _ = fmt.Fprintf(w, "</%s>\n", tag)
- }
- return gast.WalkContinue, nil
-}
-
-type table struct {
- options []TableOption
-}
-
-// Table is an extension that allow you to use GFM tables .
-var Table = &table{
- options: []TableOption{},
-}
-
-// NewTable returns a new extension with given options.
-func NewTable(opts ...TableOption) goldmark.Extender {
- return &table{
- options: opts,
- }
-}
-
-func (e *table) Extend(m goldmark.Markdown) {
- m.Parser().AddOptions(
- parser.WithParagraphTransformers(
- util.Prioritized(NewTableParagraphTransformer(), 200),
- ),
- parser.WithASTTransformers(
- util.Prioritized(defaultTableASTTransformer, 0),
- ),
- )
- m.Renderer().AddOptions(renderer.WithNodeRenderers(
- util.Prioritized(NewTableHTMLRenderer(e.options...), 500),
- ))
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/tasklist.go b/vendor/github.com/yuin/goldmark/extension/tasklist.go
deleted file mode 100644
index 4467ebfff..000000000
--- a/vendor/github.com/yuin/goldmark/extension/tasklist.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package extension
-
-import (
- "regexp"
-
- "github.com/yuin/goldmark"
- gast "github.com/yuin/goldmark/ast"
- "github.com/yuin/goldmark/extension/ast"
- "github.com/yuin/goldmark/parser"
- "github.com/yuin/goldmark/renderer"
- "github.com/yuin/goldmark/renderer/html"
- "github.com/yuin/goldmark/text"
- "github.com/yuin/goldmark/util"
-)
-
-var taskListRegexp = regexp.MustCompile(`^\[([\sxX])\]\s*`)
-
-type taskCheckBoxParser struct {
-}
-
-var defaultTaskCheckBoxParser = &taskCheckBoxParser{}
-
-// NewTaskCheckBoxParser returns a new InlineParser that can parse
-// checkboxes in list items.
-// This parser must take precedence over the parser.LinkParser.
-func NewTaskCheckBoxParser() parser.InlineParser {
- return defaultTaskCheckBoxParser
-}
-
-func (s *taskCheckBoxParser) Trigger() []byte {
- return []byte{'['}
-}
-
-func (s *taskCheckBoxParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node {
- // Given AST structure must be like
- // - List
- // - ListItem : parent.Parent
- // - TextBlock : parent
- // (current line)
- if parent.Parent() == nil || parent.Parent().FirstChild() != parent {
- return nil
- }
-
- if parent.HasChildren() {
- return nil
- }
- if _, ok := parent.Parent().(*gast.ListItem); !ok {
- return nil
- }
- line, _ := block.PeekLine()
- m := taskListRegexp.FindSubmatchIndex(line)
- if m == nil {
- return nil
- }
- value := line[m[2]:m[3]][0]
- block.Advance(m[1])
- checked := value == 'x' || value == 'X'
- return ast.NewTaskCheckBox(checked)
-}
-
-func (s *taskCheckBoxParser) CloseBlock(parent gast.Node, pc parser.Context) {
- // nothing to do
-}
-
-// TaskCheckBoxHTMLRenderer is a renderer.NodeRenderer implementation that
-// renders checkboxes in list items.
-type TaskCheckBoxHTMLRenderer struct {
- html.Config
-}
-
-// NewTaskCheckBoxHTMLRenderer returns a new TaskCheckBoxHTMLRenderer.
-func NewTaskCheckBoxHTMLRenderer(opts ...html.Option) renderer.NodeRenderer {
- r := &TaskCheckBoxHTMLRenderer{
- Config: html.NewConfig(),
- }
- for _, opt := range opts {
- opt.SetHTMLOption(&r.Config)
- }
- return r
-}
-
-// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs.
-func (r *TaskCheckBoxHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
- reg.Register(ast.KindTaskCheckBox, r.renderTaskCheckBox)
-}
-
-func (r *TaskCheckBoxHTMLRenderer) renderTaskCheckBox(
- w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
- if !entering {
- return gast.WalkContinue, nil
- }
- n := node.(*ast.TaskCheckBox)
-
- if n.IsChecked {
- _, _ = w.WriteString(`<input checked="" disabled="" type="checkbox"`)
- } else {
- _, _ = w.WriteString(`<input disabled="" type="checkbox"`)
- }
- if r.XHTML {
- _, _ = w.WriteString(" /> ")
- } else {
- _, _ = w.WriteString("> ")
- }
- return gast.WalkContinue, nil
-}
-
-type taskList struct {
-}
-
-// TaskList is an extension that allow you to use GFM task lists.
-var TaskList = &taskList{}
-
-func (e *taskList) Extend(m goldmark.Markdown) {
- m.Parser().AddOptions(parser.WithInlineParsers(
- util.Prioritized(NewTaskCheckBoxParser(), 0),
- ))
- m.Renderer().AddOptions(renderer.WithNodeRenderers(
- util.Prioritized(NewTaskCheckBoxHTMLRenderer(), 500),
- ))
-}
diff --git a/vendor/github.com/yuin/goldmark/extension/typographer.go b/vendor/github.com/yuin/goldmark/extension/typographer.go
deleted file mode 100644
index 44c15ebf1..000000000
--- a/vendor/github.com/yuin/goldmark/extension/typographer.go
+++ /dev/null
@@ -1,348 +0,0 @@
-package extension
-
-import (
- "unicode"
-
- "github.com/yuin/goldmark"
- gast "github.com/yuin/goldmark/ast"
- "github.com/yuin/goldmark/parser"
- "github.com/yuin/goldmark/text"
- "github.com/yuin/goldmark/util"
-)
-
-var uncloseCounterKey = parser.NewContextKey()
-
-type unclosedCounter struct {
- Single int
- Double int
-}
-
-func (u *unclosedCounter) Reset() {
- u.Single = 0
- u.Double = 0
-}
-
-func getUnclosedCounter(pc parser.Context) *unclosedCounter {
- v := pc.Get(uncloseCounterKey)
- if v == nil {
- v = &unclosedCounter{}
- pc.Set(uncloseCounterKey, v)
- }
- return v.(*unclosedCounter)
-}
-
-// TypographicPunctuation is a key of the punctuations that can be replaced with
-// typographic entities.
-type TypographicPunctuation int
-
-const (
- // LeftSingleQuote is ' .
- LeftSingleQuote TypographicPunctuation = iota + 1
- // RightSingleQuote is ' .
- RightSingleQuote
- // LeftDoubleQuote is " .
- LeftDoubleQuote
- // RightDoubleQuote is " .
- RightDoubleQuote
- // EnDash is -- .
- EnDash
- // EmDash is --- .
- EmDash
- // Ellipsis is ... .
- Ellipsis
- // LeftAngleQuote is << .
- LeftAngleQuote
- // RightAngleQuote is >> .
- RightAngleQuote
- // Apostrophe is ' .
- Apostrophe
-
- typographicPunctuationMax
-)
-
-// An TypographerConfig struct is a data structure that holds configuration of the
-// Typographer extension.
-type TypographerConfig struct {
- Substitutions [][]byte
-}
-
-func newDefaultSubstitutions() [][]byte {
- replacements := make([][]byte, typographicPunctuationMax)
- replacements[LeftSingleQuote] = []byte("&lsquo;")
- replacements[RightSingleQuote] = []byte("&rsquo;")
- replacements[LeftDoubleQuote] = []byte("&ldquo;")
- replacements[RightDoubleQuote] = []byte("&rdquo;")
- replacements[EnDash] = []byte("&ndash;")
- replacements[EmDash] = []byte("&mdash;")
- replacements[Ellipsis] = []byte("&hellip;")
- replacements[LeftAngleQuote] = []byte("&laquo;")
- replacements[RightAngleQuote] = []byte("&raquo;")
- replacements[Apostrophe] = []byte("&rsquo;")
-
- return replacements
-}
-
-// SetOption implements SetOptioner.
-func (b *TypographerConfig) SetOption(name parser.OptionName, value interface{}) {
- switch name {
- case optTypographicSubstitutions:
- b.Substitutions = value.([][]byte)
- }
-}
-
-// A TypographerOption interface sets options for the TypographerParser.
-type TypographerOption interface {
- parser.Option
- SetTypographerOption(*TypographerConfig)
-}
-
-const optTypographicSubstitutions parser.OptionName = "TypographicSubstitutions"
-
-// TypographicSubstitutions is a list of the substitutions for the Typographer extension.
-type TypographicSubstitutions map[TypographicPunctuation][]byte
-
-type withTypographicSubstitutions struct {
- value [][]byte
-}
-
-func (o *withTypographicSubstitutions) SetParserOption(c *parser.Config) {
- c.Options[optTypographicSubstitutions] = o.value
-}
-
-func (o *withTypographicSubstitutions) SetTypographerOption(p *TypographerConfig) {
- p.Substitutions = o.value
-}
-
-// WithTypographicSubstitutions is a functional otpion that specify replacement text
-// for punctuations.
-func WithTypographicSubstitutions[T []byte | string](values map[TypographicPunctuation]T) TypographerOption {
- replacements := newDefaultSubstitutions()
- for k, v := range values {
- replacements[k] = []byte(v)
- }
-
- return &withTypographicSubstitutions{replacements}
-}
-
-type typographerDelimiterProcessor struct {
-}
-
-func (p *typographerDelimiterProcessor) IsDelimiter(b byte) bool {
- return b == '\'' || b == '"'
-}
-
-func (p *typographerDelimiterProcessor) CanOpenCloser(opener, closer *parser.Delimiter) bool {
- return opener.Char == closer.Char
-}
-
-func (p *typographerDelimiterProcessor) OnMatch(consumes int) gast.Node {
- return nil
-}
-
-var defaultTypographerDelimiterProcessor = &typographerDelimiterProcessor{}
-
-type typographerParser struct {
- TypographerConfig
-}
-
-// NewTypographerParser return a new InlineParser that parses
-// typographer expressions.
-func NewTypographerParser(opts ...TypographerOption) parser.InlineParser {
- p := &typographerParser{
- TypographerConfig: TypographerConfig{
- Substitutions: newDefaultSubstitutions(),
- },
- }
- for _, o := range opts {
- o.SetTypographerOption(&p.TypographerConfig)
- }
- return p
-}
-
-func (s *typographerParser) Trigger() []byte {
- return []byte{'\'', '"', '-', '.', ',', '<', '>', '*', '['}
-}
-
-func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node {
- line, _ := block.PeekLine()
- c := line[0]
- if len(line) > 2 {
- if c == '-' {
- if s.Substitutions[EmDash] != nil && line[1] == '-' && line[2] == '-' { // ---
- node := gast.NewString(s.Substitutions[EmDash])
- node.SetCode(true)
- block.Advance(3)
- return node
- }
- } else if c == '.' {
- if s.Substitutions[Ellipsis] != nil && line[1] == '.' && line[2] == '.' { // ...
- node := gast.NewString(s.Substitutions[Ellipsis])
- node.SetCode(true)
- block.Advance(3)
- return node
- }
- return nil
- }
- }
- if len(line) > 1 {
- if c == '<' {
- if s.Substitutions[LeftAngleQuote] != nil && line[1] == '<' { // <<
- node := gast.NewString(s.Substitutions[LeftAngleQuote])
- node.SetCode(true)
- block.Advance(2)
- return node
- }
- return nil
- } else if c == '>' {
- if s.Substitutions[RightAngleQuote] != nil && line[1] == '>' { // >>
- node := gast.NewString(s.Substitutions[RightAngleQuote])
- node.SetCode(true)
- block.Advance(2)
- return node
- }
- return nil
- } else if s.Substitutions[EnDash] != nil && c == '-' && line[1] == '-' { // --
- node := gast.NewString(s.Substitutions[EnDash])
- node.SetCode(true)
- block.Advance(2)
- return node
- }
- }
- if c == '\'' || c == '"' {
- before := block.PrecendingCharacter()
- d := parser.ScanDelimiter(line, before, 1, defaultTypographerDelimiterProcessor)
- if d == nil {
- return nil
- }
- counter := getUnclosedCounter(pc)
- if c == '\'' {
- if s.Substitutions[Apostrophe] != nil {
- // Handle decade abbrevations such as '90s
- if d.CanOpen && !d.CanClose && len(line) > 3 &&
- util.IsNumeric(line[1]) && util.IsNumeric(line[2]) && line[3] == 's' {
- after := rune(' ')
- if len(line) > 4 {
- after = util.ToRune(line, 4)
- }
- if len(line) == 3 || util.IsSpaceRune(after) || util.IsPunctRune(after) {
- node := gast.NewString(s.Substitutions[Apostrophe])
- node.SetCode(true)
- block.Advance(1)
- return node
- }
- }
- // special cases: 'twas, 'em, 'net
- if len(line) > 1 && (unicode.IsPunct(before) || unicode.IsSpace(before)) &&
- (line[1] == 't' || line[1] == 'e' || line[1] == 'n' || line[1] == 'l') {
- node := gast.NewString(s.Substitutions[Apostrophe])
- node.SetCode(true)
- block.Advance(1)
- return node
- }
- // Convert normal apostrophes. This is probably more flexible than necessary but
- // converts any apostrophe in between two alphanumerics.
- if len(line) > 1 && (unicode.IsDigit(before) || unicode.IsLetter(before)) &&
- (unicode.IsLetter(util.ToRune(line, 1))) {
- node := gast.NewString(s.Substitutions[Apostrophe])
- node.SetCode(true)
- block.Advance(1)
- return node
- }
- }
- if s.Substitutions[LeftSingleQuote] != nil && d.CanOpen && !d.CanClose {
- nt := LeftSingleQuote
- // special cases: Alice's, I'm, Don't, You'd
- if len(line) > 1 && (line[1] == 's' || line[1] == 'm' || line[1] == 't' || line[1] == 'd') &&
- (len(line) < 3 || util.IsPunct(line[2]) || util.IsSpace(line[2])) {
- nt = RightSingleQuote
- }
- // special cases: I've, I'll, You're
- if len(line) > 2 && ((line[1] == 'v' && line[2] == 'e') ||
- (line[1] == 'l' && line[2] == 'l') || (line[1] == 'r' && line[2] == 'e')) &&
- (len(line) < 4 || util.IsPunct(line[3]) || util.IsSpace(line[3])) {
- nt = RightSingleQuote
- }
- if nt == LeftSingleQuote {
- counter.Single++
- }
-
- node := gast.NewString(s.Substitutions[nt])
- node.SetCode(true)
- block.Advance(1)
- return node
- }
- if s.Substitutions[RightSingleQuote] != nil {
- // plural possesive and abbreviations: Smiths', doin'
- if len(line) > 1 && unicode.IsSpace(util.ToRune(line, 0)) || unicode.IsPunct(util.ToRune(line, 0)) &&
- (len(line) > 2 && !unicode.IsDigit(util.ToRune(line, 1))) {
- node := gast.NewString(s.Substitutions[RightSingleQuote])
- node.SetCode(true)
- block.Advance(1)
- return node
- }
- }
- if s.Substitutions[RightSingleQuote] != nil && counter.Single > 0 {
- isClose := d.CanClose && !d.CanOpen
- maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && unicode.IsPunct(util.ToRune(line, 1)) &&
- (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2])))
- if isClose || maybeClose {
- node := gast.NewString(s.Substitutions[RightSingleQuote])
- node.SetCode(true)
- block.Advance(1)
- counter.Single--
- return node
- }
- }
- }
- if c == '"' {
- if s.Substitutions[LeftDoubleQuote] != nil && d.CanOpen && !d.CanClose {
- node := gast.NewString(s.Substitutions[LeftDoubleQuote])
- node.SetCode(true)
- block.Advance(1)
- counter.Double++
- return node
- }
- if s.Substitutions[RightDoubleQuote] != nil && counter.Double > 0 {
- isClose := d.CanClose && !d.CanOpen
- maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && (unicode.IsPunct(util.ToRune(line, 1))) &&
- (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2])))
- if isClose || maybeClose {
- // special case: "Monitor 21""
- if len(line) > 1 && line[1] == '"' && unicode.IsDigit(before) {
- return nil
- }
- node := gast.NewString(s.Substitutions[RightDoubleQuote])
- node.SetCode(true)
- block.Advance(1)
- counter.Double--
- return node
- }
- }
- }
- }
- return nil
-}
-
-func (s *typographerParser) CloseBlock(parent gast.Node, pc parser.Context) {
- getUnclosedCounter(pc).Reset()
-}
-
-type typographer struct {
- options []TypographerOption
-}
-
-// Typographer is an extension that replaces punctuations with typographic entities.
-var Typographer = &typographer{}
-
-// NewTypographer returns a new Extender that replaces punctuations with typographic entities.
-func NewTypographer(opts ...TypographerOption) goldmark.Extender {
- return &typographer{
- options: opts,
- }
-}
-
-func (e *typographer) Extend(m goldmark.Markdown) {
- m.Parser().AddOptions(parser.WithInlineParsers(
- util.Prioritized(NewTypographerParser(e.options...), 9999),
- ))
-}