NAME
Term::Fabulous::Text::Style - Parse style strings such as "bold red on #202020"
SYNOPSIS
use Term::Fabulous::Text::Style qw(parse_style style compose_styles apply_style);
my $style = parse_style('bold underline SteelBlue on #202020');
# { set => TB_BOLD | TB_UNDERLINE, clear => 0, color => [ 70, 130, 180, 255 ], background => [ 32, 32, 32, 255 ] }
my $plain = parse_style('not bold default');
# { set => 0, clear => TB_BOLD, color => [ 0, 0, 0, 0 ], background => undef }
my $same = style($style); # a style hash is checked and copied, a string parsed
my $inner = compose_styles( $style, parse_style('not bold') ); # stacked: the later wins
# { set => TB_UNDERLINE, clear => TB_BOLD, color => [ 70, 130, 180, 255 ], background => [ 32, 32, 32, 255 ] }
my $look = apply_style( { attrs => TB_ITALIC, color => [ 220, 223, 228, 255 ], background => undef }, $style );
# { attrs => TB_ITALIC | TB_BOLD | TB_UNDERLINE, color => [ 70, 130, 180, 255 ], background => [ 32, 32, 32, 255 ] }
DESCRIPTION
A style is what a span of a Term::Fabulous::Widget::Text adds to the look of the characters it covers: style bits to set or clear, a text color and a background. It is written as a string of words, in the manner of Python's rich library, or given as a hash. This module turns both into one normalized hash, stacks such hashes ("compose_styles") and applies one to a look ("apply_style"). These two functions are the only place where style bits are combined: "runs" in Term::Fabulous::Text::Marks composes the styles of overlapping ranges with the first, and Term::Fabulous::Render::Text and Term::Fabulous::Widget::CodeBlock paint each run with the second.
Style strings
A style string is words separated by whitespace, in any order:
bold,italic,underline,reverse,dim,blink,strike,overline,conceal-
Set the style bit of that name (the termbox2 attributes
TB_BOLD,TB_ITALIC,TB_UNDERLINE,TB_REVERSE,TB_DIM,TB_BLINK,TB_STRIKEOUT,TB_OVERLINEandTB_INVISIBLEof Term::Fabulous::Termbox).strikethroughis the same asstrike. Terminals show these with what their font has; a terminal may ignore some of them. not WORD-
Clear that style bit, so an inner span can switch off what an outer one set:
not bold. - A color
-
The text color: any string Term::Fabulous::Color reads (see "A string" in Term::Fabulous::Color), such as a CSS color name in any case (
SteelBlue,steelblue),#ff8800,rgb(255, 136, 0)orhsl(32, 100%, 50%).defaultis the terminal's default color (alpha 0); the style words above win over a color of the same spelling (there is none among the CSS names). on COLOR-
The background, a color as above:
on #202020,on default.
The last word wins where words contradict (bold not bold clears bold). Unknown words die with the known ones.
Palette tokens
A word that names a token of the theme's palette (accent, text_muted, selection, ... ; see "Tokens" in Term::Fabulous::Theme) is a color too: 'bold accent on surface_low'. It stays the token's name in the style, and the widget that paints the style asks its theme for the color ("resolve_style"), so a theme switch recolors the text. A word that is both a token and a color name is read as the token.
Style hashes
The normalized form has exactly these keys:
{
set => $bits, # style bits to set
clear => $bits, # style bits to clear
color => $rgba | $token | undef, # [r, g, b, a] or a palette token's name;
# undef leaves it alone
background => $rgba | $token | undef,
}
Colors are [r, g, b, a] with alpha 0 for the terminal's default color, or the name of a palette token (see "Palette tokens"); undef means the style does not touch that color.
FUNCTIONS
Nothing is exported by default.
parse_style
my $style = parse_style('bold red on #202020');
Parses a style string (see "Style strings") into a style hash. An unknown word, a not or on without its argument, undef or a reference die with a message starting with Term::Fabulous::Text::Style:.
style
my $style = style($string_or_hash);
Returns a normalized style hash for a style string or a hash with any of the keys of "Style hashes"; missing keys are 0 or undef, and the colors may be in any format Term::Fabulous::Color accepts, or a palette token's name, kept as it is. The result is a new hash. Unknown keys, invalid bits (not a non-negative integer) and invalid colors die.
compose_styles
my $style = compose_styles( $outer, $inner, $innermost );
Stacks style hashes in order and returns the style hash they make together, as if each were applied after the ones before it: a later set bit wins over an earlier clear of the same bit and the other way round (both stay recorded, so the result still clears what it must clear), and a later color replaces an earlier one. No styles give the style that touches nothing. Applying the result to a look gives the same look as applying the styles one after the other. The given hashes are not changed.
apply_style
my $look = apply_style( { attrs => $bits, color => $rgba, background => $rgba_or_undef }, $style );
Applies a style hash to a look, a hash of the termbox2 style bits attrs, the text color and the background, and returns the new look: the bits with clear removed and set added, and each color replaced when the style has one. The given look is not changed. The colors are passed through as they are, so they may be in any one form as long as the look and the style agree: Term::Fabulous::Render::Text applies Text runs whose colors are termbox attributes.
resolve_style
my $resolved = resolve_style( $style, $theme );
The style with every palette token among its color and background replaced by the [r, g, b, a] the theme gives it ($theme->token); a style without tokens comes back as it is. A token the theme does not know dies. "runs" in Term::Fabulous::Text::Marks calls it with the theme the widget draws with.
SEE ALSO
Term::Fabulous::Text::Markup, Term::Fabulous::Widget::Text, Term::Fabulous::Color, Term::Fabulous::Enum::WebColor, Term::Fabulous::Termbox.