diff options
author | Robert Griesemer <gri@golang.org> | 2009-12-17 14:10:49 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2009-12-17 14:10:49 -0800 |
commit | 7fcf4221812c8e875b4ff56632b82d2d0f560519 (patch) | |
tree | 7d506420bf5c12e1450536b83d7e2f53447202db | |
parent | d2a835fbf3f22ca3b3e5fb51c8c2756c8a7b2550 (diff) | |
download | go-7fcf4221812c8e875b4ff56632b82d2d0f560519.tar.gz go-7fcf4221812c8e875b4ff56632b82d2d0f560519.zip |
use new tab indentation format in godoc, but convert
leading tabs into spaces to ensure a good outcome in
most browsers
R=rsc
https://golang.org/cl/165051
-rw-r--r-- | src/cmd/godoc/godoc.go | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go index 1e4eb1625b..a381c3a586 100644 --- a/src/cmd/godoc/godoc.go +++ b/src/cmd/godoc/godoc.go @@ -454,15 +454,83 @@ func (s *Styler) Token(tok token.Token) (text []byte, tag printer.HTMLTag) { // ---------------------------------------------------------------------------- +// Tab conversion + +var spaces = strings.Bytes(" ") // 16 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(n int) (err os.Error) { + i := n * *tabwidth + for i > len(spaces) { + i -= len(spaces) + if _, err = p.output.Write(spaces); err != nil { + return + } + } + _, err = p.output.Write(spaces[0:i]) + return +} + + +func (p *tconv) Write(data []byte) (n int, err os.Error) { + pos := 0 // valid if p.state == collecting + var b byte + for n, b = range data { + switch p.state { + case indenting: + if b == '\t' { + p.indent++ + } else { + p.state = collecting + pos = n + if err = p.writeIndent(p.indent); 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 p.state == collecting { + _, err = p.output.Write(data[pos:]) + } + return +} + + +// ---------------------------------------------------------------------------- // Templates // Write an AST-node to w; optionally html-escaped. func writeNode(w io.Writer, node interface{}, html bool, styler printer.Styler) { - mode := printer.UseSpaces | printer.NoSemis + mode := printer.TabIndent | printer.UseSpaces | printer.NoSemis if html { mode |= printer.GenHTML } - (&printer.Config{mode, *tabwidth, styler}).Fprint(w, node) + // convert trailing tabs into spaces using a tconv filter + // to ensure a good outcome in most browsers (there may still + // be tabs in comments and strings, but converting those into + // the right number of spaces is much harder) + (&printer.Config{mode, *tabwidth, styler}).Fprint(&tconv{output: w}, node) } |