matterbridge/vendor/gitlab.com/golang-commonmark/markdown/linkify.go

132 lines
2.8 KiB
Go

// Copyright 2015 The Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package markdown
import (
"strings"
"gitlab.com/golang-commonmark/linkify"
)
func isLinkOpen(s string) bool { return isLetter(s[1]) }
func isLinkClose(s string) bool { return s[1] == '/' }
func ruleLinkify(s *StateCore) {
blockTokens := s.Tokens
if !s.Md.Linkify {
return
}
for _, tok := range blockTokens {
if tok, ok := tok.(*Inline); ok {
tokens := tok.Children
htmlLinkLevel := 0
for i := len(tokens) - 1; i >= 0; i-- {
currentTok := tokens[i]
if _, ok := currentTok.(*LinkClose); ok {
i--
for tokens[i].Level() != currentTok.Level() {
if _, ok := tokens[i].(*LinkOpen); ok {
break
}
i--
}
continue
}
if currentTok, ok := currentTok.(*HTMLInline); ok {
if isLinkOpen(currentTok.Content) && htmlLinkLevel > 0 {
htmlLinkLevel--
}
if isLinkClose(currentTok.Content) {
htmlLinkLevel++
}
}
if htmlLinkLevel > 0 {
continue
}
if currentTok, ok := currentTok.(*Text); ok {
text := currentTok.Content
links := linkify.Links(text)
if len(links) == 0 {
continue
}
var nodes []Token
level := currentTok.Lvl
lastPos := 0
for _, ln := range links {
urlText := text[ln.Start:ln.End]
url := urlText
if ln.Scheme == "" {
url = "http://" + url
} else if ln.Scheme == "mailto:" && !strings.HasPrefix(url, "mailto:") {
url = "mailto:" + url
}
url = normalizeLink(url)
if !validateLink(url) {
continue
}
if ln.Scheme == "" {
urlText = strings.TrimPrefix(normalizeLinkText("http://"+urlText), "http://")
} else if ln.Scheme == "mailto:" && !strings.HasPrefix(urlText, "mailto:") {
urlText = strings.TrimPrefix(normalizeLinkText("mailto:"+urlText), "mailto:")
} else {
urlText = normalizeLinkText(urlText)
}
pos := ln.Start
if pos > lastPos {
tok := Text{
Content: text[lastPos:pos],
Lvl: level,
}
nodes = append(nodes, &tok)
}
nodes = append(nodes, &LinkOpen{
Href: url,
Lvl: level,
})
nodes = append(nodes, &Text{
Content: urlText,
Lvl: level + 1,
})
nodes = append(nodes, &LinkClose{
Lvl: level,
})
lastPos = ln.End
}
if lastPos < len(text) {
tok := Text{
Content: text[lastPos:],
Lvl: level,
}
nodes = append(nodes, &tok)
}
children := make([]Token, len(tokens)+len(nodes)-1)
copy(children, tokens[:i])
copy(children[i:], nodes)
copy(children[i+len(nodes):], tokens[i+1:])
tok.Children = children
tokens = children
}
}
}
}
}