1
0
mirror of https://github.com/golang/go synced 2024-11-25 10:07:56 -07:00

Factored out boilerplate from all html docs in doc directory:

- the first HTML comment in those files is extracted as page
  title when serving them
- lib/godoc.html is top-level template for all pages served
- experimented a bit with package documentation layout
  (feedback welcome)
- various related cleanups

TODO:
- The / page (doc/root.html) content repeats links that are
  in the navigation bar. It needs to be cleaned up.

R=rsc
DELTA=826  (86 added, 692 deleted, 48 changed)
OCL=35230
CL=35245
This commit is contained in:
Robert Griesemer 2009-10-01 14:08:00 -07:00
parent 57f834aeff
commit 53440da835
11 changed files with 107 additions and 409 deletions

View File

@ -1,64 +1,7 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" <!-- Effective Go -->
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<!-- interfaces; slices; embedding; value vs. pointer receivers; methods on anything; errors; testing --> <!-- interfaces; slices; embedding; value vs. pointer receivers; methods on anything; errors; testing -->
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Effective Go</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="godocs.js"></script>
<style type="text/css">
pre.bad {
background-color: #ffeeee;
}
</style>
</head>
<body> <!-- onload="prettyPrint()" will color the programs -->
<div id="topnav">
<table summary=""><tr>
<td id="headerImage">
<a href="./"><img src="./logo_blue.png" height="44" width="120" alt="Go Home Page" style="border:0" /></a>
</td>
<td id="headerDocSetTitle">The Go Programming Language</td>
</tr>
</table>
</div>
<div id="linkList" style="clear:both">
<ul>
<li class="navhead">Related Guides</li>
<li><a href="go_spec.html">Language Specification</a></li>
<li><a href="go_mem.html">Memory Model</a></li>
<li><a href="go_tutorial.html">Tutorial</a></li>
<li><a href="effective_go.html">Effective Go</a></li>
<li class="blank">&nbsp;</li>
<li class="navhead">Other Resources</li>
<li><a href="go_faq.html">FAQ</a></li>
<li><a href="go_lang_faq.html">Language Design FAQ</a></li>
<li><a href="go_for_cpp_programmers.html">Go for C++ Programmers</a></li>
<li class="blank">&nbsp;</li>
<li class="navhead">Home</li>
<li><a href="/">Go documentation home</a></li>
</ul>
</div>
<div id="content">
<h1 id="effective_go">Effective Go</h1>
<!-- The Table of Contents is automatically inserted in this <div>.
Do not delete this <div>. -->
<div id="nav"></div>
<h2 id="introduction">Introduction</h2> <h2 id="introduction">Introduction</h2>
<p> <p>
@ -1337,7 +1280,3 @@ lets readers concentrate on big ones.
</p> </p>
--> -->
</div>
</body>
</html>

View File

@ -1,59 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" <!-- Go For C++ Programmers -->
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<!--
To convert <h2>Foo</h2> into <h2 id="Foo">Foo</h2>
and convert §Foo into §<a href="#Foo">Foo</a>:
Edit ,s/<(h.)>(.*)(<\/h.>)/<\1 id="\2">\2\3/g
Edit ,x g/id="/ x/id="[^"]+"/ s/ /_/g
Edit ,s/§([^),.]+)/§<a href="#\1">\1<\/a>/g
Edit ,x/href="#[^"]+"/ s/ /_/g
-->
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Go For C++ Programmers</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="godocs.js"></script>
</head>
<body>
<div id="topnav">
<table summary=""><tr>
<td id="headerImage">
<a href="./"><img src="./logo_blue.png" height="44" width="120" alt="Go Home Page" style="border:0" /></a>
</td>
<td id="headerDocSetTitle">The Go Programming Language</td>
</tr>
</table>
</div>
<div id="linkList">
<ul>
<li class="navhead">Related Guides</li>
<li><a href="go_spec.html">Language Specification</a></li>
<li><a href="go_mem.html">Memory Model</a></li>
<li><a href="go_tutorial.html">Tutorial</a></li>
<li><a href="effective_go.html">Effective Go</a></li>
<li class="blank">&nbsp;</li>
<li class="navhead">Other Resources</li>
<li><a href="go_faq.html">FAQ</a></li>
<li><a href="go_lang_faq.html">Language Design FAQ</a></li>
<li><a href="go_for_cpp_programmers.html">Go for C++ Programmers</a></li>
<li class="blank">&nbsp;</li>
<li class="navhead">Home</li>
<li><a href="/">Go documentation home</a></li>
</ul>
</div>
<div id="content">
<h1 id="The_Go_Programming_Language_Specification">Go For C++ Programmers</h1>
<p> <p>
Go is a systems programming language intended as an alternative to C++. Go is a systems programming language intended as an alternative to C++.
@ -72,11 +17,6 @@ For a detailed description of the Go language, see the
<p> <p>
There is more <a href="./">documentation about go</a>. There is more <a href="./">documentation about go</a>.
<!-- The Table of Contents is automatically inserted in this <div>.
Do not delete this <div>. -->
<div id="nav"></div>
<h2 id="Conceptual_Differences">Conceptual Differences</h2> <h2 id="Conceptual_Differences">Conceptual Differences</h2>
<ul> <ul>
@ -666,14 +606,3 @@ func f4(ch &lt;- chan cmd2) int {
return &lt;- my_ch; return &lt;- my_ch;
} }
</pre> </pre>
</div>
<div id="footer">
<p>Except as noted, this content is
licensed under <a href="http://creativecommons.org/licenses/by/3.0/">
Creative Commons Attribution 3.0</a>.
</div>
</body>
</html>

