From 5233c50321828323959663faf000d599f0cefa6c Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Fri, 12 Aug 2011 10:06:32 -0700 Subject: [PATCH] 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 --- lib/godoc/codewalk.html | 10 +-- lib/godoc/codewalkdir.html | 4 +- lib/godoc/dirlist.html | 6 +- lib/godoc/error.html | 2 +- lib/godoc/godoc.html | 12 +-- lib/godoc/package.html | 66 +++++++------- lib/godoc/package.txt | 20 ++--- lib/godoc/search.html | 37 ++++---- lib/godoc/search.txt | 9 +- src/cmd/godoc/godoc.go | 179 +++++++++++++------------------------ src/cmd/godoc/main.go | 6 +- 11 files changed, 150 insertions(+), 201 deletions(-) diff --git a/lib/godoc/codewalk.html b/lib/godoc/codewalk.html index 64d2d322532..59a9efcf2d9 100644 --- a/lib/godoc/codewalk.html +++ b/lib/godoc/codewalk.html @@ -19,7 +19,7 @@ @@ -37,15 +37,15 @@
{{range .Step}}
- -
{{.Title|html_esc}}
+ +
{{html .Title}}
{{with .Err}} - ERROR LOADING FILE: {{.|html_esc}}

+ ERROR LOADING FILE: {{html .}}

{{end}} {{.XML}}
-
{{.|html_esc}}
+
{{html .}}
{{end}}
diff --git a/lib/godoc/codewalkdir.html b/lib/godoc/codewalkdir.html index ebfc19aa6b5..b174020e8e6 100644 --- a/lib/godoc/codewalkdir.html +++ b/lib/godoc/codewalkdir.html @@ -7,9 +7,9 @@ {{range .}} - + - + {{end}}
{{.Name|html_esc}}{{html .Name}}  {{.Title|html_esc}}{{html .Title}}
diff --git a/lib/godoc/dirlist.html b/lib/godoc/dirlist.html index 7e7d4e7f294..5a3ddfaf396 100644 --- a/lib/godoc/dirlist.html +++ b/lib/godoc/dirlist.html @@ -18,11 +18,11 @@ {{range .}} - {{.|fileInfoName}} + {{.|fileInfoName|html}} - {{.|fileInfoSize}} + {{html .Size}} - {{.|fileInfoTime}} + {{.|fileInfoTime|html}} {{end}} diff --git a/lib/godoc/error.html b/lib/godoc/error.html index d349f754fdc..7573aa23671 100644 --- a/lib/godoc/error.html +++ b/lib/godoc/error.html @@ -5,5 +5,5 @@ -->

-{{.|html_esc}} +{{html .}}

diff --git a/lib/godoc/godoc.html b/lib/godoc/godoc.html index 37db860b205..91e521258d6 100644 --- a/lib/godoc/godoc.html +++ b/lib/godoc/godoc.html @@ -3,7 +3,7 @@ {{with .Title}} - {{.|html_esc}} - The Go Programming Language + {{html .}} - The Go Programming Language {{else}} The Go Programming Language {{end}} @@ -25,7 +25,7 @@
{{with .PkgRoots}} {{range .PkgRoots}} - {{.|html_esc}} | + {{html .}} | {{end}} {{else}} References: @@ -34,7 +34,7 @@ Commands | Specification {{if .SearchBox}} - + {{end}}
@@ -50,10 +50,10 @@ {{end}} {{with .Title}} -

{{.|html_esc}}

+

{{html .}}

{{end}} {{with .Subtitle}} - {{.|html_esc}} + {{html .}} {{end}} -{{$FSet := .FSet}} -{{$Info := .}} {{with .PAst}} -
{{html_esc . $FSet}}
+
{{html_node . $.FSet}}
{{end}} {{with .PDoc}} - {{if $Info.IsPkg}} - {{/* ImportPath is a string - no need for FSet */}} -

import "{{.ImportPath|html_esc}}"

+ {{if $.IsPkg}} +

import "{{html .ImportPath}}"

{{end}} - {{.Doc|html_comment}} - {{if $Info.IsPkg}} + {{html_comment .Doc}} + {{if $.IsPkg}} {{with .Filenames}} - {{/* Filenames are strings - no need for FSet */}}

Package files

{{range .}} - {{.|localname}} + {{.|localname|html}} {{end}}

@@ -32,53 +28,57 @@

Constants

{{range .}} {{html_comment .Doc}} -
{{html_esc .Decl $FSet}}
+
{{html_node .Decl $.FSet}}
{{end}} {{end}} {{with .Vars}}

Variables

{{range .}} {{html_comment .Doc}} -
{{html_esc .Decl $FSet}}
+
{{html_node .Decl $.FSet}}
{{end}} {{end}} {{with .Funcs}} {{range .}} {{/* Name is a string - no need for FSet */}} -

func {{.Name|html_esc}}

-

{{html_esc .Decl $FSet}}

- {{.Doc|html_comment}} + {{$name := html .Name}} +

func {{$name}}

+

{{html_node .Decl $.FSet}}

+ {{html_comment .Doc}} {{end}} {{end}} {{with .Types}} - {{range $type := .}} -

