2 from os
.path
import join
, abspath
4 from docutils
import core
, nodes
5 from docutils
.parsers
import rst
6 from docutils
.writers
.html4css1
import Writer
, HTMLTranslator
8 from pygments
import highlight
9 from pygments
.lexers
import get_lexer_by_name
, TextLexer
10 from pygments
.formatters
import HtmlFormatter
13 # This is a temporary hack - to extract the 'custom fields' from
14 # docutil's `docinfo` node.
16 # `HTMLTranslator` happens to process the docinfo tree and so we can steal
17 # the key,value pairs of custom fields from the `visit_field_name` function.
18 class DocInfoProxy(HTMLTranslator
):
22 def __init__(self
, *args
, **kwargs
):
23 HTMLTranslator
.__init
__(self
, *args
, **kwargs
)
24 DocInfoProxy
.ITEMS
= {}
27 # Custom fields are processed here (Tags and so on)
28 def visit_field_name(self
, node
):
29 key
= node
.astext().lower()
30 value
= node
.parent
.children
[1].astext() # from sibling
31 # print 'meta[%s] = {%s}' % (key, value)
32 DocInfoProxy
.ITEMS
[key
] = value
33 return HTMLTranslator
.visit_field_name(self
, node
)
35 # Standard fields are processed here (Date, Author and so on)
36 def visit_docinfo_item(self
, node
, name
, meta
=1):
38 value
= node
.parent
.children
[0].astext() # from sibling
39 # print '*meta[%s] = {%s}' % (key, value)
40 DocInfoProxy
.ITEMS
[key
] = value
41 return HTMLTranslator
.visit_docinfo_item(self
, node
, name
, meta
)
45 "Process the `rstfile` and return the `parts` and `meta` information"
47 writer
.translator_class
= DocInfoProxy
# see comment for `DocInfoProxy`
49 parts
= core
.publish_parts(
50 source
=open(rstfile
).read(),
51 source_path
=rstfile
, writer
=writer
)
52 meta
= DocInfoProxy
.ITEMS
.copy()
55 def htmlpath(rstfile
):
56 """Return the .html path for the given .rst path"""
57 assert rstfile
.endswith('.rst'), '<%s> is not a rst path' % rstfile
58 return rstfile
[:-4] + '.html'
60 def rstfiles(directory
):
61 for dir, subdirs
, files
in os
.walk(directory
):
63 if file.endswith('.rst'):
64 yield abspath(join(dir, file))
68 # Pygments syntax-highlighting for ReST
70 # http://dev.pocoo.org/projects/pygments/browser/external/rst-directive.py
73 DEFAULT
= HtmlFormatter(noclasses
=INLINESTYLES
)
74 # Add name -> formatter pairs for every variant you want to use
76 # 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True),
79 def pygments_directive(name
, arguments
, options
, content
, lineno
,
80 content_offset
, block_text
, state
, state_machine
):
82 lexer
= get_lexer_by_name(arguments
[0])
84 # no lexer found - use the text one instead of an exception
86 # take an arbitrary option if more than one is given
87 formatter
= options
and VARIANTS
[options
.keys()[0]] or DEFAULT
88 parsed
= highlight(u
'\n'.join(content
), lexer
, formatter
)
89 return [nodes
.raw('', parsed
, format
='html')]
91 pygments_directive
.arguments
= (1, 0, 1)
92 pygments_directive
.content
= 1
93 pygments_directive
.options
= dict([(key
, directives
.flag
) for key
in VARIANTS
])
95 rst
.directives
.register_directive('sourcecode', pygments_directive
)