1
0
mirror of https://github.com/golang/go synced 2024-11-21 21:04:41 -07:00

godoc: first round of template cleanups

- simplified pipelines
- simplified templates by using template variables
- converted most old-style formatters into new-style funcs
- fixed some escaping bugs (use of url escaping where it was missing)

R=r, dsymonds
CC=golang-dev
https://golang.org/cl/4868044
This commit is contained in:
Robert Griesemer 2011-08-12 10:06:32 -07:00
parent 4abbdc0399
commit 5233c50321
11 changed files with 150 additions and 201 deletions

View File

@ -19,7 +19,7 @@
</a>
<select id="code-selector">
{{range .File}}
<option value="/doc/codewalk/?fileprint=/{{.|urlquery_esc}}">{{.|html_esc}}</option>
<option value="/doc/codewalk/?fileprint=/{{url .}}">{{html .}}</option>
{{end}}
</select>
</div>
@ -37,15 +37,15 @@
<div id="comment-area">
{{range .Step}}
<div class="comment first last">
<a class="comment-link" href="/doc/codewalk/?fileprint=/{{.File|urlquery_esc}}&lo={{.Lo|html_esc}}&hi={{.Hi|html_esc}}#mark" target="code-display"></a>
<div class="comment-title">{{.Title|html_esc}}</div>
<a class="comment-link" href="/doc/codewalk/?fileprint=/{{url .File}}&lo={{url .Lo}}&hi={{url .Hi}}#mark" target="code-display"></a>
<div class="comment-title">{{html .Title}}</div>
<div class="comment-text">
{{with .Err}}
ERROR LOADING FILE: {{.|html_esc}}<br/><br/>
ERROR LOADING FILE: {{html .}}<br/><br/>
{{end}}
{{.XML}}
</div>
<div class="comment-text file-name"><span class="path-file">{{.|html_esc}}</span></div>
<div class="comment-text file-name"><span class="path-file">{{html .}}</span></div>
</div>
{{end}}
</div>

View File

@ -7,9 +7,9 @@
<table class="layout">
{{range .}}
<tr>
<td><a href="{{.Name|html_esc}}">{{.Name|html_esc}}</a></td>
<td><a href="{{url .Name}}">{{html .Name}}</a></td>
<td width="25">&nbsp;</td>
<td>{{.Title|html_esc}}</td>
<td>{{html .Title}}</td>
</tr>
{{end}}
</table>

View File

@ -18,11 +18,11 @@
</tr>
{{range .}}
<tr>
<td align="left"><a href="{{.|fileInfoName}}">{{.|fileInfoName}}</a></td>
<td align="left"><a href="{{.|fileInfoName|url}}">{{.|fileInfoName|html}}</a></td>
<td></td>
<td align="right">{{.|fileInfoSize}}</td>
<td align="right">{{html .Size}}</td>
<td></td>
<td align="left">{{.|fileInfoTime}}</td>
<td align="left">{{.|fileInfoTime|html}}</td>
</tr>
{{end}}

View File

@ -5,5 +5,5 @@
-->
<p>
<span class="alert" style="font-size:120%">{{.|html_esc}}</span>
<span class="alert" style="font-size:120%">{{html .}}</span>
</p>

View File