type {{html_esc .Type.Name $FSet}}

- {{.Doc|html_comment}} -

{{html_esc .Decl $FSet}}

+ {{range .}} + {{$tname := html_node .Type.Name $.FSet}} +

type {{$tname}}

+ {{html_comment .Doc}} +

{{html_node .Decl $.FSet}}

{{range .Consts}} - {{.Doc|html_comment}} -
{{html_esc .Decl $FSet}}
+ {{html_comment .Doc}} +
{{html_node .Decl $.FSet}}
{{end}} {{range .Vars}} - {{.Doc|html_comment}} -
{{html_esc .Decl $FSet}}
+ {{html_comment .Doc}} +
{{html_node .Decl $.FSet}}
{{end}} {{range .Factories}} -

func {{.Name|html_esc}}

-

{{html_esc .Decl $FSet}}

- {{.Doc|html_comment}} + {{$name := html .Name}} +

func {{$name}}

+

{{html_node .Decl $.FSet}}

+ {{html_comment .Doc}} {{end}} {{range .Methods}} -

func ({{html_esc .Recv $FSet}}) {{.Name|html_esc}}

-

{{html_esc .Decl $FSet}}

- {{.Doc|html_comment}} + {{$name := html .Name}} +

func ({{html_node .Recv $.FSet}}) {{$name}}

+

{{html_node .Decl $.FSet}}

+ {{html_comment .Doc}} {{end}} {{end}} {{end}} {{with .Bugs}}

Bugs

{{range .}} - {{.|html_comment}} + {{html_comment .}} {{end}} {{end}} {{end}} @@ -87,7 +87,7 @@

{{/* PList entries are strings - no need for FSet */}} {{range .}} - {{html .}}
+ {{html .}}
{{end}}

{{end}} @@ -102,7 +102,7 @@

- + @@ -111,7 +111,7 @@ {{range .List}} - {{.Depth|padding}} + {{repeat `` .Depth}} diff --git a/lib/godoc/package.txt b/lib/godoc/package.txt index db9e1d85e43..af1a6306934 100644 --- a/lib/godoc/package.txt +++ b/lib/godoc/package.txt @@ -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}}{{/* diff --git a/lib/godoc/search.html b/lib/godoc/search.html index 94acb837b20..4c956721f83 100644 --- a/lib/godoc/search.html +++ b/lib/godoc/search.html @@ -13,7 +13,7 @@

Did you mean: {{range .Alts}} - {{.|html_esc}} + {{html .}} {{end}}

{{end}} @@ -21,12 +21,13 @@ {{with .Decls}}

Package-level declarations

{{range .}} -

package {{.Pak.Name|html_esc}}

- {{range $File := .Files}} +

package {{html .Pak.Name}}

+ {{range .Files}} + {{$path := url_src .File.Path}} {{range .Groups}} {{range .Infos}} - {{$File.File.Path|url_src}}:{{.|infoLine}} - {{.|infoSnippet}} + {{$path}}:{{infoLine .}} + {{infoSnippet .}} {{end}} {{end}} {{end}} @@ -35,18 +36,19 @@ {{with .Others}}

Local declarations and uses

{{range .}} -

package {{.Pak.Name|html_esc}}

- {{range $File := .Files}} - {{.File.Path|url_src}} +

package {{html .Pak.Name}}

+ {{range .Files}} + {{$path := url_src .File.Path}} + {{$path}}
NameName   Synopsis
{{html .Name}} {{html .Synopsis}}
{{range .Groups}} - + @@ -58,26 +60,27 @@ {{end}} {{with .Textual}} {{if $SearchResult.Complete}} -

{{$SearchResult.Found|html_esc}} textual occurrences

+

{{html $SearchResult.Found}} textual occurrences

{{else}} -

More than {{$SearchResult.Found|html_esc}} textual occurrences

+

More than {{html $SearchResult.Found}} textual occurrences

- Not all files or lines containing "{{$SearchResult.Query|html_esc}}" are shown. + Not all files or lines containing "{{html $SearchResult.Query}}" are shown.

{{end}}

{{.Kind|infoKind}}{{infoKind .Kind}} {{range .Infos}} - {{.|infoLine}} + {{infoLine .}} {{end}}
- {{range $File := .}} + {{range .}} + {{$path := url_src .Filename}} - + `) - } -} - -// 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 { diff --git a/src/cmd/godoc/main.go b/src/cmd/godoc/main.go index 943c81cfb5a..e4c30239694 100644 --- a/src/cmd/godoc/main.go +++ b/src/cmd/godoc/main.go @@ -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() }
- {{.Filename|url_src}}: + {{$path}}: {{.Lines|numlines}}{{len .Lines}} {{range .Lines}} - {{.|html_esc}} + {{html .}} {{end}} {{if not $SearchResult.Complete}} ... diff --git a/lib/godoc/search.txt b/lib/godoc/search.txt index 81318cb6411..423712155aa 100644 --- a/lib/godoc/search.txt +++ b/lib/godoc/search.txt @@ -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}} diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go index 87f8b61faec..c70a03de821 100644 --- a/src/cmd/godoc/godoc.go +++ b/src/cmd/godoc/godoc.go @@ -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, `