NAME
Term::Fabulous::Document::Look - Styles for each kind of document text, taken from a theme
SYNOPSIS
use Term::Fabulous::Document::Look;
# The look of the theme a widget draws with:
my $look = Term::Fabulous::Document::Look->of($widget);
$text->stylize( $look->style('code'), 4, 12 );
# The look of a particular theme:
my $light = Term::Fabulous::Document::Look->new( theme => Term::Fabulous::Theme->builtin('light') );
# A look with a kind of its own and a different style for code:
class My::Look :isa(Term::Fabulous::Document::Look) {
method recipes :common () {
return (
$class->SUPER::recipes,
title => { words => 'bold', color => 'accent' },
code => { color => 'success', background => 'surface_low' },
);
}
}
DESCRIPTION
A parser records what a range of text is, such as bold text, code or a heading, as a mark of a certain kind (see "FACTORIES" in Term::Fabulous::Document). A look decides how each kind is shown. For every kind it holds a style in the sense of Term::Fabulous::Text::Style: the style bits to set and clear, a text color and a background. A Term::Fabulous::Widget::Text span takes such a style unchanged.
Links are not a kind of the look. A Text draws its links itself, in the link looks of the theme (see "Looks" in Term::Fabulous::Widget::Text).
A look takes every color from the palette of a Term::Fabulous::Theme (see "Tokens" in Term::Fabulous::Theme), never from fixed values. A document view therefore follows the theme the program runs with, whether it is built in or read from a theme file, and switching the theme restyles the text.
Recipes
The styles are defined by recipes, one per kind. A recipe is a hash reference with up to three keys, all optional:
words-
A style string of "Style strings" in Term::Fabulous::Text::Style, usually one or more style words such as
'bold'or'bold italic'. Without it, the kind sets and clears no style bits. color-
The name of a palette token for the text color, such as
'accent'. Without it, the style leaves the text color alone. background-
The name of a palette token for the background, such as
'surface_low'. Without it, the style leaves the background alone.
The style string could name colors of its own, but these would not change with the theme; use the token keys instead. A color from a token key replaces any text color or background the style string names.
When a look is created, it turns every recipe into a style: it parses words and looks up both tokens in its theme with "token" in Term::Fabulous::Theme.
KINDS
The base class defines these kinds. In the middle column, bold, italic and strike are style words and every other name is a palette token. A token on its own or after a comma is the text color; X on Y means text color X on background Y, and on Y alone sets only the background.
Kind Shown as Used for
------------- --------------------------- ---------------------------------------
bold bold bold text
italic italic italic text
strike strike struck-through text
code warning code in a paragraph
file italic, success a file name
match on selection a search match
match_current text_inverse on warning the current search match
heading1 bold, accent a first-level heading
heading2 bold, text_bright a second-level heading
heading3 bold, text a third-level heading
heading4 bold italic, text a fourth-level heading
heading5 italic, text_bright a fifth-level heading
heading6 italic, text_muted a sixth-level heading
term bold, text_bright the term of a definition list
marker accent bullets and numbers of items
quote text_muted the bar beside a block quote
code_block text on surface_low verbatim blocks
clipped text_muted on surface_low the marks of clipped code lines
Changing and adding kinds
To restyle documents or to support mark kinds of a new format, write a subclass that overrides "recipes". It returns the recipes of its parent followed by its own; a recipe with the name of an existing kind replaces that kind's recipe. Keep all kinds of the base class: the document view and Term::Fabulous::Widget::CodeBlock ask for several of them by name, and "style" dies for a kind the look does not have.
A document names the look class its factories style marks with:
my $document = Term::Fabulous::Document->new( look => 'My::Look' );
The factories of the document die at once for a mark whose kind the look class does not list in "kinds" (links need no kind), and the document's code blocks paint with the same class. "Change the styles of a document and add mark kinds (Look)" in Term::Fabulous::Cookbook::DocumentTechniques is a worked example that changes the styles of a document and adds mark kinds this way.
CONSTRUCTORS
new
my $look = Term::Fabulous::Document::Look->new( theme => $theme );
Creates the look of a Term::Fabulous::Theme, with a style for every kind of "recipes". The theme parameter is required. The constructor dies when theme is not a Term::Fabulous::Theme, when it gets an unknown parameter, and when a recipe names a palette token the theme does not know or contains a style string that does not parse.
of
my $look = Term::Fabulous::Document::Look->of($widget);
Returns the look of the theme a widget draws with: its drawing_theme, which is the theme the Term::Fabulous UI gives the widget's part of the tree, or the default theme ("default" in Term::Fabulous::Theme) while it is part of no UI or of one without themes; the default theme for a widget that does not compose Term::Fabulous::Role::Themed. So the styles of the look and the widget's own looks come from the same theme. Call of on the look class you want; the look is an instance of that class.
Each look class caches the look it made last and returns it again as long as the theme is the same object and no theme has been switched anywhere in the process since (see "generation, bump_generation" in Term::Fabulous::Theme). Calling of in every frame is therefore cheap. There is one cached look per look class, so views that use the same look class but draw with different themes make a new look whenever the theme differs from the previous call.
CLASS METHODS
recipes
my %recipe = Term::Fabulous::Document::Look->recipes;
Returns the recipes of all kinds as a list of pairs, in the form kind => { words => 'bold italic', color => TOKEN, background => TOKEN } (see "Recipes"). A subclass overrides this method to change or add kinds, as described in "Changing and adding kinds".
kinds
my @kinds = Term::Fabulous::Document::Look->kinds; # bold, clipped, code, ...
Returns the names of all kinds of the class, sorted. The factories of Term::Fabulous::Document check the kind of every mark against this list (through "token_style") and die for a kind that is missing.
token_style
my $style = Term::Fabulous::Document::Look->token_style('code'); # { set => 0, clear => 0, color => 'warning', background => undef }
Class method. The style of a kind as a style hash whose colors are still the palette tokens of its recipe, not colors: what the factories of Term::Fabulous::Document give their texts, which look the tokens up in their own theme when they paint (see "Palette tokens" in Term::Fabulous::Text::Style). A new hash on every call. An unknown or undefined kind dies with the known kinds.
METHODS
theme
my $theme = $look->theme;
Returns the Term::Fabulous::Theme the styles were made from.
style
my $style = $look->style('code'); # { set => 0, clear => 0, color => [...], background => undef }
Returns the style of a kind as a style hash (see "Style hashes" in Term::Fabulous::Text::Style). The hash and its color arrays are new copies on every call, so the caller may change them without affecting the look. An unknown or undefined kind dies with a message that lists the known kinds.
SEE ALSO
Term::Fabulous::Cookbook::DocumentTechniques, Term::Fabulous::Text::Style, Term::Fabulous::Theme, "THEMES" in Term::Fabulous::Manual::Looks, Term::Fabulous::Document, Term::Fabulous::Widget::DocumentView.