This commit is contained in:
Mark McGranaghan 2012-09-29 15:12:06 -07:00
parent 6fe814d764
commit 1219a48fa2

View File

@ -27,18 +27,18 @@ func check(err error) {
} }
// We'll implement Markdown rendering and Pygments // We'll implement Markdown rendering and Pygments
// syntax highlighting by piping data through external // syntax highlighting by piping the source data through
// programs. This is a general helper for handling both // external programs. This is a general helper for
// cases. // handling both cases.
func pipe(bin string, args []string, in string) string { func pipe(bin string, arg []string, src string) string {
cmd := exec.Command(bin, args...) cmd := exec.Command(bin, arg...)
in, err := cmd.StdinPipe() in, err := cmd.StdinPipe()
check(err) check(err)
out, err := cmd.StdoutPipe() out, err := cmd.StdoutPipe()
check(err) check(err)
err = cmd.Start() err = cmd.Start()
check(err) check(err)
in.Write([]byte(in)) in.Write([]byte(src))
check(err) check(err)
err = in.Close() err = in.Close()
check(err) check(err)
@ -76,30 +76,36 @@ func main() {
check(err) check(err)
lines := strings.Split(string(srcBytes), "\n") lines := strings.Split(string(srcBytes), "\n")
// Group lines into docs/code segments. // Group lines into docs/code segments. First,
// Special case the header to go in its own segment. // special case the header to go in its own segment.
headerDoc := docsPat.ReplaceAllString(lines[0], "") headerDoc := docsPat.ReplaceAllString(lines[0], "")
segs := []*seg{} segs := []*seg{}
segs = append(segs, &seg{code: "", docs: headerDoc}) segs = append(segs, &seg{code: "", docs: headerDoc})
// Then handle the remaining as code/doc pairs.
segs = append(segs, &seg{code: "", docs: ""}) segs = append(segs, &seg{code: "", docs: ""})
last := "" last := ""
for _, line := range lines[2:] { for _, line := range lines[2:] {
head := segs[len(segs)-1] head := segs[len(segs)-1]
// Doc line - trim off the comment markers. docMatch := docsPat.MatchString(line)
if (line == "" && last == "docs") || docsPat.MatchString(line) { docLast := last == "docs"
trimLine := docsPat.ReplaceAllString(line, "") codeLast := last == "code"
if docMatch || (line == "" && docLast) {
trimed := docsPat.ReplaceAllString(line, "")
if !(last == "code" && head.docs != "") { if !(last == "code" && head.docs != "") {
head.docs = head.docs + "\n" + trimLine head.docs = head.docs + "\n" + trimed
} else { } else {
segs = append(segs, &seg{docs: trimLine, code: ""}) newSeg := seg{docs: trimed, code: ""}
segs = append(segs, &newSeg)
} }
last = "docs" last = "docs"
// Code line - preserve all whitespace. // Code line - preserve all whitespace.
} else { } else {
if !(last == "docs" && head.code != "") { if !(codeLast && head.code != "") {
head.code = head.code + "\n" + line head.code = head.code + "\n" + line
} else { } else {
segs = append(segs, &seg{docs: "", code: line}) newSeg := seg{docs: "", code: line}
segs = append(segs, &newSeg)
} }
last = "code" last = "code"
} }
@ -107,12 +113,12 @@ func main() {
// Render docs via `markdown` and code via // Render docs via `markdown` and code via
// `pygmentize` in each segment. // `pygmentize` in each segment.
for _, seg := range segments { for _, seg := range segs {
seg.docsRendered = pipedCmd( seg.docsRendered = pipe(
markdownPath, markdownPath,
[]string{}, []string{},
seg.docs) seg.docs)
seg.codeRendered = pipedCmd( seg.codeRendered = pipe(
pygmentizePath, pygmentizePath,
[]string{"-l", "go", "-f", "html"}, []string{"-l", "go", "-f", "html"},
seg.code+" ") seg.code+" ")
@ -142,7 +148,7 @@ func main() {
<tbody>`, title) <tbody>`, title)
// Print HTML docs/code segments. // Print HTML docs/code segments.
for _, seg := range segments { for _, seg := range segs {
fmt.Printf( fmt.Printf(
`<tr> `<tr>
<td class=docs>%s</td> <td class=docs>%s</td>