Skip to content
This repository has been archived by the owner on Sep 18, 2019. It is now read-only.

Commit

Permalink
Document how to use cssselect with tinycss.
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonSapin committed Apr 25, 2012
1 parent 0896981 commit a3d3940
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 9 deletions.
50 changes: 48 additions & 2 deletions docs/css3.rst
Expand Up @@ -6,12 +6,58 @@ CSS 3 Modules
Selectors 3
-----------

See cssselect_ can be used to parse selectors.
.. currentmodule:: tinycss.css21

**TODO:** give an example of how to use it with tinycss.
On :attr:`RuleSet.selector`, the :meth:`~.token_data.TokenList.as_css` method
can be used to serialize a selector back to an Unicode string.

>>> import tinycss
>>> stylesheet = tinycss.make_parser().parse_stylesheet(
... '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'

This string can be parsed by cssselect_. The parsed objects have information
about pseudo-elements and selector specificity.

.. _cssselect: http://packages.python.org/cssselect/

>>> import cssselect
>>> selectors = cssselect.parse(selector_string)
>>> [s.specificity() for s in selectors]
[(0, 1, 1), (1, 0, 2)]
>>> [s.pseudo_element for s in selectors]
[None, u'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
somehow or reject selectors with pseudo-elements.

>>> xpath = cssselect.HTMLTranslator().selector_to_xpath(selectors[1])
>>> xpath
u"descendant-or-self::*[@id = 'root']/section"

Finally, the XPath expressions can be used with lxml_ to find the matching
elements.

>>> from lxml import etree
>>> compiled_selector = etree.XPath(xpath)
>>> document = etree.fromstring('''<section id="root">
... <section id="head">Title</section>
... <section id="content">
... Lorem <section id="sub-section">ipsum</section>
... </section>
... </section>''')
>>> [el.get('id') for el in compiled_selector(document)]
['head', 'content']

.. _lxml: http://lxml.de/xpathxslt.html#xpath

Find more details in the `cssselect documentation`_.

.. _cssselect documentation: http://packages.python.org/cssselect/


.. module:: tinycss.color3

Expand Down
8 changes: 4 additions & 4 deletions tinycss/css21.py
Expand Up @@ -123,8 +123,8 @@ class RuleSet(object):
The selector as a :class:`~.token_data.TokenList`.
In CSS 3, this is actually called a selector group.
``selector.as_css()`` can be used with `cssselect
<http://packages.python.org/cssselect/>`_, see :ref:`selectors3`.
``rule.selector.as_css()`` gives the selector as a string.
This string can be used with *cssselect*, see :ref:`selectors3`.
.. attribute:: declarations
Expand All @@ -141,8 +141,8 @@ def __init__(self, selector, declarations, line, column):
self.column = column

def __repr__(self):
return ('<{0.__class__.__name__} at {0.line}:{0.column}'
' {0.selector.as_css}>'.format(self))
return ('<{0.__class__.__name__} at {0.line}:{0.column} {1}>'
.format(self, self.selector.as_css()))


class Declaration(object):
Expand Down
13 changes: 10 additions & 3 deletions tox.ini
@@ -1,11 +1,18 @@
[tox]
envlist = py26,py27,py31,py32,pypy
envlist = py26,py27,py31,py32,pypy,sphinx-doctests

[testenv]
deps=pytest
deps = pytest
changedir = {toxworkdir}/log
commands = py.test --pyargs tinycss []

[testenv:pypy]
deps = pytest
setenv = TINYCSS_SKIP_SPEEDUPS_TESTS=1

[testenv:sphinx-doctests]
deps =
Sphinx
cssselect
lxml
changedir = docs
commands = sphinx-build -b doctest . _build/html

0 comments on commit a3d3940

Please sign in to comment.