diff --git a/cmd/godoc/handlers.go b/cmd/godoc/handlers.go index 99cd215204..7316a9647b 100644 --- a/cmd/godoc/handlers.go +++ b/cmd/godoc/handlers.go @@ -71,6 +71,9 @@ func readTemplates(p *godoc.Presentation, html bool) { p.GodocHTML = readTemplate("godoc.html") p.PackageHTML = readTemplate("package.html") p.SearchHTML = readTemplate("search.html") + p.SearchDocHTML = readTemplate("searchdoc.html") + p.SearchCodeHTML = readTemplate("searchcode.html") + p.SearchTxtHTML = readTemplate("searchtxt.html") p.SearchDescXML = readTemplate("opensearch.xml") } } diff --git a/godoc/pres.go b/godoc/pres.go index 4508fba0bb..28388fcbf5 100644 --- a/godoc/pres.go +++ b/godoc/pres.go @@ -13,6 +13,9 @@ import ( "code.google.com/p/go.tools/godoc/vfs/httpfs" ) +// SearchResultFunc functions return an HTML body for displaying search results. +type SearchResultFunc func(p *Presentation, result SearchResult) []byte + // Presentation generates output from a corpus. type Presentation struct { Corpus *Corpus @@ -29,6 +32,9 @@ type Presentation struct { PackageHTML, PackageText, SearchHTML, + SearchDocHTML, + SearchCodeHTML, + SearchTxtHTML, SearchText, SearchDescXML *template.Template @@ -76,12 +82,18 @@ type Presentation struct { // the query string highlighted. URLForSrcQuery func(src, query string, line int) string + // SearchResults optionally specifies a list of functions returning an HTML + // body for displaying search results. + SearchResults []SearchResultFunc + initFuncMapOnce sync.Once funcMap template.FuncMap templateFuncs template.FuncMap } // NewPresentation returns a new Presentation from a corpus. +// It sets SearchResults to: +// [SearchResultDoc SearchResultCode SearchResultTxt]. func NewPresentation(c *Corpus) *Presentation { if c == nil { panic("nil Corpus") @@ -94,6 +106,11 @@ func NewPresentation(c *Corpus) *Presentation { TabWidth: 4, ShowExamples: true, DeclLinks: true, + SearchResults: []SearchResultFunc{ + (*Presentation).SearchResultDoc, + (*Presentation).SearchResultCode, + (*Presentation).SearchResultTxt, + }, } p.cmdHandler = handlerServer{p, c, "/cmd/", "/src/cmd"} p.pkgHandler = handlerServer{p, c, "/pkg/", "/src/pkg"} diff --git a/godoc/search.go b/godoc/search.go index f9c0b20160..48cdf08109 100644 --- a/godoc/search.go +++ b/godoc/search.go @@ -5,6 +5,7 @@ package godoc import ( + "bytes" "fmt" "log" "net/http" @@ -75,6 +76,26 @@ func (c *Corpus) Lookup(query string) SearchResult { return *result } +// SearchResultDoc optionally specifies a function returning an HTML body +// displaying search results matching godoc documentation. +func (p *Presentation) SearchResultDoc(result SearchResult) []byte { + return applyTemplate(p.SearchDocHTML, "searchDocHTML", result) +} + +// SearchResultCode optionally specifies a function returning an HTML body +// displaying search results matching source code. +func (p *Presentation) SearchResultCode(result SearchResult) []byte { + return applyTemplate(p.SearchCodeHTML, "searchCodeHTML", result) +} + +// SearchResultTxt optionally specifies a function returning an HTML body +// displaying search results of textual matches. +func (p *Presentation) SearchResultTxt(result SearchResult) []byte { + return applyTemplate(p.SearchTxtHTML, "searchTxtHTML", result) +} + +// HandleSearch obtains results for the requested search and returns a page +// to display them. func (p *Presentation) HandleSearch(w http.ResponseWriter, r *http.Request) { query := strings.TrimSpace(r.FormValue("q")) result := p.Corpus.Lookup(query) @@ -83,28 +104,29 @@ func (p *Presentation) HandleSearch(w http.ResponseWriter, r *http.Request) { p.ServeText(w, applyTemplate(p.SearchText, "searchText", result)) return } - - haveResults := result.Hit != nil || len(result.Textual) > 0 - if !haveResults { - for _, ir := range result.Idents { - if ir != nil { - haveResults = true - break - } - } + contents := bytes.Buffer{} + for _, f := range p.SearchResults { + contents.Write(f(p, result)) } + var title string - if haveResults { + if haveResults := contents.Len() > 0; haveResults { title = fmt.Sprintf(`Results for query %q`, query) + if !p.Corpus.IndexEnabled { + result.Alert = "" + } } else { title = fmt.Sprintf(`No results found for query %q`, query) } + body := bytes.NewBuffer(applyTemplate(p.SearchHTML, "searchHTML", result)) + body.Write(contents.Bytes()) + p.ServePage(w, Page{ Title: title, Tabtitle: query, Query: query, - Body: applyTemplate(p.SearchHTML, "searchHTML", result), + Body: body.Bytes(), }) } diff --git a/godoc/static/bake.sh b/godoc/static/bake.sh index 0466682ec5..d1610b13da 100755 --- a/godoc/static/bake.sh +++ b/godoc/static/bake.sh @@ -21,6 +21,9 @@ STATIC=" playground.js search.html search.txt + searchcode.html + searchdoc.html + searchtxt.html style.css " diff --git a/godoc/static/search.html b/godoc/static/search.html index 01d9f61d39..e0d13b9b5e 100644 --- a/godoc/static/search.html +++ b/godoc/static/search.html @@ -3,7 +3,6 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -{{$query_url := urlquery .Query}} {{with .Alert}}

