diff options
Diffstat (limited to 'vendor/github.com/yuin/goldmark/extension/linkify.go')
-rw-r--r-- | vendor/github.com/yuin/goldmark/extension/linkify.go | 322 |
1 files changed, 0 insertions, 322 deletions
diff --git a/vendor/github.com/yuin/goldmark/extension/linkify.go b/vendor/github.com/yuin/goldmark/extension/linkify.go deleted file mode 100644 index ad88933ac..000000000 --- a/vendor/github.com/yuin/goldmark/extension/linkify.go +++ /dev/null @@ -1,322 +0,0 @@ -package extension - -import ( - "bytes" - "regexp" - - "github.com/yuin/goldmark" - "github.com/yuin/goldmark/ast" - "github.com/yuin/goldmark/parser" - "github.com/yuin/goldmark/text" - "github.com/yuin/goldmark/util" -) - -var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]+(?:[/#?][-a-zA-Z0-9@:%_\+.~#!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) //nolint:golint,lll - -var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp)://[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]+(?::\d+)?(?:[/#?][-a-zA-Z0-9@:%_+.~#$!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) //nolint:golint,lll - -// An LinkifyConfig struct is a data structure that holds configuration of the -// Linkify extension. -type LinkifyConfig struct { - AllowedProtocols [][]byte - URLRegexp *regexp.Regexp - WWWRegexp *regexp.Regexp - EmailRegexp *regexp.Regexp -} - -const ( - optLinkifyAllowedProtocols parser.OptionName = "LinkifyAllowedProtocols" - optLinkifyURLRegexp parser.OptionName = "LinkifyURLRegexp" - optLinkifyWWWRegexp parser.OptionName = "LinkifyWWWRegexp" - optLinkifyEmailRegexp parser.OptionName = "LinkifyEmailRegexp" -) - -// SetOption implements SetOptioner. -func (c *LinkifyConfig) SetOption(name parser.OptionName, value interface{}) { - switch name { - case optLinkifyAllowedProtocols: - c.AllowedProtocols = value.([][]byte) - case optLinkifyURLRegexp: - c.URLRegexp = value.(*regexp.Regexp) - case optLinkifyWWWRegexp: - c.WWWRegexp = value.(*regexp.Regexp) - case optLinkifyEmailRegexp: - c.EmailRegexp = value.(*regexp.Regexp) - } -} - -// A LinkifyOption interface sets options for the LinkifyOption. -type LinkifyOption interface { - parser.Option - SetLinkifyOption(*LinkifyConfig) -} - -type withLinkifyAllowedProtocols struct { - value [][]byte -} - -func (o *withLinkifyAllowedProtocols) SetParserOption(c *parser.Config) { - c.Options[optLinkifyAllowedProtocols] = o.value -} - -func (o *withLinkifyAllowedProtocols) SetLinkifyOption(p *LinkifyConfig) { - p.AllowedProtocols = o.value -} - -// WithLinkifyAllowedProtocols is a functional option that specify allowed -// protocols in autolinks. Each protocol must end with ':' like -// 'http:' . -func WithLinkifyAllowedProtocols[T []byte | string](value []T) LinkifyOption { - opt := &withLinkifyAllowedProtocols{} - for _, v := range value { - opt.value = append(opt.value, []byte(v)) - } - return opt -} - -type withLinkifyURLRegexp struct { - value *regexp.Regexp -} - -func (o *withLinkifyURLRegexp) SetParserOption(c *parser.Config) { - c.Options[optLinkifyURLRegexp] = o.value -} - -func (o *withLinkifyURLRegexp) SetLinkifyOption(p *LinkifyConfig) { - p.URLRegexp = o.value -} - -// WithLinkifyURLRegexp is a functional option that specify -// a pattern of the URL including a protocol. -func WithLinkifyURLRegexp(value *regexp.Regexp) LinkifyOption { - return &withLinkifyURLRegexp{ - value: value, - } -} - -type withLinkifyWWWRegexp struct { - value *regexp.Regexp -} - -func (o *withLinkifyWWWRegexp) SetParserOption(c *parser.Config) { - c.Options[optLinkifyWWWRegexp] = o.value -} - -func (o *withLinkifyWWWRegexp) SetLinkifyOption(p *LinkifyConfig) { - p.WWWRegexp = o.value -} - -// WithLinkifyWWWRegexp is a functional option that specify -// a pattern of the URL without a protocol. -// This pattern must start with 'www.' . -func WithLinkifyWWWRegexp(value *regexp.Regexp) LinkifyOption { - return &withLinkifyWWWRegexp{ - value: value, - } -} - -type withLinkifyEmailRegexp struct { - value *regexp.Regexp -} - -func (o *withLinkifyEmailRegexp) SetParserOption(c *parser.Config) { - c.Options[optLinkifyEmailRegexp] = o.value -} - -func (o *withLinkifyEmailRegexp) SetLinkifyOption(p *LinkifyConfig) { - p.EmailRegexp = o.value -} - -// WithLinkifyEmailRegexp is a functional otpion that specify -// a pattern of the email address. -func WithLinkifyEmailRegexp(value *regexp.Regexp) LinkifyOption { - return &withLinkifyEmailRegexp{ - value: value, - } -} - -type linkifyParser struct { - LinkifyConfig -} - -// NewLinkifyParser return a new InlineParser can parse -// text that seems like a URL. -func NewLinkifyParser(opts ...LinkifyOption) parser.InlineParser { - p := &linkifyParser{ - LinkifyConfig: LinkifyConfig{ - AllowedProtocols: nil, - URLRegexp: urlRegexp, - WWWRegexp: wwwURLRegxp, - }, - } - for _, o := range opts { - o.SetLinkifyOption(&p.LinkifyConfig) - } - return p -} - -func (s *linkifyParser) Trigger() []byte { - // ' ' indicates any white spaces and a line head - return []byte{' ', '*', '_', '~', '('} -} - -var ( - protoHTTP = []byte("http:") - protoHTTPS = []byte("https:") - protoFTP = []byte("ftp:") - domainWWW = []byte("www.") -) - -func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node { - if pc.IsInLinkLabel() { - return nil - } - line, segment := block.PeekLine() - consumes := 0 - start := segment.Start - c := line[0] - // advance if current position is not a line head. - if c == ' ' || c == '*' || c == '_' || c == '~' || c == '(' { - consumes++ - start++ - line = line[1:] - } - - var m []int - var protocol []byte - var typ ast.AutoLinkType = ast.AutoLinkURL - if s.LinkifyConfig.AllowedProtocols == nil { - if bytes.HasPrefix(line, protoHTTP) || bytes.HasPrefix(line, protoHTTPS) || bytes.HasPrefix(line, protoFTP) { - m = s.LinkifyConfig.URLRegexp.FindSubmatchIndex(line) - } - } else { - for _, prefix := range s.LinkifyConfig.AllowedProtocols { - if bytes.HasPrefix(line, prefix) { - m = s.LinkifyConfig.URLRegexp.FindSubmatchIndex(line) - break - } - } - } - if m == nil && bytes.HasPrefix(line, domainWWW) { - m = s.LinkifyConfig.WWWRegexp.FindSubmatchIndex(line) - protocol = []byte("http") - } - if m != nil && m[0] != 0 { - m = nil - } - if m != nil && m[0] == 0 { - lastChar := line[m[1]-1] - if lastChar == '.' { - m[1]-- - } else if lastChar == ')' { - closing := 0 - for i := m[1] - 1; i >= m[0]; i-- { - if line[i] == ')' { - closing++ - } else if line[i] == '(' { - closing-- - } - } - if closing > 0 { - m[1] -= closing - } - } else if lastChar == ';' { - i := m[1] - 2 - for ; i >= m[0]; i-- { - if util.IsAlphaNumeric(line[i]) { - continue - } - break - } - if i != m[1]-2 { - if line[i] == '&' { - m[1] -= m[1] - i - } - } - } - } - if m == nil { - if len(line) > 0 && util.IsPunct(line[0]) { - return nil - } - typ = ast.AutoLinkEmail - stop := -1 - if s.LinkifyConfig.EmailRegexp == nil { - stop = util.FindEmailIndex(line) - } else { - m := s.LinkifyConfig.EmailRegexp.FindSubmatchIndex(line) - if m != nil && m[0] == 0 { - stop = m[1] - } - } - if stop < 0 { - return nil - } - at := bytes.IndexByte(line, '@') - m = []int{0, stop, at, stop - 1} - if m == nil || bytes.IndexByte(line[m[2]:m[3]], '.') < 0 { - return nil - } - lastChar := line[m[1]-1] - if lastChar == '.' { - m[1]-- - } - if m[1] < len(line) { - nextChar := line[m[1]] - if nextChar == '-' || nextChar == '_' { - return nil - } - } - } - if m == nil { - return nil - } - if consumes != 0 { - s := segment.WithStop(segment.Start + 1) - ast.MergeOrAppendTextSegment(parent, s) - } - i := m[1] - 1 - for ; i > 0; i-- { - c := line[i] - switch c { - case '?', '!', '.', ',', ':', '*', '_', '~': - default: - goto endfor - } - } -endfor: - i++ - consumes += i - block.Advance(consumes) - n := ast.NewTextSegment(text.NewSegment(start, start+i)) - link := ast.NewAutoLink(typ, n) - link.Protocol = protocol - return link -} - -func (s *linkifyParser) CloseBlock(parent ast.Node, pc parser.Context) { - // nothing to do -} - -type linkify struct { - options []LinkifyOption -} - -// Linkify is an extension that allow you to parse text that seems like a URL. -var Linkify = &linkify{} - -// NewLinkify creates a new [goldmark.Extender] that -// allow you to parse text that seems like a URL. -func NewLinkify(opts ...LinkifyOption) goldmark.Extender { - return &linkify{ - options: opts, - } -} - -func (e *linkify) Extend(m goldmark.Markdown) { - m.Parser().AddOptions( - parser.WithInlineParsers( - util.Prioritized(NewLinkifyParser(e.options...), 999), - ), - ) -} |