changeset 511:1a29617a5d87 stable-0.4.x

Ported [611:614] to 0.4.x branch.
author cmlenz
date Wed, 06 Jun 2007 11:18:46 +0000
parents 90eecd360b18
children 1c9250cc4365
files doc/filters.txt doc/streams.txt doc/style/edgewall.css doc/style/pygments.css doc/templates.txt doc/text-templates.txt doc/xml-templates.txt doc/xpath.txt setup.py
diffstat 9 files changed, 390 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/doc/filters.txt
+++ b/doc/filters.txt
@@ -25,7 +25,9 @@
 
 ``HTMLFormFiller`` takes a dictionary of data to populate the form with, where
 the keys should match the names of form elements, and the values determine the
-values of those controls. For example::
+values of those controls. For example:
+
+.. code-block:: pycon
 
   >>> from genshi.filters import HTMLFormFiller
   >>> from genshi.template import MarkupTemplate
@@ -88,7 +90,9 @@
 
 The filter ``genshi.filters.HTMLSanitizer`` filter can be used to clean up
 user-submitted HTML markup, removing potentially dangerous constructs that could
-be used for various kinds of abuse, such as cross-site scripting (XSS) attacks::
+be used for various kinds of abuse, such as cross-site scripting (XSS) attacks:
+
+.. code-block:: pycon
 
   >>> from genshi.filters import HTMLSanitizer
   >>> from genshi.input import HTML
@@ -112,7 +116,9 @@
 filter will still perform sanitization on the contents any encountered inline
 styles: the proprietary ``expression()`` function (supported only by Internet
 Explorer) is removed, and any property using an ``url()`` which a potentially
-dangerous URL scheme (such as ``javascript:``) are also stripped out::
+dangerous URL scheme (such as ``javascript:``) are also stripped out:
+
+.. code-block:: pycon
 
   >>> from genshi.filters import HTMLSanitizer
   >>> from genshi.input import HTML
@@ -130,3 +136,19 @@
              suspect to various browser bugs. If you can somehow get away with
              not allowing inline styles in user-submitted content, that would
              definitely be the safer route to follow.
+
+
+Translator
+==========
+
+The ``genshi.filters.i18n.Translator`` filter implements basic support for
+internationalizing and localizing templates. When used as a filter, it
+translates a configurable set of text nodes and attribute values using a
+``gettext``-style translation function.
+
+The ``Translator`` class also defines the ``extract`` class method, which can
+be used to extract localizable messages from a template.
+
+Please refer to the API documentation for more information on this filter.
+
+.. note:: The translation filter was added in Genshi 0.4.
--- a/doc/streams.txt
+++ b/doc/streams.txt
@@ -22,7 +22,9 @@
 * programmatically generated.
 
 For example, the functions ``XML()`` and ``HTML()`` can be used to convert
