github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/godoc/pres.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package godoc
     6  
     7  import (
     8  	"net/http"
     9  	"regexp"
    10  	"sync"
    11  	"text/template"
    12  
    13  	"github.com/powerman/golang-tools/godoc/vfs/httpfs"
    14  )
    15  
    16  // SearchResultFunc functions return an HTML body for displaying search results.
    17  type SearchResultFunc func(p *Presentation, result SearchResult) []byte
    18  
    19  // Presentation generates output from a corpus.
    20  type Presentation struct {
    21  	Corpus *Corpus
    22  
    23  	mux        *http.ServeMux
    24  	fileServer http.Handler
    25  	cmdHandler handlerServer
    26  	pkgHandler handlerServer
    27  
    28  	CallGraphHTML,
    29  	DirlistHTML,
    30  	ErrorHTML,
    31  	ExampleHTML,
    32  	GodocHTML,
    33  	ImplementsHTML,
    34  	MethodSetHTML,
    35  	PackageHTML,
    36  	PackageRootHTML,
    37  	SearchHTML,
    38  	SearchDocHTML,
    39  	SearchCodeHTML,
    40  	SearchTxtHTML,
    41  	SearchDescXML *template.Template // If not nil, register a /opensearch.xml handler with this template.
    42  
    43  	// TabWidth optionally specifies the tab width.
    44  	TabWidth int
    45  
    46  	ShowTimestamps bool
    47  	ShowPlayground bool
    48  	DeclLinks      bool
    49  
    50  	// NotesRx optionally specifies a regexp to match
    51  	// notes to render in the output.
    52  	NotesRx *regexp.Regexp
    53  
    54  	// AdjustPageInfoMode optionally specifies a function to
    55  	// modify the PageInfoMode of a request. The default chosen
    56  	// value is provided.
    57  	AdjustPageInfoMode func(req *http.Request, mode PageInfoMode) PageInfoMode
    58  
    59  	// URLForSrc optionally specifies a function that takes a source file and
    60  	// returns a URL for it.
    61  	// The source file argument has the form /src/<path>/<filename>.
    62  	URLForSrc func(src string) string
    63  
    64  	// URLForSrcPos optionally specifies a function to create a URL given a
    65  	// source file, a line from the source file (1-based), and low & high offset
    66  	// positions (0-based, bytes from beginning of file). Ideally, the returned
    67  	// URL will be for the specified line of the file, while the high & low
    68  	// positions will be used to highlight a section of the file.
    69  	// The source file argument has the form /src/<path>/<filename>.
    70  	URLForSrcPos func(src string, line, low, high int) string
    71  
    72  	// URLForSrcQuery optionally specifies a function to create a URL given a
    73  	// source file, a query string, and a line from the source file (1-based).
    74  	// The source file argument has the form /src/<path>/<filename>.
    75  	// The query argument will be escaped for the purposes of embedding in a URL
    76  	// query parameter.
    77  	// Ideally, the returned URL will be for the specified line of the file with
    78  	// the query string highlighted.
    79  	URLForSrcQuery func(src, query string, line int) string
    80  
    81  	// SearchResults optionally specifies a list of functions returning an HTML
    82  	// body for displaying search results.
    83  	SearchResults []SearchResultFunc
    84  
    85  	// GoogleAnalytics optionally adds Google Analytics via the provided
    86  	// tracking ID to each page.
    87  	GoogleAnalytics string
    88  
    89  	initFuncMapOnce sync.Once
    90  	funcMap         template.FuncMap
    91  	templateFuncs   template.FuncMap
    92  }
    93  
    94  // NewPresentation returns a new Presentation from a corpus.
    95  // It sets SearchResults to:
    96  // [SearchResultDoc SearchResultCode SearchResultTxt].
    97  func NewPresentation(c *Corpus) *Presentation {
    98  	if c == nil {
    99  		panic("nil Corpus")
   100  	}
   101  	p := &Presentation{
   102  		Corpus:     c,
   103  		mux:        http.NewServeMux(),
   104  		fileServer: http.FileServer(httpfs.New(c.fs)),
   105  
   106  		TabWidth:  4,
   107  		DeclLinks: true,
   108  		SearchResults: []SearchResultFunc{
   109  			(*Presentation).SearchResultDoc,
   110  			(*Presentation).SearchResultCode,
   111  			(*Presentation).SearchResultTxt,
   112  		},
   113  	}
   114  	p.cmdHandler = handlerServer{
   115  		p:       p,
   116  		c:       c,
   117  		pattern: "/cmd/",
   118  		fsRoot:  "/src",
   119  	}
   120  	p.pkgHandler = handlerServer{
   121  		p:           p,
   122  		c:           c,
   123  		pattern:     "/pkg/",
   124  		stripPrefix: "pkg/",
   125  		fsRoot:      "/src",
   126  		exclude:     []string{"/src/cmd"},
   127  	}
   128  	p.cmdHandler.registerWithMux(p.mux)
   129  	p.pkgHandler.registerWithMux(p.mux)
   130  	p.mux.HandleFunc("/", p.ServeFile)
   131  	p.mux.HandleFunc("/search", p.HandleSearch)
   132  	if p.SearchDescXML != nil {
   133  		p.mux.HandleFunc("/opensearch.xml", p.serveSearchDesc)
   134  	}
   135  	return p
   136  }
   137  
   138  func (p *Presentation) FileServer() http.Handler {
   139  	return p.fileServer
   140  }
   141  
   142  func (p *Presentation) ServeHTTP(w http.ResponseWriter, r *http.Request) {
   143  	p.mux.ServeHTTP(w, r)
   144  }
   145  
   146  func (p *Presentation) PkgFSRoot() string {
   147  	return p.pkgHandler.fsRoot
   148  }
   149  
   150  func (p *Presentation) CmdFSRoot() string {
   151  	return p.cmdHandler.fsRoot
   152  }
   153  
   154  // TODO(bradfitz): move this to be a method on Corpus. Just moving code around for now,
   155  // but this doesn't feel right.
   156  func (p *Presentation) GetPkgPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
   157  	return p.pkgHandler.GetPageInfo(abspath, relpath, mode, "", "")
   158  }
   159  
   160  // TODO(bradfitz): move this to be a method on Corpus. Just moving code around for now,
   161  // but this doesn't feel right.
   162  func (p *Presentation) GetCmdPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
   163  	return p.cmdHandler.GetPageInfo(abspath, relpath, mode, "", "")
   164  }