From a28efa5d8c5eb42e3c7e4970734a270634d66a06 Mon Sep 17 00:00:00 2001 From: Brad Garcia Date: Mon, 6 Jan 2014 09:51:01 -0500 Subject: [PATCH] godoc: add ability to change or disable the display of search results. The display of search results can now be changed. A slice of functions for displaying the results can now be provided. By default, three functions are provided to display documentation, source code, and textual results. This makes it possible to replace them with equivalents that, say, obtain search results from alternative source code search engines. R=bradfitz, adg CC=golang-codereviews https://golang.org/cl/43470043 --- cmd/godoc/handlers.go | 3 + godoc/pres.go | 17 +++ godoc/search.go | 44 +++++-- godoc/static/bake.sh | 3 + godoc/static/search.html | 108 ---------------- godoc/static/searchcode.html | 51 ++++++++ godoc/static/searchdoc.html | 31 +++++ godoc/static/searchtxt.html | 42 +++++++ godoc/static/static.go | 235 +++++++++++++++++++---------------- 9 files changed, 307 insertions(+), 227 deletions(-) create mode 100644 godoc/static/searchcode.html create mode 100644 godoc/static/searchdoc.html create mode 100644 godoc/static/searchtxt.html 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;