godoc: support for title and subtitle headers when serving .html docs

and use it to show version (date) of go spec

Fixes #68.

R=rsc
CC=golang-dev, r
https://golang.org/cl/848042
This commit is contained in:
Robert Griesemer 2010-03-30 17:37:42 -07:00
parent 7ecefdc03f
commit e8e4987ba3
5 changed files with 42 additions and 19 deletions

View file

@ -1,4 +1,5 @@
<!-- The Go Programming Language Specification -->
<!-- title The Go Programming Language Specification -->
<!-- subtitle Version of March 25, 2010 -->
<!--
Todo

View 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;

View file

@ -133,11 +133,18 @@
</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}

View 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)
}

View 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)
}