Ellen Emilia Anna Zscheilefix various typos (#7690)a0cc05b1 year agoHistory
154 lines · 3.4 KB · Go
RawDownload
// Copyright 2019 Yusuke Inuzuka// Copyright 2019 The Gitea Authors. All rights reserved.// SPDX-License-Identifier: MIT // Most of this file is a subtly changed version of github.com/yuin/goldmark/extension/linkify.go package common 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 wwwURLRegexp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}((?:/|[#?])[-a-zA-Z0-9@:%_\+.~#!?&//=\(\);,'">\^{}\[\]` + "`" + `]*)?`) type linkifyParser struct{} var defaultLinkifyParser = &linkifyParser{} // NewLinkifyParser return a new InlineParser can parse// text that seems like a URL.func NewLinkifyParser() parser.InlineParser {	return defaultLinkifyParser} 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	typ := ast.AutoLinkURL	if bytes.HasPrefix(line, protoHTTP) || bytes.HasPrefix(line, protoHTTPS) || bytes.HasPrefix(line, protoFTP) {		m = LinkRegex.FindSubmatchIndex(line)	}	if m == nil && bytes.HasPrefix(line, domainWWW) {		m = wwwURLRegexp.FindSubmatchIndex(line)		protocol = []byte("http")	}	if m != nil {		lastChar := line[m[1]-1]		if lastChar == '.' {			m[1]--		} else if lastChar == ')' {			closing := 0			for i := m[1] - 1; i >= m[0]; i-- {				switch line[i] {				case ')':					closing++				case '(':					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 := util.FindEmailIndex(line)		if stop < 0 {			return nil		}		at := bytes.IndexByte(line, '@')		m = []int{0, stop, at, stop - 1}		if 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 consumes != 0 {		s := segment.WithStop(segment.Start + 1)		ast.MergeOrAppendTextSegment(parent, s)	}	consumes += m[1]	block.Advance(consumes)	n := ast.NewTextSegment(text.NewSegment(start, start+m[1]))	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{} // Linkify is an extension that allow you to parse text that seems like a URL.var Linkify = &linkify{} func (e *linkify) Extend(m goldmark.Markdown) {	m.Parser().AddOptions(		parser.WithInlineParsers(			util.Prioritized(NewLinkifyParser(), 999),		),	)}