output

package module
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Jun 12, 2026 License: MIT Imports: 12 Imported by: 0

README

go-output

CI Go Report Card GoDoc

A Go library that formats structured data into 16 output formats — tables, trees, and diagrams — with type-safe enums, branded IDs, and zero-config color support. Write your data once, render it anywhere.

import "github.com/larsartmann/go-output"

Quick Start

Build tabular data once, render it in any format:

data := output.NewTableData([]string{"Name", "Health", "Complexity"})
data.AddRow([]string{"Alpha", "90%", "7/10"})
data.AddRow([]string{"Beta", "75%", "5/10"})

// Optional footer row (totals/summary)
data.Footer = []string{"Total", "2", "-"}

// Markdown table
md := output.NewMarkdownTable()
md.SetHeaders(data.GetHeaders())
for _, row := range data.GetRows() {
    md.AddRow(row)
}
out, _ := md.Render()

// JSON (any data — from root package)
data, _ := output.MarshalJSONIndent(projects, "", "  ")

// CSV (requires go-output/delimited)
w := delimited.NewCSVWriter(os.Stdout)
w.WriteHeader(data.GetHeaders())
for _, row := range data.GetRows() {
    w.WriteRow(row)
}
w.Flush()

Use the Format enum for runtime format selection — perfect for CLI flags:

format, _ := output.ParseFormat("json") // validates input
fmt.Println(format.Supports(output.ShapeTable)) // true
fmt.Println(format.Shapes())                     // [table tree graph]

Why go-output?

  • 16 formats, one API — Same data, different renderers. No format-specific code paths.
  • Type-safe enumsFormat, ColorMode — all validated at parse time, never raw strings.
  • Zero heavy deps in root modulego get go-output pulls only x/term. YAML is isolated in serialization/, lipgloss in table/, D2 and graph renderers in their own modules.
  • Branded IDs — Phantom types prevent mixing D2NodeID, TreeNodeID, GraphNodeID at compile time.
  • StreamingStreamingHTMLRenderer for large datasets with minimal memory.
  • Zero-config colorColorMode (auto/always/never) with terminal detection. Wired into table, tree, and markdown renderers.

Supported Formats

Format Table Tree Graph Notes
table Terminal tables with lipgloss styling (separate table/ module)
json Shape-agnostic serialization
csv Comma-separated export
tsv Tab-separated export
xml XML with table structure
markdown Markdown tables
yaml Shape-agnostic serialization
d2 SQL tables + node-edge diagrams (separate d2/ module)
html HTML tables + collapsible tree
tree ASCII tree with box-drawing chars
mermaid Mermaid flowchart diagrams (separate graph/ module)
dot DOT/Graphviz directed graphs (separate graph/ module)
jsonl JSON Lines — one JSON object per line (separate serialization/ module)
asciidoc AsciiDoc tables (separate markup/ module)
toml TOML serialization (separate serialization/ module)
plantuml PlantUML component diagrams (separate plantuml/ module)

Set TableData.Footer for an optional totals/summary row. Tabular formats render it visually.

Format Footer Behavior
table Bold-styled footer row
markdown Second separator + bold footer row
csv Appended as last data row
tsv Appended as last data row
html <tfoot> section with footer-cell class
xml <footer> element
asciidoc Footer row cells
json Data serialization — footer skipped
yaml Data serialization — footer skipped
toml Data serialization — footer skipped
jsonl Data serialization — footer skipped
tree Hierarchical format — not tabular
d2 Diagram format — not tabular
mermaid Diagram format — not tabular
dot Diagram format — not tabular
plantuml Diagram format — not tabular
data := output.NewTableData([]string{"Name", "Score"})
data.AddRow([]string{"Alice", "95"})
data.AddRow([]string{"Bob", "87"})
data.SetFooter([]string{"Total", "182"})

All formats implement the Renderer interface:

type Renderer interface {
    Render() (string, error)
}
import (
    "github.com/larsartmann/go-output"
    "github.com/larsartmann/go-output/delimited"
    "github.com/larsartmann/go-output/serialization"
)
Table Formats
// JSON table (array of objects — requires go-output/serialization)
jt := serialization.NewJSONTableRenderer()
jt.SetHeaders([]string{"Name", "Health"})
jt.AddRow([]string{"Alpha", "90%"})
out, _ := jt.Render()
// [{"Name": "Alpha", "Health": "90%"}]

// YAML table (sequence of mappings — requires go-output/serialization)
yt := serialization.NewYAMLTableRenderer()
yt.SetHeaders([]string{"Name", "Health"})
yt.AddRow([]string{"Alpha", "90%"})
out, _ := yt.Render()

// JSON (any data — from root package)
data, _ := output.MarshalJSONIndent(projects, "", "  ")

// CSV (requires go-output/delimited)
w := delimited.NewCSVWriter(os.Stdout)
w.WriteHeader([]string{"Name", "Value"})
w.WriteRow([]string{"Item", "123"})
w.Flush()

// TSV (requires go-output/delimited)
tw := delimited.NewTSVWriter(os.Stdout)
tw.WriteHeader([]string{"Name", "Value"})
tw.WriteRow([]string{"Item", "123"})
tw.Flush()

// XML (requires go-output/markup)
data, _ := markup.MarshalXMLFromTableData(tableData)

// YAML (any data — requires go-output/serialization)
data, _ := serialization.MarshalYAML(projects)

// Markdown table
md := output.NewMarkdownTable()
md.SetHeaders([]string{"Name", "Health"})
md.AddRow([]string{"Alpha", "90%"})
out, _ := md.Render()

