github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/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  	"golang.org/x/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  	PackageText,
    37  	SearchHTML,
    38  	SearchDocHTML,
    39  	SearchCodeHTML,
    40  	SearchTxtHTML,
    41  	SearchText,
    42  	SearchDescXML *template.Template
    43  
    44  	// TabWidth optionally specifies the tab width.
    45  	TabWidth int
    46  
    47  	ShowTimestamps bool
    48  	ShowPlayground bool
    49  	ShowExamples   bool
    50  	DeclLinks      bool
    51  
    52  	// SrcMode outputs source code instead of documentation in command-line mode.
    53  	SrcMode bool
    54  	// HTMLMode outputs HTML instead of plain text in command-line mode.
    55  	HTMLMode bool
    56  
    57  	// NotesRx optionally specifies a regexp to match
    58  	// notes to render in the output.
    59  	NotesRx *regexp.Regexp
    60  
    61  	// AdjustPageInfoMode optionally specifies a function to
    62  	// modify the PageInfoMode of a request. The default chosen
    63  	// value is provided.
    64  	AdjustPageInfoMode func(req *http.Request, mode PageInfoMode) PageInfoMode
    65  
    66  	// URLForSrc optionally specifies a function that takes a source file and
    67  	// returns a URL for it.
    68  	// The source file argument has the form /src/<path>/<filename>.
    69  	URLForSrc func(src string) string
    70  
    71  	// URLForSrcPos optionally specifies a function to create a URL given a
    72  	// source file, a line from the source file (1-based), and low & high offset
    73  	// positions (0-based, bytes from beginning of file). Ideally, the returned
    74  	// URL will be for the specified line of the file, while the high & low
    75  	// positions will be used to highlight a section of the file.
    76  	// The source file argument has the form /src/<path>/<filename>.
    77  	URLForSrcPos func(src string, line, low, high int) string
    78  
    79  	// URLForSrcQuery optionally specifies a function to create a URL given a
    80  	// source file, a query string, and a line from the source file (1-based).
    81  	// The source file argument has the form /src/<path>/<filename>.
    82  	// The query argument will be escaped for the purposes of embedding in a URL
    83  	// query parameter.
    84  	// Ideally, the returned URL will be for the specified line of the file with
    85  	// the query string highlighted.
    86  	URLForSrcQuery func(src, query string, line int) string
    87  
    88  	// SearchResults optionally specifies a list of functions returning an HTML
    89  	// body for displaying search results.
    90  	SearchResults []SearchResultFunc
    91  
    92  	initFuncMapOnce sync.Once
    93  	funcMap         template.FuncMap
    94  	templateFuncs   template.FuncMap
    95  }
    96  
    97  // NewPresentation returns a new Presentation from a corpus.
    98  // It sets SearchResults to:
    99  // [SearchResultDoc SearchResultCode SearchResultTxt].
   100  func NewPresentation(c *Corpus) *Presentation {
   101  	if c == nil {
   102  		panic("nil Corpus")
   103  	}
   104  	p := &Presentation{
   105  		Corpus:     c,
   106  		mux:        http.NewServeMux(),
   107  		fileServer: http.FileServer(httpfs.New(c.fs)),
   108  
   109  		TabWidth:     4,
   110  		ShowExamples: true,
   111  		DeclLinks:    true,
   112  		SearchResults: []SearchResultFunc{
   113  			(*Presentation).SearchResultDoc,
   114  			(*Presentation).SearchResultCode,
   115  			(*Presentation).SearchResultTxt,
   116  		},
   117  	}
   118  	p.cmdHandler = handlerServer{
   119  		p:       p,
   120  		c:       c,
   121  		pattern: "/cmd/",
   122  		fsRoot:  "/src",
   123  	}
   124  	p.pkgHandler = handlerServer{
   125  		p:           p,
   126  		c:           c,
   127  		pattern:     "/pkg/",
   128  		stripPrefix: "pkg/",
   129  		fsRoot:      "/src",
   130  		exclude:     []string{"/src/cmd"},
   131  	}
   132  	p.cmdHandler.registerWithMux(p.mux)
   133  	p.pkgHandler.registerWithMux(p.mux)
   134  	p.mux.HandleFunc("/", p.ServeFile)
   135  	p.mux.HandleFunc("/search", p.HandleSearch)
   136  	p.mux.HandleFunc("/opensearch.xml", p.serveSearchDesc)
   137  	return p
   138  }
   139  
   140  func (p *Presentation) FileServer() http.Handler {
   141  	return p.fileServer
   142  }
   143  
   144  func (p *Presentation) ServeHTTP(w http.ResponseWriter, r *http.Request) {
   145  	p.mux.ServeHTTP(w, r)
   146  }
   147  
   148  func (p *Presentation) PkgFSRoot() string {
   149  	return p.pkgHandler.fsRoot
   150  }
   151  
   152  func (p *Presentation) CmdFSRoot() string {
   153  	return p.cmdHandler.fsRoot
   154  }
   155  
   156  // TODO(bradfitz): move this to be a method on Corpus. Just moving code around for now,
   157  // but this doesn't feel right.
   158  func (p *Presentation) GetPkgPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
   159  	return p.pkgHandler.GetPageInfo(abspath, relpath, mode)
   160  }
   161  
   162  // TODO(bradfitz): move this to be a method on Corpus. Just moving code around for now,
   163  // but this doesn't feel right.
   164  func (p *Presentation) GetCmdPageInfo(abspath, relpath string, mode PageInfoMode) *PageInfo {
   165  	return p.cmdHandler.GetPageInfo(abspath, relpath, mode)
   166  }