|
|
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// 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
p *Presentation }
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 += p.p.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 }
|