diff options
Diffstat (limited to 'vendor/gitlab.com/golang-commonmark/markdown/linkify.go')
-rw-r--r-- | vendor/gitlab.com/golang-commonmark/markdown/linkify.go | 131 |
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 + } + } + } + } +} |