godoc: actually include files from previous CL
This stuff was deleted from cmd/godoc, and is
moving into pkg godoc.
R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/11425043
diff --git a/godoc/tab.go b/godoc/tab.go
new file mode 100644
index 0000000..012fab6
--- /dev/null
+++ b/godoc/tab.go
@@ -0,0 +1,77 @@
+// TODO(bradfitz,adg): move to util
+
+package godoc
+
+import "io"
+
+var spaces = []byte(" ") // 32 spaces seems like a good number
+
+const (
+ indenting = iota
+ collecting
+)
+
+// A tconv is an io.Writer filter for converting leading tabs into spaces.
+type tconv struct {
+ output io.Writer
+ state int // indenting or collecting
+ indent int // valid if state == indenting
+}
+
+func (p *tconv) writeIndent() (err error) {
+ i := p.indent
+ for i >= len(spaces) {
+ i -= len(spaces)
+ if _, err = p.output.Write(spaces); err != nil {
+ return
+ }
+ }
+ // i < len(spaces)
+ if i > 0 {
+ _, err = p.output.Write(spaces[0:i])
+ }
+ return
+}
+
+func (p *tconv) Write(data []byte) (n int, err error) {
+ if len(data) == 0 {
+ return
+ }
+ pos := 0 // valid if p.state == collecting
+ var b byte
+ for n, b = range data {
+ switch p.state {
+ case indenting:
+ switch b {
+ case '\t':
+ p.indent += TabWidth
+ case '\n':
+ p.indent = 0
+ if _, err = p.output.Write(data[n : n+1]); err != nil {
+ return
+ }
+ case ' ':
+ p.indent++
+ default:
+ p.state = collecting
+ pos = n
+ if err = p.writeIndent(); err != nil {
+ return
+ }
+ }
+ case collecting:
+ if b == '\n' {
+ p.state = indenting
+ p.indent = 0
+ if _, err = p.output.Write(data[pos : n+1]); err != nil {
+ return
+ }
+ }
+ }
+ }
+ n = len(data)
+ if pos < n && p.state == collecting {
+ _, err = p.output.Write(data[pos:])
+ }
+ return
+}