formatters

package
v1.21.21 Latest Latest
Warning

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

Go to latest
Published: Jun 14, 2026 License: Apache-2.0 Imports: 28 Imported by: 3

Documentation

Overview

Package formatters provides a comprehensive data formatting system with support for multiple output formats, Tailwind CSS styling, and fluent text composition.

Quick Start

The formatters package is designed around structs with pretty tags for automatic formatting. Define your data structures with pretty tags to control how they appear in different output formats:

import "github.com/flanksource/clicky"

// Define struct for table rows (individual fields don't need table tag)
type User struct {
	Name   string `pretty:"label=Full Name"`
	Age    int    `pretty:"color=blue"`        // Uses "Age" as column header
	City   string `pretty:"label=Location,color=gray-500"`
	Status string `pretty:"sort"`              // Uses "Status" as column header
}

users := []User{
	{Name: "Alice", Age: 30, City: "New York", Status: "Active"},
	{Name: "Bob", Age: 25, City: "Los Angeles", Status: "Inactive"},
}

// When formatting a slice directly, table format is automatically detected
prettyStr, err := clicky.Format(users, clicky.FormatOptions{Format: "pretty"})

// Format as JSON
jsonStr, err := clicky.Format(users, clicky.FormatOptions{Format: "json"})

// Format as YAML
yamlStr, err := clicky.Format(users, clicky.FormatOptions{Format: "yaml"})

// Format as Markdown table
markdownStr, err := clicky.Format(users, clicky.FormatOptions{Format: "markdown"})

Table Formatting with Pretty Tags

Tables are automatically detected when formatting struct slices. Individual struct fields use pretty tags to control column appearance, while the `table` tag is only used on slice fields to explicitly request table formatting:

// Define the struct for table rows (no table tags on individual fields)
type ServerInfo struct {
	Name     string `pretty:"label=Server Name"`
	Status   string `pretty:"color=green"`       // Uses field name "Status" as header
	Uptime   string `pretty:"color=blue"`        // Uses field name "Uptime" as header
	Memory   string `pretty:"label=Memory Usage,color=yellow,sort"`
}

servers := []ServerInfo{
	{Name: "web-01", Status: "Running", Uptime: "5d 12h", Memory: "2.1GB"},
	{Name: "db-01", Status: "Running", Uptime: "15d 3h", Memory: "8.4GB"},
}

// Format slice directly (automatically detects table format)
output, err := clicky.Format(servers, clicky.FormatOptions{Format: "pretty"})

// Or use container struct with explicit table tag on slice field
type ServerReport struct {
	Servers []ServerInfo `pretty:"label=Server Status,table"`
}
report := ServerReport{Servers: servers}
output, err := clicky.Format(report, clicky.FormatOptions{Format: "pretty"})

Column Formatting Options

Individual struct fields (table columns) support these pretty tag options:

  • label=HeaderName - Sets the column header (defaults to field name)
  • color=tailwind-class - Applies color styling
  • sort - Makes column sortable
  • width=N - Sets column width
  • format=type - date, currency, percentage, etc.

Note: Column headers automatically default to the struct field name if no `label` is specified.

Tree Formatting with TreeNode Interface

Tree formatting displays hierarchical data using the TreeNode interface and pretty struct tags. Implement the api.TreeNode interface for custom tree visualization:

// FileNode implements api.TreeNode interface
type FileNode struct {
	Name     string      `json:"name"`
	Path     string      `json:"path"`
	IsDir    bool        `json:"is_dir"`
	Children []*FileNode `json:"children,omitempty"`
}

// Implement TreeNode interface methods
func (f *FileNode) Pretty() api.Text {
	icon := "📄"
	style := "text-gray-600"
	if f.IsDir {
		icon = "📁"
		style = "text-blue-600 font-bold"
	}
	return api.Text{
		Content: fmt.Sprintf("%s %s", icon, f.Name),
		Style:   style,
	}
}

func (f *FileNode) GetChildren() []api.TreeNode {
	children := make([]api.TreeNode, len(f.Children))
	for i, child := range f.Children {
		children[i] = child
	}
	return children
}

// Use with pretty tag for automatic tree formatting
type FileSystem struct {
	Root *FileNode `pretty:"tree"`
}

fs := FileSystem{
	Root: &FileNode{
		Name:  "project",
		IsDir: true,
		Children: []*FileNode{
			{Name: "main.go", IsDir: false},
			{Name: "utils.go", IsDir: false},
		},
	},
}

// Automatically formats as tree
output, err := clicky.Format(fs, clicky.FormatOptions{Format: "tree"})

Pretty Tags Reference

The pretty tag system provides comprehensive control over data formatting and styling. Use these tags on struct fields to control appearance across all output formats:

Table Tags

type Product struct {
	ID          int     `pretty:"label=Product ID,width=10"`
	Name        string  `pretty:"color=blue"`                    // Uses "Name" as header
	Price       float64 `pretty:"label=Price,format=currency,sort"`
	InStock     bool    `pretty:"label=Available,color=green"`
	CreatedAt   time.Time `pretty:"format=date"`                 // Uses "CreatedAt" as header
}

Table Tag Usage

The `table` tag is used **only on slice/array fields** to explicitly request table formatting:

type Report struct {
	Users []User `pretty:"label=User List,table"` // table tag on slice field
	Items []Item `pretty:"table"`                 // uses field name "Items" as label
}

Column Formatting Options

Individual struct fields (table columns) support these pretty tag options:

  • label=HeaderName - Sets the column header (defaults to field name)
  • color=tailwind-class - Applies color styling
  • sort - Makes column sortable
  • width=N - Sets column width
  • format=type - date, currency, percentage, etc.

Note: Column headers automatically default to the struct field name if no `label` is specified.

Tree Tags

type Organization struct {
	Department *Department `pretty:"tree"`
}

type Department struct {
	Name     string        `json:"name"`
	Manager  string        `json:"manager"`
	Teams    []*Department `json:"teams,omitempty"`
}

Tree tag options:

  • tree - Marks field for tree formatting
  • icon=custom-icon - Sets custom icon for nodes

Style Integration Tags