{{html .}} @@ -17,110 +16,3 @@ {{end}}

{{end}} -{{with .Pak}} -

Package {{html $.Query}}

-

- - {{range .}} - {{$pkg_html := pkgLink .Pak.Path | html}} - - {{end}} -
{{$pkg_html}}
-

-{{end}} -{{range $key, $val := .Idents}} - {{if $val}} -

{{$key.Name}}

- {{range $val}} - {{$pkg_html := pkgLink .Path | html}} - {{$doc_html := docLink .Path .Name| html}} - {{html .Package}}.{{.Name}} - {{if .Doc}} -

{{comment_html .Doc}}

- {{else}} -

No documentation available

- {{end}} - {{end}} - {{end}} -{{end}} -{{with .Hit}} - {{with .Decls}} -

Package-level declarations

- {{range .}} - {{$pkg_html := pkgLink .Pak.Path | html}} -

package {{html .Pak.Name}}

- {{range .Files}} - {{$file := .File.Path}} - {{range .Groups}} - {{range .}} - {{$line := infoLine .}} - {{$file}}:{{$line}} - {{infoSnippet_html .}} - {{end}} - {{end}} - {{end}} - {{end}} - {{end}} - {{with .Others}} -

Local declarations and uses

- {{range .}} - {{$pkg_html := pkgLink .Pak.Path | html}} -

package {{html .Pak.Name}}

- {{range .Files}} - {{$file := .File.Path}} - {{$file}} - - {{range .Groups}} - - - - - - - {{end}} -
{{index . 0 | infoKind_html}} - {{range .}} - {{$line := infoLine .}} - {{$line}} - {{end}} -
- {{end}} - {{end}} - {{end}} -{{end}} -{{with .Textual}} - {{if $.Complete}} -

{{html $.Found}} textual occurrences

- {{else}} -

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

-

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

- {{end}} -

- - {{range .}} - {{$file := .Filename}} - - - - - - - - {{end}} - {{if not $.Complete}} - - {{end}} -
- {{$file}}: - {{len .Lines}} - {{range .Lines}} - {{html .}} - {{end}} - {{if not $.Complete}} - ... - {{end}} -
...
-

