This document defines the behavior of term.tss (src/term/term/tss.lua):
supported properties
cascading/override rules
width semantics (w)
public API contract
TSS is a style system for terminal output.
A style sheet is defined as a Lua table with style definition, and is referred as rss (raw style sheet).
tss is an instantiated object of a particular rss, with methods to apply it:
local tss_mod = require("term.tss")
local rss = { fg = "white" }
local tss = tss_mod.new(rss)
Styles are resolved by dot-path (for example: table.border.top_line), then applied
through tss:apply() or tss:apply_sized().
TSS is used directly by terminal widgets and by markdown renderers.
These properties are understood by term.tss itself:
| Property | Type | Behavior |
|---|---|---|
fg | string / number / {r,g,b} | Foreground color |
bg | string / number / {r,g,b} | Background color |
s | string | Comma-separated style list (bold,italic,...) |
align | string | left, right, center, none |
clip | number | 0 auto-clip to configured width, >0 explicit clip position, <0 disable clipping |
text_indent | number | Text-level indentation added by tss:apply() |
block_indent | number | Block-level indentation hint for renderers (not applied by tss:apply()) |
w | number | Element width (fractional or absolute; see width semantics below) |
ts | string / table | Kitty text sizing configuration (non-cascading) |
before | string | Prefix decorator added before content |
after | string | Suffix decorator added after content |
The following are read from the final resolved style object (leaf), not from cascaded props:
| Property | Type | Behavior |
|---|---|---|
content | string | Overrides input content |
fill | boolean | Repeats content to configured width |
Because these are leaf-object properties, define them at the style you apply directly.
fg, bg, align, clip, text_indent, block_indent, before, after: overwrite
s: accumulates; reset clears previously accumulated styles
w: recalculated at each level using the previous computed width as max
ts: does not cascade; each level either sets it or clears it
tss:apply(elements, content) accepts one element or an array of elements.
When multiple elements are passed, TSS resolves them in order and merges style state
left-to-right.
w) Semanticsw rules are strict:
w <= 0: auto (no explicit width)
0 < w < 1: fractional width of current max width, with floor (minimum 1 cell)
w >= 1: absolute terminal cell width, clamped to current max width
Important consequence:
w = 1 means exactly one cell (not 100%)
w = 0.99 becomes floor(max * 0.99), so it is not guaranteed full width
For full-width behavior, use an absolute width that will clamp to max (for example, a very large value).
ts) Semanticsts supports:
preset strings: big, compact, double, half, subscript, superscript, triple
table form: { s, w, n, d, v, h }
Validation:
s: 1..7
w: 0..7
n, d: 0..15 and d > n
v: 0..2 or top|bottom|center
h: 0..2 or left|right|center
Runtime gate:
if TSS instance is created with supports_ts = false, ts is ignored by
apply() and apply_sized()
term.tss exports:
new(rss, opts?)
merge(rss_1, rss_2, opts?)
TSS object methods:
get(path, base_props?)
apply(elements, content, position?)
apply_sized(base_elements, content_buf, position?, opts?)
scope(overrides?)
set_property(path, property, value)
get_property(path, property)
get_style(path?)
get_window_width()
set_window_width(width)
get_window_size()
set_window_size(height?, width?)
get_supports_ts()
set_supports_ts(enabled)
calc_el_width(w, max?, scale?)
style_snapshot()
resolve_scale(elements)
apply() return valueapply() and apply_sized() return a table:
text: styled output string
width: terminal cell width of rendered output
height: terminal cell height of rendered output
Use .text, .width, and .height explicitly.
Some style fields used in markdown renderers are not interpreted by term.tss directly
(for example list.indent_per_level).
They are consumed by renderer code and may coexist with core TSS properties.
| Path | Type | Values | Default | Behavior |
|---|---|---|---|---|
list.indent_per_level | number | non-negative number (renderer uses floored integer) | 4 | Controls nesting indentation step for markdown list rendering (spaces per nesting level after level 1). |
table.overflow | string | wrap, clip | wrap | Controls terminal table cell overflow handling in markdown renderers. wrap expands row height and wraps cell content within fitted column width. clip preserves legacy single-line truncation with ellipsis when needed. |
Thematic break glyph customization uses core TSS fields:
thematic_break.content for the repeated pattern
thematic_break.fill = true to expand pattern to element width