diff --git a/tool/generate.go b/tool/generate.go index 3004615..44de80e 100644 --- a/tool/generate.go +++ b/tool/generate.go @@ -3,12 +3,16 @@ package main import ( + "fmt" + "io/ioutil" "os" "os/exec" - "io/ioutil" - "fmt" + "regexp" + "strings" ) +var docsPat = regexp.MustCompile("^\\s*\\/\\/\\s") + // Just be sure to blow up on non-nil errors. func check(err error) { if err != nil { @@ -16,6 +20,8 @@ func check(err error) { } } +// Pipe source data through binary at path with +// given argv, return the output. func pipedCmd(path string, argv []string, source string) string { cmd := exec.Command(path, argv...) in, err := cmd.StdinPipe() @@ -35,6 +41,10 @@ func pipedCmd(path string, argv []string, source string) string { return string(bytes) } +type segment struct { + docs, code string +} + func main() { // Accept exactly 1 argument - the input filename. if len(os.Args) != 2 { @@ -44,16 +54,45 @@ func main() { // Ensure that we have `markdown` and `pygmentize`, // binaries, remember their paths. - // markdownPath, err := exec.LookPath("markdown"); - // check(err) - // pygmentizePath, err := exec.LookPath("pygmentize") - // check(err) + markdownPath, err := exec.LookPath("markdown") + check(err) + pygmentizePath, err := exec.LookPath("pygmentize") + check(err) + fmt.Println(markdownPath, pygmentizePath) // Read the source file in. sourceBytes, err := ioutil.ReadFile(os.Args[1]) check(err) - source := string(sourceBytes) - fmt.Print(source) - // ... + // Split into lines. + lines := strings.Split(string(sourceBytes), "\n") + + // Group lines into docs/code segments. + segments := []*segment{} + segments = append(segments, &segment{code: "", docs: ""}) + lastLine := "" + for _, line := range lines { + head := segments[len(segments)-1] + // Doc line. Trim off the comment markers. + if (line == "" && lastLine == "docs") || docsPat.MatchString(line) { + trimLine := docsPat.ReplaceAllString(line, "") + if !(lastLine == "code" && head.docs != "") { + head.docs = head.docs + "\n" + trimLine + } else { + segments = append(segments, &segment{docs: trimLine, code: ""}) + } + lastLine = "docs" + // Code line. Preserve all whitespace. + } else { + if !(lastLine == "docs" && head.code != "") { + head.code = head.code + "\n" + line + } else { + segments = append(segments, &segment{docs: "", code: line}) + } + lastLine = "code" + } + } + for _, seg := range segments { + fmt.Printf("%#v\n", *seg) + } }