type StatusReport struct {
	Message string `pretty:"color:green,font:bold"`
	Level   string `pretty:"color:yellow"`
	Time    string `pretty:"color:gray-500,italic"`
}

Style tag options:

  • color=tailwind-class - Text colors (red, green, blue, etc.)
  • font=weight - bold, semibold, medium, normal
  • style=modifier - italic, underline, line-through
  • opacity=level - 25, 50, 75, 100

Supported Format Types

All struct-based data works seamlessly across multiple output formats:

  • "pretty": Human-readable tables and formatting (default)
  • "json": JSON formatted output with proper indentation
  • "yaml"/"yml": YAML formatted output
  • "csv": Comma-separated values format for tabular data
  • "markdown"/"md": Markdown tables with styling
  • "html": HTML tables with Tailwind CSS classes
  • "html-pdf": HTML-to-PDF conversion for reports
  • "excel"/"xlsx": Excel spreadsheet format
  • "tree": Hierarchical tree view for nested data
  • "slack": Slack Block Kit JSON output

Format Options

Control output behavior with FormatOptions:

options := clicky.FormatOptions{
	Format:  "markdown",
	NoColor: false,
	Output:  "report.md",
}

// Write to file
err := clicky.FormatToFile(users, options, "report.md")

// Or get as string
result, err := clicky.Format(users, options)

Tailwind CSS Support

The formatters package provides comprehensive Tailwind CSS integration through pretty tags and the api.Text system. Tailwind utility classes are automatically parsed and applied to output:

type StyledContent struct {
	Title   string `pretty:"color=blue-600,font=bold,text=lg"`
	Status  string `pretty:"color=green-500"`
	Footer  string `pretty:"color=gray-500,style=italic"`
}

Supported Tailwind utilities:

Colors

  • text-{color}-{shade} (e.g., text-blue-600, text-red-500)
  • bg-{color}-{shade} (e.g., bg-gray-100, bg-green-50)

Typography

  • font-bold, font-semibold, font-medium, font-normal
  • italic, not-italic
  • underline, line-through
  • text-xs, text-sm, text-base, text-lg, text-xl, text-2xl, etc.

Spacing

  • p-{value} (padding all sides)
  • px-{value}, py-{value} (horizontal/vertical padding)
  • pt-{value}, pr-{value}, pb-{value}, pl-{value} (individual sides)

Opacity

  • opacity-25, opacity-50, opacity-75, opacity-100

Fluent api.Text Interface

For dynamic styling, use the api.Text type with fluent interface:

text := api.Text{Content: "Hello"}
	.Styles("font-bold", "text-blue-600")
	.Text(" World", "text-green-500")
	.Append("!", "font-semibold")
	.WrapSpace()
	.Indent(4)

Methods include:

  • Styles(classes...): Add Tailwind CSS classes
  • Text(content, styles...): Add styled child text
  • Append(content, styles...): Append styled content
  • Wrap(prefix, suffix): Wrap content with strings
  • WrapSpace(): Add spaces before and after
  • Indent(spaces): Indent content and children
  • Printf(format, args...): Add formatted content

Integration Examples

Struct-based formatting integrates seamlessly with Go applications:

// Web API responses
type APIResponse struct {
	Status  string      `json:"status" pretty:"color=green"`     // Uses "Status" as header
	Message string      `json:"message"`                         // Uses "Message" as header
	Data    interface{} `json:"data" pretty:"label=Response Data"`
}

response := APIResponse{
	Status:  "success",
	Message: "Users retrieved",
	Data:    users,
}

// CLI output with format flag
var format = flag.String("format", "pretty", "Output format")
var noColor = flag.Bool("no-color", false, "Disable colors")
var output = flag.String("output", "", "Output file")

options := clicky.FormatOptions{
	Format:  *format,
	NoColor: *noColor,
}

if *output != "" {
	err := clicky.FormatToFile(response, options, *output)
} else {
	result, err := clicky.Format(response, options)
	fmt.Println(result)
}

Advanced Usage

For complex scenarios where struct tags aren't sufficient or when working with dynamic data, the formatters package provides programmatic construction and unstructured data handling.

Unstructured Data Handling

When working with dynamic data from APIs or user input, use map[string]interface{}:

// Dynamic data from external API
data := map[string]interface{}{
	"name":   "Alice",
	"age":    30,
	"city":   "New York",
	"active": true,
}

// Format dynamic data
jsonStr, err := clicky.Format(data, clicky.FormatOptions{Format: "json"})
yamlStr, err := clicky.Format(data, clicky.FormatOptions{Format: "yaml"})
prettyStr, err := clicky.Format(data, clicky.FormatOptions{Format: "pretty"})

// Handle arrays of mixed data
mixedData := []map[string]interface{}{
	{"type": "user", "name": "Alice", "role": "admin"},
	{"type": "user", "name": "Bob", "role": "user"},
}

tableOutput, err := clicky.Format(mixedData, clicky.FormatOptions{Format: "pretty"})

Advanced Programmatic Construction

For maximum control over formatting, construct tables and trees programmatically:

Advanced Table Construction

prettyData := &api.PrettyData{
	Tables: map[string][]map[string]*api.FieldValue{
		"users": {
			{
				"name": &api.FieldValue{Value: "Alice", Style: "font-bold"},
				"age":  &api.FieldValue{Value: 30, Style: "text-blue-600"},
				"city": &api.FieldValue{Value: "New York", Style: "text-gray-500"},
			},
		},
	},
	Schema: &api.PrettyObject{
		Table: &api.TableConfig{
			Headers: map[string]string{
				"name": "Full Name",
				"age":  "Age",
				"city": "Location",
			},
			SortBy: []string{"name"},
		},
	},
}

output, err := clicky.Format(prettyData, clicky.FormatOptions{Format: "pretty"})

Advanced Tree Construction

For complex trees, use the built-in api.SimpleTreeNode:

treeData := &api.SimpleTreeNode{
	Label: "Application",
	Icon:  "📁",
	Style: "text-blue-600 font-bold",
	Children: []api.TreeNode{
		&api.SimpleTreeNode{
			Label: "Frontend",
			Icon:  "📁",
			Style: "text-blue-500",
			Children: []api.TreeNode{
				&api.SimpleTreeNode{
					Label: "components",
					Icon:  "📂",
					Style: "text-gray-600",
				},
				&api.SimpleTreeNode{
					Label: "App.tsx",
					Icon:  "📜",
					Style: "text-green-500",
				},
			},
		},
		&api.SimpleTreeNode{
			Label: "Backend",
			Icon:  "📁",
			Style: "text-blue-500",
			Children: []api.TreeNode{
				&api.SimpleTreeNode{
					Label: "main.go",
					Icon:  "🐹",
					Style: "text-green-600",
				},
				&api.SimpleTreeNode{
					Label: "handlers.go",
					Icon:  "🐹",
					Style: "text-green-600",
				},
			},
		},
	},
}

output, err := clicky.Format(treeData, clicky.FormatOptions{Format: "tree"})

Tree Options

Customize tree rendering with TreeOptions:

options := &api.TreeOptions{
	ShowIcons:    true,
	IndentSize:   4,
	UseUnicode:   true,
	MaxDepth:     3,
	Compact:      false,
}

formatter := formatters.NewTreeFormatter(api.DefaultTheme(), false, options)
output := formatter.FormatTreeFromRoot(treeData)

The formatters package is designed to be the central formatting solution for all data output needs, providing consistent styling, multiple format support, and seamless integration with existing systems.

Index

Constants

View Source
const FormatSpecHelp = "Output format. Use one stdout format (pretty|json|yaml|yml|csv|markdown|md|html|html-static|html-react|clicky-json|pdf|slack|excel|xlsx|tree), " +
	"or comma-separated format=file sinks such as 'pretty,json=out.json,markdown=summary.md'."

Variables

View Source
var DEFAULT_MANAGER api.FormatManager = NewFormatManager()

Functions

func AddFormatCallback

func AddFormatCallback(callback FormatCallback)

AddFormatCallback registers a callback that is applied to subsequent formatting operations.

func BindFlags

func BindFlags(flags *flag.FlagSet, options *FormatOptions)

BindFlags adds formatting flags to the provided flag set

func BindPFlags

func BindPFlags(flags *pflag.FlagSet, options *FormatOptions)

BindPFlags adds formatting flags to the provided pflag set (for cobra)

func ClearCustomFormatters

func ClearCustomFormatters()

ClearCustomFormatters removes all registered custom formatters. This is primarily useful for testing.

func ClearFormatCallbacks

func ClearFormatCallbacks()

ClearFormatCallbacks removes all registered format callbacks. This is primarily useful in tests.

func ConvertToTreeNode

func ConvertToTreeNode(v interface{}) api.TreeNode

ConvertToTreeNode converts various types to TreeNode interface

func FlattenSlice

func FlattenSlice(val reflect.Value) reflect.Value

FlattenSlice flattens a slice of slices into a single-level slice. If the input is not a slice of slices, it returns the input unchanged. This allows safe use on any slice without pre-checking.

func GetFieldValue

func GetFieldValue(val reflect.Value, fieldName string) reflect.Value

GetFieldValue gets a field value by name from a struct Deprecated: Use api.StructParser.GetFieldValue instead

func GetFieldValueCaseInsensitive

func GetFieldValueCaseInsensitive(val reflect.Value, name string) reflect.Value

GetFieldValueCaseInsensitive tries to find a field by name with different casing

func GetFieldValueWithAliases

func GetFieldValueWithAliases(val reflect.Value, field api.PrettyField) reflect.Value

GetFieldValueWithAliases tries to get a field value using aliases first, then the field name

func GetStructHeaders

func GetStructHeaders(val reflect.Value) []string

GetStructHeaders extracts field names as headers from structs, respecting pretty tags

func GetStructRow

func GetStructRow(val reflect.Value) api.TextList

GetStructRow extracts field values as a row from structs, respecting pretty tags

func GetTableFields

func GetTableFields(val reflect.Value) ([]api.PrettyField, error)

GetTableFields extracts fields from a struct for table formatting Deprecated: Use api.StructParser.GetTableFields instead

func HasYAMLTags

func HasYAMLTags(data interface{}) bool

HasYAMLTags checks if a value or its nested structures contain yaml struct tags

func IsNoColor

func IsNoColor() bool

func ListCustomFormatters

func ListCustomFormatters() []string

ListCustomFormatters returns a sorted list of all registered custom formatter names.

func NewStructParser

func NewStructParser() *api.StructParser

NewStructParser creates a new struct parser

func ParsePrettyTag

func ParsePrettyTag(fieldName, tag string) api.PrettyField

ParsePrettyTag parses a pretty tag string into a PrettyField Deprecated: Use api.ParsePrettyTagWithName instead

func ParseStructSchema

func ParseStructSchema(val reflect.Value) (*api.PrettyObject, error)

ParseStructSchema creates a PrettyObject schema from struct tags Deprecated: Use api.StructParser.ParseStructSchema instead

func PrettifyFieldName

func PrettifyFieldName(name string) string

PrettifyFieldName converts field names to readable format Deprecated: Use api.PrettifyFieldName instead

func RegisterFormatter

func RegisterFormatter(name string, fn FormatterFunc)

RegisterFormatter registers a custom formatter with the given name. The name is case-insensitive and will be normalized to lowercase. Custom formatters take precedence over built-in formatters with the same name.

Example:

RegisterFormatter("upper", func(data interface{}, opts FormatOptions) (string, error) {
    return strings.ToUpper(fmt.Sprintf("%v", data)), nil
})

func RenderASTNode

func RenderASTNode(value interface{}, field api.PrettyField, theme api.Theme) string

RenderASTNode renders an AST node in compact format

func RenderCompactMethods

func RenderCompactMethods(value interface{}, field api.PrettyField, theme api.Theme) string

RenderCompactMethods renders a list of methods in compact format

func RenderComplexityColored

func RenderComplexityColored(value interface{}, field api.PrettyField, theme api.Theme) string

RenderComplexityColored renders a complexity value with color coding

func RenderFileTree

func RenderFileTree(value interface{}, field api.PrettyField, theme api.Theme) string

RenderFileTree renders a file tree node with appropriate icons

func RenderIconLabel

func RenderIconLabel(value interface{}, field api.PrettyField, theme api.Theme) string

RenderIconLabel renders a value with an icon prefix

func RenderLineNumber

func RenderLineNumber(value interface{}, field api.PrettyField, theme api.Theme) string

RenderLineNumber renders a line number with formatting

func SortRows

func SortRows(rows []api.PrettyDataRow, sortFields []SortField)

SortRows sorts rows based on multiple sort fields

func SplitCamelCase

func SplitCamelCase(s string) []string

SplitCamelCase splits camelCase strings into words Deprecated: Use api.SplitCamelCase instead

func StructToRow

func StructToRow(val reflect.Value) (api.PrettyDataRow, error)

StructToRow converts a struct to a PrettyDataRow Deprecated: Use api.StructParser.StructToRow instead

func ToPrettyData

func ToPrettyData(data interface{}, opts ...TypeOptions) (*api.PrettyData, error)

ToPrettyData converts various input types to PrettyData

func ToPrettyDataWithOptions

func ToPrettyDataWithOptions(data interface{}, opts FormatOptions) (*api.PrettyData, error)

ToPrettyDataWithOptions converts various input types to PrettyData using format options

func ToSlice

func ToSlice[T any](data ...any) ([]T, bool)

ToSlice converts variadic any arguments to a slice of type T if all elements implement T. It handles: - Single slice argument: []T or []any where elements are T - Multiple arguments: each implementing T - Nested slices: flattens one level if first arg is a slice

func UnregisterFormatter

func UnregisterFormatter(name string)

UnregisterFormatter removes a custom formatter by name. This is primarily useful for testing.

Types

type AfterFormatFunc

type AfterFormatFunc func(ctx any, manager *FormatManager, options FormatOptions, before any, out string) string

AfterFormatFunc can transform formatted output after rendering. before is the value that was passed into the formatter after BeforeFormat callbacks were applied.

type BeforeFormatFunc

type BeforeFormatFunc func(ctx any, manager *FormatManager, options FormatOptions, before any) any

BeforeFormatFunc can transform the input before it is formatted. ctx is nil for non-request formatting paths and may be an *http.Request, echo.Context, or another caller-provided context object.

type CSVFormatter

type CSVFormatter struct {
	Separator rune
}

CSVFormatter handles CSV formatting

func NewCSVFormatter

func NewCSVFormatter() *CSVFormatter

NewCSVFormatter creates a new CSV formatter

func (*CSVFormatter) Format

func (f *CSVFormatter) Format(data interface{}, _ FormatOptions) (string, error)

Format formats data as CSV

func (*CSVFormatter) FormatPrettyData

func (f *CSVFormatter) FormatPrettyData(data *api.PrettyData) (string, error)

FormatPrettyData formats PrettyData as CSV, flattening all fields

func (*CSVFormatter) FormatTable

func (f *CSVFormatter) FormatTable(table *api.TextTable) (string, error)

FormatTable formats a TextTable as CSV

type ClickyColumn

type ClickyColumn struct {
	Name   string      `json:"name"`
	Label  string      `json:"label,omitempty"`
	Header *ClickyNode `json:"header,omitempty"`
	Align  string      `json:"align,omitempty"`
}

type ClickyDocument

type ClickyDocument struct {
	Version int        `json:"version"`
	Node    ClickyNode `json:"node"`
}

ClickyDocument is the {version:1, node:{…}} envelope consumed by @flanksource/clicky-ui's <Clicky data={…} /> component. It is built from a PrettyData tree (clicky-json / html-react formatters) or directly from a Textable via NewClickyDocument. Every field below is concrete (no interfaces), so the document round-trips through encoding/json (Marshal and Unmarshal) with the stock codec — callers can persist it and reload it without loss.

func NewClickyDocument

func NewClickyDocument(t api.Textable) ClickyDocument

NewClickyDocument builds the {version:1, node:{…}} document directly from a Textable, reusing the same node converter the clicky-json / html-react formatters use. Unlike those formatters it does not route through PrettyData, so a hand-built rich Text (code blocks, collapsibles, tables, …) is encoded verbatim. The result is the shape consumed by @flanksource/clicky-ui's <Clicky data={…} /> component and round-trips through encoding/json.

type ClickyField

type ClickyField struct {
	Name  string     `json:"name"`
	Label string     `json:"label,omitempty"`
	Value ClickyNode `json:"value"`
}

type ClickyJSONFormatter

type ClickyJSONFormatter struct{}

ClickyJSONFormatter emits the Clicky document JSON (application/json+clicky). The HTTP layer also accepts the legacy application/clicky+json alias. The payload is the same shape consumed by @flanksource/clicky-ui's <Clicky data={...} />.

func (*ClickyJSONFormatter) Format

func (f *ClickyJSONFormatter) Format(data any, opts FormatOptions) (string, error)

Format returns the Clicky document JSON for data. Indented for readability since this format is typically consumed by humans or piped into tools.

type ClickyNode

