From dfc6ac3b5a6b8438876e4e65dc3b08b37031f728 Mon Sep 17 00:00:00 2001 From: holger krekel Date: Mon, 13 Apr 2009 14:36:16 +0200 Subject: [PATCH] use pygments for sourcecode highlightning --HG-- branch : trunk --- doc/path.txt | 30 ++++++++++++++++------- py/test/plugin/pytest_restdoc.py | 41 ++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/doc/path.txt b/doc/path.txt index 972dbe7e6..a4716922e 100644 --- a/doc/path.txt +++ b/doc/path.txt @@ -20,7 +20,9 @@ of course all the functionality is bundled together rather than spread over a number of modules. Example usage, here we use the :api:`py.test.ensuretemp()` function to create -a :api:`py.path.local` object for us (which wraps a directory):: +a :api:`py.path.local` object for us (which wraps a directory): + +.. sourcecode:: pycon >>> import py >>> temppath = py.test.ensuretemp('py.path_documentation') @@ -46,7 +48,9 @@ Both allow you to access relatively advanced features such as metadata and versioning, and both in a way more user-friendly manner than existing other solutions. -Some example usage of :api:`py.path.svnurl`:: +Some example usage of :api:`py.path.svnurl`: + +.. sourcecode:: pycon .. >>> import py .. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk') @@ -59,7 +63,9 @@ Some example usage of :api:`py.path.svnurl`:: >>> time.strftime('%Y-%m-%d', time.gmtime(firstentry.date)) '2004-10-02' -Example usage of :api:`py.path.svnwc`:: +Example usage of :api:`py.path.svnwc`: + +.. sourcecode:: pycon .. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk') >>> temp = py.test.ensuretemp('py.path_documentation') @@ -98,7 +104,7 @@ Searching `.txt` files Search for a particular string inside all files with a .txt extension in a specific directory. -:: +.. sourcecode:: pycon >>> dirpath = temppath.ensure('testdir', dir=True) >>> dirpath.join('textfile1.txt').write('foo bar baz') @@ -120,7 +126,9 @@ Working with Paths This example shows the :api:`py.path` features to deal with filesystem paths Note that the filesystem is never touched, all operations are performed on a string level (so the paths -don't have to exist, either):: +don't have to exist, either): + +.. sourcecode:: pycon >>> p1 = py.path.local('/foo/bar') >>> p2 = p1.join('baz/qux') @@ -153,7 +161,9 @@ Checking path types ....................... Now we will show a bit about the powerful 'check()' method on paths, which -allows you to check whether a file exists, what type it is, etc.:: +allows you to check whether a file exists, what type it is, etc.: + +.. sourcecode:: pycon >>> file1 = temppath.join('file1') >>> file1.check() # does it exist? @@ -177,7 +187,9 @@ Setting svn-properties ....................... As an example of 'uncommon' methods, we'll show how to read and write -properties in an :api:`py.path.svnwc` instance:: +properties in an :api:`py.path.svnwc` instance: + +.. sourcecode:: pycon .. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk') >>> wc.propget('foo') @@ -195,7 +207,9 @@ SVN authentication ....................... Some uncommon functionality can also be provided as extensions, such as SVN -authentication:: +authentication: + +.. sourcecode:: pycon .. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk') >>> auth = py.path.SvnAuth('anonymous', 'user', cache_auth=False, diff --git a/py/test/plugin/pytest_restdoc.py b/py/test/plugin/pytest_restdoc.py index 458292a2c..3a3b644b5 100644 --- a/py/test/plugin/pytest_restdoc.py +++ b/py/test/plugin/pytest_restdoc.py @@ -96,6 +96,47 @@ class ReSTSyntaxTest(py.test.collect.Item): toctree_directive.options = {'maxdepth': int, 'glob': directives.flag, 'hidden': directives.flag} directives.register_directive('toctree', toctree_directive) + self.register_pygments() + + def register_pygments(self): + # taken from pygments-main/external/rst-directive.py + try: + from pygments.formatters import HtmlFormatter + except ImportError: + def pygments_directive(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + return [] + else: + # The default formatter + DEFAULT = HtmlFormatter(noclasses=True) + # Add name -> formatter pairs for every variant you want to use + VARIANTS = { + # 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True), + } + + from docutils import nodes + from docutils.parsers.rst import directives + + from pygments import highlight + from pygments.lexers import get_lexer_by_name, TextLexer + + def pygments_directive(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + try: + lexer = get_lexer_by_name(arguments[0]) + except ValueError: + # no lexer found - use the text one instead of an exception + lexer = TextLexer() + # take an arbitrary option if more than one is given + formatter = options and VARIANTS[options.keys()[0]] or DEFAULT + parsed = highlight(u'\n'.join(content), lexer, formatter) + return [nodes.raw('', parsed, format='html')] + + pygments_directive.arguments = (1, 0, 1) + pygments_directive.content = 1 + pygments_directive.options = dict([(key, directives.flag) for key in VARIANTS]) + + directives.register_directive('sourcecode', pygments_directive) def resolve_linkrole(self, name, text, check=True): apigen_relpath = self.project.apigen_relpath