godoc: add ability to override generation of links to source code.

R=bradfitz
CC=golang-dev
https://golang.org/cl/19850046
This commit is contained in:
Brad Garcia 2013-11-01 13:20:32 -04:00
parent d259ea48d1
commit d9d5e51406
2 changed files with 53 additions and 29 deletions

View File

@ -78,7 +78,7 @@ func (p *Presentation) initFuncMap() {
// support for URL attributes // support for URL attributes
"pkgLink": pkgLinkFunc, "pkgLink": pkgLinkFunc,
"srcLink": srcLinkFunc, "srcLink": srcLinkFunc,
"posLink_url": posLink_urlFunc, "posLink_url": newPosLink_urlFunc(srcPosLinkFunc),
// formatting of Examples // formatting of Examples
"example_html": p.example_htmlFunc, "example_html": p.example_htmlFunc,
@ -89,6 +89,12 @@ func (p *Presentation) initFuncMap() {
// formatting of Notes // formatting of Notes
"noteTitle": noteTitle, "noteTitle": noteTitle,
} }
if p.URLForSrc != nil {
p.funcMap["srcLink"] = p.URLForSrc
}
if p.URLForSrcPos != nil {
p.funcMap["posLink_url"] = newPosLink_urlFunc(p.URLForSrcPos)
}
} }
func filenameFunc(path string) string { func filenameFunc(path string) string {
@ -232,37 +238,43 @@ func pkgLinkFunc(path string) string {
return "pkg/" + relpath // remove trailing '/' for relative URL return "pkg/" + relpath // remove trailing '/' for relative URL
} }
// n must be an ast.Node or a *doc.Note func newPosLink_urlFunc(srcPosLinkFunc func(s string, line, low, high int) string) func(info *PageInfo, n interface{}) string {
func posLink_urlFunc(info *PageInfo, n interface{}) string { // n must be an ast.Node or a *doc.Note
var pos, end token.Pos return func(info *PageInfo, n interface{}) string {
var pos, end token.Pos
switch n := n.(type) { switch n := n.(type) {
case ast.Node: case ast.Node:
pos = n.Pos() pos = n.Pos()
end = n.End() end = n.End()
case *doc.Note: case *doc.Note:
pos = n.Pos pos = n.Pos
end = n.End end = n.End
default: default:
panic(fmt.Sprintf("wrong type for posLink_url template formatter: %T", n)) panic(fmt.Sprintf("wrong type for posLink_url template formatter: %T", n))
} }
var relpath string var relpath string
var line int var line int
var low, high int // selection offset range var low, high int // selection offset range
if pos.IsValid() { if pos.IsValid() {
p := info.FSet.Position(pos) p := info.FSet.Position(pos)
relpath = p.Filename relpath = p.Filename
line = p.Line line = p.Line
low = p.Offset low = p.Offset
} }
if end.IsValid() { if end.IsValid() {
high = info.FSet.Position(end).Offset high = info.FSet.Position(end).Offset
}
return srcPosLinkFunc(relpath, line, low, high)
} }
}
func srcPosLinkFunc(s string, line, low, high int) string {
var buf bytes.Buffer var buf bytes.Buffer
template.HTMLEscape(&buf, []byte(relpath)) template.HTMLEscape(&buf, []byte(s))
// selection ranges are of form "s=low:high" // selection ranges are of form "s=low:high"
if low < high { if low < high {
fmt.Fprintf(&buf, "?s=%d:%d", low, high) // no need for URL escaping fmt.Fprintf(&buf, "?s=%d:%d", low, high) // no need for URL escaping
@ -278,7 +290,6 @@ func posLink_urlFunc(info *PageInfo, n interface{}) string {
if line > 0 { if line > 0 {
fmt.Fprintf(&buf, "#L%d", line) // no need for URL escaping fmt.Fprintf(&buf, "#L%d", line) // no need for URL escaping
} }
return buf.String() return buf.String()
} }

View File

@ -49,6 +49,19 @@ type Presentation struct {
// value is provided. // value is provided.
AdjustPageInfoMode func(req *http.Request, mode PageInfoMode) PageInfoMode AdjustPageInfoMode func(req *http.Request, mode PageInfoMode) PageInfoMode
// URLForSrc optionally specifies a function that takes a source file and
// returns a URL for it.
// The source file argument has the form /src/pkg/<path>/<filename>.
URLForSrc func(src string) string
// URLForSrcPos optionally specifies a function to create a URL given a
// source file, a line from the source file (1-based), and low & high offset
// positions (0-based, bytes from beginning of file). Ideally, the returned
// URL will be for the specified line of the file, while the high & low
// positions will be used to highlight a section of the file.
// The source file argument has the form /src/pkg/<path>/<filename>.
URLForSrcPos func(src string, line, low, high int) string
initFuncMapOnce sync.Once initFuncMapOnce sync.Once
funcMap template.FuncMap funcMap template.FuncMap
templateFuncs template.FuncMap templateFuncs template.FuncMap