changeset 508:cabd80e75dad

Enable syntax highlighting (with Pygments) on doc page.
author cmlenz
date Wed, 06 Jun 2007 10:06:29 +0000
parents c006015dc52d
children 1997f7af845c
files doc/streams.txt doc/style/edgewall.css doc/style/pygments.css setup.py
diffstat 4 files changed, 163 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- 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:: python
 
   >>> 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:: python
 
   >>> 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:: python
 
   >>> 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:: python
 
   >>> 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:: python
 
   >>> 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:: python
 
   >>> 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:: python
 
   >>> 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:: python
 
   >>> 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:: python
 
   >>> 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; }
@@ -45,8 +46,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;
@@ -61,7 +63,9 @@
   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;
 }
+p.admonition-title { margin-bottom: 0; }
+div.note, div.warning { font-style: italic; }
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/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