The formatter module¶
The Formatter uses a Theme
to highlight text
according to a token’s action
attribute. The action is mapped to
a TextFormat
by the theme.
It is possible to add more Themes to a formatter, coupled to a certain language, so that the formatter can switch to that theme for embedded pieces of text of that language.
All kinds of text formatting and/or highlighting can be implemented by using or inheriting of Formatter. If you need to convert the TextFormats from the theme to something else, you can provide a factory to Formatter to do that.
There is also a SimpleFormatter
which just churns out the standard
action of each token as a HTML class string, for example mapping
Literal.Number
to "literal number"
, without needing a Theme.
If you need more special behaviour, you can inherit from Formatter and
reimplement format_ranges()
, to do other things or to use a different
FormatContext.
-
class
FormatCache
(theme, base, textformat, baseformat, unparsed)¶ Bases:
tuple
FormatCache is a named tuple encapsulating formatting logic.
At least two attributes must be defined:
textformat(action)
is called to return formatting information for the specified standard action.
baseformat(role, state)
is called to return general formatting information from a Theme, converted using the factory that was given to the formatter. See the
baseformat()
method ofTheme
.
Both callables may return None. The three other attributes can be None; they are:
theme
a reference to the format cache’s Theme object.
base
the result of
baseformat("window", "default")
, indicating the general format of the text window (color, font, background color, etc). See thebaseformat()
method ofTheme
.unparsed
the result of
textformat(StandardAction("_Unparsed"))
, which denotes the text format to use for unparsed text. A Theme can define that by putting properties in the.parce ._unparsed
class. By default unparsed text is not formatted.
-
base
¶ Alias for field number 1
-
baseformat
¶ Alias for field number 3
-
textformat
¶ Alias for field number 2
-
theme
¶ Alias for field number 0
-
unparsed
¶ Alias for field number 4
-
class
FormatRange
(pos, end, textformat)¶ Bases:
tuple
A named tuple denoting a text range from
pos
toend
that should be formatted withtextformat
.The textformat can be any object, that depends on the factory function that is used to convert a standard action or (when using a
Theme
) aTextFormat
to something you can use for the output format you want to create.-
end
¶ Alias for field number 1
-
pos
¶ Alias for field number 0
-
textformat
¶ Alias for field number 2
-
-
class
AbstractFormatter
[source]¶ Bases:
object
A Formatter formats text based on the action of tokens.
-
baseformat
(role='window', state='default', language=None)[source]¶ Return the base format for the specified
role
andstate
.This is the value returned by
Theme.baseformat(role, state)
, converted by our factory (and cached of course).If the
language
is given, the theme added for that language is consulted.If the theme does not provide a baseformat, or no theme was added for the specified language, None is returned.
-
textformat
(action, language=None)[source]¶ Return the text format for the specified action.
This is the value returned by
Theme.textformat(action)
, converted by our factory (and cached of course).If the
language
is given, the theme added for that language is consulted.If the theme does not provide a text format for the action, or no theme was added for the specified language, None is returned.
-
format_caches
()[source]¶ Should return a dictionary mapping language to FormatCache.
A
FormatCache
normally encapsulates a theme. The key None should be present and denotes the default theme. Other keys should beLanguage
subclasses, and their theme is used for tokens that originate from that language.
-
format_ranges
(tree, start=0, end=None, format_context=None)[source]¶ Yield FormatRange(pos, end, format) three-tuples.
The
format
is the value returned byTheme.textformat()
for the token’s action, converted by our factory (and cached of course). Ranges with a TextFormat for which our factory returns None are skipped.
-
format_text
(text, tree, start=0, end=None, format_context=None)[source]¶ Yield all text in tuples(text, format).
For unparsed pieces of text, or pieces that had no format mapped to the action, the format is None. The FormatContext, if given, is passed on to
format_ranges()
.
-
format_document
(cursor, format_context=None)[source]¶ Yield all text in the cursor’s selection in tuples(text, format).
For unparsed pieces of text, or pieces that had no format mapped to the action, the format is None.The FormatContext, if given, is passed on to
format_ranges()
. For example:>>> from parce import Cursor, Document, theme_by_name >>> from parce.lang.css import Css >>> from parce.formatter import Formatter >>> factory = lambda tf: tf.css_properties() or None >>> f = Formatter(theme_by_name(), factory) >>> d = Document(Css.root, "h1 { color: red; }") >>> c = Cursor(d).select_all() >>> list(f.format_document(c)) [('h1', {'color': '#00008b', 'font-weight': 'bold'}), (' ', None), ('{', {'font-weight': 'bold'}), (' ', None), ('color', {'color': '#4169e1', 'font-weight': 'bold'}), (': ', None), ('red', {'color': '#2e8b57'}), ('; ', None), ('}', {'font-weight': 'bold'})]
-
-
class
Formatter
(theme=None, factory=None)[source]¶ Bases:
parce.formatter.AbstractFormatter
A Formatter is used to format or highlight text according to a Theme.
Supply the theme, and an optional factory that converts a TextFormat to something else. For example:
>>> from parce import root, find, theme_by_name >>> from parce.formatter import Formatter >>> tree = root(find("css"), "h1 { color: red; }") >>> f = Formatter(theme_by_name('default')) >>> list(f.format_ranges(tree)) [FormatRange(pos=0, end=2, textformat=<TextFormat color=Color(r=0, g=0,b=139, a=1.0), font_weight='bold'>), FormatRange(pos=3, end=4, textformat=<TextFormat font_weight='bold'>), FormatRange(pos=5, end=10, textformat=<TextFormat color=Color(r=65, g=105, b=225, a=1.0), font_weight='bold'>), FormatRange(pos=12, end=15, textformat=<TextFormat color=Color(r=46, g=139, b=87, a=1.0)>), FormatRange(pos=17, end=18, textformat=<TextFormat font_weight='bold'>)]
The default factory just yields the TextFormat right from the theme, unless the format is empty, evaluating to None.
And here is an example using a factory that converts the textformat to a dictionary of css properties, e.g. to use for inline CSS highlighting. Note that when the factory returns None, a range is skipped, so we return None in case a dictionary ends up empty:
>>> factory = lambda tf: tf.css_properties() or None >>> f = Formatter(theme_by_name('default'), factory) >>> list(f.format_ranges(tree)) [FormatRange(pos=0, end=2, textformat={'color': '#00008b', 'font-weight': 'bold'}), FormatRange(pos=3, end=4, textformat={'font-weight': 'bold'}), FormatRange(pos=5, end=10, textformat={'color': '#4169e1', 'font-weight': 'bold'}), FormatRange(pos=12, end=15, textformat={'color': '#2e8b57'}), FormatRange(pos=17, end=18, textformat={'font-weight': 'bold'})]
In addition to the default theme (which is required), other themes can be added coupled to a specific language. This allows the formatter to switch theme based on the language of the text.
-
format_caches
()[source]¶ Reimplemented to return the format caches added by add_theme().
The format cache caches formatting information from the theme, to enable fast formatting.
-
add_theme
(theme, language=None, add_baseformat=False)[source]¶ Add a Theme.
If
language
is None, the theme becomes the default theme. If aLanguage
is specified, the theme will be used for tokens from that language.If
add_baseformat
is True, the theme’s baseformat (window) will be added to all the theme’s text formats.
-
-
class
SimpleFormatter
[source]¶ Bases:
parce.formatter.AbstractFormatter
A formatter that simply yields a HTML class string for every action.
For example:
>>> import parce.formatter >>> tree = parce.root(parce.find("css"), "h1 { color: red; }") >>> f = parce.formatter.SimpleFormatter() >>> list(f.format_ranges(tree)) [FormatRange(pos=0, end=2, textformat='name tag'), FormatRange(pos=3, end=4, textformat='delimiter bracket'), FormatRange(pos=5, end=10, textformat='name property definition'), FormatRange(pos=10, end=11, textformat='delimiter'), FormatRange(pos=12, end=15, textformat='literal color'), FormatRange(pos=15, end=16, textformat='delimiter'), FormatRange(pos=17, end=18, textformat='delimiter bracket')]
This formatter does not use a theme; language switches are ignored.
-
class
FormatContext
[source]¶ Bases:
object
FormatContext can be used to track theme changes during formatting.
A FormatContext instance can be given to the
AbstractFormatter.format_ranges()
method of a formatter.Inheriting from this class and implementing the methods enable you to react to theme changes during formatting.