tabitha

package module
v0.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 28, 2026 License: Apache-2.0 Imports: 7 Imported by: 1

README

tabitha

tabitha is a no-frills tabular formatter for the terminal.

Apache 2.0 License Go Version Go Build Go Report Card

Features

  • Supports padding output to the longest display text, honoring ANSI colors
  • Simple API to add a single header and 0..n lines
  • Add "spacer" lines anywhere in the table. Character output is automatically calculated based on width of other text.
  • Customize line separator, padding character, disable padding or honoring ansi

Build/Test

go test -v -race -cover ./...

Example

The following example demonstrates usage (sans error handling).

tt := tabitha.NewWriter()
tt.Header("First", "Second", "Third", "Fourth")
tt.SpacerLine()
tt.AddLine("I'm first", "I'm second", "I'm third", "I'm fourth")
tt.SpacerLine()
tt.WriteTo(os.Stdout)

Why not text/tabwriter?

This is a little different from text/tabwriter; a main difference being that tabwriter assumes all runes are the same size and includes ANSI codes in width calculations while tabitha does not.

In tabitha, rune width is evaluated using utf8.RuneCountInString. When ANSI support is enabled, tabitha will extract non-ANSI text (the "displayable text") using regex. Since tabitha collects all tabular text before writing out to a target io.Writer, it is not expected to perform as well as tabwriter.

License

This project is licensed under Apache 2.0.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

A Writer provides a tabbed output with padding. This differs from text/tabwriter in the standard library in that Writer has fewer formatting options and honors rune-width of user inputs, whereas text/tabwriter assumes that all characters have the same width.

func NewWriter

func NewWriter() *Writer

NewWriter returns a new Writer with default configuration options

func (*Writer) AddLine

func (w *Writer) AddLine(input ...string) (err error)

AddLine collects the input strings for deferred evaluation of overall table width.

func (*Writer) CellSeparator

func (w *Writer) CellSeparator(separator rune) *Writer

CellSeparator allows the user to modify the cell separator character. Default is newline ('\t').

func (*Writer) Header

func (w *Writer) Header(input ...string) (err error)

Header defines the text for the table header. This is a semantic helper, differing from AddLine in that calling Header more than once will result in a panic.

func (*Writer) IgnoreAnsiWidths

func (w *Writer) IgnoreAnsiWidths(ignoreAnsiWidths bool) *Writer

IgnoreAnsiWidths allows the user configure how displayable text is calculated. Pass true to drop ANSI escape codes from width calculations, or false to include all ANSI escape codes in those calculations.

func (*Writer) LinesEndWith

func (w *Writer) LinesEndWith(end rune) *Writer

LinesEndWith allows the user to modify the line ending character. This is the character which closes a cell, and comes before the newline.

func (*Writer) LinesStartWith

func (w *Writer) LinesStartWith(start rune) *Writer

LinesStartWith allows the user to define a starting rune for the line.

func (*Writer) PaddingCharacter

func (w *Writer) PaddingCharacter(padChar rune) *Writer

PaddingCharacter allows the user to modify a character (specified as rune) to pad a cell when padding is enabled. Default is space (' ')

func (*Writer) SpacerLine

func (w *Writer) SpacerLine() (err error)

SpacerLine registers a line of '-' characters by default. It appends a placeholder row that is formatted using the column widths calculated from the previously added header and rows whenever WriteTo runs. The width of each column is based on the accumulated header and rows that preceded the call.

func (*Writer) WithPadding

func (w *Writer) WithPadding(padding bool) *Writer

WithPadding allows the user to specify whether padding to the width of displayable text is enabled. When IgnoreAnsiWidths is passed true, ANSI codes are extracted from cell text to return "displayable text". When IgnoreAnsiWidths is passed false, all text including ANSI codes are considered in cell width calculations.

func (*Writer) WriteTo

func (w *Writer) WriteTo(writer io.Writer) (n int64, err error)

WriteTo an io.Writer for all collected contents in tabitha.Writer. Returns runes written and an error (if populated). Note that Writer state is reset on completion of the write, allowing the Writer to be used for a new table if desired.

Example
tt := NewWriter()
_ = tt.Header("a", "bb", "cc", "dd")
_ = tt.SpacerLine()
_ = tt.AddLine("Line 1", "Under bb", "Third", "4th")
_ = tt.AddLine("cat", "dog", "bird", "frog")
_ = tt.SpacerLine()
_, _ = tt.WriteTo(os.Stdout)
Output:
    a	      bb	   cc	  dd
------	--------	-----	----
Line 1	Under bb	Third	 4th
   cat	     dog	 bird	frog
------	--------	-----	----
Example (IgnoreAnsiWidths)
// Jim Schubert => column width of 12 characters rather than 100+
jim := "\u001B[31mJ\u001B[39m\u001B[33mi\u001B[39m\u001B[32mm\u001B[39m \u001B[35mS\u001B[39m\u001B[31mc\u001B[39m\u001B[33mh\u001B[39m\u001B[32mu\u001B[39m\u001B[34mb\u001B[39m\u001B[35me\u001B[39m\u001B[31mr\u001B[39m\u001B[33mt\u001B[39m"
tt := NewWriter()
tt.IgnoreAnsiWidths(true)
_ = tt.Header("Name", "Occupation")
_ = tt.SpacerLine()
_ = tt.AddLine(jim, "Software Engineer")
_ = tt.AddLine("Al Bundy", "Shoe Salesman")
_ = tt.SpacerLine()
_, _ = tt.WriteTo(os.Stdout)
Output:
Name	       Occupation
------------	-----------------
�[31mJ�[39m�[33mi�[39m�[32mm�[39m �[35mS�[39m�[31mc�[39m�[33mh�[39m�[32mu�[39m�[34mb�[39m�[35me�[39m�[31mr�[39m�[33mt�[39m	Software Engineer
    Al Bundy	    Shoe Salesman
------------	-----------------
Example (WithInitialization)
tt := NewWriter()
tt.WithPadding(true)
tt.LinesEndWith('|')
tt.LinesStartWith('|')
tt.PaddingCharacter(' ')
tt.CellSeparator(' ')
tt.IgnoreAnsiWidths(true)

// Table example from https://www.markdownguide.org/extended-syntax/#alignment
_ = tt.Header("Syntax", "Description", "Test Text")
_ = tt.AddLine(":---", ":----:", "---:")
_ = tt.AddLine("Header", "Title", "Here's this")
_ = tt.AddLine("Paragraph", "Text", "And more")
_, _ = tt.WriteTo(os.Stdout)
Output:
|   Syntax |Description |  Test Text|
|     :--- |     :----: |       ---:|
|   Header |      Title |Here's this|
|Paragraph |       Text |   And more|

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL