Source code for cssbuilder

# python 2
from __future__ import absolute_import, print_function, unicode_literals
from builtins import str
# builtins
import logging
# plugins
from cssutils.css import Selector, Property, CSSStyleRule, CSSStyleSheet
from xml.dom import SyntaxErr
# custom
from blowdrycss.classpropertyparser import ClassPropertyParser

__author__ = 'chad nelson'
__project__ = 'blowdrycss'


[docs]class CSSBuilder(object): """ Builds CSS text with the ``cssutils.css`` module. **Note:** Removes invalid classes. A class is invalid for one of the following reasons: - It is not valid CSS. - It does not contain a valid ``blowdrycss`` encoding. **Object initialization process:** - Build CSS property rules - Add to css_rules, OR remove invalid css_class from class_set. - Build a CSS stylesheet based on the CSS ``css_rules`` set. | **Parameters: property_parser** (*ClassPropertyParser object*) -- Contains a class property parser with a populated class_set. | **Returns:** None """ def __init__(self, property_parser=ClassPropertyParser()): message = 'CSSBuilder Running...' print(message) logging.debug(msg=message) self.property_parser = property_parser self.css_rules = set() self.css_stylesheet = CSSStyleSheet() invalid_css_classes = [] reasons = [] for css_class in self.property_parser.class_set: name = self.property_parser.get_property_name(css_class=css_class) # 'name' can return an empty string '' if css_class does not match any patterns in the property_alias_dict. try: encoded_property_value = self.property_parser.get_encoded_property_value( property_name=name, css_class=css_class ) except ValueError: invalid_css_classes.append(css_class) reasons.append(' (property_name not found in property_alias_dict.)') continue priority = self.property_parser.get_property_priority(css_class=css_class) value = self.property_parser.get_property_value( property_name=name, encoded_property_value=encoded_property_value ) # Build CSS Property AND Add to css_rules OR Remove invalid css_class from class_set. try: css_property = Property(name=name, value=value, priority=priority) if css_property.valid: selector = self.build_selector(str(css_class)) css_rule = CSSStyleRule(selectorText=selector.selectorText, style=css_property.cssText) self.css_rules.add(css_rule) else: invalid_css_classes.append(css_class) reasons.append(' (cssutils invalid property value: ' + value + ')') continue # This exception can't be tested as clean_class_set() and get_property_value() prevent it.(Triple Redundant) except SyntaxErr: # Special Case - Not Tested invalid_css_classes.append(css_class) reasons.append(' (cssutils SyntaxErr invalid property value: ' + value + ')') continue # Clean out invalid CSS Classes. for i, invalid_css_class in enumerate(invalid_css_classes): self.property_parser.class_set.remove(invalid_css_class) self.property_parser.removed_class_set.add(invalid_css_class + reasons[i]) self.build_stylesheet()
[docs] def build_selector(self, css_class=''): """ Builds a CSS selector by prepending a ``'.'`` to ``css_class``, and appending an optional pseudo item. **Rules** - Always append a ``'.'`` to ``css_class``. - If a pseudo class is found append ``':' + pseuedo_class`` to ``css_class``. - If a pseudo element is found append ``'::' + pseudo_element`` to ``css_class``. :type css_class: str :param css_class: This value may or may not be identical to the property_value. :return: *str* -- The selector with a '.' prepended and an option pseudo item appended. """ self.property_parser.set_pseudo_class(css_class) self.property_parser.set_pseudo_element(css_class) css_class = '.' + css_class if self.property_parser.pseudo_class: selector = Selector(css_class + ':' + self.property_parser.pseudo_class) elif self.property_parser.pseudo_element: selector = Selector(css_class + '::' + self.property_parser.pseudo_element) else: selector = Selector(css_class) return selector
[docs] def build_stylesheet(self): """ Builds the stylesheet by adding CSS rules to the CSS stylesheet. :return: None """ for css_rule in self.css_rules: self.css_stylesheet.add(rule=css_rule)
[docs] def get_css_text(self): """ :return: str -- Returns CSS text. """ return self.css_stylesheet.cssText