83 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			83 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
// 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
 | 
						|
}
 |