@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
{{with .Title}}
<title>{{.|html_esc}} - The Go Programming Language</title>
<title>{{html .}} - The Go Programming Language</title>
{{else}}
<title>The Go Programming Language</title>
{{end}}
@ -25,7 +25,7 @@
<form method="GET" action="/search">
{{with .PkgRoots}}
{{range .PkgRoots}}
<a href="/pkg/{{.|html_esc}}">{{.|html_esc}}</a> <span class="sep">|</span>
<a href="/pkg/{{html .}}">{{html .}}</a> <span class="sep">|</span>
{{end}}
{{else}}
References:
@ -34,7 +34,7 @@
<a href="/cmd/">Commands</a> <span class="sep">|</span>
<a href="/doc/go_spec.html">Specification</a>
{{if .SearchBox}}
<input id="search" type="search" name="q" value="{{if .Query}}{{.Query|html_esc}}{{end}}" class="{{if .Query}}{{else}}inactive{{end}}" placeholder="code search" results="0" />
<input id="search" type="search" name="q" value="{{with .Query}}{{html .}}{{end}}" class="{{if not .Query}}inactive{{end}}" placeholder="code search" results="0" />
{{end}}
</form>
</div>
@ -50,10 +50,10 @@
{{end}}
{{with .Title}}
<h1 id="generatedHeader">{{.|html_esc}}</h1>
<h1 id="generatedHeader">{{html .}}</h1>
{{end}}
{{with .Subtitle}}
<span class="subtitle">{{.|html_esc}}</span>
<span class="subtitle">{{html .}}</span>
{{end}}
<!-- The Table of Contents is automatically inserted in this <div>.
@ -64,7 +64,7 @@
{{printf "%s" .Content}}
</div>
<div id="site-info">
<p>Build version {{.Version|html_esc}}. Except as noted, this content is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License</a>.</p>
<p>Build version {{html .Version}}. Except as noted, this content is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License</a>.</p>
</div>
</div>
</body>

View File

