Styled, multi-line text content: the type Harlock.Elements.text/2 accepts,
and the functions that lay it out.
Content is either a plain binary or a list of runs. A run is a binary, which
takes the element's style, or {binary, style}, where style is anything
:style accepts — a %Harlock.Render.Style{} or a keyword list:
"plain"
["CPU ", {"92%", fg: :red, bold: true}, " of 8 cores"]A run's style is layered over the style it is drawn with using
Harlock.Render.Style.merge/2: its colours win, and boolean attributes
combine. So a focused text keeps its focus highlight while a red run inside
it stays red.
"\n" always ends a line, in a plain binary as well as inside a run.
Measuring
height/2 exists for Harlock.Elements.viewport/1, which takes the height of
its content from the app. Wrapped text has no height until it is laid out at a
width, so an app scrolling a wrapped paragraph asks for it:
content_height: Harlock.Text.height(description, inner_width)
Summary
Types
A laid-out line: runs with their styles resolved against a base style.
A piece of text, optionally with its own style.
What text/2 accepts.
Functions
The number of rows content occupies when wrapped at width columns.
The display width of one laid-out line.
Lay content out as lines of styled runs.
Raise ArgumentError unless content is valid text content. Returns content.
The display width of the widest line of content, unwrapped.
Types
@type line() :: [{String.t(), Harlock.Render.Style.t()}]
A laid-out line: runs with their styles resolved against a base style.
@type run() :: String.t() | {String.t(), Harlock.Render.Style.t() | keyword()}
A piece of text, optionally with its own style.
What text/2 accepts.
Functions
@spec height(t(), pos_integer()) :: non_neg_integer()
The number of rows content occupies when wrapped at width columns.
Always at least 1 for non-empty content; "" and [] are 0.
@spec line_width(line()) :: non_neg_integer()
The display width of one laid-out line.
Lay content out as lines of styled runs.
Options:
:width— wrap at this many display columns.nil(the default) splits only on"\n".:style— the base style runs are merged over (default%Style{}).
Wrapping is Harlock.TextArea.wrap_line/2's: at the last space that fits,
mid-word only when a word is wider than the line. The space a line breaks at
is dropped, so alignment measures the visible text.
Raise ArgumentError unless content is valid text content. Returns content.
text/2 calls this so a malformed run fails inside the app's view/1, where
the stack trace points at it, rather than later inside the renderer.
@spec width(t()) :: non_neg_integer()
The display width of the widest line of content, unwrapped.