// Terminal table with lipgloss styling (requires go-output/table)
tbl := table.New()
tbl.SetHeaders("Name", "Health")
tbl.AddRow("Alpha", "90%")
out, _ := tbl.Render()
Tree Formats
root := output.NewTreeNode("root", "Projects")
root.AddChild(output.NewTreeNode("alpha", "Alpha"))
root.AddChild(output.NewTreeNode("beta", "Beta"))

// ASCII tree
tree := output.NewASCIITreeRenderer()
tree.SetRoot(root)
out, _ := tree.Render()
// Projects
// ├── Alpha
// └── Beta

// JSON tree (requires go-output/serialization)
jt := serialization.NewJSONTreeRenderer()
jt.SetRoot(root)
out, _ := jt.Render()
// {"id": "root", "label": "Projects", "children": [...]}

// YAML tree (requires go-output/serialization)
yt := serialization.NewYAMLTreeRenderer()
yt.SetRoot(root)
out, _ := yt.Render()
// id: root
// label: Projects
// children: ...

// HTML tree (requires go-output/markup)
ht := markup.NewHTMLTreeRenderer()
ht.SetRoot(root)
out, _ := ht.Render()
Graph Formats
import (
    "github.com/larsartmann/go-output"
    "github.com/larsartmann/go-output/d2"
    "github.com/larsartmann/go-output/graph"
)

nodes := []output.GraphNode{
    output.NewGraphNode("a", "API Gateway"),
    output.NewGraphNode("b", "Backend"),
}
edges := []output.GraphEdge{
    output.NewGraphEdge("a", "b"),
}

// DOT / Graphviz (requires go-output/graph)
renderer := graph.DOTFromTableData(data)
out, _ := renderer.Render()

// Mermaid flowchart (requires go-output/graph)
renderer := graph.MermaidFromTableData(data)
out, _ := renderer.Render()

// JSON graph (requires go-output/serialization)
jg := serialization.NewJSONGraphRenderer()
jg.SetNodes(nodes)
jg.SetEdges(edges)
out, _ := jg.Render()
// {"nodes": [...], "edges": [...]}

// YAML graph (requires go-output/serialization)
yg := serialization.NewYAMLGraphRenderer()
yg.SetNodes(nodes)
yg.SetEdges(edges)
out, _ := yg.Render()

// D2 diagrams (requires go-output/d2)
diagram := d2.NewD2Diagram().
    AddNodeWithShape("api", "API Gateway", d2.D2ShapeHexagon).
    AddEdgeSimple("api", "backend")
out, _ := diagram.Render()

Data Shapes

Every format declares which data shapes it supports via the capability matrix:

// Check if a format supports a specific data shape
format, _ := output.ParseFormat("d2")
fmt.Println(format.Supports(output.ShapeTable)) // true (D2 supports SQL tables)
fmt.Println(format.Supports(output.ShapeGraph)) // true (D2 supports node-edge diagrams)
fmt.Println(format.Supports(output.ShapeTree))  // false

// Get all shapes a format supports
for _, shape := range format.Shapes() {
    fmt.Println(shape) // "table", "graph"
}

// Find all formats that can render graph data
for _, f := range output.FormatsForShape(output.ShapeGraph) {
    fmt.Println(f) // json, yaml, d2, mermaid, dot
}

Installation

go get github.com/larsartmann/go-output

Sub-modules for specific formats:

go get github.com/larsartmann/go-output/delimited       # CSV + TSV writers
go get github.com/larsartmann/go-output/serialization   # JSON + YAML marshaling
go get github.com/larsartmann/go-output/markup          # XML + HTML + Streaming HTML
go get github.com/larsartmann/go-output/table           # Terminal tables with lipgloss
go get github.com/larsartmann/go-output/d2              # D2 diagrams
go get github.com/larsartmann/go-output/graph           # DOT + Mermaid renderers

Branded IDs

Type-safe identifiers prevent mixing different ID types at compile time:

nodeID := output.NewBrandedID[output.D2NodeIDBrand]("node-1")
treeID := output.NewBrandedID[output.TreeNodeIDBrand]("root")

// nodeID = treeID  // COMPILE ERROR: different branded types

Define your own branded types:

type ProjectIDBrand struct{}
projectID := output.NewBrandedID[ProjectIDBrand]("proj-123")

D2 Advanced Features

D2 diagrams support SQL tables, constraints, grid layouts, and nested containers:

table := d2.D2Table{
    Name: "users",
    Columns: []d2.D2Column{
        {Name: "id", Type: "INT", Constraint: d2.D2ConstraintPrimary},
        {Name: "email", Type: "VARCHAR(255)", Constraint: d2.D2ConstraintUnique},
        {Name: "manager_id", Type: "INT", Constraint: d2.D2ConstraintForeign},
    },
}

node := d2.D2Node{
    ID:          output.NewBrandedID[output.D2NodeIDBrand]("dashboard"),
    Label:       output.NewBrandedID[output.D2NodeLabelBrand]("Dashboard"),
    GridRows:    3,
    GridColumns: 2,
    GridGap:     8,
}

Color Modes

All terminal renderers support ColorMode for controlling ANSI color output:

// Table: functional options pattern (requires go-output/table)
tbl := table.New(table.WithColorMode(output.ColorModeAlways))

// Tree: setter method
tree := output.NewASCIITreeRenderer()
tree.SetColorMode(output.ColorModeAlways)

// Markdown: setter method (chains)
md := output.NewMarkdownTable().SetColorMode(output.ColorModeAlways)

// RenderTableData dispatch: pass via RenderOptions
output.RenderTableData(data, output.FormatTree,
    output.RenderOptions{ColorMode: output.ColorModeAlways})

Default ColorModeAuto detects terminal via golang.org/x/term, respects NO_COLOR, CI, FORCE_COLOR.