-{{end}} diff --git a/godoc/static/searchcode.html b/godoc/static/searchcode.html new file mode 100644 index 0000000000..22cd0c7356 --- /dev/null +++ b/godoc/static/searchcode.html @@ -0,0 +1,51 @@ + +{{$query_url := urlquery .Query}} +{{with .Hit}} + {{with .Decls}} +

Package-level declarations

+ {{range .}} + {{$pkg_html := pkgLink .Pak.Path | html}} +

package {{html .Pak.Name}}

+ {{range .Files}} + {{$file := .File.Path}} + {{range .Groups}} + {{range .}} + {{$line := infoLine .}} + {{$file}}:{{$line}} + {{infoSnippet_html .}} + {{end}} + {{end}} + {{end}} + {{end}} + {{end}} + {{with .Others}} +

Local declarations and uses

+ {{range .}} + {{$pkg_html := pkgLink .Pak.Path | html}} +

package {{html .Pak.Name}}

+ {{range .Files}} + {{$file := .File.Path}} + {{$file}} + + {{range .Groups}} + + + + + + + {{end}} +
{{index . 0 | infoKind_html}} + {{range .}} + {{$line := infoLine .}} + {{$line}} + {{end}} +
+ {{end}} + {{end}} + {{end}} +{{end}} diff --git a/godoc/static/searchdoc.html b/godoc/static/searchdoc.html new file mode 100644 index 0000000000..222719098b --- /dev/null +++ b/godoc/static/searchdoc.html @@ -0,0 +1,31 @@ + +{{with .Pak}} +

Package {{html $.Query}}

+

+ + {{range .}} + {{$pkg_html := pkgLink .Pak.Path | html}} + + {{end}} +
{{$pkg_html}}
+

+{{end}} +{{range $key, $val := .Idents}} + {{if $val}} +

{{$key.Name}}

+ {{range $val}} + {{$pkg_html := pkgLink .Path | html}} + {{$doc_html := docLink .Path .Name| html}} + {{html .Package}}.{{.Name}} + {{if .Doc}} +

{{comment_html .Doc}}

+ {{else}} +

No documentation available

+ {{end}} + {{end}} + {{end}} +{{end}} diff --git a/godoc/static/searchtxt.html b/godoc/static/searchtxt.html new file mode 100644 index 0000000000..7e4a978c4d --- /dev/null +++ b/godoc/static/searchtxt.html @@ -0,0 +1,42 @@ + +{{$query_url := urlquery .Query}} +{{with .Textual}} + {{if $.Complete}} +

{{html $.Found}} textual occurrences

+ {{else}} +

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

+

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

+ {{end}} +

+ + {{range .}} + {{$file := .Filename}} + + + + + + + + {{end}} + {{if not $.Complete}} + + {{end}} +
+ {{$file}}: + {{len .Lines}} + {{range .Lines}} + {{html .}} + {{end}} + {{if not $.Complete}} + ... + {{end}} +
...
+