@ -3,26 +3,22 @@
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->
{{$FSet := .FSet}}
{{$Info := .}}
{{with .PAst}}
<pre>{{html_esc . $FSet}}</pre>
<pre>{{html_node . $.FSet}}</pre>
{{end}}
{{with .PDoc}}
<!-- PackageName is printed as title by the top-level template -->
{{if $Info.IsPkg}}
{{/* ImportPath is a string - no need for FSet */}}
<p><code>import "{{.ImportPath|html_esc}}"</code></p>
{{if $.IsPkg}}
<p><code>import "{{html .ImportPath}}"</code></p>
{{end}}
{{.Doc|html_comment}}
{{if $Info.IsPkg}}
{{html_comment .Doc}}
{{if $.IsPkg}}
{{with .Filenames}}
{{/* Filenames are strings - no need for FSet */}}
<p>
<h4>Package files</h4>
<span style="font-size:90%">
{{range .}}
<a href="/{{.|url_src}}">{{.|localname}}</a>
<a href="/{{url_src .}}">{{.|localname|html}}</a>
{{end}}
</span>
</p>
@ -32,53 +28,57 @@
<h2 id="Constants">Constants</h2>
{{range .}}
{{html_comment .Doc}}
<pre>{{html_esc .Decl $FSet}}</pre>
<pre>{{html_node .Decl $.FSet}}</pre>
{{end}}
{{end}}
{{with .Vars}}
<h2 id="Variables">Variables</h2>
{{range .}}
{{html_comment .Doc}}
<pre>{{html_esc .Decl $FSet}}</pre>
<pre>{{html_node .Decl $.FSet}}</pre>
{{end}}
{{end}}
{{with .Funcs}}
{{range .}}
{{/* Name is a string - no need for FSet */}}
<h2 id="{{.Name|html_esc}}">func <a href="/{{url_pos .Decl $FSet}}">{{.Name|html_esc}}</a></h2>
<p><code>{{html_esc .Decl $FSet}}</code></p>
{{.Doc|html_comment}}
{{$name := html .Name}}
<h2 id="{{$name}}">func <a href="/{{url_pos .Decl $.FSet}}">{{$name}}</a></h2>
<p><code>{{html_node .Decl $.FSet}}</code></p>
{{html_comment .Doc}}
{{end}}
{{end}}
{{with .Types}}
{{range $type := .}}
<h2 id="{{html_esc .Type.Name $FSet}}">type <a href="/{{url_pos .Decl $FSet}}">{{html_esc .Type.Name $FSet}}</a></h2>
{{.Doc|html_comment}}
<p><pre>{{html_esc .Decl $FSet}}</pre></p>
{{range .}}
{{$tname := html_node .Type.Name $.FSet}}
<h2 id="{{$tname}}">type <a href="/{{url_pos .Decl $.FSet}}">{{$tname}}</a></h2>
{{html_comment .Doc}}
<p><pre>{{html_node .Decl $.FSet}}</pre></p>
{{range .Consts}}
{{.Doc|html_comment}}
<pre>{{html_esc .Decl $FSet}}</pre>
{{html_comment .Doc}}
<pre>{{html_node .Decl $.FSet}}</pre>
{{end}}
{{range .Vars}}
{{.Doc|html_comment}}
<pre>{{html_esc .Decl $FSet}}</pre>
{{html_comment .Doc}}
<pre>{{html_node .Decl $.FSet}}</pre>
{{end}}
{{range .Factories}}
<h3 id="{{html_esc $type.Type.Name $FSet}}.{{.Name|html_esc}}">func <a href="/{{url_pos .Decl $FSet}}">{{.Name|html_esc}}</a></h3>
<p><code>{{html_esc .Decl $FSet}}</code></p>
{{.Doc|html_comment}}
{{$name := html .Name}}
<h3 id="{{$tname}}.{{$name}}">func <a href="/{{url_pos .Decl $.FSet}}">{{$name}}</a></h3>
<p><code>{{html_node .Decl $.FSet}}</code></p>
{{html_comment .Doc}}
{{end}}
{{range .Methods}}
<h3 id="{{html_esc $type.Type.Name $FSet}}.{{.Name|html_esc}}">func ({{html_esc .Recv $FSet}}) <a href="/{{url_pos .Decl $FSet}}">{{.Name|html_esc}}</a></h3>
<p><code>{{html_esc .Decl $FSet}}</code></p>
{{.Doc|html_comment}}
{{$name := html .Name}}
<h3 id="{{$tname}}.{{$name}}">func ({{html_node .Recv $.FSet}}) <a href="/{{url_pos .Decl $.FSet}}">{{$name}}</a></h3>
<p><code>{{html_node .Decl $.FSet}}</code></p>
{{html_comment .Doc}}
{{end}}
{{end}}
{{end}}
{{with .Bugs}}
<h2 id="Bugs">Bugs</h2>
{{range .}}
{{.|html_comment}}
{{html_comment .}}
{{end}}
{{end}}
{{end}}
@ -87,7 +87,7 @@
<p>
{{/* PList entries are strings - no need for FSet */}}
{{range .}}
<a href="?p={{html .}}">{{html .}}</a><br />
<a href="?p={{url .}}">{{html .}}</a><br />
{{end}}
</p>
{{end}}
@ -102,7 +102,7 @@
<p>
<table class="layout">
<tr>
<th align="left" colspan="{{.MaxHeight|html_esc}}">Name</th>
<th align="left" colspan="{{html .MaxHeight}}">Name</th>
<td width="25">&nbsp;</td>
<th align="left">Synopsis</th>
</tr>
@ -111,7 +111,7 @@
</tr>
{{range .List}}
<tr>
{{.Depth|padding}}
{{repeat `<td width="25"></td>` .Depth}}
<td align="left" colspan="{{html .Height}}"><a href="{{html .Path}}">{{html .Name}}</a></td>
<td></td>
<td align="left">{{html .Synopsis}}</td>

View File