Streaming Renderer

For large datasets, stream output incrementally:

renderer := markup.NewStreamingHTMLRenderer()
renderer.SetData(tableData)
_ = renderer.Stream(os.Stdout)

Type-Safe Enums

All configuration types provide validation and string conversion:

format, err := output.ParseFormat("json")
if format.IsValid() {
    fmt.Println(format.String()) // "json"
}
allowed := format.AllowedValues() // []string{"table", "json", "csv", ...}

Escape Functions

The escape/ subpackage provides safe escaping for each format:

import "github.com/larsartmann/go-output/escape"

safe := escape.HTML("<script>alert('xss')</script>")
safeID := escape.D2("my-node.with.dots")
Function Purpose
escape.HTML HTML special characters
escape.XML XML special characters
escape.D2 D2 diagram identifiers
escape.DOT DOT graph identifiers
escape.MermaidID Mermaid node IDs

TUI Progress Display

The tui sub-module provides a Bubble Tea v2 TUI for real-time workflow progress with dependency tree visualization.

Keyboard Shortcuts
Key Action
j / Scroll down
k / Scroll up
pgdown Scroll half page down
pgup Scroll half page up
g / Home Scroll to top
G / End Scroll to bottom
? Toggle help overlay
q Quit (workflow continues)
ctrl+c Cancel workflow and quit
Mouse Support
Action Behavior
Left click Select/deselect tree node (highlight)
Scroll wheel Scroll viewport (3 lines per tick)

Dependencies

Root module — zero lipgloss, zero yaml in production code. (YAML dep isolated in serialization/ module).

require (
    golang.org/x/term v0.43.0
)

Serialization module (JSON + YAML — install separately):

require (
    github.com/go-faster/yaml v0.4.6
)

Terminal table module (install separately):

require (
    charm.land/lipgloss/v2 v2.0.3
)

D2 diagram module (install separately):

require github.com/larsartmann/go-output/d2 v0.0.0

DOT + Mermaid graph module (install separately):

require github.com/larsartmann/go-output/graph v0.0.0

Examples

See examples/basic/main.go for a complete example demonstrating all 16 formats with color support:

go run ./examples/basic/main.go markdown          # auto color
go run ./examples/basic/main.go tree --color always  # force colors
go run ./examples/basic/main.go table --color never   # no colors

Development

nix develop                    # Enter dev shell (Go 1.26, golangci-lint, gopls)
nix fmt                        # Format .nix files
nix flake check                # Verify formatting + pre-commit hooks
Go toolchain (manual)
go build ./...                  # Build all workspace modules
go test ./...                   # Test all modules
go test -race ./...             # Race detector
go test -cover ./...            # Coverage report
golangci-lint run --fix ./...   # Lint

API Stability

This library is pre-v1. The following guarantees apply:

  • Root module (github.com/larsartmann/go-output): Public API is stable. Breaking changes will be documented in CHANGELOG.md.
  • Sub-modules (d2, graph, table, delimited, serialization, markup, plantuml): May evolve independently. Import them explicitly to opt in.
  • Renderer interface: Stable — all formats implement Render() (string, error).
  • internal/ packages: No stability guarantee. Do not import these.
Frozen Interfaces (v1 locked)

These interfaces will not change signature:

Interface Methods Implementations
Renderer Render() (string, error) All 16 formats
TableRenderer SetHeaders([]string), AddRow([]string), Render() JSON, YAML, TOML, JSONL, HTML, Streaming HTML, AsciiDoc, Markdown (adapter), Table (adapter)
TreeOutputRenderer SetRoot(*TreeNode), Render() ASCII Tree, JSON Tree, YAML Tree, TOML Tree, HTML Tree
GraphRenderer SetNodes([]GraphNode), SetEdges([]GraphEdge), Render() D2, DOT, Mermaid, PlantUML, JSON Graph, YAML Graph, TOML Graph
StreamingRenderer Stream(io.Writer) error, Render() Streaming HTML
Frozen Types (v1 locked)
Type Package Notes
Format root 16 format string constants
Shape root 3 shape constants + capability matrix
ColorMode root auto/always/never + terminal detection
TableData root Headers, Rows, Footer — central data type
TreeNode root Hierarchical node with children
GraphNode / GraphEdge root Graph data model
GraphRendererMixin root Composition for graph renderers
D2Node, D2Edge, D2Table d2 Rich D2 domain model
D2Direction, D2NodeShape, D2ArrowType, D2Constraint d2 D2 enum types
Non-Breaking Changes Only (until v1.0)
  • Adding new Format constants
  • Adding new Shape constants
  • Adding new methods to existing types
  • Adding new RenderOptions fields
  • Adding new sub-modules
  • Adding new RegisterTableDataMarshaler entries

License

MIT

Documentation

Overview

Package output provides a reusable Go library for CLI applications offering consistent output formatting across 16 formats (Table, JSON, CSV, TSV, Markdown, XML, YAML, HTML, Tree, D2, Mermaid, DOT, JSONL, AsciiDoc, TOML, PlantUML) with type-safe enum-based configuration and a Shape capability matrix.

Quick Start

Use TableData as the single source of truth for tabular data:

data := output.NewTableData([]string{"Name", "Status"})
data.AddRow([]string{"Project A", "Active"})
data.Footer = []string{"Total", "1"}

Render to any supported format:
var buf bytes.Buffer
_ = output.RenderTableData(data, output.FormatMarkdown, output.RenderOptions{Writer: &buf})

Architecture

The library uses a multi-module workspace where each format family is an independent Go module. Users import only the formats they need:

import "github.com/larsartmann/go-output"                     // core + Markdown + Tree
import "github.com/larsartmann/go-output/table"               // terminal tables (optional)
import "github.com/larsartmann/go-output/serialization"       // JSON + YAML + TOML + JSONL (optional)
import "github.com/larsartmann/go-output/delimited"           // CSV + TSV (optional)
import "github.com/larsartmann/go-output/markup"              // XML + HTML + AsciiDoc (optional)
import "github.com/larsartmann/go-output/d2"                  // D2 diagrams (optional)
import "github.com/larsartmann/go-output/graph"               // DOT + Mermaid (optional)
import "github.com/larsartmann/go-output/plantuml"            // PlantUML diagrams (optional)

The root module has ZERO imports from sub-modules, ensuring users get zero transitive dependencies from formats they don't use.

Index

Examples

Constants

This section is empty.

Variables

AllFormats contains all valid output format values. Use this for testing AllowedValues or generating help text.

View Source
var AllShapes = []Shape{
	ShapeTable,
	ShapeTree,
	ShapeGraph,
}

AllShapes contains all valid data shape values.

Functions

func AddTreeNodes

func AddTreeNodes(
	a NodeEdgeAppender,
	node *TreeNode, parentID string,
	idFunc TreeNodeIDFunc, shape GraphShape,
)

AddTreeNodes recursively adds tree nodes and edges to the provided appender.

func DefaultGraphNodeLabel

func DefaultGraphNodeLabel(header, cell string) string

DefaultGraphNodeLabel returns a label in the format "header: cell".

func MarshalJSONIndent

func MarshalJSONIndent(v any, prefix, indent string) ([]byte, error)

MarshalJSONIndent encodes v to indented JSON.

func NewBrandedID

func NewBrandedID[Brand any](value string) id.ID[Brand, string]

NewBrandedID creates a new branded ID from a string value.

func RegisterAnyDataMarshaler added in v0.9.0

func RegisterAnyDataMarshaler(format Format, marshaler AnyDataMarshaler)

RegisterAnyDataMarshaler registers a marshaler for arbitrary (non-TableData) data. Sub-modules call this from their init() to enable RenderAnyData dispatch.

func RegisterFormatShapes added in v0.7.0

func RegisterFormatShapes(format Format, shapes ...Shape)

RegisterFormatShapes registers the data shapes a format supports. Sub-modules call this from their init() to declare capabilities.

func RegisterTableDataMarshaler added in v0.6.0

func RegisterTableDataMarshaler(format Format, marshaler TableDataMarshaler)

RegisterTableDataMarshaler registers a marshaler for a format. Sub-modules call this from their init() to enable RenderTableData dispatch.

func RenderAnyData added in v0.9.0

func RenderAnyData(data any, format Format, opts RenderOptions) error

RenderAnyData renders arbitrary data in the given format and writes to w (or os.Stdout). Supports formats that registered an AnyDataMarshaler (typically JSON, YAML, TOML). Returns UnsupportedFormatError if no marshaler is registered for the format.

func RenderTableData added in v0.5.0

func RenderTableData(data *TableData, format Format, opts RenderOptions) error

RenderTableData renders TableData in the given format and writes to w (or os.Stdout). It supports all registered formats when respective sub-modules are imported. With all sub-modules imported, all 16 formats are available: table, json, csv, tsv, markdown, xml, d2, yaml, html, tree, mermaid, dot, jsonl, asciidoc, toml, plantuml.

Types

type ASCIITreeRenderer

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

ASCIITreeRenderer implements the TreeOutputRenderer interface for ASCII tree output.

func NewASCIITreeRenderer

func NewASCIITreeRenderer() *ASCIITreeRenderer

NewASCIITreeRenderer creates a new ASCIITreeRenderer.

func TreeRendererFromTableData

func TreeRendererFromTableData(data *TableData) *ASCIITreeRenderer

TreeRendererFromTableData converts TableData to a tree using the first column as hierarchy.

func (*ASCIITreeRenderer) Render

func (r *ASCIITreeRenderer) Render() (string, error)

Render returns the tree as a string.

func (*ASCIITreeRenderer) SetColorMode added in v0.6.0

func (r *ASCIITreeRenderer) SetColorMode(mode ColorMode)

SetColorMode sets the color mode for the tree renderer.

func (*ASCIITreeRenderer) SetRoot

func (r *ASCIITreeRenderer) SetRoot(node *TreeNode)

SetRoot sets the root node of the tree.

type Alignment

type Alignment int

Alignment represents text alignment within a table cell.

const (
	AlignLeft   Alignment = alignmentLeft
	AlignRight  Alignment = alignmentRight
	AlignCenter Alignment = alignmentCenter
)

Column alignment constants.

type AnyDataMarshaler added in v0.9.0

type AnyDataMarshaler func(w io.Writer, data any, opts RenderOptions) error

AnyDataMarshaler renders arbitrary data (any) in a specific format to a writer.

type BrandedID

type BrandedID[Brand any] = id.ID[Brand, string]

BrandedID re-export for backward compatibility. Use id.ID[Brand, string] for new code.

type ColorMode

type ColorMode string

ColorMode controls terminal color output.

Example
package main

import (
	"fmt"

	"github.com/larsartmann/go-output"
)

func main() {
	fmt.Println(output.ColorModeAuto.ShouldColor())
	fmt.Println(output.ColorModeNever.ShouldColor())
}
Output:
false
false
const (
	ColorModeAuto   ColorMode = "auto"
	ColorModeAlways ColorMode = "always"
	ColorModeNever  ColorMode = "never"
)

Terminal color output modes.

func ParseColorMode

func ParseColorMode(s string) (ColorMode, error)

