]> Cypherpunks repositories - gostls13.git/commitdiff
godoc: support for title and subtitle headers when serving .html docs
authorRobert Griesemer <gri@golang.org>
Wed, 31 Mar 2010 00:37:42 +0000 (17:37 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 31 Mar 2010 00:37:42 +0000 (17:37 -0700)
and use it to show version (date) of go spec

Fixes #68.

R=rsc
CC=golang-dev, r
https://golang.org/cl/848042

doc/go_spec.html
doc/style.css
lib/godoc/godoc.html
src/cmd/godoc/godoc.go
src/cmd/godoc/main.go

index 003bbdc03a5bf669ed94fb5cfba0522ec68a53be..84480f6e8a9f224a976bf0288cd906460a48c0b2 100644 (file)
@@ -1,4 +1,5 @@
-<!-- The Go Programming Language Specification -->
+<!-- title The Go Programming Language Specification -->
+<!-- subtitle Version of March 25, 2010 -->
 
 <!--
 Todo
index 597e70bb342b5d59953bb30d4811ffa38527c3b6..38cf68d61dff35bd0b29728ffed7831cbad923f6 100644 (file)
@@ -198,6 +198,11 @@ span.highlight {
   background-color: #ffffa0;
 }
 
+span.subtitle {
+  font-weight: bold;
+  font-size: medium;
+}
+
 /* same style as for gettingStarted */
 #menu {
   margin-top: 1.5em;
index 99cd55eae68c6a78ed6a88e4e9033d4cba9a7138..dd2179981026e65281339e09a6f47056e9b7e4d2 100644 (file)
     </div>
   {.end}
 
-  <h1 id="generatedHeader">{Title|html-esc}</h1>
+  {.section Title}
+    <h1 id="generatedHeader">{@|html-esc}</h1>
+  {.end}
+  {.section Subtitle}
+    <span class="subtitle">{@|html-esc}</span>
+  {.end}
 
+  <p>
   <!-- The Table of Contents is automatically inserted in this <div>.
        Do not delete this <div>. -->
   <div id="nav"></div>
+  </p>
 
   <!-- Content is HTML-escaped elsewhere -->
   {Content}
index 62265cf6a8a7f84d74776a2dcfb04e11f4cdfd52..f302f8c7e9a9e29b205ad334e51cf2814a5ca348 100644 (file)
@@ -19,6 +19,7 @@ import (
        "log"
        "os"
        pathutil "path"
+       "regexp"
        "runtime"
        "strings"
        "sync"
@@ -874,9 +875,10 @@ func readTemplates() {
 // ----------------------------------------------------------------------------
 // Generic HTML wrapper
 
-func servePage(c *http.Conn, title, query string, content []byte) {
+func servePage(c *http.Conn, title, subtitle, query string, content []byte) {
        type Data struct {
                Title     string
+               Subtitle  string
                PkgRoots  []string
                Timestamp uint64 // int64 to be compatible with os.Dir.Mtime_ns
                Query     string
@@ -888,6 +890,7 @@ func servePage(c *http.Conn, title, query string, content []byte) {
        _, ts := fsTree.get()
        d := Data{
                Title:     title,
+               Subtitle:  subtitle,
                PkgRoots:  fsMap.PrefixList(),
                Timestamp: uint64(ts) * 1e9, // timestamp in ns
                Query:     query,
@@ -912,16 +915,16 @@ func serveText(c *http.Conn, text []byte) {
 // Files
 
 var (
-       tagBegin = []byte("<!--")
-       tagEnd   = []byte("-->")
+       titleRx        = regexp.MustCompile(`<!-- title ([^\-]*)-->`)
+       subtitleRx     = regexp.MustCompile(`<!-- subtitle ([^\-]*)-->`)
+       firstCommentRx = regexp.MustCompile(`<!--([^\-]*)-->`)
 )
 
-// commentText returns the text of the first HTML comment in src.
-func commentText(src []byte) (text string) {
-       i := bytes.Index(src, tagBegin)
-       j := bytes.Index(src, tagEnd)
-       if i >= 0 && j >= i+len(tagBegin) {
-               text = string(bytes.TrimSpace(src[i+len(tagBegin) : j]))
+
+func extractString(src []byte, rx *regexp.Regexp) (s string) {
+       m := rx.Execute(src)
+       if len(m) >= 4 {
+               s = strings.TrimSpace(string(src[m[2]:m[3]]))
        }
        return
 }
@@ -950,8 +953,15 @@ func serveHTMLDoc(c *http.Conn, r *http.Request, abspath, relpath string) {
                src = buf.Bytes()
        }
 
-       title := commentText(src)
-       servePage(c, title, "", src)
+       // get title and subtitle, if any
+       title := extractString(src, titleRx)
+       if title == "" {
+               // no title found; try first comment for backward-compatibility
+               title = extractString(src, firstCommentRx)
+       }
+       subtitle := extractString(src, subtitleRx)
+
+       servePage(c, title, subtitle, "", src)
 }
 
 
@@ -983,7 +993,7 @@ func serveGoSource(c *http.Conn, r *http.Request, abspath, relpath string) {
        info := &SourceInfo{buf.Bytes(), styler.mapping()}
 
        contents := applyTemplate(sourceHTML, "sourceHTML", info)
-       servePage(c, "Source file "+relpath, "", contents)
+       servePage(c, "Source file "+relpath, "", "", contents)
 }
 
 
@@ -1056,7 +1066,7 @@ func serveTextFile(c *http.Conn, r *http.Request, abspath, relpath string) {
        template.HTMLEscape(&buf, src)
        fmt.Fprintln(&buf, "</pre>")
 
-       servePage(c, "Text file "+relpath, "", buf.Bytes())
+       servePage(c, "Text file "+relpath, "", "", buf.Bytes())
 }
 
 
@@ -1079,7 +1089,7 @@ func serveDirectory(c *http.Conn, r *http.Request, abspath, relpath string) {
        }
 
        contents := applyTemplate(dirlistHTML, "dirlistHTML", list)
-       servePage(c, "Directory "+relpath, "", contents)
+       servePage(c, "Directory "+relpath, "", "", contents)
 }
 
 
@@ -1326,7 +1336,7 @@ func (h *httpHandler) ServeHTTP(c *http.Conn, r *http.Request) {
        }
 
        contents := applyTemplate(packageHTML, "packageHTML", info)
-       servePage(c, title, "", contents)
+       servePage(c, title, "", "", contents)
 }
 
 
@@ -1373,7 +1383,7 @@ func search(c *http.Conn, r *http.Request) {
        }
 
        contents := applyTemplate(searchHTML, "searchHTML", result)
-       servePage(c, title, query, contents)
+       servePage(c, title, "", query, contents)
 }
 
 
index 0ede0dcc949f509a34052812aefd2161100db423..7a9279a2f4261ed5a6ec311b84e09980cdb6ab21 100644 (file)
@@ -66,7 +66,7 @@ var (
 
 func serveError(c *http.Conn, r *http.Request, relpath string, err os.Error) {
        contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
-       servePage(c, "File "+relpath, "", contents)
+       servePage(c, "File "+relpath, "", "", contents)
 }