mirror of
https://github.com/cwinfo/matterbridge.git
synced 2024-12-27 08:55:39 +00:00
132 lines
2.8 KiB
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
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|