github.com/jgarto/itcv@v0.0.0-20180826224514-4eea09c1aa0d/_vendor/src/golang.org/x/tools/present/link.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package present 6 7 import ( 8 "fmt" 9 "log" 10 "net/url" 11 "strings" 12 ) 13 14 func init() { 15 Register("link", parseLink) 16 } 17 18 type Link struct { 19 URL *url.URL 20 Label string 21 } 22 23 func (l Link) TemplateName() string { return "link" } 24 25 func parseLink(ctx *Context, fileName string, lineno int, text string) (Elem, error) { 26 args := strings.Fields(text) 27 if len(args) < 2 { 28 return nil, fmt.Errorf("link element must have at least 2 arguments") 29 } 30 url, err := url.Parse(args[1]) 31 if err != nil { 32 return nil, err 33 } 34 label := "" 35 if len(args) > 2 { 36 label = strings.Join(args[2:], " ") 37 } else { 38 scheme := url.Scheme + "://" 39 if url.Scheme == "mailto" { 40 scheme = "mailto:" 41 } 42 label = strings.Replace(url.String(), scheme, "", 1) 43 } 44 return Link{url, label}, nil 45 } 46 47 func renderLink(href, text string) string { 48 text = font(text) 49 if text == "" { 50 text = href 51 } 52 // Open links in new window only when their url is absolute. 53 target := "_blank" 54 if u, err := url.Parse(href); err != nil { 55 log.Println("renderLink parsing url:", err) 56 } else if !u.IsAbs() || u.Scheme == "javascript" { 57 target = "_self" 58 } 59 60 return fmt.Sprintf(`<a href="%s" target="%s">%s</a>`, href, target, text) 61 } 62 63 // parseInlineLink parses an inline link at the start of s, and returns 64 // a rendered HTML link and the total length of the raw inline link. 65 // If no inline link is present, it returns all zeroes. 66 func parseInlineLink(s string) (link string, length int) { 67 if !strings.HasPrefix(s, "[[") { 68 return 69 } 70 end := strings.Index(s, "]]") 71 if end == -1 { 72 return 73 } 74 urlEnd := strings.Index(s, "]") 75 rawURL := s[2:urlEnd] 76 const badURLChars = `<>"{}|\^[] ` + "`" // per RFC2396 section 2.4.3 77 if strings.ContainsAny(rawURL, badURLChars) { 78 return 79 } 80 if urlEnd == end { 81 simpleUrl := "" 82 url, err := url.Parse(rawURL) 83 if err == nil { 84 // If the URL is http://foo.com, drop the http:// 85 // In other words, render [[http://golang.org]] as: 86 // <a href="http://golang.org">golang.org</a> 87 if strings.HasPrefix(rawURL, url.Scheme+"://") { 88 simpleUrl = strings.TrimPrefix(rawURL, url.Scheme+"://") 89 } else if strings.HasPrefix(rawURL, url.Scheme+":") { 90 simpleUrl = strings.TrimPrefix(rawURL, url.Scheme+":") 91 } 92 } 93 return renderLink(rawURL, simpleUrl), end + 2 94 } 95 if s[urlEnd:urlEnd+2] != "][" { 96 return 97 } 98 text := s[urlEnd+2 : end] 99 return renderLink(rawURL, text), end + 2 100 }