@ -2,7 +2,7 @@
---------------------------------------
*/}}{{with .PAst}}{{text . $FSet}}{{end}}{{/*
*/}}{{with .PAst}}{{text_node . $FSet}}{{end}}{{/*
---------------------------------------
@ -16,7 +16,7 @@ import "{{.ImportPath}}"
---------------------------------------
*/}}{{with .Doc}}{{text . $FSet}}
*/}}{{with .Doc}}{{text_node . $FSet}}
{{end}}{{/*
---------------------------------------
@ -24,7 +24,7 @@ import "{{.ImportPath}}"
*/}}{{with .Consts}}
CONSTANTS
{{range .}}{{text .Decl $FSet}}
{{range .}}{{text_node .Decl $FSet}}
{{.Doc}}{{end}}
{{end}}{{/*
@ -33,7 +33,7 @@ CONSTANTS
*/}}{{with .Vars}}
VARIABLES
{{range .}}{{text .Decl $FSet}}
{{range .}}{{text_node .Decl $FSet}}
{{.Doc}}{{end}}
{{end}}{{/*
@ -42,7 +42,7 @@ VARIABLES
*/}}{{with .Funcs}}
FUNCTIONS
{{range .}}{{text .Decl $FSet}}
{{range .}}{{text_node .Decl $FSet}}
{{.Doc}}
{{end}}{{end}}{{/*
@ -51,15 +51,15 @@ FUNCTIONS
*/}}{{with .Types}}
TYPES
{{range .}}{{text .Decl $FSet}}
{{range .}}{{text_node .Decl $FSet}}
{{.Doc}}
{{range .Consts}}{{text .Decl $FSet}}
{{range .Consts}}{{text_node .Decl $FSet}}
{{.Doc}}
{{end}}{{range .Vars}}{{text .Decl $FSet}}
{{end}}{{range .Vars}}{{text_node .Decl $FSet}}
{{.Doc}}
{{end}}{{range .Factories}}{{text .Decl $FSet}}
{{end}}{{range .Factories}}{{text_node .Decl $FSet}}
{{.Doc}}
{{end}}{{range .Methods}}{{text .Decl $FSet}}
{{end}}{{range .Methods}}{{text_node .Decl $FSet}}
{{.Doc}}
{{end}}{{end}}{{end}}{{/*

View File

@ -13,7 +13,7 @@
<p>
<span class="alert" style="font-size:120%">Did you mean: </span>
{{range .Alts}}
<a href="search?q={{.|urlquery_esc}}" style="font-size:120%">{{.|html_esc}}</a>
<a href="search?q={{url .}}" style="font-size:120%">{{html .}}</a>
{{end}}
</p>
{{end}}
@ -21,12 +21,13 @@
{{with .Decls}}
<h2 id="Global">Package-level declarations</h2>
{{range .}}
<h3 id="Global_{{.Pak.Path|url_pkg}}">package <a href="/{{.Pak.Path|url_pkg}}">{{.Pak.Name|html_esc}}</a></h3>
{{range $File := .Files}}
<h3 id="Global_{{url_pkg .Pak.Path}}">package <a href="/{{url_pkg .Pak.Path}}">{{html .Pak.Name}}</a></h3>
{{range .Files}}
{{$path := url_src .File.Path}}
{{range .Groups}}
{{range .Infos}}
<a href="/{{$File.File.Path|url_src}}?h={{$SearchResult.Query|urlquery_esc}}#L{{.|infoLine}}">{{$File.File.Path|url_src}}:{{.|infoLine}}</a>
{{.|infoSnippet}}
<a href="/{{$path}}?h={{url $SearchResult.Query}}#L{{infoLine .}}">{{$path}}:{{infoLine .}}</a>
{{infoSnippet .}}
{{end}}
{{end}}
{{end}}
@ -35,18 +36,19 @@
{{with .Others}}
<h2 id="Local">Local declarations and uses</h2>
{{range .}}
<h3 id="Local_{{.Pak.Path|url_pkg}}">package <a href="/{{.Pak.Path|url_pkg}}">{{.Pak.Name|html_esc}}</a></h3>
{{range $File := .Files}}
<a href="/{{.File.Path|url_src}}?h={{$SearchResult.Query|urlquery_esc}}">{{.File.Path|url_src}}</a>
<h3 id="Local_{{url_pkg .Pak.Path}}">package <a href="/{{url_pkg .Pak.Path}}">{{html .Pak.Name}}</a></h3>
{{range .Files}}
{{$path := url_src .File.Path}}
<a href="/{{$path}}?h={{url $SearchResult.Query}}">{{$path}}</a>
<table class="layout">
{{range .Groups}}
<tr>
<td width="25"></td>
<th align="left" valign="top">{{.Kind|infoKind}}</th>
<th align="left" valign="top">{{infoKind .Kind}}</th>
<td align="left" width="4"></td>
<td>
{{range .Infos}}
<a href="/{{$File.File.Path|url_src}}?h={{$SearchResult.Query|urlquery_esc}}#L{{.|infoLine}}">{{.|infoLine}}</a>
<a href="/{{$path}}?h={{url $SearchResult.Query}}#L{{infoLine .}}">{{infoLine .}}</a>
{{end}}
</td>
</tr>
@ -58,26 +60,27 @@
{{end}}
{{with .Textual}}
{{if $SearchResult.Complete}}
<h2 id="Textual">{{$SearchResult.Found|html_esc}} textual occurrences</h2>
<h2 id="Textual">{{html $SearchResult.Found}} textual occurrences</h2>
{{else}}
<h2 id="Textual">More than {{$SearchResult.Found|html_esc}} textual occurrences</h2>
<h2 id="Textual">More than {{html $SearchResult.Found}} textual occurrences</h2>
<p>
<span class="alert" style="font-size:120%">Not all files or lines containing "{{$SearchResult.Query|html_esc}}" are shown.</span>
<span class="alert" style="font-size:120%">Not all files or lines containing "{{html $SearchResult.Query}}" are shown.</span>
</p>
{{end}}
<p>
<table class="layout">
{{range $File := .}}
{{range .}}
{{$path := url_src .Filename}}
<tr>
<td align="left" valign="top">
<a href="/{{.Filename|url_src}}?h={{$SearchResult.Query|urlquery_esc}}">{{.Filename|url_src}}</a>:
<a href="/{{$path}}?h={{url $SearchResult.Query}}">{{$path}}</a>:
</td>
<td align="left" width="4"></td>
<th align="left" valign="top">{{.Lines|numlines}}</th>
<th align="left" valign="top">{{len .Lines}}</th>
<td align="left" width="4"></td>
<td align="left">
{{range .Lines}}
<a href="/{{$File.Filename|url_src}}?h={{$SearchResult.Query|urlquery_esc}}#L{{.|html_esc}}">{{.|html_esc}}</a>
<a href="/{{$path}}?h={{url $SearchResult.Query}}#L{{url .}}">{{html .}}</a>
{{end}}
{{if not $SearchResult.Complete}}
...

View File

@ -17,8 +17,9 @@ DID YOU MEAN
PACKAGE-LEVEL DECLARATIONS
{{range .}}package {{.Pak.Name}}
{{range $File := .Files}}{{range .Groups}}{{range .Infos}} {{$File.File.Path|url_src}}:{{.|infoLine}}{{end}}
{{end}}{{end}}{{/* .Files */}}{{end}}{{end}}{{/* .Decls */}}{{/*
{{range $File := .Files}}{{range .Groups}}{{range .Infos}} {{url_src $File.File.Path}}:{{infoLine .}}{{end}}
{{end}}{{end}}{{/* .Files */}}
{{end}}{{end}}{{/* .Decls */}}{{/*
---------------------------------------
@ -26,7 +27,7 @@ PACKAGE-LEVEL DECLARATIONS
LOCAL DECLARATIONS AND USES
{{range .}}package {{.Pak.Name}}
{{range $File := .Files}}{{range .Groups}}{{range .Infos}} {{$File.File.Path|url_src}}:{{.|infoLine}}
{{range $File := .Files}}{{range .Groups}}{{range .Infos}} {{url_src $File.File.Path}}:{{infoLine .}}
{{end}}{{end}}{{end}}{{/* .Files */}}
{{end}}{{end}}{{/* .Others */}}{{end}}{{/* .Hit */}}{{/*
@ -34,6 +35,6 @@ LOCAL DECLARATIONS AND USES
*/}}{{if .Textual}}{{if .Complete}}{{.Found}} TEXTUAL OCCURRENCES{{else}}MORE THAN {{.Found}} TEXTUAL OCCURRENCES{{end}}
{{range .Textual}}{{.Lines|numlines}} {{.Filename|url_src}}
{{range .Textual}}{{len .Lines}} {{url_src .Filename}}
{{end}}{{if not .Complete}}... ...
{{end}}{{end}}

