mirror of https://github.com/jlelse/GoBlog
Support mark tag markdown syntax
This commit is contained in:
parent
7a8487ec01
commit
2781233e8a
6
go.mod
6
go.mod
|
@ -8,8 +8,10 @@ require (
|
|||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
|
||||
github.com/boombuler/barcode v1.0.1 // indirect
|
||||
github.com/caddyserver/certmagic v0.13.1
|
||||
// master
|
||||
github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||
// master
|
||||
github.com/dgraph-io/ristretto v0.0.4-0.20210504190834-0bf2acd73aa3
|
||||
github.com/elnormous/contenttype v1.0.0
|
||||
github.com/felixge/httpsnoop v1.0.2 // indirect
|
||||
|
@ -54,14 +56,14 @@ require (
|
|||
github.com/thoas/go-funk v0.8.0
|
||||
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80
|
||||
github.com/vcraescu/go-paginator v1.0.1-0.20201114172518-2cfc59fe05c2
|
||||
github.com/yuin/goldmark v1.3.5
|
||||
github.com/yuin/goldmark v1.3.7
|
||||
github.com/yuin/goldmark-emoji v1.0.1
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
go.uber.org/zap v1.16.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect
|
||||
golang.org/x/mod v0.4.1 // indirect
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 // indirect
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
|
||||
|
|
8
go.sum
8
go.sum
|
@ -345,8 +345,8 @@ github.com/vcraescu/go-paginator v1.0.1-0.20201114172518-2cfc59fe05c2 h1:l5j4nE6
|
|||
github.com/vcraescu/go-paginator v1.0.1-0.20201114172518-2cfc59fe05c2/go.mod h1:NEDNuq1asYbAeX+uy6w56MDQSFmBQz9k+N9Hy6m4r2U=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.3.7 h1:NSaHgaeJFCtWXCBkBKXw0rhgMuJ0VoE9FB5mWldcrQ4=
|
||||
github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os=
|
||||
github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
|
@ -423,8 +423,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I=
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE=
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
|
68
markdown.go
68
markdown.go
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/yuin/goldmark/parser"
|
||||
"github.com/yuin/goldmark/renderer"
|
||||
"github.com/yuin/goldmark/renderer/html"
|
||||
"github.com/yuin/goldmark/text"
|
||||
"github.com/yuin/goldmark/util"
|
||||
)
|
||||
|
||||
|
@ -87,6 +88,9 @@ type customExtension struct {
|
|||
}
|
||||
|
||||
func (l *customExtension) Extend(m goldmark.Markdown) {
|
||||
m.Parser().AddOptions(parser.WithInlineParsers(
|
||||
util.Prioritized(&markdownMarkParser{}, 500),
|
||||
))
|
||||
m.Renderer().AddOptions(renderer.WithNodeRenderers(
|
||||
util.Prioritized(&customRenderer{
|
||||
absoluteLinks: l.absoluteLinks,
|
||||
|
@ -101,6 +105,7 @@ type customRenderer struct {
|
|||
func (c *customRenderer) RegisterFuncs(r renderer.NodeRendererFuncRegisterer) {
|
||||
r.Register(ast.KindLink, c.renderLink)
|
||||
r.Register(ast.KindImage, c.renderImage)
|
||||
r.Register(kindMarkdownMark, c.renderMarkTag)
|
||||
}
|
||||
|
||||
func (c *customRenderer) renderLink(w util.BufWriter, _ []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
|
@ -160,3 +165,66 @@ func (c *customRenderer) renderImage(w util.BufWriter, source []byte, node ast.N
|
|||
_, _ = w.WriteString("></a>")
|
||||
return ast.WalkSkipChildren, nil
|
||||
}
|
||||
|
||||
type markdownMark struct {
|
||||
ast.BaseInline
|
||||
}
|
||||
|
||||
func (n *markdownMark) Kind() ast.NodeKind {
|
||||
return kindMarkdownMark
|
||||
}
|
||||
|
||||
func (n *markdownMark) Dump(source []byte, level int) {
|
||||
ast.DumpHelper(n, source, level, nil, nil)
|
||||
}
|
||||
|
||||
type markDelimiterProcessor struct {
|
||||
}
|
||||
|
||||
func (p *markDelimiterProcessor) IsDelimiter(b byte) bool {
|
||||
return b == '='
|
||||
}
|
||||
|
||||
func (p *markDelimiterProcessor) CanOpenCloser(opener, closer *parser.Delimiter) bool {
|
||||
return opener.Char == closer.Char
|
||||
}
|
||||
|
||||
func (p *markDelimiterProcessor) OnMatch(consumes int) ast.Node {
|
||||
return &markdownMark{}
|
||||
}
|
||||
|
||||
var defaultMarkDelimiterProcessor = &markDelimiterProcessor{}
|
||||
|
||||
type markdownMarkParser struct {
|
||||
}
|
||||
|
||||
func (s *markdownMarkParser) Trigger() []byte {
|
||||
return []byte{'='}
|
||||
}
|
||||
|
||||
func (s *markdownMarkParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node {
|
||||
before := block.PrecendingCharacter()
|
||||
line, segment := block.PeekLine()
|
||||
node := parser.ScanDelimiter(line, before, 2, defaultMarkDelimiterProcessor)
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
node.Segment = segment.WithStop(segment.Start + node.OriginalLength)
|
||||
block.Advance(node.OriginalLength)
|
||||
pc.PushDelimiter(node)
|
||||
return node
|
||||
}
|
||||
|
||||
func (s *markdownMarkParser) CloseBlock(parent ast.Node, pc parser.Context) {
|
||||
}
|
||||
|
||||
var kindMarkdownMark = ast.NewNodeKind("Mark")
|
||||
|
||||
func (c *customRenderer) renderMarkTag(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
if entering {
|
||||
_, _ = w.WriteString("<mark>")
|
||||
} else {
|
||||
_, _ = w.WriteString("</mark>")
|
||||
}
|
||||
return ast.WalkContinue, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue