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:
tupleFormatCache 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:
themea reference to the format cache’s Theme object.
basethe result of
baseformat("window", "default"), indicating the general format of the text window (color, font, background color, etc). See thebaseformat()method ofTheme.unparsedthe 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 ._unparsedclass. 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:
tupleA named tuple denoting a text range from
postoendthat 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) aTextFormatto 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:
objectA Formatter formats text based on the action of tokens.
- baseformat(role='window', state='default', language=None)[source]#
Return the base format for the specified
roleandstate.This is the value returned by
Theme.baseformat(role, state), converted by our factory (and cached of course).If the
languageis 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
languageis 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
FormatCachenormally encapsulates a theme. The key None should be present and denotes the default theme. Other keys should beLanguagesubclasses, 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
formatis 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:
AbstractFormatterA 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
languageis None, the theme becomes the default theme. If aLanguageis specified, the theme will be used for tokens from that language.If
add_baseformatis True, the theme’s baseformat (window) will be added to all the theme’s text formats.
- class SimpleFormatter[source]#
Bases:
AbstractFormatterA 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:
objectFormatContext 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.