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:
		
							parent
							
								
									d259ea48d1
								
							
						
					
					
						commit
						d9d5e51406
					
				| 
						 | 
				
			
			@ -78,7 +78,7 @@ func (p *Presentation) initFuncMap() {
 | 
			
		|||
		// support for URL attributes
 | 
			
		||||
		"pkgLink":     pkgLinkFunc,
 | 
			
		||||
		"srcLink":     srcLinkFunc,
 | 
			
		||||
		"posLink_url": posLink_urlFunc,
 | 
			
		||||
		"posLink_url": newPosLink_urlFunc(srcPosLinkFunc),
 | 
			
		||||
 | 
			
		||||
		// formatting of Examples
 | 
			
		||||
		"example_html":   p.example_htmlFunc,
 | 
			
		||||
| 
						 | 
				
			
			@ -89,6 +89,12 @@ func (p *Presentation) initFuncMap() {
 | 
			
		|||
		// formatting of Notes
 | 
			
		||||
		"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 {
 | 
			
		||||
| 
						 | 
				
			
			@ -232,37 +238,43 @@ func pkgLinkFunc(path string) string {
 | 
			
		|||
	return "pkg/" + relpath // remove trailing '/' for relative URL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// n must be an ast.Node or a *doc.Note
 | 
			
		||||
func posLink_urlFunc(info *PageInfo, n interface{}) string {
 | 
			
		||||
	var pos, end token.Pos
 | 
			
		||||
func newPosLink_urlFunc(srcPosLinkFunc func(s string, line, low, high int) string) func(info *PageInfo, n interface{}) string {
 | 
			
		||||
	// n must be an ast.Node or a *doc.Note
 | 
			
		||||
	return func(info *PageInfo, n interface{}) string {
 | 
			
		||||
		var pos, end token.Pos
 | 
			
		||||
 | 
			
		||||
	switch n := n.(type) {
 | 
			
		||||
	case ast.Node:
 | 
			
		||||
		pos = n.Pos()
 | 
			
		||||
		end = n.End()
 | 
			
		||||
	case *doc.Note:
 | 
			
		||||
		pos = n.Pos
 | 
			
		||||
		end = n.End
 | 
			
		||||
	default:
 | 
			
		||||
		panic(fmt.Sprintf("wrong type for posLink_url template formatter: %T", n))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var relpath string
 | 
			
		||||
	var line int
 | 
			
		||||
	var low, high int // selection offset range
 | 
			
		||||
 | 
			
		||||
	if pos.IsValid() {
 | 
			
		||||
		p := info.FSet.Position(pos)
 | 
			
		||||
		relpath = p.Filename
 | 
			
		||||
		line = p.Line
 | 
			
		||||
		low = p.Offset
 | 
			
		||||
	}
 | 
			
		||||
	if end.IsValid() {
 | 
			
		||||
		high = info.FSet.Position(end).Offset
 | 
			
		||||
		switch n := n.(type) {
 | 
			
		||||
		case ast.Node:
 | 
			
		||||
			pos = n.Pos()
 | 
			
		||||
			end = n.End()
 | 
			
		||||
		case *doc.Note:
 | 
			
		||||
			pos = n.Pos
 | 
			
		||||
			end = n.End
 | 
			
		||||
		default:
 | 
			
		||||
			panic(fmt.Sprintf("wrong type for posLink_url template formatter: %T", n))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var relpath string
 | 
			
		||||
		var line int
 | 
			
		||||
		var low, high int // selection offset range
 | 
			
		||||
 | 
			
		||||
		if pos.IsValid() {
 | 
			
		||||
			p := info.FSet.Position(pos)
 | 
			
		||||
			relpath = p.Filename
 | 
			
		||||
			line = p.Line
 | 
			
		||||
			low = p.Offset
 | 
			
		||||
		}
 | 
			
		||||
		if end.IsValid() {
 | 
			
		||||
			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
 | 
			
		||||
	template.HTMLEscape(&buf, []byte(relpath))
 | 
			
		||||
	template.HTMLEscape(&buf, []byte(s))
 | 
			
		||||
	// selection ranges are of form "s=low:high"
 | 
			
		||||
	if low < high {
 | 
			
		||||
		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 {
 | 
			
		||||
		fmt.Fprintf(&buf, "#L%d", line) // no need for URL escaping
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return buf.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,19 @@ type Presentation struct {
 | 
			
		|||
	// value is provided.
 | 
			
		||||
	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
 | 
			
		||||
	funcMap         template.FuncMap
 | 
			
		||||
	templateFuncs   template.FuncMap
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue