mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Vendor Update (#14496)
* update code.gitea.io/sdk/gitea v0.13.1 -> v0.13.2 * update github.com/go-swagger/go-swagger v0.25.0 -> v0.26.0 * update github.com/google/uuid v1.1.2 -> v1.2.0 * update github.com/klauspost/compress v1.11.3 -> v1.11.7 * update github.com/lib/pq 083382b7e6fc -> v1.9.0 * update github.com/markbates/goth v1.65.0 -> v1.66.1 * update github.com/mattn/go-sqlite3 v1.14.4 -> v1.14.6 * update github.com/mgechev/revive 246eac737dc7 -> v1.0.3 * update github.com/minio/minio-go/v7 v7.0.6 -> v7.0.7 * update github.com/niklasfasching/go-org v1.3.2 -> v1.4.0 * update github.com/olivere/elastic/v7 v7.0.21 -> v7.0.22 * update github.com/pquerna/otp v1.2.0 -> v1.3.0 * update github.com/xanzy/go-gitlab v0.39.0 -> v0.42.0 * update github.com/yuin/goldmark v1.2.1 -> v1.3.1
This commit is contained in:
		
							
								
								
									
										88
									
								
								vendor/github.com/yuin/goldmark/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										88
									
								
								vendor/github.com/yuin/goldmark/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| goldmark | ||||
| ========================================== | ||||
|  | ||||
| [](http://godoc.org/github.com/yuin/goldmark) | ||||
| [](https://pkg.go.dev/github.com/yuin/goldmark) | ||||
| [](https://github.com/yuin/goldmark/actions?query=workflow:test) | ||||
| [](https://coveralls.io/github/yuin/goldmark) | ||||
| [](https://goreportcard.com/report/github.com/yuin/goldmark) | ||||
| @@ -173,6 +173,7 @@ Parser and Renderer options | ||||
|     - This extension enables Table, Strikethrough, Linkify and TaskList. | ||||
|     - This extension does not filter tags defined in [6.11: Disallowed Raw HTML (extension)](https://github.github.com/gfm/#disallowed-raw-html-extension-). | ||||
|     If you need to filter HTML tags, see [Security](#security). | ||||
|     - If you need to parse github emojis, you can use [goldmark-emoji](https://github.com/yuin/goldmark-emoji) extension. | ||||
| - `extension.DefinitionList` | ||||
|     - [PHP Markdown Extra: Definition lists](https://michelf.ca/projects/php-markdown/extra/#def-list) | ||||
| - `extension.Footnote` | ||||
| @@ -286,6 +287,89 @@ markdown := goldmark.New( | ||||
| ) | ||||
| ``` | ||||
|  | ||||
| ### Footnotes extension | ||||
|  | ||||
| The Footnote extension implements [PHP Markdown Extra: Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes). | ||||
|  | ||||
| This extension has some options: | ||||
|  | ||||
| | Functional option | Type | Description | | ||||
| | ----------------- | ---- | ----------- | | ||||
| | `extension.WithFootnoteIDPrefix` | `[]byte` |  a prefix for the id attributes.| | ||||
| | `extension.WithFootnoteIDPrefixFunction` | `func(gast.Node) []byte` |  a function that determines the id attribute for given Node.| | ||||
| | `extension.WithFootnoteLinkTitle` | `[]byte` |  an optional title attribute for footnote links.| | ||||
| | `extension.WithFootnoteBacklinkTitle` | `[]byte` |  an optional title attribute for footnote backlinks. | | ||||
| | `extension.WithFootnoteLinkClass` | `[]byte` |  a class for footnote links. This defaults to `footnote-ref`. | | ||||
| | `extension.WithFootnoteBacklinkClass` | `[]byte` |  a class for footnote backlinks. This defaults to `footnote-backref`. | | ||||
| | `extension.WithFootnoteBacklinkHTML` | `[]byte` |  a class for footnote backlinks. This defaults to `↩︎`. | | ||||
|  | ||||
| Some options can have special substitutions. Occurances of “^^” in the string will be replaced by the corresponding footnote number in the HTML output. Occurances of “%%” will be replaced by a number for the reference (footnotes can have multiple references). | ||||
|  | ||||
| `extension.WithFootnoteIDPrefix` and `extension.WithFootnoteIDPrefixFunction` are useful if you have multiple Markdown documents displayed inside one HTML document to avoid footnote ids to clash each other. | ||||
|  | ||||
| `extension.WithFootnoteIDPrefix` sets fixed id prefix, so you may write codes like the following: | ||||
|  | ||||
| ```go | ||||
| for _, path := range files { | ||||
|     source := readAll(path) | ||||
|     prefix := getPrefix(path) | ||||
|  | ||||
|     markdown := goldmark.New( | ||||
|         goldmark.WithExtensions( | ||||
|             NewFootnote( | ||||
|                 WithFootnoteIDPrefix([]byte(path)), | ||||
|             ), | ||||
|         ), | ||||
|     ) | ||||
|     var b bytes.Buffer | ||||
|     err := markdown.Convert(source, &b) | ||||
|     if err != nil { | ||||
|         t.Error(err.Error()) | ||||
|     } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| `extension.WithFootnoteIDPrefixFunction` determines an id prefix by calling given function, so you may write codes like the following: | ||||
|  | ||||
| ```go | ||||
| markdown := goldmark.New( | ||||
|     goldmark.WithExtensions( | ||||
|         NewFootnote( | ||||
|                 WithFootnoteIDPrefixFunction(func(n gast.Node) []byte { | ||||
|                     v, ok := n.OwnerDocument().Meta()["footnote-prefix"] | ||||
|                     if ok { | ||||
|                         return util.StringToReadOnlyBytes(v.(string)) | ||||
|                     } | ||||
|                     return nil | ||||
|                 }), | ||||
|         ), | ||||
|     ), | ||||
| ) | ||||
|  | ||||
| for _, path := range files { | ||||
|     source := readAll(path) | ||||
|     var b bytes.Buffer | ||||
|  | ||||
|     doc := markdown.Parser().Parse(text.NewReader(source)) | ||||
|     doc.Meta()["footnote-prefix"] = getPrefix(path) | ||||
|     err := markdown.Renderer().Render(&b, source, doc) | ||||
| } | ||||
| ``` | ||||
|  | ||||
| You can use [goldmark-meta](https://github.com/yuin/goldmark-meta) to define a id prefix in the markdown document: | ||||
|  | ||||
|  | ||||
| ```markdown | ||||
| --- | ||||
| title: document title | ||||
| slug: article1 | ||||
| footnote-prefix: article1 | ||||
| --- | ||||
|  | ||||
| # My article | ||||
|  | ||||
| ``` | ||||
|   | ||||
| Security | ||||
| -------------------- | ||||
| By default, goldmark does not render raw HTML or potentially-dangerous URLs. | ||||
| @@ -336,6 +420,8 @@ Extensions | ||||
|   extension for the goldmark Markdown parser. | ||||
| - [goldmark-highlighting](https://github.com/yuin/goldmark-highlighting): A syntax-highlighting extension | ||||
|   for the goldmark markdown parser. | ||||
| - [goldmark-emoji](https://github.com/yuin/goldmark-emoji): An emoji | ||||
|   extension for the goldmark Markdown parser. | ||||
| - [goldmark-mathjax](https://github.com/litao91/goldmark-mathjax): Mathjax support for the goldmark markdown parser | ||||
|  | ||||
| goldmark internal(for extension developers) | ||||
|   | ||||
							
								
								
									
										28
									
								
								vendor/github.com/yuin/goldmark/ast/ast.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/yuin/goldmark/ast/ast.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -45,11 +45,6 @@ type Attribute struct { | ||||
| 	Value interface{} | ||||
| } | ||||
|  | ||||
| var attrNameIDS = []byte("#") | ||||
| var attrNameID = []byte("id") | ||||
| var attrNameClassS = []byte(".") | ||||
| var attrNameClass = []byte("class") | ||||
|  | ||||
| // A Node interface defines basic AST node functionalities. | ||||
| type Node interface { | ||||
| 	// Type returns a type of this node. | ||||
| @@ -116,6 +111,11 @@ type Node interface { | ||||
| 	// tail of the children. | ||||
| 	InsertAfter(self, v1, insertee Node) | ||||
|  | ||||
| 	// OwnerDocument returns this node's owner document. | ||||
| 	// If this node is not a child of the Document node, OwnerDocument | ||||
| 	// returns nil. | ||||
| 	OwnerDocument() *Document | ||||
|  | ||||
| 	// Dump dumps an AST tree structure to stdout. | ||||
| 	// This function completely aimed for debugging. | ||||
| 	// level is a indent level. Implementer should indent informations with | ||||
| @@ -169,7 +169,7 @@ type Node interface { | ||||
| 	RemoveAttributes() | ||||
| } | ||||
|  | ||||
| // A BaseNode struct implements the Node interface. | ||||
| // A BaseNode struct implements the Node interface partialliy. | ||||
| type BaseNode struct { | ||||
| 	firstChild Node | ||||
| 	lastChild  Node | ||||
| @@ -358,6 +358,22 @@ func (n *BaseNode) InsertBefore(self, v1, insertee Node) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // OwnerDocument implements Node.OwnerDocument | ||||
| func (n *BaseNode) OwnerDocument() *Document { | ||||
| 	d := n.Parent() | ||||
| 	for { | ||||
| 		p := d.Parent() | ||||
| 		if p == nil { | ||||
| 			if v, ok := d.(*Document); ok { | ||||
| 				return v | ||||
| 			} | ||||
| 			break | ||||
| 		} | ||||
| 		d = p | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Text implements Node.Text  . | ||||
| func (n *BaseNode) Text(source []byte) []byte { | ||||
| 	var buf bytes.Buffer | ||||
|   | ||||
							
								
								
									
										23
									
								
								vendor/github.com/yuin/goldmark/ast/block.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								vendor/github.com/yuin/goldmark/ast/block.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -7,7 +7,7 @@ import ( | ||||
| 	textm "github.com/yuin/goldmark/text" | ||||
| ) | ||||
|  | ||||
| // A BaseBlock struct implements the Node interface. | ||||
| // A BaseBlock struct implements the Node interface partialliy. | ||||
| type BaseBlock struct { | ||||
| 	BaseNode | ||||
| 	blankPreviousLines bool | ||||
| @@ -50,6 +50,8 @@ func (b *BaseBlock) SetLines(v *textm.Segments) { | ||||
| // A Document struct is a root node of Markdown text. | ||||
| type Document struct { | ||||
| 	BaseBlock | ||||
|  | ||||
| 	meta map[string]interface{} | ||||
| } | ||||
|  | ||||
| // KindDocument is a NodeKind of the Document node. | ||||
| @@ -70,10 +72,29 @@ func (n *Document) Kind() NodeKind { | ||||
| 	return KindDocument | ||||
| } | ||||
|  | ||||
| // OwnerDocument implements Node.OwnerDocument | ||||
| func (n *Document) OwnerDocument() *Document { | ||||
| 	return n | ||||
| } | ||||
|  | ||||
| // Meta returns metadata of this document. | ||||
| func (n *Document) Meta() map[string]interface{} { | ||||
| 	if n.meta == nil { | ||||
| 		n.meta = map[string]interface{}{} | ||||
| 	} | ||||
| 	return n.meta | ||||
| } | ||||
|  | ||||
| // SetMeta sets given metadata to this document. | ||||
| func (n *Document) SetMeta(meta map[string]interface{}) { | ||||
| 	n.meta = meta | ||||
| } | ||||
|  | ||||
| // NewDocument returns a new Document node. | ||||
| func NewDocument() *Document { | ||||
| 	return &Document{ | ||||
| 		BaseBlock: BaseBlock{}, | ||||
| 		meta:      nil, | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/yuin/goldmark/ast/inline.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/yuin/goldmark/ast/inline.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -8,7 +8,7 @@ import ( | ||||
| 	"github.com/yuin/goldmark/util" | ||||
| ) | ||||
|  | ||||
| // A BaseInline struct implements the Node interface. | ||||
| // A BaseInline struct implements the Node interface partialliy. | ||||
| type BaseInline struct { | ||||
| 	BaseNode | ||||
| } | ||||
|   | ||||
							
								
								
									
										35
									
								
								vendor/github.com/yuin/goldmark/extension/ast/footnote.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								vendor/github.com/yuin/goldmark/extension/ast/footnote.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -2,6 +2,7 @@ package ast | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
|  | ||||
| 	gast "github.com/yuin/goldmark/ast" | ||||
| ) | ||||
|  | ||||
| @@ -9,13 +10,15 @@ import ( | ||||
| // (PHP Markdown Extra) text. | ||||
| type FootnoteLink struct { | ||||
| 	gast.BaseInline | ||||
| 	Index int | ||||
| 	Index    int | ||||
| 	RefCount 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) | ||||
| 	gast.DumpHelper(n, source, level, m, nil) | ||||
| } | ||||
|  | ||||
| @@ -30,36 +33,40 @@ func (n *FootnoteLink) Kind() gast.NodeKind { | ||||
| // NewFootnoteLink returns a new FootnoteLink node. | ||||
| func NewFootnoteLink(index int) *FootnoteLink { | ||||
| 	return &FootnoteLink{ | ||||
| 		Index: index, | ||||
| 		Index:    index, | ||||
| 		RefCount: 0, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // A FootnoteBackLink struct represents a link to a footnote of Markdown | ||||
| // A FootnoteBacklink struct represents a link to a footnote of Markdown | ||||
| // (PHP Markdown Extra) text. | ||||
| type FootnoteBackLink struct { | ||||
| type FootnoteBacklink struct { | ||||
| 	gast.BaseInline | ||||
| 	Index int | ||||
| 	Index    int | ||||
| 	RefCount int | ||||
| } | ||||
|  | ||||
| // Dump implements Node.Dump. | ||||
| func (n *FootnoteBackLink) Dump(source []byte, level int) { | ||||
| 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) | ||||
| 	gast.DumpHelper(n, source, level, m, nil) | ||||
| } | ||||
|  | ||||
| // KindFootnoteBackLink is a NodeKind of the FootnoteBackLink node. | ||||
| var KindFootnoteBackLink = gast.NewNodeKind("FootnoteBackLink") | ||||
| // 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 | ||||
| func (n *FootnoteBacklink) Kind() gast.NodeKind { | ||||
| 	return KindFootnoteBacklink | ||||
| } | ||||
|  | ||||
| // NewFootnoteBackLink returns a new FootnoteBackLink node. | ||||
| func NewFootnoteBackLink(index int) *FootnoteBackLink { | ||||
| 	return &FootnoteBackLink{ | ||||
| 		Index: index, | ||||
| // NewFootnoteBacklink returns a new FootnoteBacklink node. | ||||
| func NewFootnoteBacklink(index int) *FootnoteBacklink { | ||||
| 	return &FootnoteBacklink{ | ||||
| 		Index:    index, | ||||
| 		RefCount: 0, | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										382
									
								
								vendor/github.com/yuin/goldmark/extension/footnote.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										382
									
								
								vendor/github.com/yuin/goldmark/extension/footnote.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -2,6 +2,8 @@ package extension | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"strconv" | ||||
|  | ||||
| 	"github.com/yuin/goldmark" | ||||
| 	gast "github.com/yuin/goldmark/ast" | ||||
| 	"github.com/yuin/goldmark/extension/ast" | ||||
| @@ -10,10 +12,10 @@ import ( | ||||
| 	"github.com/yuin/goldmark/renderer/html" | ||||
| 	"github.com/yuin/goldmark/text" | ||||
| 	"github.com/yuin/goldmark/util" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| var footnoteListKey = parser.NewContextKey() | ||||
| var footnoteLinkListKey = parser.NewContextKey() | ||||
|  | ||||
| type footnoteBlockParser struct { | ||||
| } | ||||
| @@ -164,7 +166,20 @@ func (s *footnoteParser) Parse(parent gast.Node, block text.Reader, pc parser.Co | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	return ast.NewFootnoteLink(index) | ||||
| 	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 { | ||||
| @@ -180,23 +195,46 @@ func NewFootnoteASTTransformer() parser.ASTTransformer { | ||||
|  | ||||
| func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) { | ||||
| 	var list *ast.FootnoteList | ||||
| 	if tlist := pc.Get(footnoteListKey); tlist != nil { | ||||
| 		list = tlist.(*ast.FootnoteList) | ||||
| 	} else { | ||||
| 	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 | ||||
| 	} | ||||
| 	pc.Set(footnoteListKey, nil) | ||||
|  | ||||
| 	counter := map[int]int{} | ||||
| 	if fnlist != nil { | ||||
| 		for _, fnlink := range fnlist { | ||||
| 			if fnlink.Index >= 0 { | ||||
| 				counter[fnlink.Index]++ | ||||
| 			} | ||||
| 		} | ||||
| 		for _, fnlink := range fnlist { | ||||
| 			fnlink.RefCount = counter[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 | ||||
| 		} | ||||
| 		index := footnote.(*ast.Footnote).Index | ||||
| 		fn := footnote.(*ast.Footnote) | ||||
| 		index := fn.Index | ||||
| 		if index < 0 { | ||||
| 			list.RemoveChild(list, footnote) | ||||
| 		} else { | ||||
| 			container.AppendChild(container, ast.NewFootnoteBackLink(index)) | ||||
| 			backLink := ast.NewFootnoteBacklink(index) | ||||
| 			backLink.RefCount = counter[index] | ||||
| 			container.AppendChild(container, backLink) | ||||
| 		} | ||||
| 		footnote = next | ||||
| 	} | ||||
| @@ -214,19 +252,250 @@ func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Read | ||||
| 	node.AppendChild(node, list) | ||||
| } | ||||
|  | ||||
| // FootnoteConfig holds configuration values for the footnote extension. | ||||
| // | ||||
| // Link* and Backlink* configurations have some variables: | ||||
| // Occurrances of “^^” in the string will be replaced by the | ||||
| // corresponding footnote number in the HTML output. | ||||
| // Occurrances 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("↩︎"), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // 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(a []byte) FootnoteOption { | ||||
| 	return &withFootnoteIDPrefix{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(a []byte) FootnoteOption { | ||||
| 	return &withFootnoteLinkTitle{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(a []byte) FootnoteOption { | ||||
| 	return &withFootnoteBacklinkTitle{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(a []byte) FootnoteOption { | ||||
| 	return &withFootnoteLinkClass{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(a []byte) FootnoteOption { | ||||
| 	return &withFootnoteBacklinkClass{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(a []byte) FootnoteOption { | ||||
| 	return &withFootnoteBacklinkHTML{a} | ||||
| } | ||||
|  | ||||
| // FootnoteHTMLRenderer is a renderer.NodeRenderer implementation that | ||||
| // renders FootnoteLink nodes. | ||||
| type FootnoteHTMLRenderer struct { | ||||
| 	html.Config | ||||
| 	FootnoteConfig | ||||
| } | ||||
|  | ||||
| // NewFootnoteHTMLRenderer returns a new FootnoteHTMLRenderer. | ||||
| func NewFootnoteHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { | ||||
| func NewFootnoteHTMLRenderer(opts ...FootnoteOption) renderer.NodeRenderer { | ||||
| 	r := &FootnoteHTMLRenderer{ | ||||
| 		Config: html.NewConfig(), | ||||
| 		FootnoteConfig: NewFootnoteConfig(), | ||||
| 	} | ||||
| 	for _, opt := range opts { | ||||
| 		opt.SetHTMLOption(&r.Config) | ||||
| 		opt.SetFootnoteOption(&r.FootnoteConfig) | ||||
| 	} | ||||
| 	return r | ||||
| } | ||||
| @@ -234,7 +503,7 @@ func NewFootnoteHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { | ||||
| // 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.KindFootnoteBacklink, r.renderFootnoteBacklink) | ||||
| 	reg.Register(ast.KindFootnote, r.renderFootnote) | ||||
| 	reg.Register(ast.KindFootnoteList, r.renderFootnoteList) | ||||
| } | ||||
| @@ -243,25 +512,45 @@ func (r *FootnoteHTMLRenderer) renderFootnoteLink(w util.BufWriter, source []byt | ||||
| 	if entering { | ||||
| 		n := node.(*ast.FootnoteLink) | ||||
| 		is := strconv.Itoa(n.Index) | ||||
| 		_, _ = w.WriteString(`<sup id="fnref:`) | ||||
| 		_, _ = w.WriteString(`<sup id="`) | ||||
| 		_, _ = w.Write(r.idPrefix(node)) | ||||
| 		_, _ = w.WriteString(`fnref:`) | ||||
| 		_, _ = w.WriteString(is) | ||||
| 		_, _ = w.WriteString(`"><a href="#fn:`) | ||||
| 		_, _ = w.WriteString(`"><a href="#`) | ||||
| 		_, _ = w.Write(r.idPrefix(node)) | ||||
| 		_, _ = w.WriteString(`fn:`) | ||||
| 		_, _ = w.WriteString(is) | ||||
| 		_, _ = w.WriteString(`" class="footnote-ref" role="doc-noteref">`) | ||||
| 		_, _ = 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) { | ||||
| func (r *FootnoteHTMLRenderer) renderFootnoteBacklink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { | ||||
| 	if entering { | ||||
| 		n := node.(*ast.FootnoteBackLink) | ||||
| 		n := node.(*ast.FootnoteBacklink) | ||||
| 		is := strconv.Itoa(n.Index) | ||||
| 		_, _ = w.WriteString(` <a href="#fnref:`) | ||||
| 		_, _ = w.WriteString(` <a href="#`) | ||||
| 		_, _ = w.Write(r.idPrefix(node)) | ||||
| 		_, _ = w.WriteString(`fnref:`) | ||||
| 		_, _ = w.WriteString(is) | ||||
| 		_, _ = w.WriteString(`" class="footnote-backref" role="doc-backlink">`) | ||||
| 		_, _ = w.WriteString("↩︎") | ||||
| 		_, _ = 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 | ||||
| @@ -271,7 +560,9 @@ func (r *FootnoteHTMLRenderer) renderFootnote(w util.BufWriter, source []byte, n | ||||
| 	n := node.(*ast.Footnote) | ||||
| 	is := strconv.Itoa(n.Index) | ||||
| 	if entering { | ||||
| 		_, _ = w.WriteString(`<li id="fn:`) | ||||
| 		_, _ = w.WriteString(`<li id="`) | ||||
| 		_, _ = w.Write(r.idPrefix(node)) | ||||
| 		_, _ = w.WriteString(`fn:`) | ||||
| 		_, _ = w.WriteString(is) | ||||
| 		_, _ = w.WriteString(`" role="doc-endnote"`) | ||||
| 		if node.Attributes() != nil { | ||||
| @@ -312,11 +603,54 @@ func (r *FootnoteHTMLRenderer) renderFootnoteList(w util.BufWriter, source []byt | ||||
| 	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{} | ||||
| 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( | ||||
| @@ -331,6 +665,6 @@ func (e *footnote) Extend(m goldmark.Markdown) { | ||||
| 		), | ||||
| 	) | ||||
| 	m.Renderer().AddOptions(renderer.WithNodeRenderers( | ||||
| 		util.Prioritized(NewFootnoteHTMLRenderer(), 500), | ||||
| 		util.Prioritized(NewFootnoteHTMLRenderer(e.options...), 500), | ||||
| 	)) | ||||
| } | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/yuin/goldmark/extension/linkify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/yuin/goldmark/extension/linkify.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -11,9 +11,9 @@ import ( | ||||
| 	"github.com/yuin/goldmark/util" | ||||
| ) | ||||
|  | ||||
| var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?:(?:/|[#?])[-a-zA-Z0-9@:%_\+.~#!?&//=\(\);,'">\^{}\[\]` + "`" + `]*)?`) | ||||
| var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?:[/#?][-a-zA-Z0-9@:%_\+.~#!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) | ||||
|  | ||||
| var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp):\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?:(?:/|[#?])[-a-zA-Z0-9@:%_+.~#$!?&//=\(\);,'">\^{}\[\]` + "`" + `]*)?`) | ||||
| var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp)://[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?::\d+)?(?:[/#?][-a-zA-Z0-9@:%_+.~#$!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) | ||||
|  | ||||
| // An LinkifyConfig struct is a data structure that holds configuration of the | ||||
| // Linkify extension. | ||||
|   | ||||
							
								
								
									
										104
									
								
								vendor/github.com/yuin/goldmark/extension/table.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										104
									
								
								vendor/github.com/yuin/goldmark/extension/table.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -15,6 +15,13 @@ import ( | ||||
| 	"github.com/yuin/goldmark/util" | ||||
| ) | ||||
|  | ||||
| var escapedPipeCellListKey = parser.NewContextKey() | ||||
|  | ||||
| type escapedPipeCell struct { | ||||
| 	Cell *ast.TableCell | ||||
| 	Pos  []int | ||||
| } | ||||
|  | ||||
| // TableCellAlignMethod indicates how are table cells aligned in HTML format.indicates how are table cells aligned in HTML format. | ||||
| type TableCellAlignMethod int | ||||
|  | ||||
| @@ -148,7 +155,7 @@ func (b *tableParagraphTransformer) Transform(node *gast.Paragraph, reader text. | ||||
| 		if alignments == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		header := b.parseRow(lines.At(i-1), alignments, true, reader) | ||||
| 		header := b.parseRow(lines.At(i-1), alignments, true, reader, pc) | ||||
| 		if header == nil || len(alignments) != header.ChildCount() { | ||||
| 			return | ||||
| 		} | ||||
| @@ -156,7 +163,7 @@ func (b *tableParagraphTransformer) Transform(node *gast.Paragraph, reader text. | ||||
| 		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)) | ||||
| 			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) | ||||
| @@ -170,7 +177,7 @@ func (b *tableParagraphTransformer) Transform(node *gast.Paragraph, reader text. | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments []ast.Alignment, isHeader bool, reader text.Reader) *ast.TableRow { | ||||
| func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments []ast.Alignment, isHeader bool, reader text.Reader, pc parser.Context) *ast.TableRow { | ||||
| 	source := reader.Source() | ||||
| 	line := segment.Value(source) | ||||
| 	pos := 0 | ||||
| @@ -194,18 +201,39 @@ func (b *tableParagraphTransformer) parseRow(segment text.Segment, alignments [] | ||||
| 		} else { | ||||
| 			alignment = alignments[i] | ||||
| 		} | ||||
| 		closure := util.FindClosure(line[pos:], byte(0), '|', true, false) | ||||
| 		if closure < 0 { | ||||
| 			closure = len(line[pos:]) | ||||
| 		} | ||||
|  | ||||
| 		var escapedCell *escapedPipeCell | ||||
| 		node := ast.NewTableCell() | ||||
| 		seg := text.NewSegment(segment.Start+pos, segment.Start+pos+closure) | ||||
| 		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{}} | ||||
| 						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) | ||||
| 		node.Alignment = alignment | ||||
| 		row.AppendChild(row, node) | ||||
| 		pos += closure + 1 | ||||
| 		pos = closure + 1 | ||||
| 	} | ||||
| 	for ; i < len(alignments); i++ { | ||||
| 		row.AppendChild(row, ast.NewTableCell()) | ||||
| @@ -243,6 +271,49 @@ func (b *tableParagraphTransformer) parseDelimiter(segment text.Segment, reader | ||||
| 	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) { | ||||
| 		_ = gast.Walk(v.Cell, func(n gast.Node, entering bool) (gast.WalkStatus, error) { | ||||
| 			if n.Kind() != gast.KindCodeSpan { | ||||
| 				return gast.WalkContinue, nil | ||||
| 			} | ||||
| 			c := n.FirstChild() | ||||
| 			for c != nil { | ||||
| 				next := c.NextSibling() | ||||
| 				if c.Kind() == gast.KindText { | ||||
| 					t := c.(*gast.Text) | ||||
| 					for _, pos := range v.Pos { | ||||
| 						if t.Segment.Start <= pos && t.Segment.Stop > pos { | ||||
| 							n1 := gast.NewRawTextSegment(t.Segment.WithStop(pos)) | ||||
| 							n2 := gast.NewRawTextSegment(t.Segment.WithStart(pos + 1)) | ||||
| 							n.InsertAfter(n, c, n1) | ||||
| 							n.InsertAfter(n, n1, n2) | ||||
| 							n.RemoveChild(n, c) | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				c = next | ||||
| 			} | ||||
| 			return gast.WalkContinue, nil | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TableHTMLRenderer is a renderer.NodeRenderer implementation that | ||||
| // renders Table nodes. | ||||
| type TableHTMLRenderer struct { | ||||
| @@ -419,7 +490,7 @@ func (r *TableHTMLRenderer) renderTableCell(w util.BufWriter, source []byte, nod | ||||
| 					cob.AppendByte(';') | ||||
| 				} | ||||
| 				style := fmt.Sprintf("text-align:%s", n.Alignment.String()) | ||||
| 				cob.Append(util.StringToReadOnlyBytes(style)) | ||||
| 				cob.AppendString(style) | ||||
| 				n.SetAttributeString("style", cob.Bytes()) | ||||
| 			} | ||||
| 		} | ||||
| @@ -454,9 +525,14 @@ func NewTable(opts ...TableOption) goldmark.Extender { | ||||
| } | ||||
|  | ||||
| func (e *table) Extend(m goldmark.Markdown) { | ||||
| 	m.Parser().AddOptions(parser.WithParagraphTransformers( | ||||
| 		util.Prioritized(NewTableParagraphTransformer(), 200), | ||||
| 	)) | ||||
| 	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), | ||||
| 	)) | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/yuin/goldmark/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/yuin/goldmark/go.mod
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,3 +1,3 @@ | ||||
| module github.com/yuin/goldmark | ||||
|  | ||||
| go 1.13 | ||||
| go 1.15 | ||||
|   | ||||
							
								
								
									
										8
									
								
								vendor/github.com/yuin/goldmark/parser/link.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/yuin/goldmark/parser/link.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -2,7 +2,6 @@ package parser | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/yuin/goldmark/ast" | ||||
| @@ -113,8 +112,6 @@ func (s *linkParser) Trigger() []byte { | ||||
| 	return []byte{'!', '[', ']'} | ||||
| } | ||||
|  | ||||
| var linkDestinationRegexp = regexp.MustCompile(`\s*([^\s].+)`) | ||||
| var linkTitleRegexp = regexp.MustCompile(`\s+(\)|["'\(].+)`) | ||||
| var linkBottom = NewContextKey() | ||||
|  | ||||
| func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.Node { | ||||
| @@ -293,20 +290,17 @@ func (s *linkParser) parseLink(parent ast.Node, last *linkLabelState, block text | ||||
| func parseLinkDestination(block text.Reader) ([]byte, bool) { | ||||
| 	block.SkipSpaces() | ||||
| 	line, _ := block.PeekLine() | ||||
| 	buf := []byte{} | ||||
| 	if block.Peek() == '<' { | ||||
| 		i := 1 | ||||
| 		for i < len(line) { | ||||
| 			c := line[i] | ||||
| 			if c == '\\' && i < len(line)-1 && util.IsPunct(line[i+1]) { | ||||
| 				buf = append(buf, '\\', line[i+1]) | ||||
| 				i += 2 | ||||
| 				continue | ||||
| 			} else if c == '>' { | ||||
| 				block.Advance(i + 1) | ||||
| 				return line[1:i], true | ||||
| 			} | ||||
| 			buf = append(buf, c) | ||||
| 			i++ | ||||
| 		} | ||||
| 		return nil, false | ||||
| @@ -316,7 +310,6 @@ func parseLinkDestination(block text.Reader) ([]byte, bool) { | ||||
| 	for i < len(line) { | ||||
| 		c := line[i] | ||||
| 		if c == '\\' && i < len(line)-1 && util.IsPunct(line[i+1]) { | ||||
| 			buf = append(buf, '\\', line[i+1]) | ||||
| 			i += 2 | ||||
| 			continue | ||||
| 		} else if c == '(' { | ||||
| @@ -329,7 +322,6 @@ func parseLinkDestination(block text.Reader) ([]byte, bool) { | ||||
| 		} else if util.IsSpace(c) { | ||||
| 			break | ||||
| 		} | ||||
| 		buf = append(buf, c) | ||||
| 		i++ | ||||
| 	} | ||||
| 	block.Advance(i) | ||||
|   | ||||
							
								
								
									
										12
									
								
								vendor/github.com/yuin/goldmark/parser/parser.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/yuin/goldmark/parser/parser.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -138,6 +138,9 @@ type Context interface { | ||||
| 	// Get returns a value associated with the given key. | ||||
| 	Get(ContextKey) interface{} | ||||
|  | ||||
| 	// ComputeIfAbsent computes a value if a value associated with the given key is absent and returns the value. | ||||
| 	ComputeIfAbsent(ContextKey, func() interface{}) interface{} | ||||
|  | ||||
| 	// Set sets the given value to the context. | ||||
| 	Set(ContextKey, interface{}) | ||||
|  | ||||
| @@ -252,6 +255,15 @@ func (p *parseContext) Get(key ContextKey) interface{} { | ||||
| 	return p.store[key] | ||||
| } | ||||
|  | ||||
| func (p *parseContext) ComputeIfAbsent(key ContextKey, f func() interface{}) interface{} { | ||||
| 	v := p.store[key] | ||||
| 	if v == nil { | ||||
| 		v = f() | ||||
| 		p.store[key] = v | ||||
| 	} | ||||
| 	return v | ||||
| } | ||||
|  | ||||
| func (p *parseContext) Set(key ContextKey, value interface{}) { | ||||
| 	p.store[key] = value | ||||
| } | ||||
|   | ||||
							
								
								
									
										9
									
								
								vendor/github.com/yuin/goldmark/parser/raw_html.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/yuin/goldmark/parser/raw_html.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -2,10 +2,11 @@ package parser | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"regexp" | ||||
|  | ||||
| 	"github.com/yuin/goldmark/ast" | ||||
| 	"github.com/yuin/goldmark/text" | ||||
| 	"github.com/yuin/goldmark/util" | ||||
| 	"regexp" | ||||
| ) | ||||
|  | ||||
| type rawHTMLParser struct { | ||||
| @@ -67,8 +68,6 @@ func (s *rawHTMLParser) parseSingleLineRegexp(reg *regexp.Regexp, block text.Rea | ||||
| 	return node | ||||
| } | ||||
|  | ||||
| var dummyMatch = [][]byte{} | ||||
|  | ||||
| func (s *rawHTMLParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Reader, pc Context) ast.Node { | ||||
| 	sline, ssegment := block.Position() | ||||
| 	if block.Match(reg) { | ||||
| @@ -102,7 +101,3 @@ func (s *rawHTMLParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Read | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *rawHTMLParser) CloseBlock(parent ast.Node, pc Context) { | ||||
| 	// nothing to do | ||||
| } | ||||
|   | ||||
							
								
								
									
										16
									
								
								vendor/github.com/yuin/goldmark/util/util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/yuin/goldmark/util/util.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -37,6 +37,12 @@ func (b *CopyOnWriteBuffer) Write(value []byte) { | ||||
| 	b.buffer = append(b.buffer, value...) | ||||
| } | ||||
|  | ||||
| // WriteString writes given string to the buffer. | ||||
| // WriteString allocate new buffer and clears it at the first time. | ||||
| func (b *CopyOnWriteBuffer) WriteString(value string) { | ||||
| 	b.Write(StringToReadOnlyBytes(value)) | ||||
| } | ||||
|  | ||||
| // Append appends given bytes to the buffer. | ||||
| // Append copy buffer at the first time. | ||||
| func (b *CopyOnWriteBuffer) Append(value []byte) { | ||||
| @@ -49,6 +55,12 @@ func (b *CopyOnWriteBuffer) Append(value []byte) { | ||||
| 	b.buffer = append(b.buffer, value...) | ||||
| } | ||||
|  | ||||
| // AppendString appends given string to the buffer. | ||||
| // AppendString copy buffer at the first time. | ||||
| func (b *CopyOnWriteBuffer) AppendString(value string) { | ||||
| 	b.Append(StringToReadOnlyBytes(value)) | ||||
| } | ||||
|  | ||||
| // WriteByte writes the given byte to the buffer. | ||||
| // WriteByte allocate new buffer and clears it at the first time. | ||||
| func (b *CopyOnWriteBuffer) WriteByte(c byte) { | ||||
| @@ -804,7 +816,7 @@ func IsPunct(c byte) bool { | ||||
| 	return punctTable[c] == 1 | ||||
| } | ||||
|  | ||||
| // IsPunct returns true if the given rune is a punctuation, otherwise false. | ||||
| // IsPunctRune returns true if the given rune is a punctuation, otherwise false. | ||||
| func IsPunctRune(r rune) bool { | ||||
| 	return int32(r) <= 256 && IsPunct(byte(r)) || unicode.IsPunct(r) | ||||
| } | ||||
| @@ -814,7 +826,7 @@ func IsSpace(c byte) bool { | ||||
| 	return spaceTable[c] == 1 | ||||
| } | ||||
|  | ||||
| // IsSpace returns true if the given rune is a space, otherwise false. | ||||
| // IsSpaceRune returns true if the given rune is a space, otherwise false. | ||||
| func IsSpaceRune(r rune) bool { | ||||
| 	return int32(r) <= 256 && IsSpace(byte(r)) || unicode.IsSpace(r) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user