This commit is contained in:
Mark McGranaghan 2012-10-01 08:01:39 -07:00
parent ebec3473f2
commit 9a3987c96a
8 changed files with 139 additions and 315 deletions

View File

@ -16,11 +16,3 @@ $ go run tool/number.go
```console ```console
$ tool/gofmt $ tool/gofmt
``` ```
### Golit'ing
```console
$ go run tool/generate.go tool/generate > build/generate.html
$ open build/generate.html
```

View File

@ -8,7 +8,7 @@ func main() {
// Non-blocking receive. // Non-blocking receive.
select { select {
case msg := <- messages: case msg := <-messages:
fmt.Println("received message", msg) fmt.Println("received message", msg)
default: default:
fmt.Println("no messages received") fmt.Println("no messages received")
@ -25,9 +25,9 @@ func main() {
// Non-blocking multi-way select. // Non-blocking multi-way select.
select { select {
case msg := <- messages: case msg := <-messages:
fmt.Println("received message", msg) fmt.Println("received message", msg)
case sig := <- signals: case sig := <-signals:
fmt.Println("received signal", sig) fmt.Println("received signal", sig)
default: default:
fmt.Println("no activity") fmt.Println("no activity")

View File

@ -9,7 +9,7 @@ func main() {
go func() { go func() {
for { for {
_, more := <- jobs _, more := <-jobs
if more { if more {
fmt.Println("received job") fmt.Println("received job")
} else { } else {
@ -20,7 +20,7 @@ func main() {
} }
}() }()
for i := 0; i < 5 ; i++ { for i := 0; i < 5; i++ {
jobs <- false jobs <- false
fmt.Println("sent job") fmt.Println("sent job")
} }
@ -29,5 +29,5 @@ func main() {
close(jobs) close(jobs)
fmt.Println("sent all") fmt.Println("sent all")
<- done <-done
} }

View File

@ -35,9 +35,9 @@ func manageState(reads chan *readOp, writes chan *writeOp) {
data := make(map[int]int) data := make(map[int]int)
for { for {
select { select {
case read := <- reads: case read := <-reads:
read.resp <- data[read.key] read.resp <- data[read.key]
case write := <- writes: case write := <-writes:
data[write.key] = write.val data[write.key] = write.val
write.resp <- true write.resp <- true
} }
@ -53,7 +53,7 @@ func generateReads(reads chan *readOp) {
key := randKey() key := randKey()
read := &readOp{key: key, resp: make(chan int)} read := &readOp{key: key, resp: make(chan int)}
reads <- read reads <- read
<- read.resp <-read.resp
atomic.AddInt64(&opCount, 1) atomic.AddInt64(&opCount, 1)
} }
} }
@ -65,7 +65,7 @@ func generateWrites(writes chan *writeOp) {
val := randVal() val := randVal()
write := &writeOp{key: key, val: val, resp: make(chan bool)} write := &writeOp{key: key, val: val, resp: make(chan bool)}
writes <- write writes <- write
<- write.resp <-write.resp
atomic.AddInt64(&opCount, 1) atomic.AddInt64(&opCount, 1)
} }
} }

View File

@ -1,168 +0,0 @@
// ## golit
// **golit** generates literate-programming style HTML
// documentation from a Go source files.
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"regexp"
"strings"
)
// Recognize doc lines, extract their comment prefixes.
var docsPat = regexp.MustCompile("^\\s*\\/\\/\\s")
// Recognize title prefixes, for titling web page.
var titlePat = regexp.MustCompile("^\\/\\/\\s##\\s")
// Abort on non-nil errors.
func check(err error) {
if err != nil {
panic(err)
}
}
// We'll implement Markdown rendering and Pygments
// syntax highlighting by piping the source data through
// external programs. This is a general helper for
// handling both cases.
func pipe(bin string, arg []string, src string) string {
cmd := exec.Command(bin, arg...)
in, err := cmd.StdinPipe()
check(err)
out, err := cmd.StdoutPipe()
check(err)
err = cmd.Start()
check(err)
in.Write([]byte(src))
check(err)
err = in.Close()
check(err)
bytes, err := ioutil.ReadAll(out)
check(err)
err = cmd.Wait()
check(err)
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 seg struct {
docs, code, docsRendered, codeRendered string
}
func main() {
// Accept exactly 1 argument - the input filename,
// less the .go extension.
if len(os.Args) != 2 {
fmt.Fprintln(os.Stderr, "unexpected args")
os.Exit(1)
}
// 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)
// Read the source file in, split into lines.
srcBytes, err := ioutil.ReadFile(os.Args[1]+".go")
check(err)
lines := strings.Split(string(srcBytes), "\n")
// Group lines into docs/code segments. First,
// special case the header to go in its own segment.
headerDoc := docsPat.ReplaceAllString(lines[0], "")
segs := []*seg{}
segs = append(segs, &seg{code: "", docs: headerDoc})
// Then handle the remaining as code/doc pairs.
segs = append(segs, &seg{code: "", docs: ""})
last := ""
for _, line := range lines[2:] {
head := segs[len(segs)-1]
docsMatch := docsPat.MatchString(line)
emptyMatch := line == ""
lastDocs := last == "docs"
newDocs := (last == "code") && head.docs != ""
newCode := (last == "docs") && head.code != ""
// Docs line - strip out comment indicator.
if docsMatch || (emptyMatch && lastDocs) {
trimed := docsPat.ReplaceAllString(line, "")
if newDocs {
newSeg := seg{docs: trimed, code: ""}
segs = append(segs, &newSeg)
} else {
head.docs = head.docs + "\n" + trimed
}
last = "docs"
// Code line - preserve all whitespace.
} else {
if newCode {
newSeg := seg{docs: "", code: line}
segs = append(segs, &newSeg)
} else {
head.code = head.code + "\n" + line
}
last = "code"
}
}
// Render docs via `markdown` and code via
// `pygmentize` in each segment.
for _, seg := range segs {
seg.docsRendered = pipe(
markdownPath,
[]string{},
seg.docs)
seg.codeRendered = pipe(
pygmentizePath,
[]string{"-l", "go", "-f", "html"},
seg.code+" ")
}
// Print HTML header.
title := titlePat.ReplaceAllString(lines[0], "")
fmt.Printf(`
<!DOCTYPE html>
<html>
<head>
<meta http-eqiv="content-type"
content="text/html;charset=utf-8">
<title>%s</title>
<link rel=stylesheet href="../style/lit.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>`, title)
// Print HTML docs/code segments.
for _, seg := range segs {
fmt.Printf(
`<tr>
<td class=docs>%s</td>
<td class=code>%s</td>
</tr>`, seg.docsRendered, seg.codeRendered)
}
// Print HTML footer.
fmt.Print(`</tbody>
</table>
</div>
</body>
</html>`)
}

View File

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
ls */*.go | xargs -n 1 gofmt -tabs=false -tabwidth=4 -w=true ls src/*/*.go | xargs -n 1 gofmt -tabs=false -tabwidth=4 -w=true