The css module

This modules provides StyleSheet, Style, Element and a some utility functions that help write css properties.

StyleSheet represents a list of rules and conditions (nested @-rules) from a CSS file or string source. (The CSS format is parsed by the Css language definition in parce.lang.css and transformed to a CSS structure by the CssTransform transform class.)

Style represents a resulting list of rules, sorted on specificity, so that by selecting rules the properties that apply in a certain situation can be determined and read.

Element and AbstractElement describe elements in a HTML or XML document, and can be used to select matching rules in a stylesheet. Element provides a list-based helper, and AbstractElement can be inherited from to wrap any tree structure to use with stylesheet rule selectors.

This module is used by the theme module to provide syntax highlighting themes based on CSS files.

Workflow:

  1. Instantiate a StyleSheet from a file or other source. If needed, combine multiple StyleSheets using the + operator.

  2. Filter conditions out using filter_conditions(), like media, supports or document.

  3. Get a Style object through the style property of the StyleSheet.

  4. Use a select method to select rules based on their selectors.

  5. Use properties() to combine the properties of the selected rules to get a dictionary of the CSS properties that apply.

Example:

>>> from parce.css import Element, StyleSheet
>>> style = StyleSheet.from_file("parce/themes/default.css").style
>>> e = Element(class_="comment", parent=Element(class_="parce"))
>>> style.select_element(e).properties()
{'color': [<Value text='dimgray', color=Color(r=105, g=105, b=105, a=1.0)>],
'font-family': [<Value text='serif'>], 'font-style': [<Value text='italic'>]}
class Condition(keyword, node, style)

Bases: tuple

property keyword

Alias for field number 0

property node

Alias for field number 1

property style

Alias for field number 2

style_query(func)[source]

Make a generator method return a new Style/StyleSheet/Atrules object.

class StyleSheet(rules=None, filename='')[source]

Bases: object

Represents a list of style rules and conditions.

Normal CSS rules are translated into a Rule tuple, nested rules such as @media, @document and @supports are translated into Condition tuples, and other @-rules are put in Atrule tuples.