type ClickyNode struct {
	Kind            string             `json:"kind"`
	Plain           string             `json:"plain,omitempty"`
	Style           *ClickyStyle       `json:"style,omitempty"`
	Text            string             `json:"text,omitempty"`
	Children        []ClickyNode       `json:"children,omitempty"`
	Tooltip         *ClickyNode        `json:"tooltip,omitempty"`
	HTML            string             `json:"html,omitempty"`
	Inline          bool               `json:"inline,omitempty"`
	Ordered         bool               `json:"ordered,omitempty"`
	Unstyled        bool               `json:"unstyled,omitempty"`
	Bullet          *ClickyNode        `json:"bullet,omitempty"`
	Items           []ClickyNode       `json:"items,omitempty"`
	Fields          []ClickyField      `json:"fields,omitempty"`
	Columns         []ClickyColumn     `json:"columns,omitempty"`
	Rows            []ClickyRow        `json:"rows,omitempty"`
	Roots           []ClickyTreeItem   `json:"roots,omitempty"`
	Label           *ClickyNode        `json:"label,omitempty"`
	Content         *ClickyNode        `json:"content,omitempty"`
	Href            string             `json:"href,omitempty"`
	Target          string             `json:"target,omitempty"`
	Command         string             `json:"command,omitempty"`
	Args            []string           `json:"args,omitempty"`
	Flags           map[string]string  `json:"flags,omitempty"`
	AutoRun         bool               `json:"autoRun,omitempty"`
	ID              string             `json:"id,omitempty"`
	Payload         string             `json:"payload,omitempty"`
	Variant         string             `json:"variant,omitempty"`
	Iconify         string             `json:"iconify,omitempty"`
	Unicode         string             `json:"unicode,omitempty"`
	Language        string             `json:"language,omitempty"`
	Source          string             `json:"source,omitempty"`
	HighlightedHTML string             `json:"highlightedHtml,omitempty"`
	ExceptionClass  string             `json:"exceptionClass,omitempty"`
	Message         string             `json:"message,omitempty"`
	CausedBy        []string           `json:"causedBy,omitempty"`
	Frames          []ClickyStackFrame `json:"frames,omitempty"`
	// Badge fields — set for Kind == "badge" (LabelBadge). Rendered by
	// clicky-ui as <Badge variant="label" label={Value1} value={Value2} />.
	BadgeLabel string `json:"badgeLabel,omitempty"`
	BadgeValue string `json:"badgeValue,omitempty"`
	BadgeColor string `json:"badgeColor,omitempty"`
	BadgeText  string `json:"badgeText,omitempty"`
	BadgeShape string `json:"badgeShape,omitempty"`
	BadgeIcon  string `json:"badgeIcon,omitempty"`
}

type ClickyRow

type ClickyRow struct {
	Cells  map[string]ClickyNode `json:"cells"`
	Detail *ClickyNode           `json:"detail,omitempty"`
}

type ClickyStackFrame

type ClickyStackFrame struct {
	FunctionName      string   `json:"functionName,omitempty"`
	DisplayName       string   `json:"displayName,omitempty"`
	File              string   `json:"file,omitempty"`
	Line              int      `json:"line,omitempty"`
	Location          string   `json:"location,omitempty"`
	Kind              string   `json:"kind,omitempty"`
	Runtime           bool     `json:"runtime,omitempty"`
	NativeMethod      bool     `json:"nativeMethod,omitempty"`
	AnnotationText    string   `json:"annotationText,omitempty"`
	Class             string   `json:"class,omitempty"`
	Method            string   `json:"method,omitempty"`
	SourceLines       []string `json:"sourceLines,omitempty"`
	SourceLineNumbers []int    `json:"sourceLineNumbers,omitempty"`
	SourceStartLine   int      `json:"sourceStartLine,omitempty"`
	SourceLanguage    string   `json:"sourceLanguage,omitempty"`
}

type ClickyStyle

type ClickyStyle struct {
	ClassName       string `json:"className,omitempty"`
	Color           string `json:"color,omitempty"`
	BackgroundColor string `json:"backgroundColor,omitempty"`
	Bold            bool   `json:"bold,omitempty"`
	Faint           bool   `json:"faint,omitempty"`
	Italic          bool   `json:"italic,omitempty"`
	Underline       bool   `json:"underline,omitempty"`
	Strikethrough   bool   `json:"strikethrough,omitempty"`
	TextTransform   string `json:"textTransform,omitempty"`
	MaxWidth        int    `json:"maxWidth,omitempty"`
	MaxLines        int    `json:"maxLines,omitempty"`
	TruncateMode    string `json:"truncateMode,omitempty"`
	Monospace       bool   `json:"monospace,omitempty"`
}

type ClickyText

type ClickyText struct {
	api.Textable
}

ClickyText wraps a Textable so json.Marshal emits the structured clicky document (NewClickyDocument) instead of the flattened plain string that api.Text.MarshalJSON produces. Drop it into any struct field whose JSON should be rendered by <Clicky/>:

type Result struct {
    Detail ClickyText `json:"detail"`
}

The transported/persisted form is the concrete ClickyDocument, which is what unmarshals — ClickyText is producer-side only.

func (ClickyText) MarshalJSON

func (c ClickyText) MarshalJSON() ([]byte, error)

MarshalJSON renders the wrapped Textable as a ClickyDocument.

type ClickyTreeItem

type ClickyTreeItem struct {
	ID       string           `json:"id"`
	Label    ClickyNode       `json:"label"`
	Children []ClickyTreeItem `json:"children,omitempty"`
}

type ExcelFormatter

type ExcelFormatter struct {
	SheetName string
}

ExcelFormatter handles Excel file generation

func NewExcelFormatter

func NewExcelFormatter() *ExcelFormatter

NewExcelFormatter creates a new Excel formatter

func (*ExcelFormatter) Format

func (f *ExcelFormatter) Format(data interface{}) (string, error)

Format is not supported for Excel as it needs to write to files

func (*ExcelFormatter) FormatPrettyData

func (f *ExcelFormatter) FormatPrettyData(data *api.PrettyData) (string, error)

FormatPrettyData formats PrettyData to Excel bytes (for in-memory operations)

func (*ExcelFormatter) FormatPrettyDataToFile

func (f *ExcelFormatter) FormatPrettyDataToFile(data *api.PrettyData, filename string, file *excelize.File) error

FormatPrettyDataToFile formats PrettyData to Excel file

func (*ExcelFormatter) FormatToFile

func (f *ExcelFormatter) FormatToFile(data interface{}, filename string) error

FormatToFile creates an Excel file and saves it to the specified path

func (*ExcelFormatter) FormatValue

func (f *ExcelFormatter) FormatValue(value interface{}) (string, error)

FormatValue is not needed as we use fieldValue.Plain() for formatted text This is kept for interface compatibility if needed

type FormatCallback

type FormatCallback struct {
	BeforeFormat BeforeFormatFunc
	AfterFormat  AfterFormatFunc
}

FormatCallback registers optional before/after hooks around formatting.

type FormatManager

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

func NewFormatManager

func NewFormatManager() *FormatManager

NewFormatManager creates a new format manager with all formatters initialized

func (*FormatManager) CSV

func (f *FormatManager) CSV(data interface{}) (string, error)