ParseColorMode converts a string to ColorMode, returning an error if invalid.

func (ColorMode) AllowedValues

func (c ColorMode) AllowedValues() []string

AllowedValues returns all valid color mode values.

func (ColorMode) IsValid

func (c ColorMode) IsValid() bool

IsValid checks if the color mode is valid.

func (ColorMode) ShouldColor

func (c ColorMode) ShouldColor() bool

ShouldColor returns true if colors should be enabled.

func (ColorMode) String

func (c ColorMode) String() string

String returns the string representation of the color mode.

type D2NodeID

type D2NodeID = id.ID[D2NodeIDBrand, string]

D2NodeID is a branded identifier for D2 diagram nodes.

type D2NodeIDBrand

type D2NodeIDBrand struct{}

D2NodeIDBrand is the brand type for D2 node IDs.

type D2NodeLabel

type D2NodeLabel = id.ID[D2NodeLabelBrand, string]

D2NodeLabel is a branded identifier for D2 diagram node labels.

type D2NodeLabelBrand

type D2NodeLabelBrand struct{}

D2NodeLabelBrand is the brand type for D2 node labels.

type EdgeStyle

type EdgeStyle struct {
	// Color is the edge line color.
	Color string
	// Style is the line style ("solid", "dashed", "dotted").
	Style string
	// ArrowHead is the arrowhead style at the target end.
	ArrowHead string
	// ArrowTail is the arrowhead style at the source end.
	ArrowTail string
}

EdgeStyle represents styling attributes for an edge.

type Format

type Format string

Format represents the available output format options for CLI applications.

const (
	FormatTable    Format = "table"
	FormatJSON     Format = "json"
	FormatCSV      Format = "csv"
	FormatTSV      Format = "tsv"
	FormatMarkdown Format = "markdown"
	FormatXML      Format = "xml"
	FormatD2       Format = "d2"
	FormatYAML     Format = "yaml"
	FormatHTML     Format = "html"
	FormatTree     Format = "tree"
	FormatMermaid  Format = "mermaid"
	FormatDOT      Format = "dot"
	FormatJSONL    Format = "jsonl"
	FormatAsciiDoc Format = "asciidoc"
	FormatTOML     Format = "toml"
	FormatPlantUML Format = "plantuml"
)

Output format constants.

func FormatsForShape added in v0.5.0

func FormatsForShape(s Shape) []Format

FormatsForShape returns all formats that support the given data shape.

func ParseFormat

func ParseFormat(s string) (Format, error)

ParseFormat converts a string to Format, returning an error if invalid.

Example
package main

import (
	"fmt"
	"os"

	"github.com/larsartmann/go-output"
)

func main() {
	f, err := output.ParseFormat("json")
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(f)
}
Output:
json

func RegisteredAnyDataFormats added in v0.9.0

func RegisteredAnyDataFormats() []Format

RegisteredAnyDataFormats returns all formats with registered AnyDataMarshalers.

func RegisteredTableDataFormats added in v0.9.0

func RegisteredTableDataFormats() []Format

RegisteredTableDataFormats returns all formats with registered TableDataMarshalers.

func (Format) AllowedValues

func (f Format) AllowedValues() []string

AllowedValues returns all valid output format values for CLI help text.

func (Format) IsValid

func (f Format) IsValid() bool

IsValid returns true if the format is a valid Format value.

Example
package main

import (
	"fmt"

	"github.com/larsartmann/go-output"
)

func main() {
	fmt.Println(output.FormatCSV.IsValid())
	fmt.Println(output.Format("unknown").IsValid())
}
Output:
true
false

func (Format) Shapes added in v0.5.0

func (f Format) Shapes() []Shape

Shapes returns all data shapes this format supports.

func (Format) String

func (f Format) String() string

String returns the string representation of the format.

func (Format) Supports added in v0.5.0

func (f Format) Supports(s Shape) bool

Supports returns true if the format can render the given data shape.

type GraphEdge

type GraphEdge struct {
	// From is the source node ID.
	From GraphNodeID
	// To is the target node ID.
	To GraphNodeID
	// Label is the optional display text on the edge.
	Label GraphNodeLabel
	// Style contains optional visual styling attributes.
	Style EdgeStyle
}

GraphEdge represents an edge between two nodes.

func NewGraphEdge

func NewGraphEdge(from, to string) *GraphEdge

NewGraphEdge creates a new GraphEdge.

type GraphNode

type GraphNode struct {
	// ID is the unique identifier for the node.
	ID GraphNodeID
	// Label is the display text for the node.
	Label GraphNodeLabel
	// Shape defines the visual shape (box, ellipse, diamond, etc.).
	Shape GraphShape
	// Style contains optional visual styling attributes.
	Style GraphStyle
	// Metadata holds arbitrary key-value pairs for custom data.
	Metadata map[string]string
}

GraphNode represents a node in a graph.

func NewGraphNode

func NewGraphNode(id, label string) *GraphNode

NewGraphNode creates a new GraphNode.

func NodesFromTableData

func NodesFromTableData(data *TableData, labelFn GraphNodeLabelFunc) []GraphNode

NodesFromTableData creates GraphNodes from TableData using the provided label function.

type GraphNodeID

type GraphNodeID = id.ID[GraphNodeIDBrand, string]

GraphNodeID is a branded identifier for graph nodes.

type GraphNodeIDBrand

type GraphNodeIDBrand struct{}

GraphNodeIDBrand is the brand type for graph node IDs.

type GraphNodeLabel

type GraphNodeLabel = id.ID[GraphNodeLabelBrand, string]

GraphNodeLabel is a branded identifier for graph node labels.

type GraphNodeLabelBrand

type GraphNodeLabelBrand struct{}

