summaryrefslogtreecommitdiffstats
path: root/vendor/gitlab.com/golang-commonmark/markdown/linkify.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gitlab.com/golang-commonmark/markdown/linkify.go')
-rw-r--r--vendor/gitlab.com/golang-commonmark/markdown/linkify.go131
1 files changed, 131 insertions, 0 deletions
diff --git a/vendor/gitlab.com/golang-commonmark/markdown/linkify.go b/vendor/gitlab.com/golang-commonmark/markdown/linkify.go
new file mode 100644
index 00000000..5935af1b
--- /dev/null
+++ b/vendor/gitlab.com/golang-commonmark/markdown/linkify.go
@@ -0,0 +1,131 @@
+// 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
+ }
+ }
+ }
+ }
+}