CSV implements api.FormatManager.

func (*FormatManager) Excel

func (f *FormatManager) Excel(data interface{}) (string, error)

Excel formats data as Excel file (requires file output)

func (*FormatManager) ExcelExport

func (f *FormatManager) ExcelExport(data interface{}, filename string) error

ExcelExport exports data to Excel format using filename

func (*FormatManager) ExcelToFile

func (f *FormatManager) ExcelToFile(data interface{}, filename string) error

ExcelToFile formats data as Excel file and saves to specified path

func (*FormatManager) Format

func (f *FormatManager) Format(format string, data interface{}) (string, error)

Format implements a generic format method that delegates to specific formatters

func (*FormatManager) FormatToFile

func (f *FormatManager) FormatToFile(options FormatOptions, data interface{}) error

FormatToFile formats data and writes to a file if output is specified

func (*FormatManager) FormatToFileWithContext

func (f *FormatManager) FormatToFileWithContext(ctx any, options FormatOptions, data interface{}) error

FormatToFileWithContext formats data and writes it to a file or stdout while forwarding ctx to registered format callbacks.

func (*FormatManager) FormatWithContext

func (f *FormatManager) FormatWithContext(ctx any, options FormatOptions, data ...any) (string, error)

FormatWithContext formats data with an optional caller context that is forwarded to registered format callbacks.

func (*FormatManager) FormatWithOptions

func (f *FormatManager) FormatWithOptions(options FormatOptions, data ...any) (string, error)

func (*FormatManager) FormatWithSchema

func (f *FormatManager) FormatWithSchema(prettyData *api.PrettyData, options FormatOptions) (string, error)

FormatWithSchema handles schema-aware formatting using provided PrettyData

func (*FormatManager) FormatWithSchemaContext

func (f *FormatManager) FormatWithSchemaContext(ctx any, prettyData *api.PrettyData, options FormatOptions) (string, error)

FormatWithSchemaContext handles schema-aware formatting while forwarding ctx to registered format callbacks.

func (*FormatManager) HTML

func (f *FormatManager) HTML(data interface{}) (string, error)

HTML implements api.FormatManager.

func (*FormatManager) HTMLPDF

func (f *FormatManager) HTMLPDF(data interface{}) (string, error)

HTMLPDF implements api.FormatManager.

func (*FormatManager) HTMLStatic

func (f *FormatManager) HTMLStatic(data interface{}) (string, error)

HTMLStatic returns static HTML without JavaScript dependencies.

func (*FormatManager) JSON

func (f *FormatManager) JSON(data interface{}) (string, error)

JSON implements api.FormatManager.

func (*FormatManager) Markdown

func (f *FormatManager) Markdown(data interface{}) (string, error)

Markdown implements api.FormatManager.

func (*FormatManager) ParseSchema

func (f *FormatManager) ParseSchema(data interface{}) (*api.PrettyObject, error)

func (*FormatManager) Pdf

func (f *FormatManager) Pdf(data interface{}, filename string) error

Pdf exports data to PDF format

func (*FormatManager) Pretty

func (f *FormatManager) Pretty(data interface{}) (string, error)

Pretty implements api.FormatManager.

func (*FormatManager) Slack

func (f *FormatManager) Slack(data interface{}) (string, error)

Slack formats data as Slack Block Kit JSON.

func (*FormatManager) ToPrettyData

func (f *FormatManager) ToPrettyData(data interface{}) (*api.PrettyData, error)

ToPrettyData implements api.FormatManager.

func (*FormatManager) ToPrettyDataWithOptions

func (f *FormatManager) ToPrettyDataWithOptions(data interface{}, opts FormatOptions) (*api.PrettyData, error)

ToPrettyDataWithOptions converts data to PrettyData using format options

func (*FormatManager) Tree

func (f *FormatManager) Tree(data interface{}) (string, error)

Tree formats data as a tree structure

func (*FormatManager) YAML

func (f *FormatManager) YAML(data interface{}) (string, error)

YAML implements api.FormatManager.

type FormatOptions

type FormatOptions struct {
	Format     string            `json:"format,omitempty"`
	NoColor    bool              `json:"no_color,omitempty"`
	Output     string            `json:"output,omitempty"`
	Verbose    bool              `json:"verbose,omitempty"`
	DumpSchema bool              `json:"dump_schema,omitempty"`
	Schema     *api.PrettyObject `json:"-"`                // Schema for schema-aware formatting
	Filter     string            `json:"filter,omitempty"` // CEL expression for filtering table rows and tree nodes

	// Format-specific boolean flags (mutually exclusive)
	JSON     bool `json:"json,omitempty"`
	YAML     bool `json:"yaml,omitempty"`
	CSV      bool `json:"csv,omitempty"`
	Markdown bool `json:"markdown,omitempty"`
	Pretty   bool `json:"pretty,omitempty"`
	HTML     bool `json:"html,omitempty"`
	PDF      bool `json:"pdf,omitempty"`
	Slack    bool `json:"slack,omitempty"`

	// Display structure flags (additive with format flags)
	Tree  bool `json:"tree,omitempty"`  // Display in tree structure
	Table bool `json:"table,omitempty"` // Display in table structure

	// Paging options
	Page  int `json:"page,omitempty"`  // Current page (1-indexed)
	Limit int `json:"limit,omitempty"` // Items per page

	// Sinks is derived state populated by ParseFormatSpec from the raw Format
	// string. It holds zero or one stdout sink (File == "") plus zero or more
	// file sinks produced by "format=file" pairs in --format.
	Sinks []FormatSink `json:"-"`
	// contains filtered or unexported fields
}

FormatOptions contains options for formatting operations

func MergeOptions

func MergeOptions(opts ...FormatOptions) FormatOptions

func (FormatOptions) Depth

func (o FormatOptions) Depth() int

Depth returns the current depth (for internal use by formatters)

func (FormatOptions) IncreaseDepth

func (o FormatOptions) IncreaseDepth() FormatOptions

IncreaseDepth returns a copy of FormatOptions with depth incremented by 1

func (*FormatOptions) ParseFormatSpec

func (o *FormatOptions) ParseFormatSpec() error

