Text
Validated terminal presentation.
Produced by text, by
preformat, or by calling a Style.
Nested Text values are flattened when composed, and an ANSI reset code in a
nested value restores the enclosing style. Terminal output functions render
Text with ANSI styling when stderr is a terminal and as plain text
otherwise.
Formatting
A format specification applied to Text measures
terminal cells rather than extended grapheme clusters, the same measure
width() reports: width pads to a cell count,
precision clips to one at a cluster boundary, and SGR sequences consume
neither.
Formatting produces a Str, so it drops the styling along
with every other str conversion: "${label:6}" is laid out in cells and
plain.
The console is where the layout and the styling arrive together. Given a
FmtValue bound to a Text,
echo, print,
text and a Style apply the layout to the
encoded form themselves, in the same terminal cells, and keep the styling:
let label = text("界a", fg: :RED:)
echo (std.FmtValue label width: 6) # padded and still red
echo "${label:6}" # padded and plain
A specification asking for a debug or numeric rendering is no longer a request for terminal presentation, and is sanitized like any other value.
Sequences
A "..." concatenates its interpolations as it is built, so a Text among
them is already flattened to its content by the time the console sees the
result. A t"..." keeps them apart, and the console renders
each one for itself -- so styling survives interpolation, at any depth:
let label = text("界a", fg: :RED:)
echo t"tag: ${label:6}|" # padded in cells and still red
echo "tag: ${label:6}|" # padded and plain
let framed = t"[${label:^8}]"
echo t"<${framed:>12}>" # each level lays out what the one inside rendered
Expanding a sequence this way is the console's own decision, not a conversion: no conversion expands one, which is what stops a sequence from arriving at a consumer already flattened. See Trust.
Each segment is taken exactly as an argument in its own right would be, so
the rules above apply to it unchanged: a Text keeps its styling, a
specification asking for a debug or numeric rendering is sanitized, and
everything else is converted -- verbatim in argument
position, str inside a Text -- and sanitized.
The exception is a FmtParam. A parameter printed on its
own is just a name and shows itself as such, but a hole means nothing to the
console, so one inside a sequence raises a
ValueError.
Example
let label = term.text ERROR fg: :RED: bold: true
echo $label " request failed"
# Preserve ANSI escapes for a file or another process.
let encoded = label.encode()
Methods
(str)()
Returns the content with the styling dropped.
The escape sequences are terminal instructions, not content: a Str
carrying them counts them in its length, matches them in a search, and
writes them into whatever file or pipe it reaches. Ask for them with
encode. verbatim reproduces a value as it would
have been written in source, and styled text has no source form, so it
gives the same content this does.
clip width … -> Text
Clips the text to a terminal-cell width at an extended grapheme boundary.
SGR sequences do not contribute to the width. If the text already fits it
is returned unchanged and suffix is ignored. Otherwise the suffix is
clipped to the total budget, its width is reserved, and the longest fitting
source prefix is prepended. Styling remains valid across the cut.
Parameters
| Name | Type | Description |
|---|---|---|
width |
Int |
Non-negative terminal-cell budget. |
:suffix? |
(Str | Text) |
Suffix appended only when truncating. |
Example
encode() -> Str
Returns the ANSI representation: exactly the bytes a terminal write emits.
This is the inverse of preformat, which takes the
result back (canonicalizing the SGR it re-emits).
Example
indent spaces -> Text
Adds spaces to the beginning of each line without changing ANSI formatting.
A terminal newline does not gain a trailing indentation prefix.
Parameters
| Name | Type | Description |
|---|---|---|
spaces |
Int |
Non-negative number of spaces. |
Example
join … -> Text
Concatenates values with this text between them.
Each value is taken the way text takes an argument of
its own: a Text keeps its styling, and anything else is converted and
sanitized.
Parameters
| Name | Type | Description |
|---|---|---|
iter? |
Iterable[Value] |
Values to join. Uses the default input when omitted. |
Example
width() -> Int
Returns the visible terminal-cell width of the text.
SGR sequences do not contribute to the width. Widths are summed within each extended grapheme cluster and capped at two cells per cluster. C0 control characters contribute zero.