GoPLS Viewer

Home|gopls/present/link.go
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
5package present
6
7import (
8    "fmt"
9    "log"
10    "net/url"
11    "strings"
12)
13
14func init() {
15    Register("link"parseLink)
16}
17
18type Link struct {
19    Cmd   string // original command from present source
20    URL   *url.URL
21    Label string
22}
23
24func (l LinkPresentCmd() string   { return l.Cmd }
25func (l LinkTemplateName() string { return "link" }
26
27func parseLink(ctx *ContextfileName stringlineno inttext string) (Elemerror) {
28    args := strings.Fields(text)
29    if len(args) < 2 {
30        return nilfmt.Errorf("link element must have at least 2 arguments")
31    }
32    urlerr := url.Parse(args[1])
33    if err != nil {
34        return nilerr
35    }
36    label := ""
37    if len(args) > 2 {
38        label = strings.Join(args[2:], " ")
39    } else {
40        scheme := url.Scheme + "://"
41        if url.Scheme == "mailto" {
42            scheme = "mailto:"
43        }
44        label = strings.Replace(url.String(), scheme""1)
45    }
46    return Link{texturllabel}, nil
47}
48
49func renderLink(hreftext stringstring {
50    text = font(text)
51    if text == "" {
52        text = href
53    }
54    // Open links in new window only when their url is absolute.
55    target := "_blank"
56    if uerr := url.Parse(href); err != nil {
57        log.Println("renderLink parsing url:"err)
58    } else if !u.IsAbs() || u.Scheme == "javascript" {
59        target = "_self"
60    }
61
62    return fmt.Sprintf(`<a href="%s" target="%s">%s</a>`hreftargettext)
63}
64
65// parseInlineLink parses an inline link at the start of s, and returns
66// a rendered HTML link and the total length of the raw inline link.
67// If no inline link is present, it returns all zeroes.
68func parseInlineLink(s string) (link stringlength int) {
69    if !strings.HasPrefix(s"[[") {
70        return
71    }
72    end := strings.Index(s"]]")
73    if end == -1 {
74        return
75    }
76    urlEnd := strings.Index(s"]")
77    rawURL := s[2:urlEnd]
78    const badURLChars = `<>"{}|\^[] ` + "`" // per RFC2396 section 2.4.3
79    if strings.ContainsAny(rawURLbadURLChars) {
80        return
81    }
82    if urlEnd == end {
83        simpleURL := ""
84        urlerr := url.Parse(rawURL)
85        if err == nil {
86            // If the URL is http://foo.com, drop the http://
87            // In other words, render [[http://golang.org]] as:
88            //   <a href="http://golang.org">golang.org</a>
89            if strings.HasPrefix(rawURLurl.Scheme+"://") {
90                simpleURL = strings.TrimPrefix(rawURLurl.Scheme+"://")
91            } else if strings.HasPrefix(rawURLurl.Scheme+":") {
92                simpleURL = strings.TrimPrefix(rawURLurl.Scheme+":")
93            }
94        }
95        return renderLink(rawURLsimpleURL), end + 2
96    }
97    if s[urlEnd:urlEnd+2] != "][" {
98        return
99    }
100    text := s[urlEnd+2 : end]
101    return renderLink(rawURLtext), end + 2
102}
103
MembersX
renderLink.href
parseInlineLink.end
url
renderLink.text
renderLink.u
parseInlineLink.link
Link
parseLink.fileName
parseLink.label
renderLink.target
parseLink.ctx
parseLink.url
renderLink
Link.TemplateName
parseLink.args
parseInlineLink
parseInlineLink.s
parseInlineLink.BlockStmt.url
parseInlineLink.BlockStmt.err
Link.PresentCmd
Link.TemplateName.l
parseLink
renderLink.err
parseInlineLink.urlEnd
parseInlineLink.BlockStmt.simpleURL
log
Link.Cmd
Link.PresentCmd.l
parseLink.text
parseInlineLink.length
Link.URL
Link.Label
parseLink.lineno
parseLink.err
Members
X