-literal XML or HTML text to a markup stream::
+literal XML or HTML text to a markup stream:
+
+.. code-block:: pycon
 
   >>> from genshi import XML
   >>> stream = XML('<p class="intro">Some text and '
@@ -41,7 +43,7 @@
 * ``pos`` is a ``(filename, lineno, column)`` tuple that describes where the
   event “comes from”.
 
-::
+.. code-block:: pycon
 
   >>> for kind, data, pos in stream:
   ...     print kind, `data`, pos
@@ -64,7 +66,9 @@
 stream, either filters that come with Genshi, or your own custom filters.
 
 A filter is simply a callable that accepts the stream as parameter, and returns
-the filtered stream::
+the filtered stream:
+
+.. code-block:: python
 
   def noop(stream):
       """A filter that doesn't actually do anything with the stream."""
@@ -72,17 +76,23 @@
           yield kind, data, pos
 
 Filters can be applied in a number of ways. The simplest is to just call the
-filter directly::
+filter directly:
+
+.. code-block:: python
 
   stream = noop(stream)
 
 The ``Stream`` class also provides a ``filter()`` method, which takes an
-arbitrary number of filter callables and applies them all::
+arbitrary number of filter callables and applies them all:
+
+.. code-block:: python
 
   stream = stream.filter(noop)
 
 Finally, filters can also be applied using the *bitwise or* operator (``|``),
-which allows a syntax similar to pipes on Unix shells::
+which allows a syntax similar to pipes on Unix shells:
+
+.. code-block:: python
 
   stream = stream | noop
 
@@ -90,17 +100,23 @@
 ``genshi.filters``. It processes a stream of HTML markup, and strips out any
 potentially dangerous constructs, such as Javascript event handlers.
 ``HTMLSanitizer`` is not a function, but rather a class that implements
-``__call__``, which means instances of the class are callable::
+``__call__``, which means instances of the class are callable:
+
+.. code-block:: python
 
   stream = stream | HTMLSanitizer()
 
 Both the ``filter()`` method and the pipe operator allow easy chaining of
-filters::
+filters:
+
+.. code-block:: python
 
   from genshi.filters import HTMLSanitizer
   stream = stream.filter(noop, HTMLSanitizer())
 
-That is equivalent to::
+That is equivalent to:
+
+.. code-block:: python
 
   stream = stream | noop | HTMLSanitizer()
 
@@ -121,7 +137,9 @@
 (which are basically unicode strings that are considered safe for output on the
 web). The latter returns a single string, by default UTF-8 encoded.
 
-Here's the output from ``serialize()``::
+Here's the output from ``serialize()``:
+
+.. code-block:: pycon
 
   >>> for output in stream.serialize():
   ...     print `output`
@@ -135,14 +153,18 @@
   <Markup u'<br/>'>
   <Markup u'</p>'>
 
-And here's the output from ``render()``::
+And here's the output from ``render()``:
+
+.. code-block:: pycon
 
   >>> print stream.render()
   <p class="intro">Some text and <a href="http://example.org/">a link</a>.<br/></p>
 
 Both methods can be passed a ``method`` parameter that determines how exactly
 the events are serialzed to text. This parameter can be either “xml” (the
-default), “xhtml”, “html”, “text”, or a custom serializer class::
+default), “xhtml”, “html”, “text”, or a custom serializer class:
+
+.. code-block:: pycon
 
   >>> print stream.render('html')
   <p class="intro">Some text and <a href="http://example.org/">a link</a>.<br></p>
@@ -154,14 +176,18 @@
 defaults to “UTF-8”. If set to ``None``, the result will be a unicode string.
 
 The different serializer classes in ``genshi.output`` can also be used
-directly::
+directly:
+
+.. code-block:: pycon
 
   >>> from genshi.filters import HTMLSanitizer
   >>> from genshi.output import TextSerializer
   >>> print ''.join(TextSerializer()(HTMLSanitizer()(stream)))
   Some text and a link.
 
-The pipe operator allows a nicer syntax::
+The pipe operator allows a nicer syntax:
+
+.. code-block:: pycon
 
   >>> print stream | HTMLSanitizer() | TextSerializer()
   Some text and a link.
@@ -200,7 +226,9 @@
 ===========
 
 XPath can be used to extract a specific subset of the stream via the
-``select()`` method::
+``select()`` method:
+
+.. code-block:: pycon
 
   >>> substream = stream.select('a')
   >>> substream
@@ -211,7 +239,9 @@
 Often, streams cannot be reused: in the above example, the sub-stream is based
 on a generator. Once it has been serialized, it will have been fully consumed,
 and cannot be rendered again. To work around this, you can wrap such a stream
-in a ``list``::
+in a ``list``:
+
+.. code-block:: pycon
 
   >>> from genshi import Stream
   >>> substream = Stream(list(stream.select('a')))
@@ -251,7 +281,9 @@
 ``(tagname, attrs)``, where ``tagname`` is a ``QName`` instance describing the
 qualified name of the tag, and ``attrs`` is an ``Attrs`` instance containing
 the attribute names and values associated with the tag (excluding namespace
-declarations)::
+declarations):
+
+.. code-block:: python
 
   START, (QName(u'p'), Attrs([(u'class', u'intro')])), pos
 
@@ -260,7 +292,9 @@
 The closing tag of an element.
 
 The ``data`` item of end events consists of just a ``QName`` instance
-describing the qualified name of the tag::
+describing the qualified name of the tag:
+
+.. code-block:: python
 
   END, QName(u'p'), pos
 
@@ -268,7 +302,9 @@
 ----
 Character data outside of elements and comments.
 
-For text events, the ``data`` item should be a unicode object::
+For text events, the ``data`` item should be a unicode object:
+
+.. code-block:: python
 
   TEXT, u'Hello, world!', pos
 
@@ -279,7 +315,9 @@
 The ``data`` item of this kind of event is a tuple of the form
 ``(prefix, uri)``, where ``prefix`` is the namespace prefix and ``uri`` is the
 full URI to which the prefix is bound. Both should be unicode objects. If the
