| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | """ |
|---|
| 3 | The Pygments reStructuredText directive |
|---|
| 4 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|---|
| 5 | |
|---|
| 6 | This fragment is a Docutils_ 0.5 directive that renders source code |
|---|
| 7 | (to HTML only, currently) via Pygments. |
|---|
| 8 | |
|---|
| 9 | To use it, adjust the options below and copy the code into a module |
|---|
| 10 | that you import on initialization. The code then automatically |
|---|
| 11 | registers a ``sourcecode`` directive that you can use instead of |
|---|
| 12 | normal code blocks like this:: |
|---|
| 13 | |
|---|
| 14 | .. sourcecode:: python |
|---|
| 15 | |
|---|
| 16 | My code goes here. |
|---|
| 17 | |
|---|
| 18 | If you want to have different code styles, e.g. one with line numbers |
|---|
| 19 | and one without, add formatters with their names in the VARIANTS dict |
|---|
| 20 | below. You can invoke them instead of the DEFAULT one by using a |
|---|
| 21 | directive option:: |
|---|
| 22 | |
|---|
| 23 | .. sourcecode:: python |
|---|
| 24 | :linenos: |
|---|
| 25 | |
|---|
| 26 | My code goes here. |
|---|
| 27 | |
|---|
| 28 | Look at the `directive documentation`_ to get all the gory details. |
|---|
| 29 | |
|---|
| 30 | .. _Docutils: http://docutils.sf.net/ |
|---|
| 31 | .. _directive documentation: |
|---|
| 32 | http://docutils.sourceforge.net/docs/howto/rst-directives.html |
|---|
| 33 | |
|---|
| 34 | :copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS. |
|---|
| 35 | :license: BSD, see LICENSE for details. |
|---|
| 36 | """ |
|---|
| 37 | |
|---|
| 38 | # Options |
|---|
| 39 | # ~~~~~~~ |
|---|
| 40 | |
|---|
| 41 | # Set to True if you want inline CSS styles instead of classes |
|---|
| 42 | INLINESTYLES = False |
|---|
| 43 | |
|---|
| 44 | from pygments.formatters import HtmlFormatter |
|---|
| 45 | |
|---|
| 46 | # The default formatter |
|---|
| 47 | DEFAULT = HtmlFormatter(noclasses=INLINESTYLES) |
|---|
| 48 | |
|---|
| 49 | # Add name -> formatter pairs for every variant you want to use |
|---|
| 50 | VARIANTS = { |
|---|
| 51 | # 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True), |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | |
|---|
| 55 | from docutils import nodes |
|---|
| 56 | from docutils.parsers.rst import directives, Directive |
|---|
| 57 | |
|---|
| 58 | from pygments import highlight |
|---|
| 59 | from pygments.lexers import get_lexer_by_name, TextLexer |
|---|
| 60 | |
|---|
| 61 | class Pygments(Directive): |
|---|
| 62 | """ Source code syntax hightlighting. |
|---|
| 63 | """ |
|---|
| 64 | required_arguments = 1 |
|---|
| 65 | optional_arguments = 0 |
|---|
| 66 | final_argument_whitespace = True |
|---|
| 67 | option_spec = dict([(key, directives.flag) for key in VARIANTS]) |
|---|
| 68 | has_content = True |
|---|
| 69 | |
|---|
| 70 | def run(self): |
|---|
| 71 | self.assert_has_content() |
|---|
| 72 | try: |
|---|
| 73 | lexer = get_lexer_by_name(self.arguments[0]) |
|---|
| 74 | except ValueError: |
|---|
| 75 | # no lexer found - use the text one instead of an exception |
|---|
| 76 | lexer = TextLexer() |
|---|
| 77 | # take an arbitrary option if more than one is given |
|---|
| 78 | formatter = self.options and VARIANTS[self.options.keys()[0]] or DEFAULT |
|---|
| 79 | parsed = highlight(u'\n'.join(self.content), lexer, formatter) |
|---|
| 80 | return [nodes.raw('', parsed, format='html')] |
|---|
| 81 | |
|---|
| 82 | directives.register_directive('sourcecode', Pygments) |
|---|
| 83 | |
|---|