GraphNodeLabelBrand is the brand type for graph node labels.

type GraphNodeLabelFunc

type GraphNodeLabelFunc func(header, cell string) string

GraphNodeLabelFunc is a function that formats a cell value with its header into a label.

type GraphRenderer

type GraphRenderer interface {
	Renderer
	// SetNodes sets the graph nodes.
	SetNodes(nodes []GraphNode)
	// SetEdges sets the graph edges.
	SetEdges(edges []GraphEdge)
}

GraphRenderer defines the interface for graph format renderers.

type GraphRendererState added in v0.7.0

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

GraphRendererState contains shared fields and methods for graph renderers.

D2 does not use this mixin because it has richer domain-specific types (D2Node, D2Edge with classes, SQL tables, shapes, arrow types, etc.) that do not map to the simpler GraphNode/GraphEdge model.

func NewGraphRendererState added in v0.7.0

func NewGraphRendererState() GraphRendererState

NewGraphRendererState creates a new GraphRendererState with initialized slices.

func (*GraphRendererState) AddEdge added in v0.7.0

func (m *GraphRendererState) AddEdge(edge GraphEdge)

AddEdge appends an edge to the graph.

func (*GraphRendererState) AddNode added in v0.7.0

func (m *GraphRendererState) AddNode(node GraphNode)

AddNode appends a node to the graph.

func (*GraphRendererState) AddRowEdges added in v0.7.0

func (m *GraphRendererState) AddRowEdges(data *TableData)

AddRowEdges adds edges from data.CreateRowEdges() to the graph.

func (*GraphRendererState) Edges added in v0.7.0

func (m *GraphRendererState) Edges() []GraphEdge

Edges returns the graph edges.

func (*GraphRendererState) Nodes added in v0.7.0

func (m *GraphRendererState) Nodes() []GraphNode

Nodes returns the graph nodes.

func (*GraphRendererState) SetEdges added in v0.7.0

func (m *GraphRendererState) SetEdges(edges []GraphEdge)

SetEdges sets the graph edges.

func (*GraphRendererState) SetNodes added in v0.7.0

func (m *GraphRendererState) SetNodes(nodes []GraphNode)

SetNodes sets the graph nodes.

func (*GraphRendererState) SetNodesFromTableData added in v0.7.0

func (m *GraphRendererState) SetNodesFromTableData(
	data *TableData,
	modifyNode func(i int, n *GraphNode),
)

SetNodesFromTableData creates nodes from TableData, applies per-node modifications, adds them to the graph, and adds row edges.

type GraphShape

type GraphShape string

GraphShape represents the shape of a graph node.

const (
	ShapeBox           GraphShape = "box"
	ShapeEllipse       GraphShape = "ellipse"
	ShapeDiamond       GraphShape = "diamond"
	ShapeCircle        GraphShape = "circle"
	ShapeCylinder      GraphShape = "cylinder"
	ShapeHexagon       GraphShape = "hexagon"
	ShapeParallelogram GraphShape = "parallelogram"
	ShapeRect          GraphShape = "rect"
)

GraphShape constants define the available shapes for graph nodes.

func ParseGraphShape

func ParseGraphShape(s string) (GraphShape, error)

ParseGraphShape converts a string to GraphShape, returning an error if invalid.

func (GraphShape) AllowedValues

func (s GraphShape) AllowedValues() []string

AllowedValues returns all valid graph shape values.

func (GraphShape) IsValid

func (s GraphShape) IsValid() bool

IsValid checks if the graph shape is valid.

func (GraphShape) String

func (s GraphShape) String() string

String returns the string representation of the graph shape.

type GraphStyle

type GraphStyle struct {
	// FillColor is the background color (e.g., "#f9f9f9").
	FillColor string
	// StrokeColor is the border color.
	StrokeColor string
	// FontColor is the text color.
	FontColor string
	// FontSize is the text size in points.
	FontSize int
}

GraphStyle represents styling attributes for a graph node.

type InvalidColorModeError added in v0.5.0

type InvalidColorModeError struct {
	Value string
}

InvalidColorModeError is returned when an invalid color mode is provided.

func (*InvalidColorModeError) Error added in v0.5.0

func (e *InvalidColorModeError) Error() string

Error returns a descriptive error message for the invalid color mode.

type InvalidFormatError

type InvalidFormatError struct {
	Value   string
	Allowed []Format
}

InvalidFormatError represents an invalid format error.

func (*InvalidFormatError) Error

func (e *InvalidFormatError) Error() string

Error returns a descriptive error message including allowed values.

type InvalidGraphShapeError added in v0.5.0

type InvalidGraphShapeError struct {
	Value string
}

InvalidGraphShapeError is returned when an invalid graph shape is provided.

func (*InvalidGraphShapeError) Error added in v0.5.0

func (e *InvalidGraphShapeError) Error() string

Error returns a descriptive error message for the invalid graph shape.

type InvalidShapeError added in v0.5.0

type InvalidShapeError struct {
	Value string
}

InvalidShapeError is returned when an invalid data shape is provided.

func (*InvalidShapeError) Error added in v0.5.0

func (e *InvalidShapeError) Error() string

Error returns a descriptive error message for the invalid shape.

type MarkdownTable

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

MarkdownTable builds Markdown tables.

func NewMarkdownTable

func NewMarkdownTable() *MarkdownTable

NewMarkdownTable creates a new MarkdownTable.

func NewMarkdownTableFromData

func NewMarkdownTableFromData(data *TableData) *MarkdownTable

NewMarkdownTableFromData creates a MarkdownTable populated from TableData.

func (*MarkdownTable) AddRow

func (m *MarkdownTable) AddRow(row []string) *MarkdownTable

AddRow adds a row to the table.

func (*MarkdownTable) AsTableRenderer added in v0.6.1

func (m *MarkdownTable) AsTableRenderer() TableRenderer

AsTableRenderer returns a TableRenderer that delegates to this MarkdownTable. This adapts the fluent API (returning *MarkdownTable) to the TableRenderer interface.

func (*MarkdownTable) Render

func (m *MarkdownTable) Render() (string, error)

Render returns the Markdown table string.

func (*MarkdownTable) SetAlign

func (m *MarkdownTable) SetAlign(col int, alignment Alignment) *MarkdownTable

SetAlign sets column alignment.

func (*MarkdownTable) SetColorMode added in v0.6.0

func (m *MarkdownTable) SetColorMode(mode ColorMode) *MarkdownTable

SetColorMode sets the color mode for terminal output.

func (*MarkdownTable) SetFooter added in v0.6.1

func (m *MarkdownTable) SetFooter(footer []string) *MarkdownTable

SetFooter sets the footer row for the table.

func (*MarkdownTable) SetHeaders

func (m *MarkdownTable) SetHeaders(headers []string) *MarkdownTable

SetHeaders sets the table headers.

type NodeEdgeAppender added in v0.7.0

type NodeEdgeAppender interface {
	AddNode(node GraphNode)
	AddEdge(edge GraphEdge)
}

NodeEdgeAppender is implemented by types that can add nodes and edges.

type RenderOptions added in v0.5.0

type RenderOptions struct {
	// Title is used as the document title for HTML output and as a header for Markdown.
	Title string

	// GraphID is used as the graph identifier for DOT output.
	GraphID string

	// Writer overrides the default os.Stdout output destination.
	Writer io.Writer

	// ColorMode controls terminal color output. Defaults to ColorModeAuto.
	ColorMode ColorMode
}

RenderOptions configures optional behavior for RenderTableData.

type Renderer

type Renderer interface {
	// Render returns the formatted output as a string.
	Render() (string, error)
}

Renderer defines the interface for output format renderers.

type RowEdge

type RowEdge struct {
	From string
	To   string
}

RowEdge represents a directed edge between two row identifiers.

type Shape added in v0.5.0

type Shape string

Shape represents a data shape that a format can render.

Example
package main

import (
	"fmt"

	"github.com/larsartmann/go-output"
)

func main() {
	fmt.Println(output.FormatCSV.Supports(output.ShapeTable))
	fmt.Println(output.FormatCSV.Supports(output.ShapeTree))
}
Output:
true
false
const (
	ShapeTable Shape = "table" // Tabular data with headers and rows
	ShapeTree  Shape = "tree"  // Hierarchical data with parent-child nodes
	ShapeGraph Shape = "graph" // Network data with nodes and edges
)

Data shape constants for format capability classification.

func ParseShape added in v0.5.0

func ParseShape(s string) (Shape, error)

ParseShape converts a string to Shape, returning an error if invalid.

func (Shape) AllowedValues added in v0.5.0

func (s Shape) AllowedValues() []string

AllowedValues returns all valid data shape values for CLI help text.

func (Shape) IsValid added in v0.5.0

func (s Shape) IsValid() bool

IsValid returns true if the shape is a valid Shape value.

func (Shape) String added in v0.5.0

func (s Shape) String() string

String returns the string representation of the data shape.

type StreamingRenderer

type StreamingRenderer interface {
	Renderer
	// Stream writes the rendered output to an io.Writer in chunks.
	Stream(w io.Writer) error
}

StreamingRenderer is an interface for renderers that support streaming output. This is useful for rendering large datasets without loading everything into memory.

Important: Not all implementations provide true streaming. The adapter returned by StreamingRendererFromRenderer collects output before writing. Only StreamingHTMLRenderer (in the markup sub-module) provides genuine streaming behavior.

func StreamingRendererFromRenderer

func StreamingRendererFromRenderer(r Renderer) StreamingRenderer

StreamingRendererFromRenderer wraps a standard Renderer to implement StreamingRenderer. Important: This adapter does not provide true streaming behavior - it collects all output via Render() and then writes it at once. It exists to satisfy the StreamingRenderer interface for renderers that don't have native streaming support.

type TableData

type TableData struct {
	// Headers are the column header labels.
	Headers []string
	// Rows contains the data rows, each a slice of cell values.
	Rows [][]string
	// Footer is an optional totals/summary row rendered after all data rows.
	// Tabular formats (CSV, TSV, Markdown, HTML, XML, AsciiDoc, Table) render it visually.
	// Data formats (JSON, YAML, TOML, JSONL) and non-tabular formats skip it.
	Footer []string
}

TableData represents tabular data with headers, rows, and an optional footer.

func NewTableData

func NewTableData(headers []string) *TableData

NewTableData creates a new TableData with the given headers.

func (*TableData) AddRow

func (d *TableData) AddRow(row []string)

AddRow adds a row to the table data.

This method does NOT validate the row's column count. Use AddRowChecked to return an error, or call Validate() before rendering to surface mismatched rows. Existing callers that rely on silent acceptance are preserved; new code should prefer AddRowChecked for fail-fast behavior.

func (*TableData) AddRowChecked added in v0.9.0

func (d *TableData) AddRowChecked(row []string) error

AddRowChecked adds a row to the table data and returns an error if the row's column count does not match the header count.

Returns nil if no headers are set, deferring validation to Validate(). Returns ErrColumnMismatch if the row length differs from len(Headers).

func (*TableData) ColCount

func (d *TableData) ColCount() int

ColCount returns the number of columns (based on headers).

func (*TableData) CreateRowEdges

func (d *TableData) CreateRowEdges() []RowEdge

CreateRowEdges generates edge data connecting consecutive rows. Used by graph renderers to create edges between table rows.

func (*TableData) GetFooter added in v0.6.1

func (d *TableData) GetFooter() []string

GetFooter returns the footer row, or nil if none is set. Satisfies the table.FooterProvider optional interface.

func (*TableData) GetHeaders

func (d *TableData) GetHeaders() []string

GetHeaders returns the column headers. Satisfies the table.TableDataProvider interface.

func (*TableData) GetRows

func (d *TableData) GetRows() [][]string

GetRows returns the data rows. Satisfies the table.TableDataProvider interface.

func (*TableData) HasFooter added in v0.6.1

func (d *TableData) HasFooter() bool

HasFooter returns true if a footer row is present.

func (*TableData) RowCount

func (d *TableData) RowCount() int

RowCount returns the number of data rows.

func (*TableData) SetFooter added in v0.6.1

func (d *TableData) SetFooter(footer []string)

SetFooter sets the footer row.

func (*TableData) ToMapSlice added in v0.5.0

func (d *TableData) ToMapSlice() []map[string]string

ToMapSlice converts TableData to a slice of maps (header→cell). Returns nil if data is nil or has no headers.

func (*TableData) Validate added in v0.6.1

func (d *TableData) Validate() error

Validate checks the TableData for consistency. Returns an error if rows are nil, or if the footer column count does not match the header count.

Example
package main

import (
	"fmt"

	"github.com/larsartmann/go-output"
)

func main() {
	data := output.NewTableData([]string{"Name", "Count"})
	data.AddRow([]string{"Alice", "10"})
	data.SetFooter([]string{"Total", "10"})

	fmt.Println(data.Validate())
}
Output:
<nil>

type TableDataMarshaler added in v0.6.0

type TableDataMarshaler func(w io.Writer, data *TableData, opts RenderOptions) error

TableDataMarshaler renders TableData in a specific format to a writer.

type TableDataStore added in v0.7.0

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

TableDataStore provides common table data storage for renderers.

func (*TableDataStore) AddRow added in v0.7.0

func (b *TableDataStore) AddRow(row []string)

AddRow adds a data row.

func (*TableDataStore) Data added in v0.7.0

func (b *TableDataStore) Data() *TableData

Data returns the underlying TableData.

func (*TableDataStore) HasFooter added in v0.7.0

func (b *TableDataStore) HasFooter() bool

HasFooter returns true if a footer row is present.

func (*TableDataStore) SetData added in v0.7.0

func (b *TableDataStore) SetData(data *TableData)

SetData sets the table data directly.

func (*TableDataStore) SetFooter added in v0.7.0

func (b *TableDataStore) SetFooter(footer []string)

SetFooter sets the footer row.

func (*TableDataStore) SetHeaders added in v0.7.0

func (b *TableDataStore) SetHeaders(headers []string)

SetHeaders sets the column headers.

type TableRenderer

type TableRenderer interface {
	Renderer
	// SetHeaders sets the column headers.
	SetHeaders(headers []string)
	// AddRow adds a data row.
	AddRow(row []string)
}

TableRenderer defines the interface for table format renderers.

type TreeNode

type TreeNode struct {
	// ID is the unique identifier for the node.
	ID TreeNodeID
	// Label is the display text for the node.
	Label TreeNodeLabel
	// Children holds the child nodes.
	Children []*TreeNode
	// Metadata holds arbitrary key-value pairs for custom data.
	Metadata map[string]string
	// contains filtered or unexported fields
}

TreeNode represents a node in a tree structure.

func NewTreeNode

func NewTreeNode(id, label string) *TreeNode

NewTreeNode creates a new TreeNode with the given ID and label.

func (*TreeNode) AddChild

func (n *TreeNode) AddChild(child *TreeNode)

AddChild adds a child node to this node.

func (*TreeNode) Depth

func (n *TreeNode) Depth() int

Depth returns the depth of this node in the tree (root = 0).

func (*TreeNode) Parent

func (n *TreeNode) Parent() *TreeNode

Parent returns the parent node (nil for root).

type TreeNodeID

type TreeNodeID = id.ID[TreeNodeIDBrand, string]

TreeNodeID is a branded identifier for tree nodes.

type TreeNodeIDBrand

type TreeNodeIDBrand struct{}

TreeNodeIDBrand is the brand type for tree node IDs.

type TreeNodeIDFunc

type TreeNodeIDFunc func(*TreeNode) string

TreeNodeIDFunc resolves a TreeNode's ID for a specific graph format.

type TreeNodeLabel

type TreeNodeLabel = id.ID[TreeNodeLabelBrand, string]

TreeNodeLabel is a branded identifier for tree node labels.

type TreeNodeLabelBrand

type TreeNodeLabelBrand struct{}

TreeNodeLabelBrand is the brand type for tree node labels.

type TreeOutputRenderer

type TreeOutputRenderer interface {
	Renderer
	// SetRoot sets the root node of the tree.
	SetRoot(node *TreeNode)
}

TreeOutputRenderer defines the interface for tree format renderers.

type UnsupportedFormatError added in v0.5.0

type UnsupportedFormatError struct {
	Format Format
}

UnsupportedFormatError is returned when RenderTableData cannot handle a format.

func (*UnsupportedFormatError) Error added in v0.5.0

func (e *UnsupportedFormatError) Error() string

Directories

Path Synopsis
d2 module
daghtml module
delimited module
enum module
envdetect module
escape module
graph module
markdown module
markup module
nom module
plantuml module
sort module
table module
testhelpers module
graphtest module
tree module
tui module

Jump to

Keyboard shortcuts

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