A Rule consists of selectors and properties. The selectors are the tokens in a rule before the {. The properties is a dict mapping css property names to the list of tokens representing their value.

A Condition consists of keyword, node and style; the node is Css.atrule context containing all text from the @ upto the opening {. The style is another StyleSheet object representing the nested style sheet.

An Atrule tuple consists of keyword and node, where the node is the Css.atrule context.

You can combine stylesheets from different files or sources using the + operator.

The style property returns the Style object representing all combined rules, and allowing further queries. The at property returns an Atrules instance containing the atrules that do not belong to the nested at-rules.

filename = ''

our filename, if we were loaded from a file

classmethod load_from_data(data)[source]

Return a Css.root tree from data, handling the encoding.

static load_from_text(text)[source]

Return a CSS structure from text.

classmethod load_from_file(filename)[source]

Return a CSS structure from filename, handling the encoding.

classmethod from_file(filename, path=None, allow_import=True)[source]

Return a new StyleSheet adding Rules and Conditions from a local filename.

The path argument is currently unused. If allow_import is False, the @import atrule is ignored.

classmethod from_text(text, filename='', path=None, allow_import=True)[source]

Return a new StyleSheet adding Rules and Conditions from a string.

The filename argument is used to handle @import rules correctly. The path argument is currently unused. If allow_import is False, the @import atrule is ignored.

classmethod from_data(data, filename='', path=None, allow_import=True)[source]

Return a new StyleSheet adding Rules and Conditions from a bytes string.

The filename argument is used to handle @import rules correctly. The path argument is currently unused. If allow_import is False, the @import atrule is ignored.

classmethod from_css(css, filename='', path=None, allow_import=True)[source]

Return a new StyleSheet adding Rules and Conditions from a CSS structure.

The filename argument is used to handle @import rules correctly. The path argument is currently unused. If allow_import is False, the @import atrule is ignored.

filter_conditions(keyword, predicate)[source]

Return a new StyleSheet object where conditions are filtered out.

For Condition instances with the specified keyword, the predicate is called with the contents of the rule (the full Atrule) of each Condition, and if the return value doesn’t evaluate to True, the Condition is removed from the resulting set. Conditions with other keywords are kept.

Currently (CSS3), Conditions have the “media”, “supports” or “document” keyword. @import rules that have a media query after the filename are also stored as a Condition.

For example, this is a crude way to only get the @media rules for “screen”:

filter_conditions("media", lambda rule: "screen" in rule.contents)

Of course, a better parser for @media expressions could be written :-)

filenames()[source]

Return a list of filenames the currently selected rules depend on.

Our own filename will be the first in the list, and filenames of @import-ed rules that are still selected are appended to the list.

property style

Return a Style object with the remaining rules.

All rules that still are behind a condition, are let through. The rules are sorted on specificity.

property at

Return an Atrules object containing the remaining at-rules.

All rules that still are behind a condition, are let through.

class Style(rules)[source]

Bases: object

Represents the list of rules created by the StyleSheet object.

All select-methods/properties return a new Style object with the narrowed-down selection of rules.

Use properties() to get the dictionary of combined properties that apply to the selected rules.

select_element(element)[source]

Select the rules that match with Element.

select_lxml_element(element)[source]

Select the rules that match with lxml.etree.Element.

properties()[source]

Return the combined properties of the current set of rules. (Endpoint.)

Returns a dictionary with the properties. The value of each property is a list of Value instances.

class Atrules(rules)[source]

Bases: object

Represents the @rules that are not nested, e.g. @page etc.

select(*keywords)[source]
class AbstractElement[source]

Bases: object

Base implementation for an Element object that Style uses for matching.

You may reimplement this to wrap any tree structure you want to use with the css module. You should then implement:

  • __init__()

  • get_name()

  • get_parent()

  • get_attributes()

  • get_pseudo_classes() (if needed)

  • get_pseudo_elements() (if needed)

  • children()

  • get_child_count()

  • previous_siblings()

  • next_siblings()

If you wrap other objects, be sure to reimplement __eq__ and __ne__, to compare those objects and not the wrappers, which may be recreated each time.

get_name()[source]

Implement to return the element’s name.

get_parent()[source]

Implement to return the parent Element or None.

get_attributes()[source]

Implement to return a dictionary of attributes, keys and values are str.

get_pseudo_classes()[source]

Implement to return a list of pseudo classes.

get_pseudo_elements()[source]

Implement to return a list of pseudo elements.

children()[source]

Implement to yield our children.

get_child_count()[source]

Implement to return the number of children.

previous_siblings()[source]

Implement to yield our previous siblings in backward order.

next_siblings()[source]

Implement to yield our next siblings in forward order.

get_classes()[source]

Return a tuple of classes, by default from the ‘class’ attribute.

The returned tuple may be empty, when there are no class names.

get_id()[source]

Return the id or None, by default read from the ‘id’ attribute.

next_sibling()[source]

Return the next sibling.

previous_sibling()[source]

Return the previous sibling.

is_first_child()[source]

Return True if we are the first child.

is_last_child()[source]

Return True if we are the last child.

is_only_child()[source]

Return True if we are the only child.

is_first_of_type()[source]

Return True if we are the first of our type.

is_last_of_type()[source]

Return True if we are the last of our type.

is_empty()[source]

Return True if we have no child elements.

match(prelude)[source]

Match with a compound selector expression (prelude part of Rule).

match_selectors(selectors)[source]

Match with a list of selectors with operators in between.

match_selector(selector)[source]

Match with a single CSS selector dictionary.

Returns True if the element matches with the selector.

class Element(name='', parent=None, pseudo_classes=None, pseudo_elements=None, **attrs)[source]

Bases: parce.css.AbstractElement, list

Mimic an Element CSS selector rules are matched with.

Use “class_” when specifying the class with a keyword argument. You can also manipulate the attributes after instantiating.

get_name()[source]

Implemented to return the element’s name.

get_parent()[source]

Implemented to return the parent Element or None.

get_attributes()[source]

Implemented to return a dictionary of attributes.

get_pseudo_classes()[source]

Implemented to return a list of pseudo classes.

get_pseudo_elements()[source]

Implemented to return a list of pseudo elements.

children()[source]

Implemented to yield our children.

get_child_count()[source]

Implemented to return the number of children.

previous_siblings()[source]

Yield our previous siblings in backward order.

next_siblings()[source]

Yield our next siblings in forward order.

class LxmlElement(element)[source]

Bases: parce.css.AbstractElement

An Element wrapping an element from a lxml.etree tree.

get_name()[source]

Return the element’s name.

get_parent()[source]

Return the parent Element or None.

get_attributes()[source]

Return a dictionary of attributes, keys and values are str.

get_pseudo_classes()[source]

Implement to return a list of pseudo classes.

get_pseudo_elements()[source]

Implement to return a list of pseudo elements.

children()[source]

Yield our children.

get_child_count()[source]

Return the number of children.

previous_siblings()[source]

Yield our previous siblings in backward order.

next_siblings()[source]

Yield our next siblings in forward order.

calculate_specificity(prelude)[source]

Calculate the specificity of the Css rule prelude.

Returns a three-tuple (ids, clss, elts), where ids is the number of ID selectors, clss the number of class, attribute or pseudo-class selectors, and elts the number of element or pseudo-elements.

Currently, does not handle functions like :not(), :is(), although that would not be difficult to implement.

color2hex(color)[source]

Return a hexadecimal string with ‘#’ prepended for the Color instance.

quote_if_needed(s)[source]

Double-quote the string for CSS if it is not a valid ident-token.

escape(char)[source]

Escape the specified character for CSS.