The theme module#
This module provides the Theme class, which provides text formatting properties based on the action (standard action) of a Token.
These properties can be used to colorize text according to a language definition.
By default, the properties are read from a normal CSS (Cascading StyleSheets) file and presented to the user of the Theme module through TextFormat objects, although other storage backends could be devised.
A Theme provides a textformat()
for standard actions, and a
baseformat()
for general roles, such as "window"
, which denotes an
editor window (or an encompassing DIV or PRE block in HTML), "selection"
,
which is used for selected text, "current-line"
, which can highlight the
current line the cursor is in in an editor.
From the TextFormat returned by baseformat("selection")
and
"current-line"
, in most cases only the background color will be used.
For the roles "window"
, "selection"
and "current-line"
, the
baseformat()
method also accepts a state argument, which can be
"default"
, "focus"
or "disabled"
. A theme always supports the
"default"
state, but can provide separate colors for the "focus"
or
"disabled"
state, which can be used to change the basic formatting in an
editor window based on its state (in keyboard focus or disabled). If a theme
does not support the "disabled"
and/or "focus"
state, the default
scheme is used.
A Theme is loaded from a CSS file using:
>>> from parce.theme import Theme
>>> th = Theme('/path/to/my/custom.css')
Get a TextFormat for an action, use e.g.:
>>> f = th.textformat(String)
>>> f
<TextFormat color=Color(r=192, g=0, b=0, a=255)>
Multiple CSS files can be combined into one theme, and CSS rules can also be provided as plain text when instantiating a Theme.
Mapping actions to CSS classes#
Standard actions are mapped to one or more CSS class names using
css_class()
; it uses the action itself and the actions it descends from.
All CSS rules are combined, the one with the most matches comes first.
For example, Comment
maps to the "comment"
CSS class, and Number
maps to "literal number"
because Number is a descendant action of Literal.
Some actions might have the same name, e.g. Escape
and String.Escape
.
Both match CSS rules with the .escape
class selector, but a rule with
.string.escape
will have a higher precedence.
The order of the action names does not matter. E.g. an action Text.Comment
will match exactly the same CSS rules as an action Comment.Text
. So you
should take some care when designing you action hierachy and not add too much
base action types.
- class AbstractTheme[source]#
Bases:
object
Defines the interface of a Theme as used by a formatter.
- class Theme(*filenames, stylesheet='', basename='')[source]#
Bases:
AbstractTheme
A Theme maps a StandardAction to a TextFormat with CSS properties.
Zero or more
filenames
can be given, which are loaded after another. If thestylesheet
text is given, it is added to the stylesheets loaded from the filename(s). (If thebasename
is given, it is used to resolve@import
rules in thestylesheet
text.)- baseformat(role='window', state='default')[source]#
Return a TextFormat for a specific role and a state.
The
role
may be any string that maps to a CSS class in the theme CSS file that is available there together with theparce
class.The following roles are recognized and used by parce, but you may also define your own roles in your (applications’) theme CSS files:
"window"
The TextFormat for the editor window or the encompassing DIV when formatting HTML. Corresponds to the “parce” CSS class alone in the theme file. You can set color, background and, if desired, font preferences.
"selection"
The TextFormat to use for selected text. Uses the
::selection
pseudo element."current-line"
The TextFormat for the current line. If you use it, set only the background color in your theme file.
The state argument may be “default”, “focus”, or “disabled”, and reflects the state of the user interface the style variant is used for. If the state is “focus” or “disabled”, it is added as a pseudo class.
- class TextFormat(properties)[source]#
Bases:
object
Simple textformat that reads CSS properties and supports a subset of those.
This factory is used by default by Theme, but you can implement your own. Such a factory only needs to implement an
__init__
method that reads the dictionary of property Value lists returned by Style.properties().A TextFormat has a False boolean value if no single property is set.
You can add and subtract TextFormats:
>>> import parce >>> t = parce.theme_by_name() >>> f = t.baseformat() >>> f <TextFormat background_color=Color(r=255, g=255, b=240, a=1.0), color= Color(r=0, g=0, b=0, a=1.0), font_family=['monospace'], font_size=12, font_size_unit='pt'> >>> f2 = t.textformat(parce.Comment) >>> f2 <TextFormat color=Color(r=105, g=105, b=105, a=1.0), font_family=['serif'], font_style='italic'> >>> f + f2 <TextFormat background_color=Color(r=255, g=255, b=240, a=1.0), color= Color(r=105, g=105, b=105, a=1.0), font_family=['serif'], font_size=12, font_size_unit='pt', font_style='italic'> >>> f - f2 <TextFormat background_color=Color(r=255, g=255, b=240, a=1.0), color= Color(r=0, g=0, b=0, a=1.0), font_family=['monospace'], font_size=12, font_size_unit='pt'> >>>
Adding a TextFormat returns a new format with our properties set and then the properties of the other. This is useful when it is not possible to overlay properties with underlying window properties.
Subtracting a TextFormat returns a new format with the properties removed that are the same in the other format. This is useful when properties of a certain action happen to be the same as the underlying window properties; it is not needed to set these again in such cases.
- color = None#
the foreground color as Color(r, g, b, a) tuple
- background_color = None#
the background color (id)
- caret_color = None#
the color for the text cursor
- text_decoration_color = None#
the color for text decoration
- text_decoration_line = ()#
underline, overline and/or line-through
- text_decoration_style = None#
solid, double, dotted, dashed or wavy
- font_family = ()#
family or generic name
- font_kerning = None#
font kerning
- font_size = None#
font size
- font_size_unit = None#
font size unit if given
- font_stretch = None#
font stretch value (keyword or float, 1.0 is normal)
- font_style = None#
normal, italic or oblique
- font_style_angle = None#
oblique slant if given
- font_style_angle_unit = None#
oblique slant unit if given
- font_variant_caps = None#
all kind of small caps
- font_variant_position = None#
normal, sub or super
- font_weight = None#
100 - 900 or keyword like
bold
- css_class(action)[source]#
Return a CSS class string for the specified standard action.
The class names are simply the name of the action and all its ancestor actions. Class names are lowercase and space-separated. For example:
>>> from parce.action import Number >>> Number Literal.Number >>> css_class(Number) 'literal number'