devtools/hackdoc: render TOC

Change-Id: I03c224675c0d142d630d872994658faa2ac70691
diff --git a/devtools/hackdoc/markdown.go b/devtools/hackdoc/markdown.go
index fb46c5d..06e2c6e 100644
--- a/devtools/hackdoc/markdown.go
+++ b/devtools/hackdoc/markdown.go
@@ -16,13 +16,16 @@
 // renderMarkdown renders markdown to HTML, replacing all relative (intra-hackdoc) links with version that have ref set.
 func renderMarkdown(input []byte, ref string) []byte {
 	r := blackfriday.NewHTMLRenderer(blackfriday.HTMLRendererParameters{
-		Flags: blackfriday.CommonHTMLFlags,
+		Flags: blackfriday.CommonHTMLFlags | blackfriday.TOC,
 	})
 
 	parser := blackfriday.New(blackfriday.WithRenderer(r), blackfriday.WithExtensions(blackfriday.CommonExtensions))
 	ast := parser.Parse(input)
 
 	var buf bytes.Buffer
+	buf.Write([]byte(`<div class="toc"><h1>Page Contents</h1>`))
+	r.RenderHeader(&buf, ast)
+	buf.Write([]byte(`</div><div class="content">`))
 	ast.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
 		if ref != "" && entering && node.Type == blackfriday.Link {
 			dest := string(node.Destination)
@@ -37,6 +40,8 @@
 		}
 		return r.RenderNode(&buf, node, entering)
 	})
+	buf.Write([]byte(`</div>`))
+	r.RenderFooter(&buf, ast)
 	return buf.Bytes()
 }
 
diff --git a/devtools/hackdoc/tpl/default.html b/devtools/hackdoc/tpl/default.html
index a6c1d42..3e3b268 100644
--- a/devtools/hackdoc/tpl/default.html
+++ b/devtools/hackdoc/tpl/default.html
@@ -122,57 +122,96 @@
     font-family: helvetica, arial, sans-serif;
 }
 
-h1 {
+.content h1 {
     font-size: 1.6em;
     padding: 1em 0 0 0;
     font-weight: 800;
 }
-h2 {
+
+.content h2 {
     font-size: 1.3em;
     padding: 0.8em 0 0 0;
     color: #333;
     font-weight: 800;
 }
-h3 {
+
+.content h3 {
     font-size: 1.2em;
     padding: 0.4em 0 0 0;
     color: #444;
 }
-h4 {
+
+.content h4 {
     font-size: 1.0em;
     color: #555;
 }
-code {
+
+.content code {
     font-family: Consolas, monospace;
     background-color: #f8f8f8;
 }
-pre {
+
+.content pre {
     background-color: #f8f8f8;
     border: 1px solid #d8d8d8;
     margin: 1em;
     padding: 0.5em;
     overflow: auto;
 }
-p {
+
+.content p {
     margin-top: 0.8em;
     line-height: 1.5em;
 }
 
-ul {
+.content ul {
     padding-top: 0.5em;
 }
 
-ul li {
+.content ul li {
     padding-left: 1em;
 }
 
-ul li::before {
+.content ul li::before {
     content: "•";
     color: #333;;
     display: inline-block;
     width: 1em;
     margin-left: -1em;
 }
+
+.toc {
+    float: right;
+    padding: 1em 1em 1em 1em;
+    border: 1px solid #ddd;
+    background-color: #f8f8f8;
+    margin: 2em;
+    max-width: 30%;
+}
+
+.toc h1 {
+    font-size: 1.2em;
+    padding-bottom: 0.5em;
+}
+
+.toc a {
+    text-decoration: none;
+}
+
+.toc li {
+    padding-left: 0.5em;
+}
+
+.toc ul {
+    list-style-type: disc;
+    padding-left: 1em;
+}
+
+.toc ul ul {
+    list-style-type: circle;
+}
+
+
 </style>
 {{ end }}
 {{ define "body" }}