зеркало из https://github.com/golang/tools.git
godoc: Add URLForSrcQuery option to godoc.Presentation.
This allows the creation of URLs to lines of source code with a query term highlighted without assuming godoc source code URL parameters. Needed for interfacing with other source code viewing servers. R=bradfitz CC=golang-dev https://golang.org/cl/34200043
This commit is contained in:
Родитель
df34f98521
Коммит
ff7cfafc58
|
@ -22,6 +22,7 @@ import (
|
|||
"os"
|
||||
pathpkg "path"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
|
@ -80,6 +81,7 @@ func (p *Presentation) initFuncMap() {
|
|||
"srcLink": srcLinkFunc,
|
||||
"posLink_url": newPosLink_urlFunc(srcPosLinkFunc),
|
||||
"docLink": docLinkFunc,
|
||||
"queryLink": queryLinkFunc,
|
||||
|
||||
// formatting of Examples
|
||||
"example_html": p.example_htmlFunc,
|
||||
|
@ -96,6 +98,9 @@ func (p *Presentation) initFuncMap() {
|
|||
if p.URLForSrcPos != nil {
|
||||
p.funcMap["posLink_url"] = newPosLink_urlFunc(p.URLForSrcPos)
|
||||
}
|
||||
if p.URLForSrcQuery != nil {
|
||||
p.funcMap["queryLink"] = p.URLForSrcQuery
|
||||
}
|
||||
}
|
||||
|
||||
func filenameFunc(path string) string {
|
||||
|
@ -298,6 +303,19 @@ func srcLinkFunc(s string) string {
|
|||
return pathpkg.Clean("/" + s)
|
||||
}
|
||||
|
||||
// queryLinkFunc returns a URL for a line in a source file with a highlighted
|
||||
// query term.
|
||||
// s is expected to be a path to a source file.
|
||||
// query is expected to be a string that has already been appropriately escaped
|
||||
// for use in a URL query.
|
||||
func queryLinkFunc(s, query string, line int) string {
|
||||
url := pathpkg.Clean("/"+s) + "?h=" + query
|
||||
if line > 0 {
|
||||
url += "#L" + strconv.Itoa(line)
|
||||
}
|
||||
return url
|
||||
}
|
||||
|
||||
func docLinkFunc(s string, ident string) string {
|
||||
s = strings.TrimPrefix(s, "/src")
|
||||
return pathpkg.Clean("/"+s) + "/#" + ident
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright 2013 The Go 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 godoc
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPkgLinkFunc(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
path string
|
||||
want string
|
||||
}{
|
||||
{"/src/pkg/fmt", "pkg/fmt"},
|
||||
{"/fmt", "pkg/fmt"},
|
||||
} {
|
||||
if got, want := pkgLinkFunc(tc.path), tc.want; got != want {
|
||||
t.Errorf("pkgLinkFunc(%v) = %v; want %v", tc.path, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSrcPosLinkFunc(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
src string
|
||||
line int
|
||||
low int
|
||||
high int
|
||||
want string
|
||||
}{
|
||||
{"/src/pkg/fmt/print.go", 42, 30, 50, "/src/pkg/fmt/print.go?s=30:50#L32"},
|
||||
{"/src/pkg/fmt/print.go", 2, 1, 5, "/src/pkg/fmt/print.go?s=1:5#L1"},
|
||||
{"/src/pkg/fmt/print.go", 2, 0, 0, "/src/pkg/fmt/print.go#L2"},
|
||||
{"/src/pkg/fmt/print.go", 0, 0, 0, "/src/pkg/fmt/print.go"},
|
||||
{"/src/pkg/fmt/print.go", 0, 1, 5, "/src/pkg/fmt/print.go?s=1:5#L1"},
|
||||
} {
|
||||
if got, want := srcPosLinkFunc(tc.src, tc.line, tc.low, tc.high), tc.want; got != want {
|
||||
t.Errorf("srcLinkFunc(%v, %v, %v, %v) = %v; want %v", tc.src, tc.line, tc.low, tc.high, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSrcLinkFunc(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
src string
|
||||
want string
|
||||
}{
|
||||
{"/src/pkg/fmt/print.go", "/src/pkg/fmt/print.go"},
|
||||
{"src/pkg/fmt/print.go", "/src/pkg/fmt/print.go"},
|
||||
} {
|
||||
if got, want := srcLinkFunc(tc.src), tc.want; got != want {
|
||||
t.Errorf("srcLinkFunc(%v) = %v; want %v", tc.src, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryLinkFunc(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
src string
|
||||
query string
|
||||
line int
|
||||
want string
|
||||
}{
|
||||
{"/src/pkg/fmt/print.go", "Sprintf", 33, "/src/pkg/fmt/print.go?h=Sprintf#L33"},
|
||||
{"/src/pkg/fmt/print.go", "Sprintf", 0, "/src/pkg/fmt/print.go?h=Sprintf"},
|
||||
{"src/pkg/fmt/print.go", "EOF", 33, "/src/pkg/fmt/print.go?h=EOF#L33"},
|
||||
{"src/pkg/fmt/print.go", "a%3f+%26b", 1, "/src/pkg/fmt/print.go?h=a%3f+%26b#L1"},
|
||||
} {
|
||||
if got, want := queryLinkFunc(tc.src, tc.query, tc.line), tc.want; got != want {
|
||||
t.Errorf("queryLinkFunc(%v, %v, %v) = %v; want %v", tc.src, tc.query, tc.line, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocLinkFunc(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
src string
|
||||
ident string
|
||||
want string
|
||||
}{
|
||||
{"/src/pkg/fmt", "Sprintf", "/pkg/fmt/#Sprintf"},
|
||||
{"/src/pkg/fmt", "EOF", "/pkg/fmt/#EOF"},
|
||||
} {
|
||||
if got, want := docLinkFunc(tc.src, tc.ident), tc.want; got != want {
|
||||
t.Errorf("docLinkFunc(%v, %v) = %v; want %v", tc.src, tc.ident, got, want)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -67,6 +67,15 @@ type Presentation struct {
|
|||
// The source file argument has the form /src/pkg/<path>/<filename>.
|
||||
URLForSrcPos func(src string, line, low, high int) string
|
||||
|
||||
// URLForSrcQuery optionally specifies a function to create a URL given a
|
||||
// source file, a query string, and a line from the source file (1-based).
|
||||
// The source file argument has the form /src/pkg/<path>/<filename>.
|
||||
// The query argument will be escaped for the purposes of embedding in a URL
|
||||
// query parameter.
|
||||
// Ideally, the returned URL will be for the specified line of the file with
|
||||
// the query string highlighted.
|
||||
URLForSrcQuery func(src, query string, line int) string
|
||||
|
||||
initFuncMapOnce sync.Once
|
||||
funcMap template.FuncMap
|
||||
templateFuncs template.FuncMap
|
||||
|
|
|
@ -50,10 +50,11 @@
|
|||
{{$pkg_html := pkgLink .Pak.Path | html}}
|
||||
<h3 id="Global_{{$pkg_html}}">package <a href="/{{$pkg_html}}">{{html .Pak.Name}}</a></h3>
|
||||
{{range .Files}}
|
||||
{{$src_html := srcLink .File.Path | html}}
|
||||
{{$file := .File.Path}}
|
||||
{{range .Groups}}
|
||||
{{range .}}
|
||||
<a href="{{$src_html}}?h={{$query_url}}#L{{infoLine .}}">{{$src_html}}:{{infoLine .}}</a>
|
||||
{{$line := infoLine .}}
|
||||
<a href="{{queryLink $file $query_url $line | html}}">{{$file}}:{{$line}}</a>
|
||||
{{infoSnippet_html .}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
@ -66,8 +67,8 @@
|
|||
{{$pkg_html := pkgLink .Pak.Path | html}}
|
||||
<h3 id="Local_{{$pkg_html}}">package <a href="/{{$pkg_html}}">{{html .Pak.Name}}</a></h3>
|
||||
{{range .Files}}
|
||||
{{$src_html := srcLink .File.Path | html}}
|
||||
<a href="{{$src_html}}?h={{$query_url}}">{{$src_html}}</a>
|
||||
{{$file := .File.Path}}
|
||||
<a href="{{queryLink $file $query_url 0 | html}}">{{$file}}</a>
|
||||
<table class="layout">
|
||||
{{range .Groups}}
|
||||
<tr>
|
||||
|
@ -76,7 +77,8 @@
|
|||
<td align="left" width="4"></td>
|
||||
<td>
|
||||
{{range .}}
|
||||
<a href="{{$src_html}}?h={{$query_url}}#L{{infoLine .}}">{{infoLine .}}</a>
|
||||
{{$line := infoLine .}}
|
||||
<a href="{{queryLink $file $query_url $line | html}}">{{$line}}</a>
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -98,17 +100,17 @@
|
|||
<p>
|
||||
<table class="layout">
|
||||
{{range .}}
|
||||
{{$src_html := srcLink .Filename | html}}
|
||||
{{$file := .Filename}}
|
||||
<tr>
|
||||
<td align="left" valign="top">
|
||||
<a href="{{$src_html}}?h={{$query_url}}">{{$src_html}}</a>:
|
||||
<a href="{{queryLink $file $query_url 0}}">{{$file}}</a>:
|
||||
</td>
|
||||
<td align="left" width="4"></td>
|
||||
<th align="left" valign="top">{{len .Lines}}</th>
|
||||
<td align="left" width="4"></td>
|
||||
<td align="left">
|
||||
{{range .Lines}}
|
||||
<a href="{{$src_html}}?h={{$query_url}}#L{{html .}}">{{html .}}</a>
|
||||
<a href="{{queryLink $file $query_url .}}">{{html .}}</a>
|
||||
{{end}}
|
||||
{{if not $.Complete}}
|
||||
...
|
||||
|
|
|
@ -1413,10 +1413,11 @@ function PlaygroundOutput(el) {
|
|||
{{$pkg_html := pkgLink .Pak.Path | html}}
|
||||
<h3 id="Global_{{$pkg_html}}">package <a href="/{{$pkg_html}}">{{html .Pak.Name}}</a></h3>
|
||||
{{range .Files}}
|
||||
{{$src_html := srcLink .File.Path | html}}
|
||||
{{$file := .File.Path}}
|
||||
{{range .Groups}}
|
||||
{{range .}}
|
||||
<a href="{{$src_html}}?h={{$query_url}}#L{{infoLine .}}">{{$src_html}}:{{infoLine .}}</a>
|
||||
{{$line := infoLine .}}
|
||||
<a href="{{queryLink $file $query_url $line | html}}">{{$file}}:{{$line}}</a>
|
||||
{{infoSnippet_html .}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
@ -1429,8 +1430,8 @@ function PlaygroundOutput(el) {
|
|||
{{$pkg_html := pkgLink .Pak.Path | html}}
|
||||
<h3 id="Local_{{$pkg_html}}">package <a href="/{{$pkg_html}}">{{html .Pak.Name}}</a></h3>
|
||||
{{range .Files}}
|
||||
{{$src_html := srcLink .File.Path | html}}
|
||||
<a href="{{$src_html}}?h={{$query_url}}">{{$src_html}}</a>
|
||||
{{$file := .File.Path}}
|
||||
<a href="{{queryLink $file $query_url 0 | html}}">{{$file}}</a>
|
||||
<table class="layout">
|
||||
{{range .Groups}}
|
||||
<tr>
|
||||
|
@ -1439,7 +1440,8 @@ function PlaygroundOutput(el) {
|
|||
<td align="left" width="4"></td>
|
||||
<td>
|
||||
{{range .}}
|
||||
<a href="{{$src_html}}?h={{$query_url}}#L{{infoLine .}}">{{infoLine .}}</a>
|
||||
{{$line := infoLine .}}
|
||||
<a href="{{queryLink $file $query_url $line | html}}">{{$line}}</a>
|
||||
{{end}}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -1461,17 +1463,17 @@ function PlaygroundOutput(el) {
|
|||
<p>
|
||||
<table class="layout">
|
||||
{{range .}}
|
||||
{{$src_html := srcLink .Filename | html}}
|
||||
{{$file := .Filename}}
|
||||
<tr>
|
||||
<td align="left" valign="top">
|
||||
<a href="{{$src_html}}?h={{$query_url}}">{{$src_html}}</a>:
|
||||
<a href="{{queryLink $file $query_url 0}}">{{$file}}</a>:
|
||||
</td>
|
||||
<td align="left" width="4"></td>
|
||||
<th align="left" valign="top">{{len .Lines}}</th>
|
||||
<td align="left" width="4"></td>
|
||||
<td align="left">
|
||||
{{range .Lines}}
|
||||
<a href="{{$src_html}}?h={{$query_url}}#L{{html .}}">{{html .}}</a>
|
||||
<a href="{{queryLink $file $query_url .}}">{{html .}}</a>
|
||||
{{end}}
|
||||
{{if not $.Complete}}
|
||||
...
|
||||
|
|
Загрузка…
Ссылка в новой задаче