View File

@ -371,38 +371,6 @@ func writeNode(w io.Writer, fset *token.FileSet, x interface{}) {
(&printer.Config{mode, *tabwidth}).Fprint(&tconv{output: w}, fset, x)
}
// Write anything to w.
func writeAny(w io.Writer, fset *token.FileSet, x interface{}) {
switch v := x.(type) {
case []byte:
w.Write(v)
case string:
w.Write([]byte(v))
case ast.Decl, ast.Expr, ast.Stmt, *ast.File:
writeNode(w, fset, x)
default:
fmt.Fprint(w, x)
}
}
// Write anything html-escaped to w.
func writeAnyHTML(w io.Writer, fset *token.FileSet, x interface{}) {
switch v := x.(type) {
case []byte:
template.HTMLEscape(w, v)
case string:
template.HTMLEscape(w, []byte(v))
case ast.Decl, ast.Expr, ast.Stmt, *ast.File:
var buf bytes.Buffer
writeNode(&buf, fset, x)
FormatText(w, buf.Bytes(), -1, true, "", nil)
default:
var buf bytes.Buffer
fmt.Fprint(&buf, x)
template.HTMLEscape(w, buf.Bytes())
}
}
func fileset(x []interface{}) *token.FileSet {
if len(x) > 1 {
if fset, ok := x[1].(*token.FileSet); ok {
@ -412,32 +380,6 @@ func fileset(x []interface{}) *token.FileSet {
return nil
}
// Template formatter for "html-esc" format.
func htmlEscFmt(w io.Writer, format string, x ...interface{}) {
writeAnyHTML(w, fileset(x), x[0])
}
// Template formatter for "html-comment" format.
func htmlCommentFmt(w io.Writer, format string, x ...interface{}) {
var buf bytes.Buffer
writeAny(&buf, fileset(x), x[0])
// TODO(gri) Provide list of words (e.g. function parameters)
// to be emphasized by ToHTML.
doc.ToHTML(w, buf.Bytes(), nil) // does html-escaping
}
// Template formatter for "" (default) format.
func textFmt(w io.Writer, format string, x ...interface{}) {
writeAny(w, fileset(x), x[0])
}
// Template formatter for "urlquery-esc" format.
func urlQueryEscFmt(w io.Writer, format string, x ...interface{}) {
var buf bytes.Buffer
writeAny(&buf, fileset(x), x[0])
template.HTMLEscape(w, []byte(http.URLEscape(string(buf.Bytes()))))
}
// Template formatter for the various "url-xxx" formats excluding url-esc.
func urlFmt(w io.Writer, format string, x ...interface{}) {
var path string
@ -559,56 +501,17 @@ func infoSnippetFmt(w io.Writer, format string, x ...interface{}) {
w.Write(text)
}
// Template formatter for "padding" format.
func paddingFmt(w io.Writer, format string, x ...interface{}) {
for i := x[0].(int); i > 0; i-- {
fmt.Fprint(w, `<td width="25"></td>`)
}
}
// Template formatter for "localname" format.
func localnameFmt(w io.Writer, format string, x ...interface{}) {
_, localname := filepath.Split(x[0].(string))
template.HTMLEscape(w, []byte(localname))
}
// Template formatter for "fileInfoName" format.
func fileInfoNameFmt(w io.Writer, format string, x ...interface{}) {
fi := x[0].(FileInfo)
template.HTMLEscape(w, []byte(fi.Name()))
if fi.IsDirectory() {
w.Write([]byte{'/'})
}
}
// Template formatter for "fileInfoSize" format.
func fileInfoSizeFmt(w io.Writer, format string, x ...interface{}) {
fmt.Fprintf(w, "%d", x[0].(FileInfo).Size())
}
// Template formatter for "fileInfoTime" format.
func fileInfoTimeFmt(w io.Writer, format string, x ...interface{}) {
if t := x[0].(FileInfo).Mtime_ns(); t != 0 {
template.HTMLEscape(w, []byte(time.SecondsToLocalTime(t/1e9).String()))
}
// don't print epoch if time is obviously not set
}
// Template formatter for "numlines" format.
func numlinesFmt(w io.Writer, format string, x ...interface{}) {
list := x[0].([]int)
fmt.Fprintf(w, "%d", len(list))
}
// TODO(gri): Remove this type once fmtMap2funcMap is gone.
type FormatterMap map[string]func(io.Writer, string, ...interface{})
// TODO(gri): Remove the need for this conversion function by rewriting
// the old template formatters into new template functions.
func fmtMap2funcMap(fmtMap FormatterMap) template.FuncMap {
funcMap := make(template.FuncMap)
func append2funcMap(funcMap template.FuncMap, fmtMap FormatterMap) template.FuncMap {
for n, f := range fmtMap {
name, fmt := n, f // separate instance of name, fmt for each closure!
if _, ok := funcMap[name]; ok {
panic("function already in map: " + name)
}
funcMap[name] = func(args ...interface{}) string {
var buf bytes.Buffer
fmt(&buf, name, args...)
@ -618,23 +521,63 @@ func fmtMap2funcMap(fmtMap FormatterMap) template.FuncMap {
return funcMap
}
var fmap = fmtMap2funcMap(FormatterMap{
"text": textFmt,
"html_esc": htmlEscFmt,
"html_comment": htmlCommentFmt,
"urlquery_esc": urlQueryEscFmt,
"url_pkg": urlFmt,
"url_src": urlFmt,
"url_pos": urlFmt,
"infoKind": infoKindFmt,
"infoLine": infoLineFmt,
"infoSnippet": infoSnippetFmt,
"padding": paddingFmt,
"fileInfoName": fileInfoNameFmt,
"fileInfoSize": fileInfoSizeFmt,
"fileInfoTime": fileInfoTimeFmt,
"localname": localnameFmt,
"numlines": numlinesFmt,
func textNodeFunc(node interface{}, fset *token.FileSet) string {
var buf bytes.Buffer
writeNode(&buf, fset, node)
return buf.String()
}
func htmlNodeFunc(node interface{}, fset *token.FileSet) string {
var buf1 bytes.Buffer
writeNode(&buf1, fset, node)
var buf2 bytes.Buffer
FormatText(&buf2, buf1.Bytes(), -1, true, "", nil)
return buf2.String()
}
func htmlCommentFunc(comment string) string {
var buf bytes.Buffer
// TODO(gri) Provide list of words (e.g. function parameters)
// to be emphasized by ToHTML.
doc.ToHTML(&buf, []byte(comment), nil) // does html-escaping
return buf.String()
}
func fileInfoNameFunc(fi FileInfo) string {
name := fi.Name()
if fi.IsDirectory() {
name += "/"
}
return name
}
func fileInfoTimeFunc(fi FileInfo) string {
if t := fi.Mtime_ns(); t != 0 {
return time.SecondsToLocalTime(t / 1e9).String()
}
return "" // don't return epoch if time is obviously not set
}
func localnameFunc(path string) string {
_, localname := filepath.Split(path)
return localname
}
var fmap = append2funcMap(template.FuncMap{
"text_node": textNodeFunc,
"html_node": htmlNodeFunc,
"html_comment": htmlCommentFunc,
"fileInfoName": fileInfoNameFunc,
"fileInfoTime": fileInfoTimeFunc,
"localname": localnameFunc,
"repeat": strings.Repeat,
}, FormatterMap{
"url_pkg": urlFmt,
"url_src": urlFmt,
"url_pos": urlFmt,
"infoKind": infoKindFmt,
"infoLine": infoLineFmt,
"infoSnippet": infoSnippetFmt,
})
func readTemplate(name string) *template.Template {

View File

@ -401,9 +401,11 @@ func main() {
fmt.Println()
}
if *html {
writeAnyHTML(os.Stdout, info.FSet, d)
var buf bytes.Buffer
writeNode(&buf, info.FSet, d)
FormatText(os.Stdout, buf.Bytes(), -1, true, "", nil)
} else {
writeAny(os.Stdout, info.FSet, d)
writeNode(os.Stdout, info.FSet, d)
}
fmt.Println()
}