parent
					
						
							
								74433c91bf
							
						
					
				
			
			
				commit
				
					
						15c7738b3a
					
				
			
		
					 18 changed files with 1902 additions and 120 deletions
				
			
		
							
								
								
									
										2
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
										
									
									
									
								
							| 
						 | 
					@ -96,7 +96,7 @@ require (
 | 
				
			||||||
	github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141
 | 
						github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141
 | 
				
			||||||
	github.com/urfave/cli v1.20.0
 | 
						github.com/urfave/cli v1.20.0
 | 
				
			||||||
	github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53
 | 
						github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53
 | 
				
			||||||
	github.com/yuin/goldmark v1.1.19
 | 
						github.com/yuin/goldmark v1.1.23
 | 
				
			||||||
	go.etcd.io/bbolt v1.3.3 // indirect
 | 
						go.etcd.io/bbolt v1.3.3 // indirect
 | 
				
			||||||
	golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d
 | 
						golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d
 | 
				
			||||||
	golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa
 | 
						golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
										
									
									
									
								
							| 
						 | 
					@ -574,8 +574,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q
 | 
				
			||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
 | 
					github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
 | 
				
			||||||
github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53 h1:HsIQ6yAjfjQ3IxPGrTusxp6Qxn92gNVq2x5CbvQvx3w=
 | 
					github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53 h1:HsIQ6yAjfjQ3IxPGrTusxp6Qxn92gNVq2x5CbvQvx3w=
 | 
				
			||||||
github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53/go.mod h1:f6elajwZV+xceiaqgRL090YzLEDGSbqr3poGL3ZgXYo=
 | 
					github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53/go.mod h1:f6elajwZV+xceiaqgRL090YzLEDGSbqr3poGL3ZgXYo=
 | 
				
			||||||
github.com/yuin/goldmark v1.1.19 h1:0s2/60x0XsFCXHeFut+F3azDVAAyIMyUfJRbRexiTYs=
 | 
					github.com/yuin/goldmark v1.1.23 h1:eTodJ8hwEUvwXhb9qxQNuL/q1d+xMQClrXR4mdvV7gs=
 | 
				
			||||||
github.com/yuin/goldmark v1.1.19/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 | 
					github.com/yuin/goldmark v1.1.23/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 | 
				
			||||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
 | 
					github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
 | 
				
			||||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
 | 
					github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
 | 
				
			||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 | 
					go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										170
									
								
								vendor/github.com/yuin/goldmark/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										170
									
								
								vendor/github.com/yuin/goldmark/README.md
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -6,48 +6,48 @@ goldmark
 | 
				
			||||||
[](https://coveralls.io/github/yuin/goldmark)
 | 
					[](https://coveralls.io/github/yuin/goldmark)
 | 
				
			||||||
[](https://goreportcard.com/report/github.com/yuin/goldmark)
 | 
					[](https://goreportcard.com/report/github.com/yuin/goldmark)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
> A Markdown parser written in Go. Easy to extend, standard compliant, well structured.
 | 
					> A Markdown parser written in Go. Easy to extend, standards-compliant, well-structured.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
goldmark is compliant with CommonMark 0.29.
 | 
					goldmark is compliant with CommonMark 0.29.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Motivation
 | 
					Motivation
 | 
				
			||||||
----------------------
 | 
					----------------------
 | 
				
			||||||
I need a Markdown parser for Go that meets following conditions:
 | 
					I needed a Markdown parser for Go that satisfies the following requirements:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- Easy to extend.
 | 
					- Easy to extend.
 | 
				
			||||||
    - Markdown is poor in document expressions compared with other light markup languages like reStructuredText.
 | 
					    - Markdown is poor in document expressions compared to other light markup languages such as reStructuredText.
 | 
				
			||||||
    - We have extensions to the Markdown syntax, e.g. PHP Markdown Extra, GitHub Flavored Markdown.
 | 
					    - We have extensions to the Markdown syntax, e.g. PHP Markdown Extra, GitHub Flavored Markdown.
 | 
				
			||||||
- Standard compliant.
 | 
					- Standards-compliant.
 | 
				
			||||||
    - Markdown has many dialects.
 | 
					    - Markdown has many dialects.
 | 
				
			||||||
    - GitHub Flavored Markdown is widely used and it is based on CommonMark aside from whether CommonMark is good specification or not.
 | 
					    - GitHub-Flavored Markdown is widely used and is based upon CommonMark, effectively mooting the question of whether or not CommonMark is an ideal specification.
 | 
				
			||||||
        - CommonMark is too complicated and hard to implement.
 | 
					        - CommonMark is complicated and hard to implement.
 | 
				
			||||||
- Well structured.
 | 
					- Well-structured.
 | 
				
			||||||
    - AST based, and preserves source position of nodes.
 | 
					    - AST-based; preserves source position of nodes.
 | 
				
			||||||
- Written in pure Go.
 | 
					- Written in pure Go.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[golang-commonmark](https://gitlab.com/golang-commonmark/markdown) may be a good choice, but it seems to be a copy of [markdown-it](https://github.com/markdown-it).
 | 
					[golang-commonmark](https://gitlab.com/golang-commonmark/markdown) may be a good choice, but it seems to be a copy of [markdown-it](https://github.com/markdown-it).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[blackfriday.v2](https://github.com/russross/blackfriday/tree/v2) is a fast and widely used implementation, but it is not CommonMark compliant and cannot be extended from outside of the package since its AST uses structs instead of interfaces.
 | 
					[blackfriday.v2](https://github.com/russross/blackfriday/tree/v2) is a fast and widely-used implementation, but is not CommonMark-compliant and cannot be extended from outside of the package, since its AST uses structs instead of interfaces.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Furthermore, its behavior differs from other implementations in some cases, especially regarding lists: ([Deep nested lists don't output correctly #329](https://github.com/russross/blackfriday/issues/329), [List block cannot have a second line #244](https://github.com/russross/blackfriday/issues/244), etc).
 | 
					Furthermore, its behavior differs from other implementations in some cases, especially regarding lists: [Deep nested lists don't output correctly #329](https://github.com/russross/blackfriday/issues/329), [List block cannot have a second line #244](https://github.com/russross/blackfriday/issues/244), etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This behavior sometimes causes problems. If you migrate your Markdown text to blackfriday-based wikis from GitHub, many lists will immediately be broken.
 | 
					This behavior sometimes causes problems. If you migrate your Markdown text from GitHub to blackfriday-based wikis, many lists will immediately be broken.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
As mentioned above, CommonMark is too complicated and hard to implement, so Markdown parsers based on CommonMark barely exist.
 | 
					As mentioned above, CommonMark is complicated and hard to implement, so Markdown parsers based on CommonMark are few and far between.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Features
 | 
					Features
 | 
				
			||||||
----------------------
 | 
					----------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- **Standard compliant.**  goldmark gets full compliance with the latest CommonMark spec.
 | 
					- **Standards-compliant.**  goldmark is fully compliant with the latest [CommonMark](https://commonmark.org/) specification.
 | 
				
			||||||
- **Extensible.**  Do you want to add a `@username` mention syntax to Markdown?
 | 
					- **Extensible.**  Do you want to add a `@username` mention syntax to Markdown?
 | 
				
			||||||
  You can easily do it in goldmark. You can add your AST nodes,
 | 
					  You can easily do so in goldmark. You can add your AST nodes,
 | 
				
			||||||
  parsers for block level elements, parsers for inline level elements,
 | 
					  parsers for block-level elements, parsers for inline-level elements,
 | 
				
			||||||
  transformers for paragraphs, transformers for whole AST structure, and
 | 
					  transformers for paragraphs, transformers for the whole AST structure, and
 | 
				
			||||||
  renderers.
 | 
					  renderers.
 | 
				
			||||||
- **Performance.**  goldmark performs pretty much equally to cmark,
 | 
					- **Performance.**  goldmark's performance is on par with that of cmark,
 | 
				
			||||||
  the CommonMark reference implementation written in C.
 | 
					  the CommonMark reference implementation written in C.
 | 
				
			||||||
- **Robust.**  goldmark is tested with [go-fuzz](https://github.com/dvyukov/go-fuzz), a fuzz testing tool.
 | 
					- **Robust.**  goldmark is tested with [go-fuzz](https://github.com/dvyukov/go-fuzz), a fuzz testing tool.
 | 
				
			||||||
- **Builtin extensions.**  goldmark ships with common extensions like tables, strikethrough,
 | 
					- **Built-in extensions.**  goldmark ships with common extensions like tables, strikethrough,
 | 
				
			||||||
  task lists, and definition lists.
 | 
					  task lists, and definition lists.
 | 
				
			||||||
- **Depends only on standard libraries.**
 | 
					- **Depends only on standard libraries.**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,15 +62,15 @@ Usage
 | 
				
			||||||
----------------------
 | 
					----------------------
 | 
				
			||||||
Import packages:
 | 
					Import packages:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```go
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
					    "bytes"
 | 
				
			||||||
	"github.com/yuin/goldmark"
 | 
					    "github.com/yuin/goldmark"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Convert Markdown documents with the CommonMark compliant mode:
 | 
					Convert Markdown documents with the CommonMark-compliant mode:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```go
 | 
					```go
 | 
				
			||||||
var buf bytes.Buffer
 | 
					var buf bytes.Buffer
 | 
				
			||||||
| 
						 | 
					@ -105,11 +105,11 @@ Custom parser and renderer
 | 
				
			||||||
--------------------------
 | 
					--------------------------
 | 
				
			||||||
```go
 | 
					```go
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
					    "bytes"
 | 
				
			||||||
	"github.com/yuin/goldmark"
 | 
					    "github.com/yuin/goldmark"
 | 
				
			||||||
	"github.com/yuin/goldmark/extension"
 | 
					    "github.com/yuin/goldmark/extension"
 | 
				
			||||||
	"github.com/yuin/goldmark/parser"
 | 
					    "github.com/yuin/goldmark/parser"
 | 
				
			||||||
	"github.com/yuin/goldmark/renderer/html"
 | 
					    "github.com/yuin/goldmark/renderer/html"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
md := goldmark.New(
 | 
					md := goldmark.New(
 | 
				
			||||||
| 
						 | 
					@ -128,6 +128,14 @@ if err := md.Convert(source, &buf); err != nil {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| Functional option | Type | Description |
 | 
				
			||||||
 | 
					| ----------------- | ---- | ----------- |
 | 
				
			||||||
 | 
					| `goldmark.WithParser` | `parser.Parser`  | This option must be passed before `goldmark.WithParserOptions` and `goldmark.WithExtensions` |
 | 
				
			||||||
 | 
					| `goldmark.WithRenderer` | `renderer.Renderer`  | This option must be passed before `goldmark.WithRendererOptions` and `goldmark.WithExtensions`  |
 | 
				
			||||||
 | 
					| `goldmark.WithParserOptions` | `...parser.Option`  |  |
 | 
				
			||||||
 | 
					| `goldmark.WithRendererOptions` | `...renderer.Option` |  |
 | 
				
			||||||
 | 
					| `goldmark.WithExtensions` | `...goldmark.Extender`  |  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Parser and Renderer options
 | 
					Parser and Renderer options
 | 
				
			||||||
------------------------------
 | 
					------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -147,33 +155,33 @@ Parser and Renderer options
 | 
				
			||||||
| Functional option | Type | Description |
 | 
					| Functional option | Type | Description |
 | 
				
			||||||
| ----------------- | ---- | ----------- |
 | 
					| ----------------- | ---- | ----------- |
 | 
				
			||||||
| `html.WithWriter` | `html.Writer` | `html.Writer` for writing contents to an `io.Writer`. |
 | 
					| `html.WithWriter` | `html.Writer` | `html.Writer` for writing contents to an `io.Writer`. |
 | 
				
			||||||
| `html.WithHardWraps` | `-` | Render new lines as `<br>`.|
 | 
					| `html.WithHardWraps` | `-` | Render newlines as `<br>`.|
 | 
				
			||||||
| `html.WithXHTML` | `-` | Render as XHTML. |
 | 
					| `html.WithXHTML` | `-` | Render as XHTML. |
 | 
				
			||||||
| `html.WithUnsafe` | `-` | By default, goldmark does not render raw HTML and potentially dangerous links. With this option, goldmark renders these contents as written. |
 | 
					| `html.WithUnsafe` | `-` | By default, goldmark does not render raw HTML or potentially dangerous links. With this option, goldmark renders such content as written. |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Built-in extensions
 | 
					### Built-in extensions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- `extension.Table`
 | 
					- `extension.Table`
 | 
				
			||||||
  - [GitHub Flavored Markdown: Tables](https://github.github.com/gfm/#tables-extension-)
 | 
					    - [GitHub Flavored Markdown: Tables](https://github.github.com/gfm/#tables-extension-)
 | 
				
			||||||
- `extension.Strikethrough`
 | 
					- `extension.Strikethrough`
 | 
				
			||||||
  - [GitHub Flavored Markdown: Strikethrough](https://github.github.com/gfm/#strikethrough-extension-)
 | 
					    - [GitHub Flavored Markdown: Strikethrough](https://github.github.com/gfm/#strikethrough-extension-)
 | 
				
			||||||
- `extension.Linkify`
 | 
					- `extension.Linkify`
 | 
				
			||||||
  - [GitHub Flavored Markdown: Autolinks](https://github.github.com/gfm/#autolinks-extension-)
 | 
					    - [GitHub Flavored Markdown: Autolinks](https://github.github.com/gfm/#autolinks-extension-)
 | 
				
			||||||
- `extension.TaskList`
 | 
					- `extension.TaskList`
 | 
				
			||||||
  - [GitHub Flavored Markdown: Task list items](https://github.github.com/gfm/#task-list-items-extension-)
 | 
					    - [GitHub Flavored Markdown: Task list items](https://github.github.com/gfm/#task-list-items-extension-)
 | 
				
			||||||
- `extension.GFM`
 | 
					- `extension.GFM`
 | 
				
			||||||
  - This extension enables Table, Strikethrough, Linkify and TaskList.
 | 
					    - 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-).
 | 
					    - 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 filter HTML tags, see [Security](#security).
 | 
				
			||||||
- `extension.DefinitionList`
 | 
					- `extension.DefinitionList`
 | 
				
			||||||
  - [PHP Markdown Extra: Definition lists](https://michelf.ca/projects/php-markdown/extra/#def-list)
 | 
					    - [PHP Markdown Extra: Definition lists](https://michelf.ca/projects/php-markdown/extra/#def-list)
 | 
				
			||||||
- `extension.Footnote`
 | 
					- `extension.Footnote`
 | 
				
			||||||
  - [PHP Markdown Extra: Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes)
 | 
					    - [PHP Markdown Extra: Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes)
 | 
				
			||||||
- `extension.Typographer`
 | 
					- `extension.Typographer`
 | 
				
			||||||
  - This extension substitutes punctuations with typographic entities like [smartypants](https://daringfireball.net/projects/smartypants/).
 | 
					    - This extension substitutes punctuations with typographic entities like [smartypants](https://daringfireball.net/projects/smartypants/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Attributes
 | 
					### Attributes
 | 
				
			||||||
`parser.WithAttribute` option allows you to define attributes on some elements.
 | 
					The `parser.WithAttribute` option allows you to define attributes on some elements.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Currently only headings support attributes.
 | 
					Currently only headings support attributes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -197,7 +205,7 @@ heading {#id .className attrName=attrValue}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Typographer extension
 | 
					### Typographer extension
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Typographer extension translates plain ASCII punctuation characters into typographic punctuation HTML entities.
 | 
					The Typographer extension translates plain ASCII punctuation characters into typographic-punctuation HTML entities.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Default substitutions are:
 | 
					Default substitutions are:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -211,25 +219,65 @@ Default substitutions are:
 | 
				
			||||||
| `<<`       | `«` |
 | 
					| `<<`       | `«` |
 | 
				
			||||||
| `>>`       | `»` |
 | 
					| `>>`       | `»` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can overwrite the substitutions by `extensions.WithTypographicSubstitutions`.
 | 
					You can override the defualt substitutions via `extensions.WithTypographicSubstitutions`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```go
 | 
					```go
 | 
				
			||||||
markdown := goldmark.New(
 | 
					markdown := goldmark.New(
 | 
				
			||||||
	goldmark.WithExtensions(
 | 
					    goldmark.WithExtensions(
 | 
				
			||||||
		extension.NewTypographer(
 | 
					        extension.NewTypographer(
 | 
				
			||||||
			extension.WithTypographicSubstitutions(extension.TypographicSubstitutions{
 | 
					            extension.WithTypographicSubstitutions(extension.TypographicSubstitutions{
 | 
				
			||||||
				extension.LeftSingleQuote:  []byte("‚"),
 | 
					                extension.LeftSingleQuote:  []byte("‚"),
 | 
				
			||||||
				extension.RightSingleQuote: nil, // nil disables a substitution
 | 
					                extension.RightSingleQuote: nil, // nil disables a substitution
 | 
				
			||||||
			}),
 | 
					            }),
 | 
				
			||||||
		),
 | 
					        ),
 | 
				
			||||||
	),
 | 
					    ),
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Linkify extension
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The Linkify extension implements [Autolinks(extension)](https://github.github.com/gfm/#autolinks-extension-), as
 | 
				
			||||||
 | 
					defined in [GitHub Flavored Markdown Spec](https://github.github.com/gfm/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Since the spec does not define details about URLs, there are numerous ambiguous cases.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You can override autolinking patterns via options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| Functional option | Type | Description |
 | 
				
			||||||
 | 
					| ----------------- | ---- | ----------- |
 | 
				
			||||||
 | 
					| `extension.WithLinkifyAllowedProtocols` | `[][]byte` | List of allowed protocols such as `[][]byte{ []byte("http:") }` |
 | 
				
			||||||
 | 
					| `extension.WithLinkifyURLRegexp` | `*regexp.Regexp` | Regexp that defines URLs, including protocols |
 | 
				
			||||||
 | 
					| `extension.WithLinkifyWWWRegexp` | `*regexp.Regexp` | Regexp that defines URL starting with `www.`. This pattern corresponds to [the extended www autolink](https://github.github.com/gfm/#extended-www-autolink) |
 | 
				
			||||||
 | 
					| `extension.WithLinkifyEmailRegexp` | `*regexp.Regexp` | Regexp that defines email addresses` |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example, using [xurls](https://github.com/mvdan/xurls):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					import "mvdan.cc/xurls/v2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					markdown := goldmark.New(
 | 
				
			||||||
 | 
					    goldmark.WithRendererOptions(
 | 
				
			||||||
 | 
					        html.WithXHTML(),
 | 
				
			||||||
 | 
					        html.WithUnsafe(),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
 | 
					    goldmark.WithExtensions(
 | 
				
			||||||
 | 
					        extension.NewLinkify(
 | 
				
			||||||
 | 
					            extension.WithLinkifyAllowedProtocols([][]byte{
 | 
				
			||||||
 | 
					                []byte("http:"),
 | 
				
			||||||
 | 
					                []byte("https:"),
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            extension.WithLinkifyURLRegexp(
 | 
				
			||||||
 | 
					                xurls.Strict(),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ),
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Security
 | 
					Security
 | 
				
			||||||
--------------------
 | 
					--------------------
 | 
				
			||||||
By default, goldmark does not render raw HTML and potentially dangerous URLs.
 | 
					By default, goldmark does not render raw HTML or potentially-dangerous URLs.
 | 
				
			||||||
If you need to gain more control over untrusted contents, it is recommended to
 | 
					If you need to gain more control over untrusted contents, it is recommended that you
 | 
				
			||||||
use an HTML sanitizer such as [bluemonday](https://github.com/microcosm-cc/bluemonday).
 | 
					use an HTML sanitizer such as [bluemonday](https://github.com/microcosm-cc/bluemonday).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Benchmark
 | 
					Benchmark
 | 
				
			||||||
| 
						 | 
					@ -238,11 +286,10 @@ You can run this benchmark in the `_benchmark` directory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### against other golang libraries
 | 
					### against other golang libraries
 | 
				
			||||||
 | 
					
 | 
				
			||||||
blackfriday v2 seems to be fastest, but it is not CommonMark compliant, so the performance of
 | 
					blackfriday v2 seems to be the fastest, but as it is not CommonMark compliant, its performance cannot be directly compared to that of the CommonMark-compliant libraries.
 | 
				
			||||||
blackfriday v2 cannot simply be compared with that of the other CommonMark compliant libraries.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Though goldmark builds clean extensible AST structure and get full compliance with
 | 
					goldmark, meanwhile, builds a clean, extensible AST structure, achieves full compliance with
 | 
				
			||||||
CommonMark, it is reasonably fast and has lower memory consumption.
 | 
					CommonMark, and consumes less memory, all while being reasonably fast.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
goos: darwin
 | 
					goos: darwin
 | 
				
			||||||
| 
						 | 
					@ -268,21 +315,21 @@ iteration: 50
 | 
				
			||||||
average: 0.0040964230 sec
 | 
					average: 0.0040964230 sec
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
As you can see, goldmark performs pretty much equally to cmark.
 | 
					As you can see, goldmark's performance is on par with cmark's.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Extensions
 | 
					Extensions
 | 
				
			||||||
--------------------
 | 
					--------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- [goldmark-meta](https://github.com/yuin/goldmark-meta): A YAML metadata
 | 
					- [goldmark-meta](https://github.com/yuin/goldmark-meta): A YAML metadata
 | 
				
			||||||
  extension for the goldmark Markdown parser.
 | 
					  extension for the goldmark Markdown parser.
 | 
				
			||||||
- [goldmark-highlighting](https://github.com/yuin/goldmark-highlighting): A Syntax highlighting extension
 | 
					- [goldmark-highlighting](https://github.com/yuin/goldmark-highlighting): A syntax-highlighting extension
 | 
				
			||||||
  for the goldmark markdown parser.
 | 
					  for the goldmark markdown parser.
 | 
				
			||||||
- [goldmark-mathjax](https://github.com/litao91/goldmark-mathjax): Mathjax support for goldmark markdown parser
 | 
					- [goldmark-mathjax](https://github.com/litao91/goldmark-mathjax): Mathjax support for the goldmark markdown parser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
goldmark internal(for extension developers)
 | 
					goldmark internal(for extension developers)
 | 
				
			||||||
----------------------------------------------
 | 
					----------------------------------------------
 | 
				
			||||||
### Overview
 | 
					### Overview
 | 
				
			||||||
goldmark's Markdown processing is outlined as a bellow diagram.
 | 
					goldmark's Markdown processing is outlined in the diagram below.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
            <Markdown in []byte, parser.Context>
 | 
					            <Markdown in []byte, parser.Context>
 | 
				
			||||||
| 
						 | 
					@ -313,10 +360,11 @@ goldmark's Markdown processing is outlined as a bellow diagram.
 | 
				
			||||||
### Parsing
 | 
					### Parsing
 | 
				
			||||||
Markdown documents are read through `text.Reader` interface.
 | 
					Markdown documents are read through `text.Reader` interface.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AST nodes do not have concrete text. AST nodes have segment information of the documents. It is represented by `text.Segment` .
 | 
					AST nodes do not have concrete text. AST nodes have segment information of the documents, represented by `text.Segment` .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`text.Segment` has 3 attributes: `Start`, `End`, `Padding` .
 | 
					`text.Segment` has 3 attributes: `Start`, `End`, `Padding` .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(TBC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**TODO**
 | 
					**TODO**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								vendor/github.com/yuin/goldmark/ast/ast.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/yuin/goldmark/ast/ast.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -236,10 +236,12 @@ func (n *BaseNode) RemoveChild(self, v Node) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RemoveChildren implements Node.RemoveChildren .
 | 
					// RemoveChildren implements Node.RemoveChildren .
 | 
				
			||||||
func (n *BaseNode) RemoveChildren(self Node) {
 | 
					func (n *BaseNode) RemoveChildren(self Node) {
 | 
				
			||||||
	for c := n.firstChild; c != nil; c = c.NextSibling() {
 | 
						for c := n.firstChild; c != nil; {
 | 
				
			||||||
		c.SetParent(nil)
 | 
							c.SetParent(nil)
 | 
				
			||||||
		c.SetPreviousSibling(nil)
 | 
							c.SetPreviousSibling(nil)
 | 
				
			||||||
 | 
							next := c.NextSibling()
 | 
				
			||||||
		c.SetNextSibling(nil)
 | 
							c.SetNextSibling(nil)
 | 
				
			||||||
 | 
							c = next
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	n.firstChild = nil
 | 
						n.firstChild = nil
 | 
				
			||||||
	n.lastChild = nil
 | 
						n.lastChild = nil
 | 
				
			||||||
| 
						 | 
					@ -466,20 +468,25 @@ type Walker func(n Node, entering bool) (WalkStatus, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Walk walks a AST tree by the depth first search algorithm.
 | 
					// Walk walks a AST tree by the depth first search algorithm.
 | 
				
			||||||
func Walk(n Node, walker Walker) error {
 | 
					func Walk(n Node, walker Walker) error {
 | 
				
			||||||
 | 
						_, err := walkHelper(n, walker)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func walkHelper(n Node, walker Walker) (WalkStatus, error) {
 | 
				
			||||||
	status, err := walker(n, true)
 | 
						status, err := walker(n, true)
 | 
				
			||||||
	if err != nil || status == WalkStop {
 | 
						if err != nil || status == WalkStop {
 | 
				
			||||||
		return err
 | 
							return status, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if status != WalkSkipChildren {
 | 
						if status != WalkSkipChildren {
 | 
				
			||||||
		for c := n.FirstChild(); c != nil; c = c.NextSibling() {
 | 
							for c := n.FirstChild(); c != nil; c = c.NextSibling() {
 | 
				
			||||||
			if err = Walk(c, walker); err != nil {
 | 
								if st, err := walkHelper(c, walker); err != nil || st == WalkStop {
 | 
				
			||||||
				return err
 | 
									return WalkStop, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	status, err = walker(n, false)
 | 
						status, err = walker(n, false)
 | 
				
			||||||
	if err != nil || status == WalkStop {
 | 
						if err != nil || status == WalkStop {
 | 
				
			||||||
		return err
 | 
							return WalkStop, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return WalkContinue, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								vendor/github.com/yuin/goldmark/ast/block.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/yuin/goldmark/ast/block.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -303,11 +303,11 @@ func NewBlockquote() *Blockquote {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A List structr represents a list of Markdown text.
 | 
					// A List struct represents a list of Markdown text.
 | 
				
			||||||
type List struct {
 | 
					type List struct {
 | 
				
			||||||
	BaseBlock
 | 
						BaseBlock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Marker is a markar character like '-', '+', ')' and '.'.
 | 
						// Marker is a marker character like '-', '+', ')' and '.'.
 | 
				
			||||||
	Marker byte
 | 
						Marker byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// IsTight is a true if this list is a 'tight' list.
 | 
						// IsTight is a true if this list is a 'tight' list.
 | 
				
			||||||
| 
						 | 
					@ -364,7 +364,7 @@ func NewList(marker byte) *List {
 | 
				
			||||||
type ListItem struct {
 | 
					type ListItem struct {
 | 
				
			||||||
	BaseBlock
 | 
						BaseBlock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Offset is an offset potision of this item.
 | 
						// Offset is an offset position of this item.
 | 
				
			||||||
	Offset int
 | 
						Offset int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								vendor/github.com/yuin/goldmark/ast/inline.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/yuin/goldmark/ast/inline.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -170,7 +170,7 @@ func NewText() *Text {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewTextSegment returns a new Text node with the given source potision.
 | 
					// NewTextSegment returns a new Text node with the given source position.
 | 
				
			||||||
func NewTextSegment(v textm.Segment) *Text {
 | 
					func NewTextSegment(v textm.Segment) *Text {
 | 
				
			||||||
	return &Text{
 | 
						return &Text{
 | 
				
			||||||
		BaseInline: BaseInline{},
 | 
							BaseInline: BaseInline{},
 | 
				
			||||||
| 
						 | 
					@ -467,7 +467,7 @@ type AutoLink struct {
 | 
				
			||||||
// Inline implements Inline.Inline.
 | 
					// Inline implements Inline.Inline.
 | 
				
			||||||
func (n *AutoLink) Inline() {}
 | 
					func (n *AutoLink) Inline() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Dump implenets Node.Dump
 | 
					// Dump implements Node.Dump
 | 
				
			||||||
func (n *AutoLink) Dump(source []byte, level int) {
 | 
					func (n *AutoLink) Dump(source []byte, level int) {
 | 
				
			||||||
	segment := n.value.Segment
 | 
						segment := n.value.Segment
 | 
				
			||||||
	m := map[string]string{
 | 
						m := map[string]string{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								vendor/github.com/yuin/goldmark/extension/ast/tasklist.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/yuin/goldmark/extension/ast/tasklist.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -11,7 +11,7 @@ type TaskCheckBox struct {
 | 
				
			||||||
	IsChecked bool
 | 
						IsChecked bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Dump impelemtns Node.Dump.
 | 
					// Dump implements Node.Dump.
 | 
				
			||||||
func (n *TaskCheckBox) Dump(source []byte, level int) {
 | 
					func (n *TaskCheckBox) Dump(source []byte, level int) {
 | 
				
			||||||
	m := map[string]string{
 | 
						m := map[string]string{
 | 
				
			||||||
		"Checked": fmt.Sprintf("%v", n.IsChecked),
 | 
							"Checked": fmt.Sprintf("%v", n.IsChecked),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										179
									
								
								vendor/github.com/yuin/goldmark/extension/linkify.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										179
									
								
								vendor/github.com/yuin/goldmark/extension/linkify.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -2,27 +2,153 @@ package extension
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/yuin/goldmark"
 | 
						"github.com/yuin/goldmark"
 | 
				
			||||||
	"github.com/yuin/goldmark/ast"
 | 
						"github.com/yuin/goldmark/ast"
 | 
				
			||||||
	"github.com/yuin/goldmark/parser"
 | 
						"github.com/yuin/goldmark/parser"
 | 
				
			||||||
	"github.com/yuin/goldmark/text"
 | 
						"github.com/yuin/goldmark/text"
 | 
				
			||||||
	"github.com/yuin/goldmark/util"
 | 
						"github.com/yuin/goldmark/util"
 | 
				
			||||||
	"regexp"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}((?:/|[#?])[-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]{2,6}((?:/|[#?])[-a-zA-Z0-9@:%_+.~#$!?&//=\(\);,'">\^{}\[\]` + "`" + `]*)?`)
 | 
					var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp):\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]+(?:(?:/|[#?])[-a-zA-Z0-9@:%_+.~#$!?&//=\(\);,'">\^{}\[\]` + "`" + `]*)?`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type linkifyParser struct {
 | 
					// 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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var defaultLinkifyParser = &linkifyParser{}
 | 
					const optLinkifyAllowedProtocols parser.OptionName = "LinkifyAllowedProtocols"
 | 
				
			||||||
 | 
					const optLinkifyURLRegexp parser.OptionName = "LinkifyURLRegexp"
 | 
				
			||||||
 | 
					const optLinkifyWWWRegexp parser.OptionName = "LinkifyWWWRegexp"
 | 
				
			||||||
 | 
					const 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(value [][]byte) LinkifyOption {
 | 
				
			||||||
 | 
						return &withLinkifyAllowedProtocols{
 | 
				
			||||||
 | 
							value: value,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WithLinkifyWWWRegexp is a functional option that specify
 | 
				
			||||||
 | 
					// a pattern of the URL without a protocol.
 | 
				
			||||||
 | 
					// This pattern must start with 'www.' .
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func WithLinkifyWWWRegexp(value *regexp.Regexp) LinkifyOption {
 | 
				
			||||||
 | 
						return &withLinkifyWWWRegexp{
 | 
				
			||||||
 | 
							value: value,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WithLinkifyWWWRegexp is a functional otpion that specify
 | 
				
			||||||
 | 
					// a pattern of the email address.
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func WithLinkifyEmailRegexp(value *regexp.Regexp) LinkifyOption {
 | 
				
			||||||
 | 
						return &withLinkifyEmailRegexp{
 | 
				
			||||||
 | 
							value: value,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type linkifyParser struct {
 | 
				
			||||||
 | 
						LinkifyConfig
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewLinkifyParser return a new InlineParser can parse
 | 
					// NewLinkifyParser return a new InlineParser can parse
 | 
				
			||||||
// text that seems like a URL.
 | 
					// text that seems like a URL.
 | 
				
			||||||
func NewLinkifyParser() parser.InlineParser {
 | 
					func NewLinkifyParser(opts ...LinkifyOption) parser.InlineParser {
 | 
				
			||||||
	return defaultLinkifyParser
 | 
						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 {
 | 
					func (s *linkifyParser) Trigger() []byte {
 | 
				
			||||||
| 
						 | 
					@ -53,14 +179,26 @@ func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Cont
 | 
				
			||||||
	var m []int
 | 
						var m []int
 | 
				
			||||||
	var protocol []byte
 | 
						var protocol []byte
 | 
				
			||||||
	var typ ast.AutoLinkType = ast.AutoLinkURL
 | 
						var typ ast.AutoLinkType = ast.AutoLinkURL
 | 
				
			||||||
	if bytes.HasPrefix(line, protoHTTP) || bytes.HasPrefix(line, protoHTTPS) || bytes.HasPrefix(line, protoFTP) {
 | 
						if s.LinkifyConfig.AllowedProtocols == nil {
 | 
				
			||||||
		m = urlRegexp.FindSubmatchIndex(line)
 | 
							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) {
 | 
						if m == nil && bytes.HasPrefix(line, domainWWW) {
 | 
				
			||||||
		m = wwwURLRegxp.FindSubmatchIndex(line)
 | 
							m = s.LinkifyConfig.WWWRegexp.FindSubmatchIndex(line)
 | 
				
			||||||
		protocol = []byte("http")
 | 
							protocol = []byte("http")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if m != nil {
 | 
						if m != nil && m[0] != 0 {
 | 
				
			||||||
 | 
							m = nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if m != nil && m[0] == 0 {
 | 
				
			||||||
		lastChar := line[m[1]-1]
 | 
							lastChar := line[m[1]-1]
 | 
				
			||||||
		if lastChar == '.' {
 | 
							if lastChar == '.' {
 | 
				
			||||||
			m[1]--
 | 
								m[1]--
 | 
				
			||||||
| 
						 | 
					@ -96,7 +234,15 @@ func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Cont
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		typ = ast.AutoLinkEmail
 | 
							typ = ast.AutoLinkEmail
 | 
				
			||||||
		stop := util.FindEmailIndex(line)
 | 
							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 {
 | 
							if stop < 0 {
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -136,15 +282,22 @@ func (s *linkifyParser) CloseBlock(parent ast.Node, pc parser.Context) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type linkify struct {
 | 
					type linkify struct {
 | 
				
			||||||
 | 
						options []LinkifyOption
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Linkify is an extension that allow you to parse text that seems like a URL.
 | 
					// Linkify is an extension that allow you to parse text that seems like a URL.
 | 
				
			||||||
var Linkify = &linkify{}
 | 
					var Linkify = &linkify{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewLinkify(opts ...LinkifyOption) goldmark.Extender {
 | 
				
			||||||
 | 
						return &linkify{
 | 
				
			||||||
 | 
							options: opts,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *linkify) Extend(m goldmark.Markdown) {
 | 
					func (e *linkify) Extend(m goldmark.Markdown) {
 | 
				
			||||||
	m.Parser().AddOptions(
 | 
						m.Parser().AddOptions(
 | 
				
			||||||
		parser.WithInlineParsers(
 | 
							parser.WithInlineParsers(
 | 
				
			||||||
			util.Prioritized(NewLinkifyParser(), 999),
 | 
								util.Prioritized(NewLinkifyParser(e.options...), 999),
 | 
				
			||||||
		),
 | 
							),
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								vendor/github.com/yuin/goldmark/extension/table.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/yuin/goldmark/extension/table.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -27,7 +27,7 @@ type tableParagraphTransformer struct {
 | 
				
			||||||
var defaultTableParagraphTransformer = &tableParagraphTransformer{}
 | 
					var defaultTableParagraphTransformer = &tableParagraphTransformer{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewTableParagraphTransformer returns  a new ParagraphTransformer
 | 
					// NewTableParagraphTransformer returns  a new ParagraphTransformer
 | 
				
			||||||
// that can transform pargraphs into tables.
 | 
					// that can transform paragraphs into tables.
 | 
				
			||||||
func NewTableParagraphTransformer() parser.ParagraphTransformer {
 | 
					func NewTableParagraphTransformer() parser.ParagraphTransformer {
 | 
				
			||||||
	return defaultTableParagraphTransformer
 | 
						return defaultTableParagraphTransformer
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										29
									
								
								vendor/github.com/yuin/goldmark/extension/typographer.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/yuin/goldmark/extension/typographer.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,6 +1,8 @@
 | 
				
			||||||
package extension
 | 
					package extension
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"unicode"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/yuin/goldmark"
 | 
						"github.com/yuin/goldmark"
 | 
				
			||||||
	gast "github.com/yuin/goldmark/ast"
 | 
						gast "github.com/yuin/goldmark/ast"
 | 
				
			||||||
	"github.com/yuin/goldmark/parser"
 | 
						"github.com/yuin/goldmark/parser"
 | 
				
			||||||
| 
						 | 
					@ -31,6 +33,8 @@ const (
 | 
				
			||||||
	LeftAngleQuote
 | 
						LeftAngleQuote
 | 
				
			||||||
	// RightAngleQuote is >>
 | 
						// RightAngleQuote is >>
 | 
				
			||||||
	RightAngleQuote
 | 
						RightAngleQuote
 | 
				
			||||||
 | 
						// Apostrophe is '
 | 
				
			||||||
 | 
						Apostrophe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	typographicPunctuationMax
 | 
						typographicPunctuationMax
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -52,6 +56,7 @@ func newDefaultSubstitutions() [][]byte {
 | 
				
			||||||
	replacements[Ellipsis] = []byte("…")
 | 
						replacements[Ellipsis] = []byte("…")
 | 
				
			||||||
	replacements[LeftAngleQuote] = []byte("«")
 | 
						replacements[LeftAngleQuote] = []byte("«")
 | 
				
			||||||
	replacements[RightAngleQuote] = []byte("»")
 | 
						replacements[RightAngleQuote] = []byte("»")
 | 
				
			||||||
 | 
						replacements[Apostrophe] = []byte("’")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return replacements
 | 
						return replacements
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -189,6 +194,26 @@ func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if c == '\'' {
 | 
							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 := util.ToRune(line, 4)
 | 
				
			||||||
 | 
										if len(line) == 3 || unicode.IsSpace(after) || unicode.IsPunct(after) {
 | 
				
			||||||
 | 
											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)) && (util.IsAlphaNumeric(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 {
 | 
								if s.Substitutions[LeftSingleQuote] != nil && d.CanOpen && !d.CanClose {
 | 
				
			||||||
				node := gast.NewString(s.Substitutions[LeftSingleQuote])
 | 
									node := gast.NewString(s.Substitutions[LeftSingleQuote])
 | 
				
			||||||
				node.SetCode(true)
 | 
									node.SetCode(true)
 | 
				
			||||||
| 
						 | 
					@ -228,10 +253,10 @@ type typographer struct {
 | 
				
			||||||
	options []TypographerOption
 | 
						options []TypographerOption
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Typographer is an extension that repalace punctuations with typographic entities.
 | 
					// Typographer is an extension that replaces punctuations with typographic entities.
 | 
				
			||||||
var Typographer = &typographer{}
 | 
					var Typographer = &typographer{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewTypographer returns a new Entender that repalace punctuations with typographic entities.
 | 
					// NewTypographer returns a new Extender that replaces punctuations with typographic entities.
 | 
				
			||||||
func NewTypographer(opts ...TypographerOption) goldmark.Extender {
 | 
					func NewTypographer(opts ...TypographerOption) goldmark.Extender {
 | 
				
			||||||
	return &typographer{
 | 
						return &typographer{
 | 
				
			||||||
		options: opts,
 | 
							options: opts,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								vendor/github.com/yuin/goldmark/parser/delimiter.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/yuin/goldmark/parser/delimiter.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -11,7 +11,7 @@ import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A DelimiterProcessor interface provides a set of functions about
 | 
					// A DelimiterProcessor interface provides a set of functions about
 | 
				
			||||||
// Deliiter nodes.
 | 
					// Delimiter nodes.
 | 
				
			||||||
type DelimiterProcessor interface {
 | 
					type DelimiterProcessor interface {
 | 
				
			||||||
	// IsDelimiter returns true if given character is a delimiter, otherwise false.
 | 
						// IsDelimiter returns true if given character is a delimiter, otherwise false.
 | 
				
			||||||
	IsDelimiter(byte) bool
 | 
						IsDelimiter(byte) bool
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@ type Delimiter struct {
 | 
				
			||||||
	// See https://spec.commonmark.org/0.29/#can-open-emphasis for details.
 | 
						// See https://spec.commonmark.org/0.29/#can-open-emphasis for details.
 | 
				
			||||||
	CanClose bool
 | 
						CanClose bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Length is a remaining length of this delmiter.
 | 
						// Length is a remaining length of this delimiter.
 | 
				
			||||||
	Length int
 | 
						Length int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// OriginalLength is a original length of this delimiter.
 | 
						// OriginalLength is a original length of this delimiter.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										36
									
								
								vendor/github.com/yuin/goldmark/parser/link.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/yuin/goldmark/parser/link.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -147,11 +147,6 @@ func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.N
 | 
				
			||||||
		ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment)
 | 
							ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment)
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	labelValue := block.Value(text.NewSegment(last.Segment.Start+1, segment.Start))
 | 
					 | 
				
			||||||
	if util.IsBlank(labelValue) && !last.IsImage {
 | 
					 | 
				
			||||||
		ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment)
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c := block.Peek()
 | 
						c := block.Peek()
 | 
				
			||||||
	l, pos := block.Position()
 | 
						l, pos := block.Position()
 | 
				
			||||||
| 
						 | 
					@ -351,14 +346,31 @@ func parseLinkTitle(block text.Reader) ([]byte, bool) {
 | 
				
			||||||
	if opener == '(' {
 | 
						if opener == '(' {
 | 
				
			||||||
		closer = ')'
 | 
							closer = ')'
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	line, _ := block.PeekLine()
 | 
						savedLine, savedPosition := block.Position()
 | 
				
			||||||
	pos := util.FindClosure(line[1:], opener, closer, false, true)
 | 
						var title []byte
 | 
				
			||||||
	if pos < 0 {
 | 
						for i := 0; ; i++ {
 | 
				
			||||||
		return nil, false
 | 
							line, _ := block.PeekLine()
 | 
				
			||||||
 | 
							if line == nil {
 | 
				
			||||||
 | 
								block.SetPosition(savedLine, savedPosition)
 | 
				
			||||||
 | 
								return nil, false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							offset := 0
 | 
				
			||||||
 | 
							if i == 0 {
 | 
				
			||||||
 | 
								offset = 1
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							pos := util.FindClosure(line[offset:], opener, closer, false, true)
 | 
				
			||||||
 | 
							if pos < 0 {
 | 
				
			||||||
 | 
								title = append(title, line[offset:]...)
 | 
				
			||||||
 | 
								block.AdvanceLine()
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							pos += offset + 1 // 1: closer
 | 
				
			||||||
 | 
							block.Advance(pos)
 | 
				
			||||||
 | 
							if i == 0 { // avoid allocating new slice
 | 
				
			||||||
 | 
								return line[offset : pos-1], true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return append(title, line[offset:pos-1]...), true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pos += 2 // opener + closer
 | 
					 | 
				
			||||||
	block.Advance(pos)
 | 
					 | 
				
			||||||
	return line[1 : pos-1], true
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *linkParser) CloseBlock(parent ast.Node, block text.Reader, pc Context) {
 | 
					func (s *linkParser) CloseBlock(parent ast.Node, block text.Reader, pc Context) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								vendor/github.com/yuin/goldmark/parser/parser.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/yuin/goldmark/parser/parser.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -459,7 +459,7 @@ type Parser interface {
 | 
				
			||||||
	// Parse parses the given Markdown text into AST nodes.
 | 
						// Parse parses the given Markdown text into AST nodes.
 | 
				
			||||||
	Parse(reader text.Reader, opts ...ParseOption) ast.Node
 | 
						Parse(reader text.Reader, opts ...ParseOption) ast.Node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// AddOption adds the given option to thie parser.
 | 
						// AddOption adds the given option to this parser.
 | 
				
			||||||
	AddOptions(...Option)
 | 
						AddOptions(...Option)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -505,7 +505,7 @@ type BlockParser interface {
 | 
				
			||||||
	// Close will be called when the parser returns Close.
 | 
						// Close will be called when the parser returns Close.
 | 
				
			||||||
	Close(node ast.Node, reader text.Reader, pc Context)
 | 
						Close(node ast.Node, reader text.Reader, pc Context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// CanInterruptParagraph returns true if the parser can interrupt pargraphs,
 | 
						// CanInterruptParagraph returns true if the parser can interrupt paragraphs,
 | 
				
			||||||
	// otherwise false.
 | 
						// otherwise false.
 | 
				
			||||||
	CanInterruptParagraph() bool
 | 
						CanInterruptParagraph() bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								vendor/github.com/yuin/goldmark/renderer/html/html.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/yuin/goldmark/renderer/html/html.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -660,13 +660,13 @@ func RenderAttributes(w util.BufWriter, node ast.Node, filter util.BytesFilter)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A Writer interface wirtes textual contents to a writer.
 | 
					// A Writer interface writes textual contents to a writer.
 | 
				
			||||||
type Writer interface {
 | 
					type Writer interface {
 | 
				
			||||||
	// Write writes the given source to writer with resolving references and unescaping
 | 
						// Write writes the given source to writer with resolving references and unescaping
 | 
				
			||||||
	// backslash escaped characters.
 | 
						// backslash escaped characters.
 | 
				
			||||||
	Write(writer util.BufWriter, source []byte)
 | 
						Write(writer util.BufWriter, source []byte)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// RawWrite wirtes the given source to writer without resolving references and
 | 
						// RawWrite writes the given source to writer without resolving references and
 | 
				
			||||||
	// unescaping backslash escaped characters.
 | 
						// unescaping backslash escaped characters.
 | 
				
			||||||
	RawWrite(writer util.BufWriter, source []byte)
 | 
						RawWrite(writer util.BufWriter, source []byte)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								vendor/github.com/yuin/goldmark/text/segment.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/yuin/goldmark/text/segment.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -7,7 +7,7 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var space = []byte(" ")
 | 
					var space = []byte(" ")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// A Segment struct holds information about source potisions.
 | 
					// A Segment struct holds information about source positions.
 | 
				
			||||||
type Segment struct {
 | 
					type Segment struct {
 | 
				
			||||||
	// Start is a start position of the segment.
 | 
						// Start is a start position of the segment.
 | 
				
			||||||
	Start int
 | 
						Start int
 | 
				
			||||||
| 
						 | 
					@ -197,7 +197,7 @@ func (s *Segments) Sliced(lo, hi int) []Segment {
 | 
				
			||||||
	return s.values[lo:hi]
 | 
						return s.values[lo:hi]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Clear delete all element of the collction.
 | 
					// Clear delete all element of the collection.
 | 
				
			||||||
func (s *Segments) Clear() {
 | 
					func (s *Segments) Clear() {
 | 
				
			||||||
	s.values = nil
 | 
						s.values = nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1491
									
								
								vendor/github.com/yuin/goldmark/util/unicode_case_folding.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1491
									
								
								vendor/github.com/yuin/goldmark/util/unicode_case_folding.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										60
									
								
								vendor/github.com/yuin/goldmark/util/util.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										60
									
								
								vendor/github.com/yuin/goldmark/util/util.go
									
										
									
										generated
									
									
										vendored
									
									
								
							| 
						 | 
					@ -8,7 +8,6 @@ import (
 | 
				
			||||||
	"regexp"
 | 
						"regexp"
 | 
				
			||||||
	"sort"
 | 
						"sort"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"unicode/utf8"
 | 
						"unicode/utf8"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,7 +54,7 @@ func (b *CopyOnWriteBuffer) IsCopied() bool {
 | 
				
			||||||
	return b.copied
 | 
						return b.copied
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsEscapedPunctuation returns true if caracter at a given index i
 | 
					// IsEscapedPunctuation returns true if character at a given index i
 | 
				
			||||||
// is an escaped punctuation, otherwise false.
 | 
					// is an escaped punctuation, otherwise false.
 | 
				
			||||||
func IsEscapedPunctuation(source []byte, i int) bool {
 | 
					func IsEscapedPunctuation(source []byte, i int) bool {
 | 
				
			||||||
	return source[i] == '\\' && i < len(source)-1 && IsPunct(source[i+1])
 | 
						return source[i] == '\\' && i < len(source)-1 && IsPunct(source[i+1])
 | 
				
			||||||
| 
						 | 
					@ -229,7 +228,7 @@ func IndentWidth(bs []byte, currentPos int) (width, pos int) {
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FirstNonSpacePosition returns a potisoin line that is a first nonspace
 | 
					// FirstNonSpacePosition returns a position line that is a first nonspace
 | 
				
			||||||
// character.
 | 
					// character.
 | 
				
			||||||
func FirstNonSpacePosition(bs []byte) int {
 | 
					func FirstNonSpacePosition(bs []byte) int {
 | 
				
			||||||
	i := 0
 | 
						i := 0
 | 
				
			||||||
| 
						 | 
					@ -387,6 +386,52 @@ func TrimRightSpace(source []byte) []byte {
 | 
				
			||||||
	return TrimRight(source, spaces)
 | 
						return TrimRight(source, spaces)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DoFullUnicodeCaseFolding performs full unicode case folding to given bytes.
 | 
				
			||||||
 | 
					func DoFullUnicodeCaseFolding(v []byte) []byte {
 | 
				
			||||||
 | 
						var rbuf []byte
 | 
				
			||||||
 | 
						cob := NewCopyOnWriteBuffer(v)
 | 
				
			||||||
 | 
						n := 0
 | 
				
			||||||
 | 
						for i := 0; i < len(v); i++ {
 | 
				
			||||||
 | 
							c := v[i]
 | 
				
			||||||
 | 
							if c < 0xb5 {
 | 
				
			||||||
 | 
								if c >= 0x41 && c <= 0x5a {
 | 
				
			||||||
 | 
									// A-Z to a-z
 | 
				
			||||||
 | 
									cob.Write(v[n:i])
 | 
				
			||||||
 | 
									cob.WriteByte(c + 32)
 | 
				
			||||||
 | 
									n = i + 1
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if !utf8.RuneStart(c) {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							r, length := utf8.DecodeRune(v[i:])
 | 
				
			||||||
 | 
							if r == utf8.RuneError {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							folded, ok := unicodeCaseFoldings[r]
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cob.Write(v[n:i])
 | 
				
			||||||
 | 
							if rbuf == nil {
 | 
				
			||||||
 | 
								rbuf = make([]byte, 4)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for _, f := range folded {
 | 
				
			||||||
 | 
								l := utf8.EncodeRune(rbuf, f)
 | 
				
			||||||
 | 
								cob.Write(rbuf[:l])
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							i += length - 1
 | 
				
			||||||
 | 
							n = i + 1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if cob.IsCopied() {
 | 
				
			||||||
 | 
							cob.Write(v[n:])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return cob.Bytes()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ReplaceSpaces replaces sequence of spaces with the given repl.
 | 
					// ReplaceSpaces replaces sequence of spaces with the given repl.
 | 
				
			||||||
func ReplaceSpaces(source []byte, repl byte) []byte {
 | 
					func ReplaceSpaces(source []byte, repl byte) []byte {
 | 
				
			||||||
	var ret []byte
 | 
						var ret []byte
 | 
				
			||||||
| 
						 | 
					@ -439,13 +484,14 @@ func ToValidRune(v rune) rune {
 | 
				
			||||||
	return v
 | 
						return v
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ToLinkReference convert given bytes into a valid link reference string.
 | 
					// ToLinkReference converts given bytes into a valid link reference string.
 | 
				
			||||||
// ToLinkReference trims leading and trailing spaces and convert into lower
 | 
					// ToLinkReference performs unicode case folding, trims leading and trailing spaces,  converts into lower
 | 
				
			||||||
// case and replace spaces with a single space character.
 | 
					// case and replace spaces with a single space character.
 | 
				
			||||||
func ToLinkReference(v []byte) string {
 | 
					func ToLinkReference(v []byte) string {
 | 
				
			||||||
	v = TrimLeftSpace(v)
 | 
						v = TrimLeftSpace(v)
 | 
				
			||||||
	v = TrimRightSpace(v)
 | 
						v = TrimRightSpace(v)
 | 
				
			||||||
	return strings.ToLower(string(ReplaceSpaces(v, ' ')))
 | 
						v = DoFullUnicodeCaseFolding(v)
 | 
				
			||||||
 | 
						return string(ReplaceSpaces(v, ' '))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var htmlEscapeTable = [256][]byte{nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []byte("""), nil, nil, nil, []byte("&"), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []byte("<"), nil, []byte(">"), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil}
 | 
					var htmlEscapeTable = [256][]byte{nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []byte("""), nil, nil, nil, []byte("&"), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []byte("<"), nil, []byte(">"), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil}
 | 
				
			||||||
| 
						 | 
					@ -589,7 +635,7 @@ var htmlSpace = []byte("%20")
 | 
				
			||||||
//   2. resolve numeric references
 | 
					//   2. resolve numeric references
 | 
				
			||||||
//   3. resolve entity references
 | 
					//   3. resolve entity references
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// URL encoded values (%xx) are keeped as is.
 | 
					// URL encoded values (%xx) are kept as is.
 | 
				
			||||||
func URLEscape(v []byte, resolveReference bool) []byte {
 | 
					func URLEscape(v []byte, resolveReference bool) []byte {
 | 
				
			||||||
	if resolveReference {
 | 
						if resolveReference {
 | 
				
			||||||
		v = UnescapePunctuations(v)
 | 
							v = UnescapePunctuations(v)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								vendor/modules.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/modules.txt
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -450,7 +450,7 @@ github.com/willf/bitset
 | 
				
			||||||
github.com/xanzy/ssh-agent
 | 
					github.com/xanzy/ssh-agent
 | 
				
			||||||
# github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53
 | 
					# github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53
 | 
				
			||||||
github.com/yohcop/openid-go
 | 
					github.com/yohcop/openid-go
 | 
				
			||||||
# github.com/yuin/goldmark v1.1.19
 | 
					# github.com/yuin/goldmark v1.1.23
 | 
				
			||||||
github.com/yuin/goldmark
 | 
					github.com/yuin/goldmark
 | 
				
			||||||
github.com/yuin/goldmark/ast
 | 
					github.com/yuin/goldmark/ast
 | 
				
			||||||
github.com/yuin/goldmark/extension
 | 
					github.com/yuin/goldmark/extension
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue