Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add an example for extending the parser.

  • Loading branch information...
commit 1ab4a855f5d70370c61b04dc04d9f80e50e5f1ee 1 parent ddf0471
@SimonSapin authored
View
6 docs/css3.rst
@@ -16,7 +16,7 @@ can be used to serialize a selector back to an Unicode string.
... 'div.error, #root > section:first-letter { color: red }')
>>> selector_string = stylesheet.rules[0].selector.as_css()
>>> selector_string
- u'div.error, #root > section:first-letter'
+ 'div.error, #root > section:first-letter'
This string can be parsed by cssselect_. The parsed objects have information
about pseudo-elements and selector specificity.
@@ -28,7 +28,7 @@ about pseudo-elements and selector specificity.
>>> [s.specificity() for s in selectors]
[(0, 1, 1), (1, 0, 2)]
>>> [s.pseudo_element for s in selectors]
- [None, u'first-letter']
+ [None, 'first-letter']
These objects can in turn be translated to XPath expressions. Note that
the translation ignores pseudo-elements, you have to account for them
@@ -36,7 +36,7 @@ somehow or reject selectors with pseudo-elements.
>>> xpath = cssselect.HTMLTranslator().selector_to_xpath(selectors[1])
>>> xpath
- u"descendant-or-self::*[@id = 'root']/section"
+ "descendant-or-self::*[@id = 'root']/section"
Finally, the XPath expressions can be used with lxml_ to find the matching
elements.
View
42 docs/extending.rst
@@ -17,6 +17,48 @@ and send a pull request: see :ref:`hacking`.
.. currentmodule:: tinycss.css21
+Example: star hack
+------------------
+
+.. _star hack: https://en.wikipedia.org/wiki/CSS_filter#Star_hack
+
+The `star hack`_ uses invalid declarations that are only parsed by some
+versions of Internet Explorer. By default, tinycss ignores invalid
+declarations and logs an error.
+
+ >>> from tinycss.css21 import CSS21Parser
+ >>> css = '#elem { width: [W3C Model Width]; *width: [BorderBox Model]; }'
+ >>> stylesheet = CSS21Parser().parse_stylesheet(css)
+ >>> stylesheet.errors
+ [ParseError('Parse error at 1:35, expected a property name, got DELIM',)]
+ >>> [decl.name for decl in stylesheet.rules[0].declarations]
+ ['width']
+
+If for example a minifier based on tinycss wants to support the star hack,
+it can by extending the parser::
+
+ >>> class CSSStarHackParser(CSS21Parser):
+ ... def parse_declaration(self, tokens):
+ ... has_star_hack = (tokens[0].type == 'DELIM' and tokens[0].value == '*')
+ ... if has_star_hack:
+ ... tokens = tokens[1:]
+ ... declaration = super(CSSStarHackParser, self).parse_declaration(tokens)
+ ... declaration.has_star_hack = has_star_hack
+ ... return declaration
+ ...
+ >>> stylesheet = CSSStarHackParser().parse_stylesheet(css)
+ >>> stylesheet.errors
+ []
+ >>> [(d.name, d.has_star_hack) for d in stylesheet.rules[0].declarations]
+ [('width', False), ('width', True)]
+
+This class extends the :meth:`~CSS21Parser.parse_declaration` method.
+It removes any ``*`` delimeter :class:`~.token_data.Token` at the start of
+a declaration, and adds a ``has_star_hack`` boolean attribute on parsed
+:class:`Declaration` objects: ``True`` if a ``*`` was removed, ``False`` for
+“normal” declarations.
+
+
Parser methods
--------------
View
4 docs/parsing.rst
@@ -17,9 +17,9 @@ and parse a stylesheet:
... p.error { color: red } @lorem-ipsum;
... @page tables { size: landscape }''')
>>> stylesheet.rules
- [<ImportRule 1:1 foo.css>, <RuleSet at 2:5 p.error>, <PageRule 3:5 (u'tables', None)>]
+ [<ImportRule 1:1 foo.css>, <RuleSet at 2:5 p.error>, <PageRule 3:5 ('tables', None)>]
>>> stylesheet.errors
- [ParseError(u'Parse error at 2:29, unknown at-rule in stylesheet context: @lorem-ipsum',)]
+ [ParseError('Parse error at 2:29, unknown at-rule in stylesheet context: @lorem-ipsum',)]
You’ll get a :class:`~tinycss.css21.Stylesheet` object which contains
all the parsed content as well as a list of encountered errors.
View
3  tinycss/css21.py
@@ -180,7 +180,8 @@ def __init__(self, name, value, priority, line, column):
def __repr__(self):
priority = ' !' + self.priority if self.priority else ''
return ('<{0.__class__.__name__} {0.line}:{0.column}'
- ' {0.name}: {0.value.as_css}{1}>'.format(self, priority))
+ ' {0.name}: {1}{2}>'.format(
+ self, self.value.as_css(), priority))
class PageRule(object):
View
1  tox.ini
@@ -10,6 +10,7 @@ commands = py.test --pyargs tinycss []
setenv = TINYCSS_SKIP_SPEEDUPS_TESTS=1
[testenv:sphinx-doctests]
+basepython = python3
deps =
Sphinx
cssselect
Please sign in to comment.
Something went wrong with that request. Please try again.