diff --git a/extension/_test/linkify.txt b/extension/_test/linkify.txt index eef889d..669ab72 100644 --- a/extension/_test/linkify.txt +++ b/extension/_test/linkify.txt @@ -137,3 +137,19 @@ https://github.com?q=stars:>1 //- - - - - - - - -//

https://github.com?q=stars:>1

//= = = = = = = = = = = = = = = = = = = = = = = =// + + +14 +//- - - - - - - - -// +[https://google.com](https://google.com) +//- - - - - - - - -// +

https://google.com

+//= = = = = = = = = = = = = = = = = = = = = = = =// + + +15 +//- - - - - - - - -// +This is a `git@github.com:vim/vim` +//- - - - - - - - -// +

This is a git@github.com:vim/vim

+//= = = = = = = = = = = = = = = = = = = = = = = =// diff --git a/extension/linkify.go b/extension/linkify.go index 454abf8..6d28af8 100644 --- a/extension/linkify.go +++ b/extension/linkify.go @@ -36,6 +36,9 @@ var protoFTP = []byte("ftp:") var domainWWW = []byte("www.") func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node { + if pc.IsInLinkLabel() { + return nil + } line, segment := block.PeekLine() consumes := 0 start := segment.Start @@ -89,6 +92,9 @@ func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Cont } } if m == nil { + if len(line) > 0 && util.IsPunct(line[0]) { + return nil + } typ = ast.AutoLinkEmail stop := util.FindEmailIndex(line) if stop < 0 { @@ -132,43 +138,6 @@ func (s *linkifyParser) CloseBlock(parent ast.Node, pc parser.Context) { type linkify struct { } -type linkifyASTTransformer struct { -} - -var defaultLinkifyASTTransformer = &linkifyASTTransformer{} - -// NewLinkifyASTTransformer returns a new parser.ASTTransformer that -// is related to AutoLink. -func NewLinkifyASTTransformer() parser.ASTTransformer { - return defaultLinkifyASTTransformer -} - -func (a *linkifyASTTransformer) Transform(node *ast.Document, reader text.Reader, pc parser.Context) { - var autoLinks []*ast.AutoLink - _ = ast.Walk(node, func(n ast.Node, entering bool) (ast.WalkStatus, error) { - if entering { - if autoLink, ok := n.(*ast.AutoLink); ok { - autoLinks = append(autoLinks, autoLink) - } - } - return ast.WalkContinue, nil - - }) - for _, autoLink := range autoLinks { - nested := false - for p := autoLink.Parent(); p != nil; p = p.Parent() { - if _, ok := p.(*ast.Link); ok { - nested = true - break - } - } - if nested { - parent := autoLink.Parent() - parent.ReplaceChild(parent, autoLink, ast.NewString(autoLink.Label(reader.Source()))) - } - } -} - // Linkify is an extension that allow you to parse text that seems like a URL. var Linkify = &linkify{} @@ -177,8 +146,5 @@ func (e *linkify) Extend(m goldmark.Markdown) { parser.WithInlineParsers( util.Prioritized(NewLinkifyParser(), 999), ), - parser.WithASTTransformers( - util.Prioritized(NewLinkifyASTTransformer(), 999), - ), ) } diff --git a/parser/parser.go b/parser/parser.go index a154454..abe0887 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -196,6 +196,9 @@ type Context interface { // LastOpenedBlock returns a last node that is currently in parsing. LastOpenedBlock() Block + + // IsInLinkLabel returns true if current position seems to be in link label. + IsInLinkLabel() bool } // A ContextConfig struct is a data structure that holds configuration of the Context. @@ -378,6 +381,11 @@ func (p *parseContext) LastOpenedBlock() Block { return Block{} } +func (p *parseContext) IsInLinkLabel() bool { + tlist := p.Get(linkLabelStateKey) + return tlist != nil +} + // State represents parser's state. // State is designed to use as a bit flag. type State int