diff --git a/tool/generate.go b/tool/generate.go index 9ef09d5..bebba82 100644 --- a/tool/generate.go +++ b/tool/generate.go @@ -17,7 +17,15 @@ func check(err error) { } } -func pipe(bin string, arg []string, src string) string { +func whichRenderers() (string, string) { + markdownPath, err := exec.LookPath("markdown") + check(err) + pygmentizePath, err := exec.LookPath("pygmentize") + check(err) + return markdownPath, pygmentizePath +} + +func render(bin string, arg []string, src string) string { cmd := exec.Command(bin, arg...) in, _ := cmd.StdinPipe() out, _ := cmd.StdoutPipe() @@ -31,9 +39,19 @@ func pipe(bin string, arg []string, src string) string { } func readLines(path string) []string { - srcBytes, err := ioutil.ReadFile(path) + srcBytes, err := ioutil.ReadFile(path) check(err) - return strings.Split(string(srcBytes), "\n") + return strings.Split(string(srcBytes), "\n") +} + +func whichLexer(path string) string { + if strings.HasSuffix(path, ".go") { + return "go" + } else if strings.HasSuffix(path, ".sh") { + return "console" + } + panic("No lexer for " + path) + return "" } var docsPat = regexp.MustCompile("^\\s*(\\/\\/|#)\\s") @@ -44,69 +62,12 @@ type seg struct { } func main() { - if len(os.Args) != 2 { - fmt.Fprintln(os.Stderr, "usage: tool/generate input.go > output.html") + if len(os.Args) <= 1 { + fmt.Fprintln(os.Stderr, "usage: tool/generate *.{go,sh} > output.html") os.Exit(1) } - sourcePath := os.Args[1] - markdownPath, err := exec.LookPath("markdown") - check(err) - pygmentizePath, err := exec.LookPath("pygmentize") - check(err) - - lines := readLines(sourcePath) - - segs := []*seg{} - segs = append(segs, &seg{code: "", docs: ""}) - lastSeen := "" - for _, line := range lines { - headerMatch := headerPat.MatchString(line) - docsMatch := docsPat.MatchString(line) - emptyMatch := line == "" - lastSeg := segs[len(segs)-1] - lastHeader := lastSeen == "header" - lastDocs := lastSeen == "docs" - newHeader := (lastSeen != "header") && lastSeg.docs != "" - newDocs := (lastSeen != "docs") && lastSeg.docs != "" - newCode := (lastSeen != "code") && lastSeg.code != "" - if headerMatch || (emptyMatch && lastHeader) { - trimmed := docsPat.ReplaceAllString(line, "") - if newHeader { - newSeg := seg{docs: trimmed, code: ""} - segs = append(segs, &newSeg) - } else { - lastSeg.docs = lastSeg.docs + "\n" + trimmed - } - lastSeen = "header" - } else if docsMatch || (emptyMatch && lastDocs) { - trimmed := docsPat.ReplaceAllString(line, "") - if newDocs { - newSeg := seg{docs: trimmed, code: ""} - segs = append(segs, &newSeg) - } else { - lastSeg.docs = lastSeg.docs + "\n" + trimmed - } - lastSeen = "docs" - } else { - if newCode { - newSeg := seg{docs: "", code: line} - segs = append(segs, &newSeg) - } else { - lastSeg.code = lastSeg.code + "\n" + line - } - lastSeen = "code" - } - } - - for _, seg := range segs { - if seg.docs != "" { - seg.docsRendered = pipe(markdownPath, []string{}, seg.docs) - } - if seg.code != "" { - seg.codeRendered = pipe(pygmentizePath, []string{"-l", "go", "-f", "html"}, seg.code+" ") - } - } + markdownPath, pygmentizePath := whichRenderers() fmt.Print(` @@ -121,16 +82,73 @@ func main() { `) - for _, seg := range segs { - codeClasses := "code" - if seg.code == "" { - codeClasses = codeClasses + " empty" - } - fmt.Printf( - ` - - - `, seg.docsRendered, codeClasses, seg.codeRendered) + for _, sourcePath := range os.Args[1:] { + lexer := whichLexer(sourcePath) + lines := readLines(sourcePath) + + segs := []*seg{} + segs = append(segs, &seg{code: "", docs: ""}) + lastSeen := "" + for _, line := range lines { + headerMatch := headerPat.MatchString(line) + docsMatch := docsPat.MatchString(line) + emptyMatch := line == "" + lastSeg := segs[len(segs)-1] + lastHeader := lastSeen == "header" + lastDocs := lastSeen == "docs" + newHeader := (lastSeen != "header") && lastSeg.docs != "" + newDocs := (lastSeen != "docs") && lastSeg.docs != "" + newCode := (lastSeen != "code") && lastSeg.code != "" + if headerMatch || (emptyMatch && lastHeader) { + trimmed := docsPat.ReplaceAllString(line, "") + if newHeader { + newSeg := seg{docs: trimmed, code: ""} + segs = append(segs, &newSeg) + } else { + lastSeg.docs = lastSeg.docs + "\n" + trimmed + } + lastSeen = "header" + } else if docsMatch || (emptyMatch && lastDocs) { + trimmed := docsPat.ReplaceAllString(line, "") + if newDocs { + newSeg := seg{docs: trimmed, code: ""} + segs = append(segs, &newSeg) + } else { + lastSeg.docs = lastSeg.docs + "\n" + trimmed + } + lastSeen = "docs" + } else { + if newCode { + newSeg := seg{docs: "", code: line} + segs = append(segs, &newSeg) + } else { + lastSeg.code = lastSeg.code + "\n" + line + } + lastSeen = "code" + } + } + segs = append(segs, &seg{code: "", docs: ""}) + + for _, seg := range segs { + if seg.docs != "" { + seg.docsRendered = render(markdownPath, []string{}, seg.docs) + } + if seg.code != "" { + seg.codeRendered = render(pygmentizePath, []string{"-l", lexer, "-f", "html"}, seg.code+" ") + } + } + + for _, seg := range segs { + codeClasses := "code" + if seg.code == "" { + codeClasses = codeClasses + " empty" + } + fmt.Printf( + ` + + + `, seg.docsRendered, codeClasses, seg.codeRendered) + } } fmt.Print(`
%s%s
%s%s
`) diff --git a/tool/gofmt b/tool/gofmt index c66a42c..331602b 100755 --- a/tool/gofmt +++ b/tool/gofmt @@ -1,3 +1,6 @@ #!/bin/bash -ls src/*/*.go | xargs -n 1 gofmt -tabs=false -tabwidth=4 -w=true +set -e +set -o pipefail + +ls tool/*.go src/*/*.go | xargs -n 1 gofmt -tabs=false -tabwidth=4 -w=true diff --git a/tool/number.go b/tool/number.go index aa6d737..aa87dc5 100644 --- a/tool/number.go +++ b/tool/number.go @@ -28,10 +28,10 @@ func main() { } baseTrimmer, _ := regexp.Compile("^[0-9x]+-") for _, fi := range fileInfos { - if fi.Name() != "index.txt" { - baseName := baseTrimmer.ReplaceAllString(fi.Name(), "") - sourceNames = append(sourceNames, baseName) - sourceMap[baseName] = fi.Name() + if fi.Name() != "index.txt" { + baseName := baseTrimmer.ReplaceAllString(fi.Name(), "") + sourceNames = append(sourceNames, baseName) + sourceMap[baseName] = fi.Name() } }