+{{end}} diff --git a/godoc/static/static.go b/godoc/static/static.go index bb3afbc656..df75f100a0 100644 --- a/godoc/static/static.go +++ b/godoc/static/static.go @@ -1372,7 +1372,6 @@ function PlaygroundOutput(el) { Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -{{$query_url := urlquery .Query}} {{with .Alert}}

{{html .}} @@ -1386,113 +1385,6 @@ function PlaygroundOutput(el) { {{end}}

{{end}} -{{with .Pak}} -

Package {{html $.Query}}

-

- - {{range .}} - {{$pkg_html := pkgLink .Pak.Path | html}} - - {{end}} -
{{$pkg_html}}
-

-{{end}} -{{range $key, $val := .Idents}} - {{if $val}} -

{{$key.Name}}

- {{range $val}} - {{$pkg_html := pkgLink .Path | html}} - {{$doc_html := docLink .Path .Name| html}} - {{html .Package}}.{{.Name}} - {{if .Doc}} -

{{comment_html .Doc}}

- {{else}} -

No documentation available

- {{end}} - {{end}} - {{end}} -{{end}} -{{with .Hit}} - {{with .Decls}} -

Package-level declarations

- {{range .}} - {{$pkg_html := pkgLink .Pak.Path | html}} -

package {{html .Pak.Name}}

- {{range .Files}} - {{$file := .File.Path}} - {{range .Groups}} - {{range .}} - {{$line := infoLine .}} - {{$file}}:{{$line}} - {{infoSnippet_html .}} - {{end}} - {{end}} - {{end}} - {{end}} - {{end}} - {{with .Others}} -

Local declarations and uses

- {{range .}} - {{$pkg_html := pkgLink .Pak.Path | html}} -

package {{html .Pak.Name}}

- {{range .Files}} - {{$file := .File.Path}} - {{$file}} - - {{range .Groups}} - - - - - - - {{end}} -
{{index . 0 | infoKind_html}} - {{range .}} - {{$line := infoLine .}} - {{$line}} - {{end}} -
- {{end}} - {{end}} - {{end}} -{{end}} -{{with .Textual}} - {{if $.Complete}} -

{{html $.Found}} textual occurrences

- {{else}} -

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

-

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

- {{end}} -

- - {{range .}} - {{$file := .Filename}} - - - - - - - - {{end}} - {{if not $.Complete}} - - {{end}} -
- {{$file}}: - {{len .Lines}} - {{range .Lines}} - {{html .}} - {{end}} - {{if not $.Complete}} - ... - {{end}} -
...
-

-{{end}} `, "search.txt": `QUERY {{.Query}} @@ -1548,6 +1440,133 @@ function PlaygroundOutput(el) { {{range .Textual}}{{len .Lines}} {{srcLink .Filename}} {{end}}{{if not .Complete}}... ... {{end}}{{end}} +`, + "searchcode.html": ` +{{$query_url := urlquery .Query}} +{{with .Hit}} + {{with .Decls}} +

Package-level declarations

+ {{range .}} + {{$pkg_html := pkgLink .Pak.Path | html}} +

package {{html .Pak.Name}}

+ {{range .Files}} + {{$file := .File.Path}} + {{range .Groups}} + {{range .}} + {{$line := infoLine .}} + {{$file}}:{{$line}} + {{infoSnippet_html .}} + {{end}} + {{end}} + {{end}} + {{end}} + {{end}} + {{with .Others}} +

Local declarations and uses

+ {{range .}} + {{$pkg_html := pkgLink .Pak.Path | html}} +

package {{html .Pak.Name}}

+ {{range .Files}} + {{$file := .File.Path}} + {{$file}} + + {{range .Groups}} + + + + + + + {{end}} +
{{index . 0 | infoKind_html}} + {{range .}} + {{$line := infoLine .}} + {{$line}} + {{end}} +
+ {{end}} + {{end}} + {{end}} +{{end}} +`, + "searchdoc.html": ` +{{with .Pak}} +

Package {{html $.Query}}

+

+ + {{range .}} + {{$pkg_html := pkgLink .Pak.Path | html}} + + {{end}} +
{{$pkg_html}}
+

+{{end}} +{{range $key, $val := .Idents}} + {{if $val}} +

{{$key.Name}}

+ {{range $val}} + {{$pkg_html := pkgLink .Path | html}} + {{$doc_html := docLink .Path .Name| html}} + {{html .Package}}.{{.Name}} + {{if .Doc}} +

{{comment_html .Doc}}

+ {{else}} +

No documentation available

+ {{end}} + {{end}} + {{end}} +{{end}} +`, + "searchtxt.html": ` +{{$query_url := urlquery .Query}} +{{with .Textual}} + {{if $.Complete}} +

{{html $.Found}} textual occurrences

+ {{else}} +

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

+

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

+ {{end}} +

+ + {{range .}} + {{$file := .Filename}} + + + + + + + + {{end}} + {{if not $.Complete}} + + {{end}} +
+ {{$file}}: + {{len .Lines}} + {{range .Lines}} + {{html .}} + {{end}} + {{if not $.Complete}} + ... + {{end}} +
...
+

+{{end}} `, "style.css": `body { margin: 0;