View File

@ -1,54 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" <!-- The Go Programming Language Design FAQ -->
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>The Go Programming Language Design FAQ</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="godocs.js"></script>
</head>
<body>
<div id="topnav">
<table summary=""><tr>
<td id="headerImage">
<a href="./"><img src="./logo_blue.png" height="44" width="120" alt="Go Home Page" style="border:0" /></a>
</td>
<td id="headerDocSetTitle">The Go Programming Language</td>
</tr>
</table>
</div>
<div id="linkList">
<ul>
<li class="navhead">Related Guides</li>
<li><a href="go_spec.html">Language Specification</a></li>
<li><a href="go_mem.html">Memory Model</a></li>
<li><a href="go_tutorial.html">Tutorial</a></li>
<li><a href="effective_go.html">Effective Go</a></li>
<li class="blank">&nbsp;</li>
<li class="navhead">Other Resources</li>
<li><a href="go_faq.html">FAQ</a></li>
<li><a href="go_lang_faq.html">Language Design FAQ</a></li>
<li><a href="go_for_cpp_programmers.html">Go for C++ Programmers</a></li>
<li class="blank">&nbsp;</li>
<li class="navhead">Home</li>
<li><a href="/">Go documentation home</a></li>
</ul>
</div>
<div id="content">
<h1 id="The_Go_Programming_Language_Design_FAQ">The Go Programming Language Design FAQ</h1>
<!-- The Table of Contents is automatically inserted in this <div>.
Do not delete this <div>. -->
<div id="nav"></div>
<h2 id="origins">Origins</h2> <h2 id="origins">Origins</h2>
@ -416,15 +366,3 @@ why no automatic numeric conversions?
make vs new make vs new
</pre> </pre>
</div>
<div id="footer">
<p>Except as noted, this content is
licensed under <a href="http://creativecommons.org/licenses/by/3.0/">
Creative Commons Attribution 3.0</a>.
</div>
</body>
</html>

View File

@ -1,64 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" <!-- The Go Memory Model -->
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<!--
To convert <h2>Foo</h2> into <h2 id="Foo">Foo</h2>
and convert §Foo into §<a href="#Foo">Foo</a>:
Edit ,s/<(h.)>(.*)(<\/h.>)/<\1 id="\2">\2\3/g
Edit ,x g/id="/ x/id="[^"]+"/ s/ /_/g
Edit ,s/§([^),.]+)/§<a href="#\1">\1<\/a>/g
Edit ,x/href="#[^"]+"/ s/ /_/g
-->
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>The Go Memory Model</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="godocs.js"></script>
</head>
<body>
<div id="topnav">
<table summary=""><tr>
<td id="headerImage">
<a href="./"><img src="./logo_blue.png" height="44" width="120" alt="Go Home Page" style="border:0" /></a>
</td>
<td id="headerDocSetTitle">The Go Programming Language</td>
</tr>
</table>
</div>
<div id="linkList">
<ul>
<li class="navhead">Related Guides</li>
<li><a href="go_spec.html">Language Specification</a></li>
<li><a href="go_mem.html">Memory Model</a></li>
<li><a href="go_tutorial.html">Tutorial</a></li>
<li><a href="effective_go.html">Effective Go</a></li>
<li class="blank">&nbsp;</li>
<li class="navhead">Other Resources</li>
<li><a href="go_faq.html">FAQ</a></li>
<li><a href="go_lang_faq.html">Language Design FAQ</a></li>
<li><a href="go_for_cpp_programmers.html">Go for C++ Programmers</a></li>
<li class="blank">&nbsp;</li>
<li class="navhead">Home</li>
<li><a href="/">Go documentation home</a></li>
</ul>
</div>
<div id="content">
<h1 id="The_Go_Programming_Language_Specification">The Go Memory Model</h1>
<!-- The Table of Contents is automatically inserted in this <div>.
Do not delete this <div>. -->
<div id="nav"></div>
<h2>Introduction</h2> <h2>Introduction</h2>

