presenter

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Mar 1, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package presenter provides schema-aware rendering for Basecamp entities. It sits between commands and the output renderer, using declarative YAML schemas to transform generic data into human-centered terminal output.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EvalCondition

func EvalCondition(condition string, data map[string]any) bool

EvalCondition evaluates a template condition (from affordance "when" field). Returns true if the template renders to exactly "true" (as produced by Go's text/template for boolean true values and the {{not}} helper). Empty conditions are always true (unconditional visibility).

func FormatField

func FormatField(spec FieldSpec, key string, val any, locale Locale) string

FormatField formats a field value according to its FieldSpec using the given locale.

func IsOverdue

func IsOverdue(val any) bool

IsOverdue checks if a date value is before the start of today in local time. Handles both date-only ("2006-01-02") and RFC3339 timestamps.

func Present

func Present(w io.Writer, data any, entityHint string, mode RenderMode) bool

Present attempts schema-aware rendering of the data. Returns true if a schema was found and rendering was handled. Returns false if no schema matched (caller should fall back to generic rendering).

func PresentWithTheme

func PresentWithTheme(w io.Writer, data any, entityHint string, mode RenderMode, theme tui.Theme, locale Locale) bool

PresentWithTheme is like Present but accepts a theme and locale directly (for testing).

func RenderDetail

func RenderDetail(w io.Writer, schema *EntitySchema, data map[string]any, styles Styles, locale Locale) error

RenderDetail renders a single entity using its schema's detail view.

func RenderDetailMarkdown

func RenderDetailMarkdown(w io.Writer, schema *EntitySchema, data map[string]any, locale Locale) error

RenderDetailMarkdown renders a single entity as Markdown.

func RenderHeadline

func RenderHeadline(schema *EntitySchema, data map[string]any) string

RenderHeadline selects and renders the appropriate headline for the data.

func RenderList

func RenderList(w io.Writer, schema *EntitySchema, data []map[string]any, styles Styles, locale Locale) error

RenderList renders a slice of entities using the schema's list view.

func RenderListMarkdown

func RenderListMarkdown(w io.Writer, schema *EntitySchema, data []map[string]any, locale Locale) error

RenderListMarkdown renders a slice of entities as a Markdown table.

func RenderTemplate

func RenderTemplate(tmpl string, data map[string]any) string

RenderTemplate executes a Go text/template with the given data. Numeric values that are integer-like floats (common from JSON) are coerced to int64 before rendering to avoid scientific notation in output. Returns a placeholder on parse/execute errors to make failures visible.

Types

type Affordance

type Affordance struct {
	Action string `yaml:"action"`
	Cmd    string `yaml:"cmd"`
	Label  string `yaml:"label"`
	When   string `yaml:"when"`
}

Affordance is a templated CLI action the user can take.

type CompactView

type CompactView struct {
	Show   []string `yaml:"show"`
	Inline bool     `yaml:"inline"`
}

CompactView configures a minimal inline presentation.

type DetailSection

type DetailSection struct {
	Heading string   `yaml:"heading"`
	Fields  []string `yaml:"fields"`
}

DetailSection groups fields under an optional heading.

type DetailView

type DetailView struct {
	Sections []DetailSection `yaml:"sections"`
}

DetailView configures the single-entity detail presentation.

type EntitySchema

type EntitySchema struct {
	Entity    string                  `yaml:"entity"`
	Kind      string                  `yaml:"kind"`
	TypeKey   string                  `yaml:"type_key"`
	Identity  Identity                `yaml:"identity"`
	Headline  map[string]HeadlineSpec `yaml:"headline"`
	Fields    map[string]FieldSpec    `yaml:"fields"`
	Views     ViewSpecs               `yaml:"views"`
	Relations map[string]Relationship `yaml:"relationships"`
	Actions   []Affordance            `yaml:"affordances"`
}

EntitySchema describes how a Basecamp entity wants to be presented. Schemas are declarative metadata loaded from YAML files.

func Detect

func Detect(data any, entityHint string) *EntitySchema

Detect finds a schema from data. It checks an explicit entity name hint first, then falls back to auto-detection from the data's "type" field.

func LookupByName

func LookupByName(name string) *EntitySchema

LookupByName returns a schema by entity name (e.g. "todo").

func LookupByTypeKey

func LookupByTypeKey(typeKey string) *EntitySchema

LookupByTypeKey returns a schema by API type key (e.g. "Todo").

type FieldSpec

type FieldSpec struct {
	Role        string            `yaml:"role"`
	Emphasis    string            `yaml:"emphasis"`
	Format      string            `yaml:"format"`
	Collapse    bool              `yaml:"collapse"`
	Labels      map[string]string `yaml:"labels"`
	WhenOverdue string            `yaml:"when_overdue"`
}

FieldSpec describes how a single field should be presented.

type HeadlineSpec

type HeadlineSpec struct {
	Template string `yaml:"template"`
}

HeadlineSpec defines a headline template, optionally conditional.

type Identity

type Identity struct {
	Label string `yaml:"label"`
	ID    string `yaml:"id"`
	Icon  string `yaml:"icon"`
}

Identity identifies the entity's label and ID fields.

type ListView

type ListView struct {
	Columns []string `yaml:"columns"`
}

ListView configures the table/list presentation.

type Locale

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

Locale holds resolved formatting conventions for dates and numbers. It supports separate tags for date and number formatting to honor POSIX category-specific overrides (LC_TIME vs LC_NUMERIC).

func DetectLocale

func DetectLocale() Locale

DetectLocale resolves the user's locale from environment variables. Respects the POSIX precedence: LC_ALL overrides everything, then category-specific variables (LC_TIME for dates, LC_NUMERIC for numbers), then LANG as fallback. Falls back to en-US if nothing is set.

func NewLocale

func NewLocale(raw string) Locale

NewLocale creates a Locale from a POSIX locale string (e.g. "de_DE.UTF-8") or BCP 47 tag (e.g. "de-DE"). Uses the same tag for both date and number formatting. Returns en-US for empty or unparseable input.

func NewLocaleSplit

func NewLocaleSplit(dateRaw, numRaw string) Locale

NewLocaleSplit creates a Locale with separate tags for date and number formatting, matching POSIX behavior where LC_TIME and LC_NUMERIC can differ.

func (Locale) FormatDate

func (l Locale) FormatDate(t time.Time) string

FormatDate formats a time.Time as a locale-appropriate date string.

func (Locale) FormatNumber

func (l Locale) FormatNumber(v float64) string

FormatNumber formats a float64 with locale-appropriate grouping and decimal separators.

func (Locale) Tag

func (l Locale) Tag() language.Tag

Tag returns the resolved date language tag (used for date formatting decisions).

type Registry

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

Registry holds loaded entity schemas indexed by name and type key.

type Relationship

type Relationship struct {
	Entity      string `yaml:"entity"`
	Via         string `yaml:"via"`
	Label       string `yaml:"label"`
	Cardinality string `yaml:"cardinality"`
}

Relationship describes a connection to another entity.

type RenderMode

type RenderMode int

RenderMode controls the output format.

const (
	ModeStyled   RenderMode = iota // ANSI styled terminal output
	ModeMarkdown                   // Literal Markdown syntax
)

type Styles

type Styles struct {
	Primary lipgloss.Style
	Normal  lipgloss.Style
	Muted   lipgloss.Style
	Subtle  lipgloss.Style // for footer elements (most understated)
	Success lipgloss.Style
	Warning lipgloss.Style
	Error   lipgloss.Style
	Heading lipgloss.Style
	Label   lipgloss.Style
	Body    lipgloss.Style
}

Styles holds the lipgloss styles used by the presenter.

func NewStyles

func NewStyles(theme tui.Theme, styled bool) Styles

NewStyles creates presenter styles from a theme.

func (Styles) EmphasisStyle

func (s Styles) EmphasisStyle(emphasis string) lipgloss.Style

EmphasisStyle returns the style for a given emphasis string.

type ViewSpecs

type ViewSpecs struct {
	List    ListView    `yaml:"list"`
	Detail  DetailView  `yaml:"detail"`
	Compact CompactView `yaml:"compact"`
}

ViewSpecs declares which fields appear per presentation context.

Jump to

Keyboard shortcuts

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