-namespace is not bound to any prefix, the ``prefix`` item is an empty string::
+namespace is not bound to any prefix, the ``prefix`` item is an empty string:
+
+.. code-block:: python
 
   START_NS, (u'svg', u'http://www.w3.org/2000/svg'), pos
 
@@ -288,7 +326,9 @@
 The end of a namespace mapping.
 
 The ``data`` item of such events consists of only the namespace prefix (a
-unicode object)::
+unicode object):
+
+.. code-block:: python
 
   END_NS, u'svg', pos
 
@@ -299,7 +339,9 @@
 For this type of event, the ``data`` item is a tuple of the form
 ``(name, pubid, sysid)``, where ``name`` is the name of the root element,
 ``pubid`` is the public identifier of the DTD (or ``None``), and ``sysid`` is
-the system identifier of the DTD (or ``None``)::
+the system identifier of the DTD (or ``None``):
+
+.. code-block:: python
 
   DOCTYPE, (u'html', u'-//W3C//DTD XHTML 1.0 Transitional//EN', \
             u'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'), pos
@@ -309,7 +351,9 @@
 A comment.
 
 For such events, the ``data`` item is a unicode object containing all character
-data between the comment delimiters::
+data between the comment delimiters:
+
+.. code-block:: python
 
   COMMENT, u'Commented out', pos
 
@@ -320,7 +364,9 @@
 The ``data`` item is a tuple of the form ``(target, data)`` for processing
 instructions, where ``target`` is the target of the PI (used to identify the
 application by which the instruction should be processed), and ``data`` is text
-following the target (excluding the terminating question mark)::
+following the target (excluding the terminating question mark):
+
+.. code-block:: python
 
   PI, (u'php', u'echo "Yo" '), pos
 
@@ -328,7 +374,9 @@
 -----------
 Marks the beginning of a ``CDATA`` section.
 
-The ``data`` item for such events is always ``None``::
+The ``data`` item for such events is always ``None``:
+
+.. code-block:: python
 
   START_CDATA, None, pos
 
@@ -336,6 +384,8 @@
 ---------
 Marks the end of a ``CDATA`` section.
 
-The ``data`` item for such events is always ``None``::
+The ``data`` item for such events is always ``None``:
+
+.. code-block:: python
 
   END_CDATA, None, pos