ParseFormatSpec parses the raw Format string into Sinks.

Accepts a single format name ("json"), a comma-separated list of "format=file" pairs ("json=out.json,markdown=summary.md"), or a mix ("pretty,json=out.json"). A bare format name becomes a stdout sink; no more than one stdout sink may appear in a single spec. "format=file" pairs are additive file sinks and have no upper bound.

When Sinks has already been set (e.g. by a previous call or direct assignment in tests) the method is a no-op.

If Format is empty and one of the legacy mutually-exclusive boolean toggles (JSON/HTML/...) is set, a matching single stdout sink is synthesized so existing call sites keep working unchanged.

func (*FormatOptions) ResolveFormat

func (options *FormatOptions) ResolveFormat() string

ResolveFormat resolves the output format from format-specific flags

func (*FormatOptions) ResolveNoColor

func (options *FormatOptions) ResolveNoColor()

ResolveNoColor checks env vars and sets NoColor accordingly. Respects: NO_COLOR (https://no-color.org/), COLOR=no|false, TERM=dumb. The --no-color CLI flag takes precedence (already set before this is called).

func (FormatOptions) SkipTable

func (o FormatOptions) SkipTable() bool

func (FormatOptions) SkipTree

func (o FormatOptions) SkipTree() bool

type FormatSink

type FormatSink struct {
	Format string
	File   string
}

FormatSink is one (format, file) pair parsed from the --format spec. When File == "" the sink renders to stdout; otherwise it is written to the given file via FormatManager.FormatToFile.

type FormatterFunc

type FormatterFunc func(data interface{}, options FormatOptions) (string, error)

FormatterFunc is a custom formatter function that converts data to a formatted string. It receives the data to format and format options, returning the formatted output or an error.

func GetCustomFormatter

func GetCustomFormatter(name string) (FormatterFunc, bool)

GetCustomFormatter retrieves a custom formatter by name. Returns the formatter function and true if found, nil and false otherwise. The name lookup is case-insensitive.

type HTMLFormatter

type HTMLFormatter struct {
	IncludeCSS bool
	IsPDFMode  bool
	EmailMode  bool
}

HTMLFormatter handles HTML formatting

func NewEmailHTMLFormatter

func NewEmailHTMLFormatter() *HTMLFormatter

NewEmailHTMLFormatter creates an HTML formatter suitable for email clients.

func NewHTMLFormatter

func NewHTMLFormatter() *HTMLFormatter

NewHTMLFormatter creates a new HTML formatter

func NewStaticHTMLFormatter

func NewStaticHTMLFormatter() *HTMLFormatter

NewStaticHTMLFormatter creates an HTML formatter that uses static HTML without JavaScript dependencies (Grid.js, Alpine.js). Suitable for PDF generation or environments where JavaScript may not execute.

func (*HTMLFormatter) Format

func (f *HTMLFormatter) Format(in interface{}, options FormatOptions) (string, error)

Format formats PrettyData into HTML output

func (*HTMLFormatter) FormatPrettyData

func (f *HTMLFormatter) FormatPrettyData(data *api.PrettyData) (string, error)

FormatPrettyData formats PrettyData directly as HTML

func (*HTMLFormatter) ToPrettyData

func (f *HTMLFormatter) ToPrettyData(data interface{}) (*api.PrettyData, error)

ToPrettyData converts various input types to PrettyData

type HTMLPDFFormatter

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

HTMLPDFFormatter handles HTML-to-PDF conversion using ChromiumConverter

func NewHTMLPDFFormatter

func NewHTMLPDFFormatter() *HTMLPDFFormatter

NewHTMLPDFFormatter creates a new HTML-PDF formatter

func (*HTMLPDFFormatter) Format

func (f *HTMLPDFFormatter) Format(data interface{}, opts FormatOptions) (string, error)

Format formats data as PDF by first rendering as HTML, then converting with Chromium

func (*HTMLPDFFormatter) FormatPrettyData

func (f *HTMLPDFFormatter) FormatPrettyData(data *api.PrettyData) (string, error)

FormatPrettyData formats PrettyData as PDF by first rendering as HTML, then converting with Chromium

func (*HTMLPDFFormatter) FormatToFile

func (f *HTMLPDFFormatter) FormatToFile(data interface{}, outputPath string) error

FormatToFile formats data and writes PDF directly to a file

func (*HTMLPDFFormatter) ToPrettyData

func (f *HTMLPDFFormatter) ToPrettyData(data interface{}) (*api.PrettyData, error)

ToPrettyData converts various input types to PrettyData

type HTMLReactFormatter

type HTMLReactFormatter struct{}

func (*HTMLReactFormatter) Format

func (f *HTMLReactFormatter) Format(data any, opts FormatOptions) (string, error)

type JSONFormatter

type JSONFormatter struct {
	Indent string
}

JSONFormatter handles JSON formatting

func NewJSONFormatter

func NewJSONFormatter() *JSONFormatter

NewJSONFormatter creates a new JSON formatter

func (*JSONFormatter) Format

func (f *JSONFormatter) Format(data interface{}) (string, error)

Format formats data as JSON

func (*JSONFormatter) FormatCompact

func (f *JSONFormatter) FormatCompact(data interface{}) (string, error)

FormatCompact formats data as compact JSON (no indentation)

func (*JSONFormatter) FormatPrettyData

func (f *JSONFormatter) FormatPrettyData(data *api.PrettyData) (string, error)

FormatPrettyData formats PrettyData as JSON using the original data if available

func (*JSONFormatter) FormatValue

func (f *JSONFormatter) FormatValue(data interface{}) (string, error)

FormatValue is a helper to format any value as JSON

type MarkdownFormatter

type MarkdownFormatter struct {
	NoColor bool
}

MarkdownFormatter handles Markdown formatting

func NewMarkdownFormatter

func NewMarkdownFormatter() *MarkdownFormatter

NewMarkdownFormatter creates a new Markdown formatter

func (*MarkdownFormatter) Format

func (f *MarkdownFormatter) Format(data interface{}) (string, error)

Format formats data as Markdown

func (*MarkdownFormatter) FormatPrettyData

func (f *MarkdownFormatter) FormatPrettyData(data *api.PrettyData, opts FormatOptions) (string, error)

FormatPrettyData formats PrettyData as Markdown

type PDFFormatter

type PDFFormatter struct{}

PDFFormatter handles PDF formatting using HTML-to-PDF conversion via Playwright/Chromium

func NewPDFFormatter

func NewPDFFormatter() *PDFFormatter

NewPDFFormatter creates a new PDF formatter

func (*PDFFormatter) Format

func (f *PDFFormatter) Format(data *api.PrettyData) (string, error)

Format formats PrettyData as PDF using Rod/Chromium

type PrettyFormatter

type PrettyFormatter struct {
	Theme   api.Theme
	NoColor bool
	// contains filtered or unexported fields
}

PrettyFormatter handles formatting of structs with pretty tags

func NewPrettyFormatter

func NewPrettyFormatter() *PrettyFormatter

NewPrettyFormatter creates a new formatter with adaptive theme

func NewPrettyFormatterWithTheme

func NewPrettyFormatterWithTheme(theme api.Theme) *PrettyFormatter

NewPrettyFormatterWithTheme creates a new formatter with a specific theme

func (*PrettyFormatter) Format

func (p *PrettyFormatter) Format(data interface{}) (string, error)

Format formats data and returns formatted output

func (*PrettyFormatter) FormatPrettyData

func (p *PrettyFormatter) FormatPrettyData(data *api.PrettyData) (string, error)

FormatPrettyData formats PrettyData structure

func (*PrettyFormatter) Parse

func (p *PrettyFormatter) Parse(data interface{}) (*api.PrettyData, error)

type PrettyMixin

type PrettyMixin interface {
	Pretty() api.Text
}

type SchemaFormatter

type SchemaFormatter struct {
	Schema *api.PrettyObject
	Parser *api.StructParser
}

SchemaFormatter handles schema-based formatting operations

func LoadSchemaFromYAML

func LoadSchemaFromYAML(schemaFile string) (*SchemaFormatter, error)

LoadSchemaFromYAML creates a SchemaFormatter from a YAML schema file

func NewSchemaFormatter

func NewSchemaFormatter(schemaFile string) (*SchemaFormatter, error)

NewSchemaFormatter creates a new schema formatter with the given schema file

func (*SchemaFormatter) FormatData

func (sf *SchemaFormatter) FormatData(data *api.PrettyData, options FormatOptions) (string, error)

FormatData formats PrettyData using the specified format

func (*SchemaFormatter) FormatFile

func (sf *SchemaFormatter) FormatFile(dataFile string, options FormatOptions) (string, error)

FormatFile formats a single data file using the schema

func (*SchemaFormatter) FormatFiles

func (sf *SchemaFormatter) FormatFiles(dataFiles []string, options FormatOptions) error

FormatFiles formats multiple data files using the schema

type SlackFormatter

type SlackFormatter struct {
	MaxTextLen int
}

func NewSlackFormatter

func NewSlackFormatter() *SlackFormatter

func (*SlackFormatter) Format

func (f *SlackFormatter) Format(in interface{}, options FormatOptions) (string, error)

Format formats data into Slack Block Kit JSON.

func (*SlackFormatter) FormatPrettyData

func (f *SlackFormatter) FormatPrettyData(data *api.PrettyData, options FormatOptions) (string, error)

FormatPrettyData formats PrettyData into Slack Block Kit JSON.

type SortField

type SortField struct {
	Name      string
	Priority  int
	Direction string // "asc" or "desc"
}

SortField represents a field to sort by with its priority

func ExtractSortFields

func ExtractSortFields(typ reflect.Type) []SortField

ExtractSortFields extracts sort fields from struct tags

type TextTree

type TextTree struct {
	Node     api.Textable
	Children []TextTree
}

type TreeFormatter

type TreeFormatter struct {
	Theme   api.Theme
	NoColor bool
	Options *api.TreeOptions
}

TreeFormatter handles tree structure formatting

func NewTreeFormatter

func NewTreeFormatter(theme api.Theme, noColor bool, options *api.TreeOptions) *TreeFormatter

NewTreeFormatter creates a new tree formatter

func (*TreeFormatter) Format

func (f *TreeFormatter) Format(data ...any) (string, error)

Format formats data as a tree structure

func (*TreeFormatter) FormatCompactList

func (f *TreeFormatter) FormatCompactList(items []string, separator string) string

FormatCompactList formats a list of items in compact mode

func (*TreeFormatter) FormatInlineTree

func (f *TreeFormatter) FormatInlineTree(nodes []api.TreeNode, separator string) string

FormatInlineTree formats a tree structure for inline display

func (*TreeFormatter) FormatPrettyData

func (f *TreeFormatter) FormatPrettyData(data *api.PrettyData) (string, error)

FormatPrettyData formats PrettyData as a tree structure

func (*TreeFormatter) FormatTreeFromRoot

func (f *TreeFormatter) FormatTreeFromRoot(root api.TreeNode) string

FormatTreeFromRoot formats a tree starting from the root node using lipgloss

func (*TreeFormatter) WrapCompactList

func (f *TreeFormatter) WrapCompactList(items []string, maxWidth int, indent string) string

WrapCompactList wraps a compact list to fit within a specified width

type TypeOptions

type TypeOptions struct {
	SkipTable bool
	SkipTree  bool
}

TypeOptions controls how data is converted to PrettyData

type YAMLFormatter

type YAMLFormatter struct{}

YAMLFormatter handles YAML formatting

func NewYAMLFormatter

func NewYAMLFormatter() *YAMLFormatter

NewYAMLFormatter creates a new YAML formatter

func (*YAMLFormatter) Format

func (f *YAMLFormatter) Format(data interface{}) (string, error)

Format formats data as YAML

func (*YAMLFormatter) FormatPrettyData

func (f *YAMLFormatter) FormatPrettyData(data *api.PrettyData) (string, error)

FormatPrettyData formats PrettyData as YAML using the original data if available

func (*YAMLFormatter) FormatValue

func (f *YAMLFormatter) FormatValue(data interface{}) (string, error)

FormatValue is a helper to format any value as YAML

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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