some deletions
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / blog / blog.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/blog/blog.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/blog/blog.go
deleted file mode 100644 (file)
index a87401c..0000000
+++ /dev/null
@@ -1,502 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package blog implements a web server for articles written in present format.
-package blog // import "golang.org/x/tools/blog"
-
-import (
-       "bytes"
-       "encoding/json"
-       "encoding/xml"
-       "fmt"
-       "html/template"
-       "log"
-       "net/http"
-       "os"
-       "path/filepath"
-       "regexp"
-       "sort"
-       "strings"
-       "time"
-
-       "golang.org/x/tools/blog/atom"
-       "golang.org/x/tools/present"
-)
-
-var (
-       validJSONPFunc = regexp.MustCompile(`(?i)^[a-z_][a-z0-9_.]*$`)
-       // used to serve relative paths when ServeLocalLinks is enabled.
-       golangOrgAbsLinkReplacer = strings.NewReplacer(
-               `href="https://golang.org/pkg`, `href="/pkg`,
-               `href="https://golang.org/cmd`, `href="/cmd`,
-       )
-)
-
-// Config specifies Server configuration values.
-type Config struct {
-       ContentPath  string // Relative or absolute location of article files and related content.
-       TemplatePath string // Relative or absolute location of template files.
-
-       BaseURL       string        // Absolute base URL (for permalinks; no trailing slash).
-       BasePath      string        // Base URL path relative to server root (no trailing slash).
-       GodocURL      string        // The base URL of godoc (for menu bar; no trailing slash).
-       Hostname      string        // Server host name, used for rendering ATOM feeds.
-       AnalyticsHTML template.HTML // Optional analytics HTML to insert at the beginning of <head>.
-
-       HomeArticles int    // Articles to display on the home page.
-       FeedArticles int    // Articles to include in Atom and JSON feeds.
-       FeedTitle    string // The title of the Atom XML feed
-
-       PlayEnabled     bool
-       ServeLocalLinks bool // rewrite golang.org/{pkg,cmd} links to host-less, relative paths.
-}
-
-// Doc represents an article adorned with presentation data.
-type Doc struct {
-       *present.Doc
-       Permalink string        // Canonical URL for this document.
-       Path      string        // Path relative to server root (including base).
-       HTML      template.HTML // rendered article
-
-       Related      []*Doc
-       Newer, Older *Doc
-}
-
-// Server implements an http.Handler that serves blog articles.
-type Server struct {
-       cfg       Config
-       docs      []*Doc
-       redirects map[string]string
-       tags      []string
-       docPaths  map[string]*Doc // key is path without BasePath.
-       docTags   map[string][]*Doc
-       template  struct {
-               home, index, article, doc *template.Template
-       }
-       atomFeed []byte // pre-rendered Atom feed
-       jsonFeed []byte // pre-rendered JSON feed
-       content  http.Handler
-}
-
-// NewServer constructs a new Server using the specified config.
-func NewServer(cfg Config) (*Server, error) {
-       present.PlayEnabled = cfg.PlayEnabled
-
-       if notExist(cfg.TemplatePath) {
-               return nil, fmt.Errorf("template directory not found: %s", cfg.TemplatePath)
-       }
-       root := filepath.Join(cfg.TemplatePath, "root.tmpl")
-       parse := func(name string) (*template.Template, error) {
-               path := filepath.Join(cfg.TemplatePath, name)
-               if notExist(path) {
-                       return nil, fmt.Errorf("template %s was not found in %s", name, cfg.TemplatePath)
-               }
-               t := template.New("").Funcs(funcMap)
-               return t.ParseFiles(root, path)
-       }
-
-       s := &Server{cfg: cfg}
-
-       // Parse templates.
-       var err error
-       s.template.home, err = parse("home.tmpl")
-       if err != nil {
-               return nil, err
-       }
-       s.template.index, err = parse("index.tmpl")
-       if err != nil {
-               return nil, err
-       }
-       s.template.article, err = parse("article.tmpl")
-       if err != nil {
-               return nil, err
-       }
-       p := present.Template().Funcs(funcMap)
-       s.template.doc, err = p.ParseFiles(filepath.Join(cfg.TemplatePath, "doc.tmpl"))
-       if err != nil {
-               return nil, err
-       }
-
-       // Load content.
-       content := filepath.Clean(cfg.ContentPath)
-       err = s.loadDocs(content)
-       if err != nil {
-               return nil, err
-       }
-
-       err = s.renderAtomFeed()
-       if err != nil {
-               return nil, err
-       }
-
-       err = s.renderJSONFeed()
-       if err != nil {
-               return nil, err
-       }
-
-       // Set up content file server.
-       s.content = http.StripPrefix(s.cfg.BasePath, http.FileServer(http.Dir(cfg.ContentPath)))
-
-       return s, nil
-}
-
-var funcMap = template.FuncMap{
-       "sectioned": sectioned,
-       "authors":   authors,
-}
-
-// sectioned returns true if the provided Doc contains more than one section.
-// This is used to control whether to display the table of contents and headings.
-func sectioned(d *present.Doc) bool {
-       return len(d.Sections) > 1
-}
-
-// authors returns a comma-separated list of author names.
-func authors(authors []present.Author) string {
-       var b bytes.Buffer
-       last := len(authors) - 1
-       for i, a := range authors {
-               if i > 0 {
-                       if i == last {
-                               if len(authors) > 2 {
-                                       b.WriteString(",")
-                               }
-                               b.WriteString(" and ")
-                       } else {
-                               b.WriteString(", ")
-                       }
-               }
-               b.WriteString(authorName(a))
-       }
-       return b.String()
-}
-
-// authorName returns the first line of the Author text: the author's name.
-func authorName(a present.Author) string {
-       el := a.TextElem()
-       if len(el) == 0 {
-               return ""
-       }
-       text, ok := el[0].(present.Text)
-       if !ok || len(text.Lines) == 0 {
-               return ""
-       }
-       return text.Lines[0]
-}
-
-// loadDocs reads all content from the provided file system root, renders all
-// the articles it finds, adds them to the Server's docs field, computes the
-// denormalized docPaths, docTags, and tags fields, and populates the various
-// helper fields (Next, Previous, Related) for each Doc.
-func (s *Server) loadDocs(root string) error {
-       // Read content into docs field.
-       const ext = ".article"
-       fn := func(p string, info os.FileInfo, err error) error {
-               if err != nil {
-                       return err
-               }
-
-               if filepath.Ext(p) != ext {
-                       return nil
-               }
-               f, err := os.Open(p)
-               if err != nil {
-                       return err
-               }
-               defer f.Close()
-               d, err := present.Parse(f, p, 0)
-               if err != nil {
-                       return err
-               }
-               var html bytes.Buffer
-               err = d.Render(&html, s.template.doc)
-               if err != nil {
-                       return err
-               }
-               p = p[len(root) : len(p)-len(ext)] // trim root and extension
-               p = filepath.ToSlash(p)
-               s.docs = append(s.docs, &Doc{
-                       Doc:       d,
-                       Path:      s.cfg.BasePath + p,
-                       Permalink: s.cfg.BaseURL + p,
-                       HTML:      template.HTML(html.String()),
-               })
-               return nil
-       }
-       err := filepath.Walk(root, fn)
-       if err != nil {
-               return err
-       }
-       sort.Sort(docsByTime(s.docs))
-
-       // Pull out doc paths and tags and put in reverse-associating maps.
-       s.docPaths = make(map[string]*Doc)
-       s.docTags = make(map[string][]*Doc)
-       s.redirects = make(map[string]string)
-       for _, d := range s.docs {
-               s.docPaths[strings.TrimPrefix(d.Path, s.cfg.BasePath)] = d
-               for _, t := range d.Tags {
-                       s.docTags[t] = append(s.docTags[t], d)
-               }
-       }
-       for _, d := range s.docs {
-               for _, old := range d.OldURL {
-                       if !strings.HasPrefix(old, "/") {
-                               old = "/" + old
-                       }
-                       if _, ok := s.docPaths[old]; ok {
-                               return fmt.Errorf("redirect %s -> %s conflicts with document %s", old, d.Path, old)
-                       }
-                       if new, ok := s.redirects[old]; ok {
-                               return fmt.Errorf("redirect %s -> %s conflicts with redirect %s -> %s", old, d.Path, old, new)
-                       }
-                       s.redirects[old] = d.Path
-               }
-       }
-
-       // Pull out unique sorted list of tags.
-       for t := range s.docTags {
-               s.tags = append(s.tags, t)
-       }
-       sort.Strings(s.tags)
-
-       // Set up presentation-related fields, Newer, Older, and Related.
-       for _, doc := range s.docs {
-               // Newer, Older: docs adjacent to doc
-               for i := range s.docs {
-                       if s.docs[i] != doc {
-                               continue
-                       }
-                       if i > 0 {
-                               doc.Newer = s.docs[i-1]
-                       }
-                       if i+1 < len(s.docs) {
-                               doc.Older = s.docs[i+1]
-                       }
-                       break
-               }
-
-               // Related: all docs that share tags with doc.
-               related := make(map[*Doc]bool)
-               for _, t := range doc.Tags {
-                       for _, d := range s.docTags[t] {
-                               if d != doc {
-                                       related[d] = true
-                               }
-                       }
-               }
-               for d := range related {
-                       doc.Related = append(doc.Related, d)
-               }
-               sort.Sort(docsByTime(doc.Related))
-       }
-
-       return nil
-}
-
-// renderAtomFeed generates an XML Atom feed and stores it in the Server's
-// atomFeed field.
-func (s *Server) renderAtomFeed() error {
-       var updated time.Time
-       if len(s.docs) > 0 {
-               updated = s.docs[0].Time
-       }
-       feed := atom.Feed{
-               Title:   s.cfg.FeedTitle,
-               ID:      "tag:" + s.cfg.Hostname + ",2013:" + s.cfg.Hostname,
-               Updated: atom.Time(updated),
-               Link: []atom.Link{{
-                       Rel:  "self",
-                       Href: s.cfg.BaseURL + "/feed.atom",
-               }},
-       }
-       for i, doc := range s.docs {
-               if i >= s.cfg.FeedArticles {
-                       break
-               }
-
-               // Use original article path as ID in atom feed
-               // to avoid articles being treated as new when renamed.
-               idPath := doc.Path
-               if len(doc.OldURL) > 0 {
-                       old := doc.OldURL[0]
-                       if !strings.HasPrefix(old, "/") {
-                               old = "/" + old
-                       }
-                       idPath = old
-               }
-
-               e := &atom.Entry{
-                       Title: doc.Title,
-                       ID:    feed.ID + idPath,
-                       Link: []atom.Link{{
-                               Rel:  "alternate",
-                               Href: doc.Permalink,
-                       }},
-                       Published: atom.Time(doc.Time),
-                       Updated:   atom.Time(doc.Time),
-                       Summary: &atom.Text{
-                               Type: "html",
-                               Body: summary(doc),
-                       },
-                       Content: &atom.Text{
-                               Type: "html",
-                               Body: string(doc.HTML),
-                       },
-                       Author: &atom.Person{
-                               Name: authors(doc.Authors),
-                       },
-               }
-               feed.Entry = append(feed.Entry, e)
-       }
-       data, err := xml.Marshal(&feed)
-       if err != nil {
-               return err
-       }
-       s.atomFeed = data
-       return nil
-}
-
-type jsonItem struct {
-       Title   string
-       Link    string
-       Time    time.Time
-       Summary string
-       Content string
-       Author  string
-}
-
-// renderJSONFeed generates a JSON feed and stores it in the Server's jsonFeed
-// field.
-func (s *Server) renderJSONFeed() error {
-       var feed []jsonItem
-       for i, doc := range s.docs {
-               if i >= s.cfg.FeedArticles {
-                       break
-               }
-               item := jsonItem{
-                       Title:   doc.Title,
-                       Link:    doc.Permalink,
-                       Time:    doc.Time,
-                       Summary: summary(doc),
-                       Content: string(doc.HTML),
-                       Author:  authors(doc.Authors),
-               }
-               feed = append(feed, item)
-       }
-       data, err := json.Marshal(feed)
-       if err != nil {
-               return err
-       }
-       s.jsonFeed = data
-       return nil
-}
-
-// summary returns the first paragraph of text from the provided Doc.
-func summary(d *Doc) string {
-       if len(d.Sections) == 0 {
-               return ""
-       }
-       for _, elem := range d.Sections[0].Elem {
-               text, ok := elem.(present.Text)
-               if !ok || text.Pre {
-                       // skip everything but non-text elements
-                       continue
-               }
-               var buf bytes.Buffer
-               for _, s := range text.Lines {
-                       buf.WriteString(string(present.Style(s)))
-                       buf.WriteByte('\n')
-               }
-               return buf.String()
-       }
-       return ""
-}
-
-// rootData encapsulates data destined for the root template.
-type rootData struct {
-       Doc           *Doc
-       BasePath      string
-       GodocURL      string
-       AnalyticsHTML template.HTML
-       Data          interface{}
-}
-
-// ServeHTTP serves the front, index, and article pages
-// as well as the ATOM and JSON feeds.
-func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-       var (
-               d = rootData{
-                       BasePath:      s.cfg.BasePath,
-                       GodocURL:      s.cfg.GodocURL,
-                       AnalyticsHTML: s.cfg.AnalyticsHTML,
-               }
-               t *template.Template
-       )
-       switch p := strings.TrimPrefix(r.URL.Path, s.cfg.BasePath); p {
-       case "/":
-               d.Data = s.docs
-               if len(s.docs) > s.cfg.HomeArticles {
-                       d.Data = s.docs[:s.cfg.HomeArticles]
-               }
-               t = s.template.home
-       case "/index":
-               d.Data = s.docs
-               t = s.template.index
-       case "/feed.atom", "/feeds/posts/default":
-               w.Header().Set("Content-type", "application/atom+xml; charset=utf-8")
-               w.Write(s.atomFeed)
-               return
-       case "/.json":
-               if p := r.FormValue("jsonp"); validJSONPFunc.MatchString(p) {
-                       w.Header().Set("Content-type", "application/javascript; charset=utf-8")
-                       fmt.Fprintf(w, "%v(%s)", p, s.jsonFeed)
-                       return
-               }
-               w.Header().Set("Content-type", "application/json; charset=utf-8")
-               w.Write(s.jsonFeed)
-               return
-       default:
-               if redir, ok := s.redirects[p]; ok {
-                       http.Redirect(w, r, redir, http.StatusMovedPermanently)
-                       return
-               }
-               doc, ok := s.docPaths[p]
-               if !ok {
-                       // Not a doc; try to just serve static content.
-                       s.content.ServeHTTP(w, r)
-                       return
-               }
-               d.Doc = doc
-               t = s.template.article
-       }
-       var err error
-       if s.cfg.ServeLocalLinks {
-               var buf bytes.Buffer
-               err = t.ExecuteTemplate(&buf, "root", d)
-               if err != nil {
-                       log.Println(err)
-                       return
-               }
-               _, err = golangOrgAbsLinkReplacer.WriteString(w, buf.String())
-       } else {
-               err = t.ExecuteTemplate(w, "root", d)
-       }
-       if err != nil {
-               log.Println(err)
-       }
-}
-
-// docsByTime implements sort.Interface, sorting Docs by their Time field.
-type docsByTime []*Doc
-
-func (s docsByTime) Len() int           { return len(s) }
-func (s docsByTime) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s docsByTime) Less(i, j int) bool { return s[i].Time.After(s[j].Time) }
-
-// notExist reports whether the path exists or not.
-func notExist(path string) bool {
-       _, err := os.Stat(path)
-       return os.IsNotExist(err)
-}