View File

@ -1,64 +1,4 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" <!-- The Go Programming Language Specification -->
"http://www.w3.org/TR/html4/transitional.dtd">
<html>
<head>
<!--
To convert <h2>Foo</h2> into <h2 id="Foo">Foo</h2>
and convert §Foo into §<a href="#Foo">Foo</a>:
Edit ,s/<(h.)>(.*)(<\/h.>)/<\1 id="\2">\2\3/g
Edit ,x g/id="/ x/id="[^"]+"/ s/ /_/g
Edit ,s/§([^),.]+)/§<a href="#\1">\1<\/a>/g
Edit ,x/href="#[^"]+"/ s/ /_/g
-->
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>The Go Programming Language Specification</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="godocs.js"></script>
</head>
<body>
<div id="topnav">
<table summary=""><tr>
<td id="headerImage">
<a href="./"><img src="./logo_blue.png" height="44" width="120" alt="Go Home Page" style="border:0" /></a>
</td>
<td id="headerDocSetTitle">The Go Programming Language</td>
</tr>
</table>
</div>
<div id="linkList" style="clear:both">
<ul>
<li class="navhead">Related Guides</li>
<li><a href="go_spec.html">Language Specification</a></li>
<li><a href="go_mem.html">Memory Model</a></li>
<li><a href="go_tutorial.html">Tutorial</a></li>
<li><a href="effective_go.html">Effective Go</a></li>
<li class="blank">&nbsp;</li>
<li class="navhead">Other Resources</li>
<li><a href="go_faq.html">FAQ</a></li>
<li><a href="go_lang_faq.html">Language Design FAQ</a></li>
<li><a href="go_for_cpp_programmers.html">Go for C++ Programmers</a></li>
<li class="blank">&nbsp;</li>
<li class="navhead">Home</li>
<li><a href="/">Go documentation home</a></li>
</ul>
</div>
<div id="content">
<h1 id="The_Go_Programming_Language_Specification">The Go Programming Language Specification</h1>
<!-- The Table of Contents is automatically inserted in this <div>.
Do not delete this <div>. -->
<div id="nav"></div>
<!-- <!--
Todo Todo
@ -4613,14 +4553,3 @@ The following minimal alignment properties are guaranteed:
<li><font color=red>Gccgo does not implement the blank identifier.</font></li> <li><font color=red>Gccgo does not implement the blank identifier.</font></li>
<li><font color=red>Method expressions are not implemented.</font></li> <li><font color=red>Method expressions are not implemented.</font></li>
</ul> </ul>
</div>
<div id="footer">
<p>Except as noted, this content is
licensed under <a href="http://creativecommons.org/licenses/by/3.0/">
Creative Commons Attribution 3.0</a>.
</div>
</body>
</html>

View File

@ -1,8 +1,3 @@
<div id="content"> <!-- Let's Go -->
<h1 id="Lets_Go">Let's Go</h1>
<!-- The Table of Contents is automatically inserted in this <div>.
Do not delete this <div>. -->
<div id="nav"></div>
<h2>Introduction</h2> <h2>Introduction</h2>

View File

@ -1,8 +1,4 @@
<h1 id="Lets_Go">Let's Go</h1> <!-- Let's Go -->
<!-- The Table of Contents is automatically inserted in this <div>.
Do not delete this <div>. -->
<div id="nav"></div>
<h2>Introduction</h2> <h2>Introduction</h2>
<p> <p>
@ -1354,5 +1350,3 @@ at the end of main:
There's a lot more to Go programming and concurrent programming in general but this There's a lot more to Go programming and concurrent programming in general but this
quick tour should give you some of the basics. quick tour should give you some of the basics.
</table> </table>
</body>
</html>

