// 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 }