generate proof

This commit is contained in:
Mark McGranaghan 2012-09-24 08:50:54 -07:00
parent 072bc78ecd
commit 1b74499f1f

View File

@ -1,4 +1,7 @@
// Generate HTTML document form a Go source file. // ## golit
// Generate literate-programming style HTTML
// documentation form Go source files.
package main package main
@ -11,17 +14,19 @@ import (
"strings" "strings"
) )
// Recognize doc lines, extract their comment prefixes.
var docsPat = regexp.MustCompile("^\\s*\\/\\/\\s") var docsPat = regexp.MustCompile("^\\s*\\/\\/\\s")
// Just be sure to blow up on non-nil errors. // Abort on non-nil errors.
func check(err error) { func check(err error) {
if err != nil { if err != nil {
panic(err) panic(err)
} }
} }
// Pipe source data through binary at path with // For docs and code rendering: pipe source data
// given argv, return the output. // through binary at path with given argv, return
// the output.
func pipedCmd(path string, argv []string, source string) string { func pipedCmd(path string, argv []string, source string) string {
cmd := exec.Command(path, argv...) cmd := exec.Command(path, argv...)
in, err := cmd.StdinPipe() in, err := cmd.StdinPipe()
@ -41,8 +46,11 @@ func pipedCmd(path string, argv []string, source string) string {
return string(bytes) return string(bytes)
} }
// We'll break the code into {docs, code} pairs,
// and then render those text segments before
// including them in the HTML doc.
type segment struct { type segment struct {
docs, code string docs, code, docsRendered, codeRendered string
} }
func main() { func main() {
@ -58,13 +66,10 @@ func main() {
check(err) check(err)
pygmentizePath, err := exec.LookPath("pygmentize") pygmentizePath, err := exec.LookPath("pygmentize")
check(err) check(err)
fmt.Println(markdownPath, pygmentizePath)
// Read the source file in. // Read the source file in, split into lines.
sourceBytes, err := ioutil.ReadFile(os.Args[1]) sourceBytes, err := ioutil.ReadFile(os.Args[1])
check(err) check(err)
// Split into lines.
lines := strings.Split(string(sourceBytes), "\n") lines := strings.Split(string(sourceBytes), "\n")
// Group lines into docs/code segments. // Group lines into docs/code segments.
@ -73,7 +78,7 @@ func main() {
lastLine := "" lastLine := ""
for _, line := range lines { for _, line := range lines {
head := segments[len(segments)-1] head := segments[len(segments)-1]
// Doc line. Trim off the comment markers. // Doc line - trim off the comment markers.
if (line == "" && lastLine == "docs") || docsPat.MatchString(line) { if (line == "" && lastLine == "docs") || docsPat.MatchString(line) {
trimLine := docsPat.ReplaceAllString(line, "") trimLine := docsPat.ReplaceAllString(line, "")
if !(lastLine == "code" && head.docs != "") { if !(lastLine == "code" && head.docs != "") {
@ -82,7 +87,7 @@ func main() {
segments = append(segments, &segment{docs: trimLine, code: ""}) segments = append(segments, &segment{docs: trimLine, code: ""})
} }
lastLine = "docs" lastLine = "docs"
// Code line. Preserve all whitespace. // Code line - preserve all whitespace.
} else { } else {
if !(lastLine == "docs" && head.code != "") { if !(lastLine == "docs" && head.code != "") {
head.code = head.code + "\n" + line head.code = head.code + "\n" + line
@ -92,7 +97,43 @@ func main() {
lastLine = "code" lastLine = "code"
} }
} }
// Render docs via `markdown` and code via
// `pygmentize`in each segment.
for _, seg := range segments { for _, seg := range segments {
fmt.Printf("%#v\n", *seg) seg.docsRendered = pipedCmd(markdownPath, []string{}, seg.docs)
seg.codeRendered = pipedCmd(pygmentizePath, []string{"-l", "go", "-f", "html"}, seg.code)
} }
// Print HTML header.
fmt.Print(`
<!DOCTYPE html>
<html>
<head>
<meta http-eqiv="content-type" content="text/html;charset=utf-8">
<title>Page Title</title>
<link rel=stylesheet href="book.css">
</head>
<body>
<div id="container">
<div id="background"></div>
<table cellspacing="0" cellpadding="0">
<thead>
<tr><td class=docs></td><td class=code></td></tr>
</thead>
<tbody>`)
// Print HTML docs/code segments.
for _, seg := range segments {
fmt.Printf("<tr><td class=docs>%s</td><td class=code>%s</td></tr>\n", seg.docsRendered, seg.codeRendered)
}
// Print HTML footer.
fmt.Print(`
</tbody>
</table>
</div>
</body>
</html>
`)
} }