View File

@ -4,14 +4,8 @@
license that can be found in the LICENSE file. license that can be found in the LICENSE file.
--> -->
{.section Dirs}
<h2>Subdirectories</h2>
{.repeated section @}
<a href="{Name|html}">{Name|html}</a><br />
{.end}
{.end}
{.section PDoc} {.section PDoc}
<h1>package {PackageName|html}</h1> <!-- PackageName is printed as title by the top-level template -->
<p><code>import "{ImportPath|html}"</code></p> <p><code>import "{ImportPath|html}"</code></p>
{Doc|html-comment} {Doc|html-comment}
{.section Filenames} {.section Filenames}
@ -77,3 +71,9 @@
{.end} {.end}
{.end} {.end}
{.end} {.end}
{.section Dirs}
<h2>Subdirectories</h2>
{.repeated section @}
<a href="{Name|html}">{Name|html}</a><br />
{.end}
{.end}

View File

@ -1,10 +1,3 @@
{.section Dirs}
SUBDIRECTORIES
{.repeated section @}
{Name}
{.end}
{.end}
{.section PDoc} {.section PDoc}
PACKAGE PACKAGE
@ -75,3 +68,11 @@ BUGS
{.end} {.end}
{.end} {.end}
{.end} {.end}
{.section Dirs}
SUBDIRECTORIES
{.repeated section @}
{Name}
{.end}
{.end}

View File

@ -4,7 +4,7 @@
license that can be found in the LICENSE file. license that can be found in the LICENSE file.
--> -->
<h1>Parse errors in {filename}</h1>
<pre> <pre>
{.repeated section list} {.repeated section list}
{src}{.section msg}<b><font color=red>«{msg|html}»</font></b>{.end}{.end}</pre> {src}{.section msg}<b><font color=red>«{msg|html}»</font></b>{.end}{.end}
</pre>

View File