--- a/doc/style/edgewall.css
+++ b/doc/style/edgewall.css
@@ -1,4 +1,5 @@
-@import(docutils.css);
+@import url(docutils.css);
+@import url(pygments.css);
 
 html, body { height: 100%; margin: 0; padding: 0; }
 html, body { background: #4b4d4d url(bkgnd_pattern.png); color: #000; }
@@ -37,8 +38,9 @@
 h1.title { background: url(vertbars.png) repeat-x; }
 div.document#genshi h1.title { text-indent: -4000px; }
 div.document#genshi h1 { text-align: center; }
-pre.literal-block { background: #d7d7d7; border: 1px solid #e6e6e6; color: #000;
-  margin: 1em 1em; padding: .25em; overflow: auto;
+pre.literal-block, div.highlight pre { background: #f4f4f4;
+  border: 1px solid #e6e6e6; color: #000; margin: 1em 1em; padding: .25em;
+  overflow: auto;
 }
 
 div.contents { font-size: 90%; position: absolute; position: fixed;
@@ -53,7 +55,14 @@
   color: #fff;
 }
 
-p.admonition-title { font-weight: bold; margin-bottom: 0; }
-div.note, div.warning { font-style: italic; margin-left: 2em;
-  margin-right: 2em;
+div.admonition, div.attention, div.caution, div.danger, div.error, div.hint,
+div.important, div.note, div.tip, div.warning {
+  border: none; color: #333; font-style: italic; margin: 1em 2em;
 }
+div.attention p.admonition-title, div.caution p.admonition-title, div.danger
+p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+  color: #b00;
+}
+p.admonition-title { margin-bottom: 0; text-transform: uppercase; }
+tt.docutils { background-color: transparent; }
new file mode 100644
--- /dev/null
+++ b/doc/style/pygments.css
@@ -0,0 +1,57 @@
+div.highlight { background: #ffffff; }
+div.highlight .c { color: #999988; font-style: italic }
+div.highlight .err { color: #a61717; background-color: #e3d2d2 }
+div.highlight .k { font-weight: bold }
+div.highlight .o { font-weight: bold }
+div.highlight .cm { color: #999988; font-style: italic }
+div.highlight .cp { color: #999999; font-weight: bold }
+div.highlight .c1 { color: #999988; font-style: italic }
+div.highlight .cs { color: #999999; font-weight: bold; font-style: italic }
+div.highlight .gd { color: #000000; background-color: #ffdddd }
+div.highlight .ge { font-style: italic }
+div.highlight .gr { color: #aa0000 }
+div.highlight .gh { color: #999999 }
+div.highlight .gi { color: #000000; background-color: #ddffdd }
+div.highlight .go { color: #888888 }
+div.highlight .gp { color: #555555 }
+div.highlight .gs { font-weight: bold }
+div.highlight .gu { color: #aaaaaa }
+div.highlight .gt { color: #aa0000 }
+div.highlight .kc { font-weight: bold }
+div.highlight .kd { font-weight: bold }
+div.highlight .kp { font-weight: bold }
+div.highlight .kr { font-weight: bold }
+div.highlight .kt { color: #445588; font-weight: bold }
+div.highlight .m { color: #009999 }
+div.highlight .s { color: #bb8844 }
+div.highlight .na { color: #008080 }
+div.highlight .nb { color: #999999 }
+div.highlight .nc { color: #445588; font-weight: bold }
+div.highlight .no { color: #008080 }
+div.highlight .ni { color: #800080 }
+div.highlight .ne { color: #990000; font-weight: bold }
+div.highlight .nf { color: #990000; font-weight: bold }
+div.highlight .nn { color: #555555 }
+div.highlight .nt { color: #000080 }
+div.highlight .nv { color: #008080 }
+div.highlight .ow { font-weight: bold }
+div.highlight .mf { color: #009999 }
+div.highlight .mh { color: #009999 }
+div.highlight .mi { color: #009999 }
+div.highlight .mo { color: #009999 }
+div.highlight .sb { color: #bb8844 }
+div.highlight .sc { color: #bb8844 }
+div.highlight .sd { color: #bb8844 }
+div.highlight .s2 { color: #bb8844 }
+div.highlight .se { color: #bb8844 }
+div.highlight .sh { color: #bb8844 }
+div.highlight .si { color: #bb8844 }
+div.highlight .sx { color: #bb8844 }
+div.highlight .sr { color: #808000 }
+div.highlight .s1 { color: #bb8844 }
+div.highlight .ss { color: #bb8844 }
+div.highlight .bp { color: #999999 }
+div.highlight .vc { color: #008080 }
+div.highlight .vg { color: #008080 }
+div.highlight .vi { color: #008080 }
+div.highlight .il { color: #009999 }
--- a/doc/templates.txt
+++ b/doc/templates.txt
@@ -32,7 +32,9 @@
 used to generate any kind of HTML or XML output, as they provide many advantages
 over simple text-based templates (such as automatic escaping of strings).
 
-The following illustrates a very basic Genshi markup template::
+The following illustrates a very basic Genshi markup template:
+
+.. code-block:: genshi
 
   <?python
     title = "A Genshi Template"
@@ -60,7 +62,9 @@
 (c) usage of templates directives (``py:content`` and ``py:for``)
 (d) an inline Python expression (``${fruit}``).
 
-The template would generate output similar to this::
+The template would generate output similar to this:
+
+.. code-block:: genshi
 
   <html>
     <head>
@@ -79,7 +83,9 @@
 
 A *text template* is a simple plain text document that can also contain embedded
 Python code. Text templates can be used to generate simple *non-markup* text
-formats, such as the body of an plain text email. For example::
+formats, such as the body of an plain text email. For example:
+
+.. code-block:: genshitext
 
   Dear $name,
   
@@ -103,7 +109,9 @@
   be made available to the template as keyword arguments.
 * Serialize the resulting stream using its ``render()`` method.
 
-For example::
+For example:
+
+.. code-block:: pycon
 
   >>> from genshi.template import MarkupTemplate
   >>> tmpl = MarkupTemplate('<h1>Hello, $name!</h1>')
@@ -111,7 +119,9 @@
   >>> print stream.render()
   <h1>Hello, world!</h1>
 
-Using a text template is similar::
+Using a text template is similar:
+
+.. code-block:: pycon
 
   >>> from genshi.template import TextTemplate
   >>> tmpl = TextTemplate('Hello, $name!')
@@ -129,7 +139,9 @@
 automatically cached, and only parsed again when the template file changes. In
 addition, it enables the use of a *template search path*, allowing template
 directories to be spread across different file-system locations. Using a
-template loader would generally look as follows::
+template loader would generally look as follows:
+
+.. code-block:: python
 
   from genshi.template import TemplateLoader
   loader = TemplateLoader([templates_dir1, templates_dir2])
@@ -158,7 +170,9 @@
 If the expression starts with a letter and contains only letters, digits, dots,
 and underscores, the curly braces may be omitted. In all other cases, the
 braces are required so that the template processor knows where the expression
-ends::
+ends:
+
+.. code-block:: pycon
 
   >>> from genshi.template import MarkupTemplate
   >>> tmpl = MarkupTemplate('<em>${items[0].capitalize()} item</em>')
@@ -168,7 +182,9 @@
 Expressions support the full power of Python. In addition, it is possible to
 access items in a dictionary using “dotted notation” (i.e. as if they were
 attributes), and vice-versa (i.e. access attributes as if they were items in a
-dictionary)::
+dictionary):
+
+.. code-block:: pycon
 
   >>> from genshi.template import MarkupTemplate
   >>> tmpl = MarkupTemplate('<em>${dict.foo}</em>')
@@ -188,7 +204,9 @@
 ===========
 
 XML templates also support full Python code blocks using the ``<?python ?>``
-processing instruction::
+processing instruction:
+
+.. code-block:: genshi
 
   <div>
     <?python
@@ -198,7 +216,9 @@
     ${greeting('world')}
   </div>
 
-This will produce the following output::
+This will produce the following output:
+
+.. code-block:: genshi
 
   <div>
     <b>Hello, world!</b>
@@ -229,7 +249,9 @@
 ==============
 
 By default, Genshi allows you to access variables that are not defined, without
-raising a ``NameError`` exception as regular Python code would::
+raising a ``NameError`` exception as regular Python code would:
+
+.. code-block:: pycon
 
   >>> from genshi.template import MarkupTemplate
   >>> tmpl = MarkupTemplate('<p>${doh}</p>')
@@ -237,7 +259,9 @@
   <p></p>
 
 You *will* however get an exception if you try to call an undefined variable, or
-do anything else with it, such as accessing its attributes::
+do anything else with it, such as accessing its attributes:
+
+.. code-block:: pycon
 
   >>> from genshi.template import MarkupTemplate
   >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>')
@@ -247,7 +271,9 @@
   UndefinedError: "doh" not defined
 
 If you need to know whether a variable is defined, you can check its type
-against the ``Undefined`` class, for example in a conditional directive::
+against the ``Undefined`` class, for example in a conditional directive:
+
+.. code-block:: pycon
 
   >>> from genshi.template import MarkupTemplate
   >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>')
@@ -266,7 +292,9 @@
 
 This mode can be chosen by passing the ``lookup='strict'`` keyword argument to
 the template initializer, or by passing the ``variable_lookup='strict'`` keyword
-argument to the ``TemplateLoader`` initializer::
+argument to the ``TemplateLoader`` initializer:
+
+.. code-block:: pycon
 
   >>> from genshi.template import MarkupTemplate
   >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='strict')
--- a/doc/text-templates.txt
+++ b/doc/text-templates.txt
@@ -57,7 +57,9 @@
 ``#if``
 ---------
 
-The content is only rendered if the expression evaluates to a truth value::
+The content is only rendered if the expression evaluates to a truth value:
+
+.. code-block:: genshitext
 
   #if foo
     ${bar}
@@ -82,7 +84,9 @@
 no ``#when`` branch matches, the ``#otherwise`` branch is be rendered.
 
 If the ``#choose`` directive has no argument the nested ``#when`` directives
-will be tested for truth::
+will be tested for truth:
+
+.. code-block:: genshitext
 
   The answer is:
   #choose
@@ -103,7 +107,9 @@
       1
 
 If the ``#choose`` does have an argument, the nested ``#when`` directives will
-be tested for equality to the parent ``#choose`` value::
+be tested for equality to the parent ``#choose`` value:
+
+.. code-block:: genshitext
 
   The answer is:
   #choose 1
@@ -132,7 +138,9 @@
 ``#for``
 ----------
 
-The content is repeated for every item in an iterable::
+The content is repeated for every item in an iterable:
+
+.. code-block:: genshitext
 
   Your items:
   #for item in items
@@ -158,7 +166,9 @@
 
 The ``#def`` directive can be used to create macros, i.e. snippets of template
 text that have a name and optionally some parameters, and that can be inserted
-in other places::
+in other places:
+
+.. code-block:: genshitext
 
   #def greeting(name)
     Hello, ${name}!
@@ -172,7 +182,9 @@
     Hello, everyone else!
 
 If a macro doesn't require parameters, it can be defined as well as called
-without the parenthesis. For example::
+without the parenthesis. For example:
+
+.. code-block:: genshitext
 
   #def greeting
     Hello, world!
@@ -198,7 +210,9 @@
 than once, and that actually results in a database query, assigning the results
 to a variable using this directive would probably help.
 
-For example::
+For example:
+
+.. code-block:: genshitext
 
   Magic numbers!
   #with y=7; z=x+10
--- a/doc/xml-templates.txt
+++ b/doc/xml-templates.txt
@@ -42,7 +42,9 @@
 conditionals and looping, among others.
 
 To use directives in a template, the namespace must be declared, which is
-usually done on the root element::
+usually done on the root element:
+
+.. code-block:: genshi
 
   <html xmlns="http://www.w3.org/1999/xhtml"
         xmlns:py="http://genshi.edgewall.org/"
@@ -55,7 +57,9 @@
 
 All directives can be applied as attributes, and some can also be used as
 elements. The ``if`` directives for conditionals, for example, can be used in
-both ways::
+both ways:
+
+.. code-block:: genshi
 
   <html xmlns="http://www.w3.org/1999/xhtml"
         xmlns:py="http://genshi.edgewall.org/"
@@ -67,7 +71,9 @@
     ...
   </html>
 
-This is basically equivalent to the following::
+This is basically equivalent to the following:
+
+.. code-block:: genshi
 
   <html xmlns="http://www.w3.org/1999/xhtml"
         xmlns:py="http://genshi.edgewall.org/"
@@ -95,20 +101,26 @@
 ``py:if``
 ---------
 
-The element is only rendered if the expression evaluates to a truth value::
+The element is only rendered if the expression evaluates to a truth value:
+
+.. code-block:: genshi
 
   <div>
     <b py:if="foo">${bar}</b>
   </div>
 
 Given the data ``foo=True`` and ``bar='Hello'`` in the template context, this
-would produce::
+would produce:
+
+.. code-block:: html
 
   <div>
     <b>Hello</b>
   </div>
 
-This directive can also be used as an element::
+This directive can also be used as an element:
+
+.. code-block:: genshi
 
   <div>
     <py:if test="foo">
@@ -129,7 +141,9 @@
 if no ``py:when`` branch matches, the ``py:otherwise`` branch is rendered.
 
 If the ``py:choose`` directive is empty the nested ``py:when`` directives will
-be tested for truth::
+be tested for truth:
+
+.. code-block:: genshi
 
   <div py:choose="">
     <span py:when="0 == 1">0</span>
@@ -137,14 +151,18 @@
     <span py:otherwise="">2</span>
   </div>
 
-This would produce the following output::
+This would produce the following output:
+
+.. code-block:: html
 
   <div>
     <span>1</span>
   </div>
 
 If the ``py:choose`` directive contains an expression the nested ``py:when``
-directives will be tested for equality to the parent ``py:choose`` value::
+directives will be tested for equality to the parent ``py:choose`` value:
+
+.. code-block:: genshi
 
   <div py:choose="1">
     <span py:when="0">0</span>
@@ -152,7 +170,9 @@
     <span py:otherwise="">2</span>
   </div>
 
-This would produce the following output::
+This would produce the following output:
+
+.. code-block:: html
 
   <div>
     <span>1</span>
@@ -167,19 +187,25 @@
 ``py:for``
 ----------
 
-The element is repeated for every item in an iterable::
+The element is repeated for every item in an iterable:
+
+.. code-block:: genshi
 
   <ul>
     <li py:for="item in items">${item}</li>
   </ul>
 
-Given ``items=[1, 2, 3]`` in the context data, this would produce::
+Given ``items=[1, 2, 3]`` in the context data, this would produce:
+
+.. code-block:: html
 
   <ul>
     <li>1</li><li>2</li><li>3</li>
   </ul>
 
-This directive can also be used as an element::
+This directive can also be used as an element:
+
+.. code-block:: genshi
 
   <ul>
     <py:for each="item in items">
@@ -199,7 +225,9 @@
 
 The ``py:def`` directive can be used to create macros, i.e. snippets of
 template code that have a name and optionally some parameters, and that can be
-inserted in other places::
+inserted in other places:
+
+.. code-block:: genshi
 
   <div>
     <p py:def="greeting(name)" class="greeting">
@@ -209,7 +237,9 @@
     ${greeting('everyone else')}
   </div>
 
-The above would be rendered to::
+The above would be rendered to:
+
+.. code-block:: html
 
   <div>
     <p class="greeting">
@@ -221,7 +251,9 @@
   </div>
 
 If a macro doesn't require parameters, it can be defined without the 
-parenthesis. For example::
+parenthesis. For example:
+
+.. code-block:: genshi
 
   <div>
     <p py:def="greeting" class="greeting">
@@ -230,7 +262,9 @@
     ${greeting()}
   </div>
 
-The above would be rendered to::
+The above would be rendered to:
+
+.. code-block:: html
 
   <div>
     <p class="greeting">
@@ -238,7 +272,9 @@
     </p>
   </div>
 
-This directive can also be used as an element::
+This directive can also be used as an element:
+
+.. code-block:: genshi
 
   <div>
     <py:def function="greeting(name)">
@@ -258,7 +294,9 @@
 content.
 
 For example, the match template defined in the following template matches any
-element with the tag name “greeting”::
+element with the tag name “greeting”:
+
+.. code-block:: genshi
 
   <div>
     <span py:match="greeting">
@@ -267,7 +305,9 @@
     <greeting name="Dude" />
   </div>
 
-This would result in the following output::
+This would result in the following output:
+
+.. code-block:: html
 
   <div>
     <span>
@@ -282,7 +322,9 @@
 
 .. _`Using XPath`: streams.html#using-xpath
 
-This directive can also be used as an element::
+This directive can also be used as an element:
+
+.. code-block:: genshi
 
   <div>
     <py:match path="greeting">
@@ -306,19 +348,25 @@
 than once, and that actually results in a database query, assigning the results
 to a variable using this directive would probably help.
 
-For example::
+For example:
+
+.. code-block:: genshi
 
   <div>
     <span py:with="y=7; z=x+10">$x $y $z</span>
   </div>
 
-Given ``x=42`` in the context data, this would produce::
+Given ``x=42`` in the context data, this would produce:
+
+.. code-block:: html
 
   <div>
     <span>42 7 52</span>
   </div>
 
-This directive can also be used as an element::
+This directive can also be used as an element:
+
+.. code-block:: genshi
 
   <div>
     <py:with vars="y=7; z=x+10">$x $y $z</py:with>
@@ -338,21 +386,27 @@
 ``py:attrs``
 ------------
 
-This directive adds, modifies or removes attributes from the element::
+This directive adds, modifies or removes attributes from the element:
+
+.. code-block:: genshi
 
   <ul>
     <li py:attrs="foo">Bar</li>
   </ul>
 
 Given ``foo={'class': 'collapse'}`` in the template context, this would
-produce::
+produce:
+
+.. code-block:: html
 
   <ul>
     <li class="collapse">Bar</li>
   </ul>
 
 Attributes with the value ``None`` are omitted, so given ``foo={'class': None}``
-in the context for the same template this would produce::
+in the context for the same template this would produce:
+
+.. code-block:: html
 
   <ul>
     <li>Bar</li>
@@ -367,13 +421,17 @@
 --------------
 
 This directive replaces any nested content with the result of evaluating the
-expression::
+expression:
+
+.. code-block:: genshi
 
   <ul>
     <li py:content="bar">Hello</li>
   </ul>
 
-Given ``bar='Bye'`` in the context data, this would produce::
+Given ``bar='Bye'`` in the context data, this would produce:
+
+.. code-block:: html
 
   <ul>
     <li>Bye</li>
@@ -388,13 +446,17 @@
 --------------
 
 This directive replaces the element itself with the result of evaluating the
-expression::
+expression:
+
+.. code-block:: genshi
 
   <div>
     <span py:replace="bar">Hello</span>
   </div>
 
-Given ``bar='Bye'`` in the context data, this would produce::
+Given ``bar='Bye'`` in the context data, this would produce:
+
+.. code-block:: html
 
   <div>
     Bye
@@ -410,13 +472,17 @@
 
 This directive conditionally strips the top-level element from the output. When
 the value of the ``py:strip`` attribute evaluates to ``True``, the element is
-stripped from the output::
+stripped from the output:
+
+.. code-block:: genshi
 
   <div>
     <div py:strip="True"><b>foo</b></div>
   </div>
 
-This would be rendered as::
+This would be rendered as:
+
+.. code-block:: html
 
   <div>
     <b>foo</b>
@@ -462,7 +528,9 @@
 
 For this, you need to declare the XInclude namespace (commonly bound to the
 prefix “xi”) and use the ``<xi:include>`` element where you want the external
-file to be pulled in::
+file to be pulled in:
+
+.. code-block:: genshi
 
   <html xmlns="http://www.w3.org/1999/xhtml"
         xmlns:py="http://genshi.edgewall.org/"
@@ -485,7 +553,9 @@
 By default, an error will be raised if an included file is not found. If that's
 not what you want, you can specify fallback content that should be used if the
 include fails. For example, to to make the include above fail silently, you'd
-write::
+write:
+
+.. code-block:: genshi
 
   <xi:include href="base.html"><xi:fallback /></xi:include>
 
@@ -497,7 +567,9 @@
 Incudes in Genshi are fully dynamic: Just like normal attributes, the `href`
 attribute accepts expressions, and directives_ can be used on the
 ``<xi:include />`` element just as on any other element, meaning you can do
-things like conditional includes::
+things like conditional includes:
+
+.. code-block:: genshi
 
   <xi:include href="${name}.html" py:if="not in_popup"
               py:for="name in ('foo', 'bar', 'baz')" />
@@ -509,17 +581,23 @@
 Comments
 --------
 
-Normal XML/HTML comment syntax can be used in templates::
+Normal XML/HTML comment syntax can be used in templates:
+
+.. code-block:: genshi
 
   <!-- this is a comment -->
 
 However, such comments get passed through the processing pipeline and are by
 default included in the final output. If that's not desired, prefix the comment
-text with an exclamation mark::
+text with an exclamation mark:
+
+.. code-block:: genshi
 
   <!-- !this is a comment too, but one that will be stripped from the output -->
 
 Note that it does not matter whether there's whitespace before or after the
-exclamation mark, so the above could also be written as follows::
+exclamation mark, so the above could also be written as follows:
+
+.. code-block:: genshi
 
   <!--! this is a comment too, but one that will be stripped from the output -->
--- a/doc/xpath.txt
+++ b/doc/xpath.txt
@@ -62,24 +62,25 @@
 Querying Streams
 ----------------
 
-::
-
-  from genshi.input import XML
+The ``Stream`` class provides a ``select(path)`` function that can be used to
+retrieve subsets of the stream:
 
-  doc = XML('''<doc>
-   <items count="2">
-        <item status="new">
-          <summary>Foo</summary>
-        </item>
-        <item status="closed">
-          <summary>Bar</summary>
-        </item>
-    </items>
-  </doc>''')
-  print doc.select('items/item[@status="closed"]/summary/text()')
+.. code-block:: pycon
 
-This would result in the following output::
-
+  >>> from genshi.input import XML
+  
+  >>> doc = XML('''<doc>
+  ...   <items count="2">
+  ...     <item status="new">
+  ...       <summary>Foo</summary>
+  ...     </item>
+  ...     <item status="closed">
+  ...       <summary>Bar</summary>
+  ...     </item>
+  ...    </items>
+  ... </doc>''')
+  
+  >>> print doc.select('items/item[@status="closed"]/summary/text()')
   Bar
 
 
--- a/setup.py
+++ b/setup.py
@@ -35,9 +35,29 @@
 
     def run(self):
         from docutils.core import publish_cmdline
+        from docutils.nodes import raw
+        from docutils.parsers import rst
+
         docutils_conf = os.path.join('doc', 'docutils.conf')
         epydoc_conf = os.path.join('doc', 'epydoc.conf')
 
+        try:
+            from pygments import highlight
+            from pygments.lexers import get_lexer_by_name
+            from pygments.formatters import HtmlFormatter
+
+            def code_block(name, arguments, options, content, lineno,
+                           content_offset, block_text, state, state_machine):
+                lexer = get_lexer_by_name(arguments[0])
+                html = highlight('\n'.join(content), lexer, HtmlFormatter())
+                return [raw('', html, format='html')]
+            code_block.arguments = (1, 0, 0)
+            code_block.options = {'language' : rst.directives.unchanged}
+            code_block.content = 1
+            rst.directives.register_directive('code-block', code_block)
+        except ImportError:
+            print 'Pygments not installed, syntax highlighting disabled'
+
         for source in glob('doc/*.txt'):
             dest = os.path.splitext(source)[0] + '.html'
             if not os.path.exists(dest) or \
@@ -58,7 +78,6 @@
             ]
             cli.cli()
             sys.argv[1:] = old_argv
-
         except ImportError:
             print 'epydoc not installed, skipping API documentation.'
 
Copyright (C) 2012-2017 Edgewall Software