-<!-- Defer, Panic, and Recover -->
+<!--{
+ "Title": "Defer, Panic, and Recover"
+}-->
<!--
DO NOT EDIT: created by
tmpltohtml articles/defer_panic_recover.tmpl
-<!-- Defer, Panic, and Recover -->
+<!--{
+ "Title": "Defer, Panic, and Recover"
+}-->
{{donotedit}}
<p>
Go has the usual mechanisms for control flow: if, for, switch, goto. It also
-<!-- Error Handling and Go -->
+<!--{
+ "Title": "Error Handling and Go"
+}-->
<!--
DO NOT EDIT: created by
tmpltohtml articles/error_handling.tmpl
-<!-- Error Handling and Go -->
+<!--{
+ "Title": "Error Handling and Go"
+}-->
{{donotedit}}
<p>
If you have written any Go code you have probably encountered the built-in
-<!-- Slices: usage and internals -->
+<!--{
+ "Title": "Slices: usage and internals"
+}-->
<!--
DO NOT EDIT: created by
tmpltohtml articles/slices_usage_and_internals.tmpl
-<!-- Slices: usage and internals -->
+<!--{
+ "Title": "Slices: usage and internals"
+}-->
{{donotedit}}
<p>
-<!-- How to Write Go Code -->
+<!--{
+ "Title": "How to Write Go Code"
+}-->
<h2 id="Introduction">Introduction</h2>
-<!-- Using Mercurial Queues with Codereview -->
+<!--{
+ "Title": "Using Mercurial Queues with Codereview"
+}-->
<h2 id="Introduction">Introduction</h2>
-<!-- title Community -->
+<!--{
+ "Title": "Community"
+}-->
<div class="left-column">
-<!-- title Contributing -->
+<!--{
+ "Title": "Contributing"
+}-->
<div class="left-column">
-<!-- Contribution Guidelines -->
+<!--{
+ "Title": "Contribution Guidelines"
+}-->
<h2 id="Introduction">Introduction</h2>
-<!-- title Debugging Go Code with GDB -->
+<!--{
+ "Title": "Debugging Go Code with GDB"
+}-->
<p><i>
This applies to the 6g toolchain. Gccgo has native gdb support. Besides this
-<!-- title Documentation -->
+<!--{
+ "Title": "Documentation"
+}-->
<div class="left-column">
-<!-- Effective Go -->
+<!--{
+ "Title": "Effective Go"
+}-->
<!--
DO NOT EDIT: created by
tmpltohtml effective_go.tmpl
-<!-- Effective Go -->
+<!--{
+ "Title": "Effective Go"
+}-->
{{donotedit}}
<h2 id="introduction">Introduction</h2>
-<!-- Contributing to the gccgo frontend -->
+<!--{
+ "Title": "Contributing to the gccgo frontend"
+}-->
<h2>Introduction</h2>
-<!-- Setting up and using gccgo -->
+<!--{
+ "Title": "Setting up and using gccgo"
+}-->
<p>
This document explains how to use <code>gccgo</code>, a compiler for
-<!-- Go 1 Release Notes -->
+<!--{
+ "Title": "Go 1 Release Notes"
+}-->
<!--
DO NOT EDIT: created by
tmpltohtml go1.tmpl
-<!-- Go 1 Release Notes -->
+<!--{
+ "Title": "Go 1 Release Notes"
+}-->
{{donotedit}}
<h2 id="introduction">Introduction to Go 1</h2>
-<!-- FAQ -->
+<!--{
+ "Title": "FAQ"
+}-->
<h2 id="Origins">Origins</h2>
-<!-- Go For C++ Programmers -->
+<!--{
+ "Title": "Go For C++ Programmers"
+}-->
<p>
Go is a systems programming language intended to be a general-purpose
-<!-- The Go Memory Model -->
-<!-- subtitle Version of June 10, 2011 -->
+<!--{
+ "Title": "The Go Memory Model",
+ "Subtitle": "Version of June 10, 2011"
+}-->
<style>
p.rule {
-<!-- title The Go Programming Language Specification -->
-<!-- subtitle Version of January 13, 2012 -->
+<!--{
+ "Title": "The Go Programming Language Specification",
+ "Subtitle": "Version of January 13, 2012"
+}-->
<!--
TODO
-<!-- A Tutorial for the Go Programming Language -->
+<!--{
+ "Title": "A Tutorial for the Go Programming Language"
+}-->
<!--
DO NOT EDIT: created by
tmpltohtml go_tutorial.tmpl
-<!-- A Tutorial for the Go Programming Language -->
+<!--{
+ "Title": "A Tutorial for the Go Programming Language"
+}-->
{{donotedit}}
<h2>Introduction</h2>
-<!-- Getting Started -->
+<!--{
+ "Title": "Getting Started"
+}-->
<h2 id="introduction">Introduction</h2>
-<!-- About the Go Playground -->
+<!--{
+ "Title": "About the Go Playground"
+}-->
<div class="left-column">
<p>
import (
"bytes"
+ "encoding/json"
"flag"
"fmt"
"go/ast"
// Files
var (
- titleRx = regexp.MustCompile(`<!-- title ([^\-]*)-->`)
- subtitleRx = regexp.MustCompile(`<!-- subtitle ([^\-]*)-->`)
- firstCommentRx = regexp.MustCompile(`<!--([^\-]*)-->`)
+ doctype = []byte("<!DOCTYPE ")
+ jsonStart = []byte("<!--{")
+ jsonEnd = []byte("}-->")
)
-func extractString(src []byte, rx *regexp.Regexp) (s string) {
- m := rx.FindSubmatch(src)
- if m != nil {
- s = strings.TrimSpace(string(m[1]))
- }
- return
+type Metadata struct {
+ Title string
+ Subtitle string
}
func serveHTMLDoc(w http.ResponseWriter, r *http.Request, abspath, relpath string) {
// if it begins with "<!DOCTYPE " assume it is standalone
// html that doesn't need the template wrapping.
- if bytes.HasPrefix(src, []byte("<!DOCTYPE ")) {
+ if bytes.HasPrefix(src, doctype) {
w.Write(src)
return
}
+ // if it begins with a JSON blob, read in the metadata.
+ var meta Metadata
+ if bytes.HasPrefix(src, jsonStart) {
+ if end := bytes.Index(src, jsonEnd); end > -1 {
+ b := src[len(jsonStart)-1 : end+1] // drop leading <!-- and include trailing }
+ if err := json.Unmarshal(b, &meta); err != nil {
+ log.Printf("decoding metadata for %s: %v", relpath, err)
+ }
+ src = src[end+len(jsonEnd):]
+ }
+ }
+
// if it's the language spec, add tags to EBNF productions
if strings.HasSuffix(abspath, "go_spec.html") {
var buf bytes.Buffer
src = buf.Bytes()
}
- // 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(w, title, subtitle, "", src)
+ servePage(w, meta.Title, meta.Subtitle, "", src)
}
func applyTemplate(t *template.Template, name string, data interface{}) []byte {