# package tabwriter

`import "text/tabwriter"`

tabwriter包实现了写入过滤器（tabwriter.Writer），可以将输入的缩进修正为正确的对齐文本。

本包采用的Elastic Tabstops算法参见http://nickgravgaard.com/elastictabstops/index.html

## Constants

    const (
        // 忽略html标签，并将字符实体（以'&'开始，以';'结束）视为单字符
        FilterHTML uint = 1 << iota
        // 将转义后文本两端的转义字符去掉
        StripEscape
        // 强制单元格右对齐，默认是左对齐的
        AlignRight
        // 剔除空行
        DiscardEmptyColumns
        // 使用tab而不是空格进行缩进
        TabIndent
        // 在格式化后在每一列两侧添加'|'并忽略空行
        Debug
    )

这些标志用于控制格式化。

    const Escape = '\xff'

用于包围转义字符，避免该字符被转义；例如字符串"Ignore this tab: \xff\t\xff"中的'\t'不被转义，不结束单元；格式化时Escape视为长度1的单字符。

选择'\xff'是因为该字符不能出现在合法的utf-8序列里。

## type Writer

    type Writer struct {
        // 内含隐藏或非导出字段
    }

Writer是一个过滤器，会在输入的tab划分的列进行填充，在输出中对齐它们。

它会将输入的序列视为utf-8编码的文本，包含一系列被垂直制表符、水平制表符、换行符、回车符分割的单元。临近的单元组成一列，根据需要填充空格使所有的单元有相同的宽度，高效对齐各列。它假设所有的字符都有相同的宽度，除了tab，tab宽度应该被指定。注意单元以tab截止，而不是被tab分隔，行最后的非tab文本不被视为列的单元。

Writer假设所有的unicode字符有着同样的宽度，这一点其实在很多字体里是错误的。

如果设置了DiscardEmptyColumns，以垂直制表符结尾的空列会被丢弃，水平制表符截止的空列则不会被影响。

如果设置了FilterHTML，HTML标签和实体会被放过，标签宽度视为0，实体宽度视为1。文本段可能被转义字符包围，此时tabwriter不会修改该文本段，不会打断段中的任何tab或换行。

如果设置了StripEscape，则不会计算转义字符的宽度（输出中也会去除转义字符）。

进纸符'\f'被视为换行，但也会截止当前行的所有列（有效的刷新）；除非在HTML标签内或者在转义文本段内，输出中'\f'都被作为换行。

Writer会在内部缓存输入以便有效的对齐，调用者必须在写完后执行Flush方法。

### func NewWriter

    func NewWriter(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer

创建并初始化一个tabwriter.Writer，参数用法和Init函数类似。

### func (*Writer) Init

    func (b *Writer) Init(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer

初始化一个Writer，第一个参数指定格式化后的输出目标，其余的参数控制格式化：

    minwidth 最小单元长度
    tabwidth tab字符的宽度
    padding  计算单元宽度时会额外加上它
    padchar  用于填充的ASCII字符，
             如果是'\t'，则Writer会假设tabwidth作为输出中tab的宽度，且单元必然左对齐。
    flags    格式化控制

Example

    w := new(tabwriter.Writer)
    // Format in tab-separated columns with a tab stop of 8.
    w.Init(os.Stdout, 0, 8, 0, '\t', 0)
    fmt.Fprintln(w, "a\tb\tc\td\t.")
    fmt.Fprintln(w, "123\t12345\t1234567\t123456789\t.")
    fmt.Fprintln(w)
    w.Flush()
    // Format right-aligned in space-separated columns of minimal width 5
    // and at least one blank of padding (so wider column entries do not
    // touch each other).
    w.Init(os.Stdout, 5, 0, 1, ' ', tabwriter.AlignRight)
    fmt.Fprintln(w, "a\tb\tc\td\t.")
    fmt.Fprintln(w, "123\t12345\t1234567\t123456789\t.")
    fmt.Fprintln(w)
    w.Flush()

Output:

    a	b	c	d		.
    123	12345	1234567	123456789	.
        a     b       c         d.
      123 12345 1234567 123456789.

### func (*Writer) Write

    func (b *Writer) Write(buf []byte) (n int, err error)

将buf写入b，实现io.Writer接口，只有在写入底层输出流是才可能发生并返回错误。

### func (*Writer) Flush

    func (b *Writer) Flush() (err error)

在最后一次调用Write后，必须调用Flush方法以清空缓存，并将格式化对齐后的文本写入生成时提供的output中。