diff --git a/src/contents/contents.html b/src/contents/contents.html
index 1e8b6cd..6a46643 100644
--- a/src/contents/contents.html
+++ b/src/contents/contents.html
@@ -1,7 +1,7 @@
 <h2>Contents</h2>
 
 <ul class="toc">
-  <li><a href="#009-for">For</a></li>
-  <li><a href="#023-pointers">Pointers</a></li>
-  <li><a href="#041-worker-pools">Worker Pools</a></li>
+  <li><a href="#for">For</a></li>
+  <li><a href="#pointers">Pointers</a></li>
+  <li><a href="#worker-pools">Worker Pools</a></li>
 </ul>
diff --git a/src/signals/signals.go b/src/signals/signals.go
index d4a68b0..b5d9dd6 100644
--- a/src/signals/signals.go
+++ b/src/signals/signals.go
@@ -37,6 +37,6 @@ func main() {
     // The program will wait here until it gets the
     // expected signal, and then exit.
     fmt.Println("awaiting signal")
-    <- done
+    <-done
     fmt.Println("exiting")
 }
diff --git a/tool/build-html b/tool/build-html
index b8a16e6..d01a53b 100755
--- a/tool/build-html
+++ b/tool/build-html
@@ -1,3 +1,3 @@
 #!/bin/bash
 
-exec go run tool/build-html.go
+exec go run tool/build-html.go $1
diff --git a/tool/build-html.go b/tool/build-html.go
index 2644de9..4e5a9b8 100644
--- a/tool/build-html.go
+++ b/tool/build-html.go
@@ -171,38 +171,74 @@ func parseAndRenderSegs(sourcePath string) []*seg {
 }
 
 func main() {
+    if len(os.Args) != 2 {
+        panic("Wrong number of args")
+    }
+    outF, err := os.Create(os.Args[1])
+    if err != nil {
+        panic(err)
+    }
     ensureCache()
-    fmt.Print(`<!DOCTYPE html>
-               <html>
-                 <head>
-                   <meta http-eqiv="content-type" content="text/html;charset=utf-8">
-                   <title>Go by Example</title>
-                   <link rel=stylesheet href="../style/book.css">
-                 </head>
-                 <body>`)
-    chapterPaths := mustGlob("./src/0*")
-    for _, chapterPath := range chapterPaths {
-        if strings.HasSuffix(chapterPath, ".html") {
-            
-        } else {
-            fmt.Printf(`<table cellspacing="0" cellpadding="0" id="%s"><tbody>`, chapterPath)
-            sourcePaths := mustGlob(chapterPath + "/*")
-            for _, sourcePath := range sourcePaths {
-                segs := parseAndRenderSegs(sourcePath)
-                for _, seg := range segs {
-                    codeClasses := "code"
-                    if seg.code == "" {
-                        codeClasses = codeClasses + " empty"
-                    }
-                    fmt.Printf(
-                        `<tr>
-    		    		 <td class=docs>%s</td>
-    		    		 <td class="%s">%s</td>
-    		    		 </tr>`, seg.docsRendered, codeClasses, seg.codeRendered)
-                }
-            }
-            fmt.Print(`</tbody></table>`)
+    fmt.Fprint(outF,
+        `<!DOCTYPE html>
+        <html>
+          <head>
+            <meta http-eqiv="content-type" content="text/html;charset=utf-8">
+            <title>Go by Example</title>
+            <link rel=stylesheet href="../src/book.css">
+          </head>
+          <body>`)
+
+    indexBytes, err := ioutil.ReadFile("src/index.txt")
+    if err != nil {
+        panic(err)
+    }
+    indexLines := strings.Split(string(indexBytes), "\n")
+    indexNames := make([]string, 0)
+    for _, indexLine := range indexLines {
+        if indexLine != "" && !strings.Contains(indexLine, "#") && !strings.Contains(indexLine, "~") {
+            indexNames = append(indexNames, indexLine)
         }
     }
-    fmt.Print(`</body></html>`)
+
+    for _, indexName := range indexNames {
+        fmt.Fprintf(outF, `<div id="%s">`, indexName)
+        if (indexName == "title") || (indexName == "contents") || (indexName == "introduction") {
+            sourcePath := "src/" + indexName + "/" + indexName + ".html"
+            sourceBytes, err := ioutil.ReadFile(sourcePath)
+            if err != nil {
+                panic(err)
+            }
+            _, err = outF.Write(sourceBytes)
+            if err != nil {
+                panic(err)
+            }
+        } else {
+            chapterPath := "src/" + indexName
+            fmt.Fprintf(outF,
+                `<table cellspacing="0" cellpadding="0" id="%s"><tbody>`,
+                chapterPath)
+            sourcePaths := mustGlob(chapterPath + "/*")
+            for _, sourcePath := range sourcePaths {
+                if strings.HasSuffix(sourcePath, ".go") || strings.HasSuffix(sourcePath, ".sh") {
+                    segs := parseAndRenderSegs(sourcePath)
+                    for _, seg := range segs {
+                        codeClasses := "code"
+                        if seg.code == "" {
+                            codeClasses = codeClasses + " empty"
+                        }
+                        fmt.Fprintf(outF,
+                            `<tr>
+    		        		 <td class=docs>%s</td>
+    		        		 <td class="%s">%s</td>
+    		        		 </tr>`,
+                            seg.docsRendered, codeClasses, seg.codeRendered)
+                    }
+                }
+            }
+            fmt.Fprint(outF, `</tbody></table>`)
+        }
+        fmt.Fprintf(outF, `</div>`)
+    }
+    fmt.Fprint(outF, `</body></html>`)
 }
diff --git a/tool/build-pdf b/tool/build-pdf
index 9bc8d64..f0bdc86 100755
--- a/tool/build-pdf
+++ b/tool/build-pdf
@@ -1,3 +1,3 @@
 #!/bin/bash
 
-exec prince build/gobyexample.html -o build/gobyexample.pdf
+exec prince $1 -o $2
diff --git a/tool/gofmt b/tool/gofmt
index 31481f7..1afd1ba 100755
--- a/tool/gofmt
+++ b/tool/gofmt
@@ -3,4 +3,4 @@
 set -e
 set -o pipefail
 
-ls tool/src/*.go src/*/*.go | xargs gofmt -tabs=false -tabwidth=4 -w=true
+ls tool/*.go src/*/*.go | xargs gofmt -tabs=false -tabwidth=4 -w=true