feedburner support
[wrigit.git] / rst.py
blob79da05d5b3fbfe85ee458815cae45f5621caa75e
1 import os
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):
20 ITEMS = {}
22 def __init__(self, *args, **kwargs):
23 HTMLTranslator.__init__(self, *args, **kwargs)
24 DocInfoProxy.ITEMS = {}
25 self.__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):
37 key = name.lower()
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)
44 def process(rstfile):
45 "Process the `rstfile` and return the `parts` and `meta` information"
46 writer = Writer()
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()
53 return parts, meta
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):
62 for file in files:
63 if file.endswith('.rst'):
64 yield abspath(join(dir, file))
68 # Pygments syntax-highlighting for ReST
69 # adapted from,
70 # http://dev.pocoo.org/projects/pygments/browser/external/rst-directive.py
72 INLINESTYLES = False
73 DEFAULT = HtmlFormatter(noclasses=INLINESTYLES)
74 # Add name -> formatter pairs for every variant you want to use
75 VARIANTS = {
76 # 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True),
79 def pygments_directive(name, arguments, options, content, lineno,
80 content_offset, block_text, state, state_machine):
81 try:
82 lexer = get_lexer_by_name(arguments[0])
83 except ValueError:
84 # no lexer found - use the text one instead of an exception
85 lexer = TextLexer()
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)