ANSIA String carrying color markup, e.g. #ANSI'a [#ff6961]red[/] word'. A [...] tag opens a styled span — space-separated attributes: a named color (red, bright-cyan, gray), a #rrggbb hex, styles (bold, dim, italic, underline, strike, reverse, blink), and on <color> for the background — and [/] closes it, restoring the ENCLOSING style (spans nest). A bracket run that isn't a tag is literal text ([IO]Stdout needs no escaping); write [[ for a literal [ that would otherwise start a tag. % interpolation slots fill in later. Written to a terminal it renders as ANSI escape codes; written anywhere else the markup is stripped. Build one with the tagged literal #ANSI'...'.
The empty ANSI string.
The constructor behind the #ANSI'...' literal: wrap an already-marked-up String.
Interpolate like String#%, escaping the values so a stray '[' in a value can't open a tag (or corrupt the template). A nested ANSI argument is left alone, so its own markup still renders.
(#ANSI'ok %' % 'a[b').string "* -> ok a[[b
Store the wrapped markup String (used by new:; prefer the #ANSI'...' literal).
The length of the underlying markup String — markup and interpolation characters count too. For the rendered width use renderedLength.
The visible text — tags applied and stripped, exactly what a non-color write emits.
#ANSI'a [red]hot[/] pan'.plain "* -> a hot pan
How many characters actually render — the width for terminal layout, which length (markup characters included) overstates.
#ANSI'[red]hot[/]'.renderedLength "* -> 3
Renders as the tagged-literal form.
#ANSI'hi'.s "* -> #ANSI'hi'
The raw markup template, exactly as written — no color rendering.
#ANSI'hi %1'.string "* -> hi %1