@ -50,10 +50,7 @@ import (
) )
const ( const Pkg = "/pkg/"; // name for auto-generated package documentation tree
Pkg = "/pkg/"; // name for auto-generated package documentation tree
Spec = "/doc/go_spec.html";
)
type delayTime struct { type delayTime struct {
@ -186,7 +183,7 @@ type parseErrors struct {
func parse(path string, mode uint) (*ast.File, *parseErrors) { func parse(path string, mode uint) (*ast.File, *parseErrors) {
src, err := io.ReadFile(path); src, err := io.ReadFile(path);
if err != nil { if err != nil {
log.Stderrf("ReadFile %s: %v", path, err); log.Stderrf("%v", err);
errs := []parseError{parseError{nil, 0, err.String()}}; errs := []parseError{parseError{nil, 0, err.String()}};
return nil, &parseErrors{path, errs, nil}; return nil, &parseErrors{path, errs, nil};
} }
@ -349,16 +346,16 @@ func readTemplates() {
func servePage(c *http.Conn, title, content interface{}) { func servePage(c *http.Conn, title, content interface{}) {
type Data struct { type Data struct {
title interface{}; title interface{};
header interface{};
timestamp string; timestamp string;
content interface{}; content interface{};
} }
var d Data; d := Data{
d.title = title; title: title,
d.header = title; timestamp: time.SecondsToLocalTime(syncTime.get()).String(),
d.timestamp = time.SecondsToLocalTime(syncTime.get()).String(); content: content,
d.content = content; };
if err := godocHtml.Execute(&d, c); err != nil { if err := godocHtml.Execute(&d, c); err != nil {
log.Stderrf("godocHtml.Execute: %s", err); log.Stderrf("godocHtml.Execute: %s", err);
} }
@ -374,18 +371,57 @@ func serveText(c *http.Conn, text []byte) {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Files // Files
var (
tagBegin = strings.Bytes("<!--");
tagEnd = strings.Bytes("-->");
)
// 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]));
}
return;
}
func serveHtmlDoc(c *http.Conn, r *http.Request, filename string) {
// get HTML body contents
path := pathutil.Join(goroot, filename);
src, err := io.ReadFile(path);
if err != nil {
log.Stderrf("%v", err);
http.NotFound(c, r);
return;
}
// if it's the language spec, add tags to EBNF productions
if strings.HasSuffix(path, "go_spec.html") {
var buf bytes.Buffer;
linkify(&buf, src);
src = buf.Bytes();
}
title := commentText(src);
servePage(c, title, src);
}
func serveParseErrors(c *http.Conn, errors *parseErrors) { func serveParseErrors(c *http.Conn, errors *parseErrors) {
// format errors // format errors
var buf bytes.Buffer; var buf bytes.Buffer;
if err := parseerrorHtml.Execute(errors, &buf); err != nil { if err := parseerrorHtml.Execute(errors, &buf); err != nil {
log.Stderrf("parseerrorHtml.Execute: %s", err); log.Stderrf("parseerrorHtml.Execute: %s", err);
} }
servePage(c, errors.filename + " - Parse Errors", buf.Bytes()); servePage(c, "Parse errors in source file " + errors.filename, buf.Bytes());
} }
func serveGoSource(c *http.Conn, name string) { func serveGoSource(c *http.Conn, filename string) {
prog, errors := parse(name, parser.ParseComments); path := pathutil.Join(goroot, filename);
prog, errors := parse(path, parser.ParseComments);
if errors != nil { if errors != nil {
serveParseErrors(c, errors); serveParseErrors(c, errors);
return; return;
@ -396,43 +432,35 @@ func serveGoSource(c *http.Conn, name string) {
writeNode(&buf, prog, true); writeNode(&buf, prog, true);
fmt.Fprintln(&buf, "</pre>"); fmt.Fprintln(&buf, "</pre>");
servePage(c, name + " - Go source", buf.Bytes()); servePage(c, "Source file " + filename, buf.Bytes());
}
func serveGoSpec(c *http.Conn, r *http.Request) {
src, err := io.ReadFile(pathutil.Join(goroot, Spec));
if err != nil {
http.NotFound(c, r);
return;
}
linkify(c, src);
} }
var fileServer = http.FileServer(".", ""); var fileServer = http.FileServer(".", "");
func serveFile(c *http.Conn, req *http.Request) { func serveFile(c *http.Conn, r *http.Request) {
path := r.Url.Path;
// pick off special cases and hand the rest to the standard file server // pick off special cases and hand the rest to the standard file server
switch { switch ext := pathutil.Ext(path); {
case req.Url.Path == "/": case path == "/":
// serve landing page. serveHtmlDoc(c, r, "doc/root.html");
// TODO: hide page from ordinary file serving.
// writing doc/index.html will take care of that.
http.ServeFile(c, req, "doc/root.html");
case req.Url.Path == "/doc/root.html": case r.Url.Path == "/doc/root.html":
// hide landing page from its real name // hide landing page from its real name
// TODO why - there is no reason for this (remove eventually) http.NotFound(c, r);
http.NotFound(c, req);
case pathutil.Ext(req.Url.Path) == ".go": case ext == ".html":
serveGoSource(c, req.Url.Path[1 : len(req.Url.Path)]); // strip leading '/' from name serveHtmlDoc(c, r, path);
case ext == ".go":
serveGoSource(c, path);
default: default:
// TODO not good enough - don't want to download files // TODO:
// want to see them // - need to decide what to serve and what not to serve
fileServer.ServeHTTP(c, req); // - don't want to download files, want to see them
fileServer.ServeHTTP(c, r);
} }
} }
@ -496,6 +524,7 @@ func getPageInfo(path string) PageInfo {
// get package AST // get package AST
pkg, err := parser.ParsePackage(dirname, filter, parser.ParseComments); pkg, err := parser.ParsePackage(dirname, filter, parser.ParseComments);
if err != nil { if err != nil {
// TODO: parse errors should be shown instead of an empty directory
log.Stderr(err); log.Stderr(err);
} }
@ -548,7 +577,12 @@ func servePkg(c *http.Conn, r *http.Request) {
if path == "" { if path == "" {
path = "."; // don't display an empty path path = "."; // don't display an empty path
} }
servePage(c, path + " - Go package documentation", buf.Bytes()); title := "Directory " + path;
if info.PDoc != nil {
title = "Package " + info.PDoc.PackageName;
}
servePage(c, title, buf.Bytes());
} }
@ -665,7 +699,6 @@ func main() {
handler = loggingHandler(handler); handler = loggingHandler(handler);
} }
http.Handle(Spec, http.HandlerFunc(serveGoSpec));
http.Handle(Pkg, http.HandlerFunc(servePkg)); http.Handle(Pkg, http.HandlerFunc(servePkg));
if *syncCmd != "" { if *syncCmd != "" {
http.Handle("/debug/sync", http.HandlerFunc(dosync)); http.Handle("/debug/sync", http.HandlerFunc(dosync));