frosix

Multiparty signature service (experimental)
Log | Files | Refs | README | LICENSE

__init__.py (6351B)


      1 """Sphinx Guzzle theme."""
      2 
      3 import os
      4 from os import path
      5 import xml.etree.ElementTree as ET
      6 
      7 from docutils import nodes
      8 from sphinx.locale import admonitionlabels
      9 from sphinx.writers.html import HTMLTranslator as SphinxHTMLTranslator
     10 
     11 from pygments.style import Style
     12 from pygments.token import Keyword, Name, Comment, String, Error, \
     13      Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
     14 
     15 
     16 def setup(app):
     17     """Setup conntects events to the sitemap builder"""
     18     app.connect('html-page-context', add_html_link)
     19     app.connect('build-finished', create_sitemap)
     20     app.set_translator('html', MyHTMLTranslator)
     21     app.set_translator('html-linked', MyHTMLTranslator)
     22     app.sitemap_links = []
     23     app.add_html_theme('taler_sphinx_theme', path.abspath(path.dirname(__file__) + "/guzzle_sphinx_theme"))
     24 
     25 
     26 def add_html_link(app, pagename, templatename, context, doctree):
     27     """As each page is built, collect page names for the sitemap"""
     28     base_url = app.config['html_theme_options'].get('base_url', '')
     29     if base_url:
     30         app.sitemap_links.append(base_url + pagename + ".html")
     31 
     32 
     33 def create_sitemap(app, exception):
     34     """Generates the sitemap.xml from the collected HTML page links"""
     35     if (not app.config['html_theme_options'].get('base_url', '') or
     36            exception is not None or
     37            not app.sitemap_links):
     38         return
     39 
     40     filename = app.outdir + "/sitemap.xml"
     41     print("Generating sitemap.xml in %s" % filename)
     42 
     43     root = ET.Element("urlset")
     44     root.set("xmlns", "http://www.sitemaps.org/schemas/sitemap/0.9")
     45 
     46     for link in app.sitemap_links:
     47         url = ET.SubElement(root, "url")
     48         ET.SubElement(url, "loc").text = link
     49 
     50     ET.ElementTree(root).write(filename)
     51 
     52 
     53 def html_theme_path():
     54     return [os.path.dirname(os.path.abspath(__file__))]
     55 
     56 
     57 class MyHTMLTranslator(SphinxHTMLTranslator):
     58     """
     59     Handle translating to bootstrap structure.
     60     """
     61     def visit_table(self, node, name=''):
     62         """
     63         Override docutils default table formatter to not include a border
     64         and to use Bootstrap CSS
     65         See: http://sourceforge.net/p/docutils/code/HEAD/tree/trunk/docutils/docutils/writers/html4css1/__init__.py#l1550
     66         """
     67         self.context.append(self.compact_p)
     68         self.compact_p = True
     69         classes = 'table table-bordered ' + self.settings.table_style
     70         classes = classes.strip()
     71         self.body.append(
     72             self.starttag(node, 'table', CLASS=classes))
     73 
     74     def depart_table(self, node):
     75         """
     76         This needs overridin' too
     77         """
     78         self.compact_p = self.context.pop()
     79         self.body.append('</table>\n')
     80 
     81     def visit_field(self, node):
     82         pass
     83 
     84     def depart_field(self, node):
     85         pass
     86 
     87     def visit_field_name(self, node):
     88         atts = {}
     89         if self.in_docinfo:
     90             atts['class'] = 'docinfo-name'
     91         else:
     92             atts['class'] = 'field-name'
     93         self.context.append('')
     94         self.body.append(self.starttag(node, 'dt', '', **atts))
     95 
     96     def depart_field_name(self, node):
     97         self.body.append('</dt>')
     98         self.body.append(self.context.pop())
     99 
    100     def visit_field_body(self, node):
    101         self.body.append(self.starttag(node, 'dd', '', CLASS='field-body'))
    102         self.set_class_on_child(node, 'first', 0)
    103         field = node.parent
    104         if (self.compact_field_list or
    105             isinstance(field.parent, nodes.docinfo) or
    106             field.parent.index(field) == len(field.parent) - 1):
    107             # If we are in a compact list, the docinfo, or if this is
    108             # the last field of the field list, do not add vertical
    109             # space after last element.
    110             self.set_class_on_child(node, 'last', -1)
    111 
    112     def depart_field_body(self, node):
    113         self.body.append('</dd>\n')
    114 
    115     def visit_field_list(self, node):
    116         self.context.append((self.compact_field_list, self.compact_p))
    117         self.compact_p = None
    118         if 'compact' in node['classes']:
    119             self.compact_field_list = True
    120         elif (self.settings.compact_field_lists
    121               and 'open' not in node['classes']):
    122             self.compact_field_list = True
    123         if self.compact_field_list:
    124             for field in node:
    125                 field_body = field[-1]
    126                 assert isinstance(field_body, nodes.field_body)
    127                 children = [n for n in field_body
    128                             if not isinstance(n, nodes.Invisible)]
    129                 if not (len(children) == 0 or
    130                         len(children) == 1 and
    131                         isinstance(children[0],
    132                                    (nodes.paragraph, nodes.line_block))):
    133                     self.compact_field_list = False
    134                     break
    135         self.body.append(self.starttag(node, 'dl', frame='void',
    136                                        rules='none',
    137                                        CLASS='docutils field-list'))
    138 
    139     def depart_field_list(self, node):
    140         self.body.append('</dl>\n')
    141         self.compact_field_list, self.compact_p = self.context.pop()
    142 
    143     def visit_container(self, node):
    144         self.body.append(self.starttag(node, 'div', CLASS='docutils'))
    145 
    146     def add_secnumber(self, node):
    147         # type: (nodes.Element) -> None
    148         if node.get('secnumber'):
    149             numbers = list(map(str, node['secnumber']))
    150             if len(numbers) <= 3:
    151                 self.body.append('.'.join(numbers) + self.secnumber_suffix)
    152         elif isinstance(node.parent, nodes.section):
    153             if self.builder.name == 'singlehtml':
    154                 docname = self.docnames[-1]
    155                 anchorname = "%s/#%s" % (docname, node.parent['ids'][0])
    156                 if anchorname not in self.builder.secnumbers:
    157                     anchorname = "%s/" % docname  # try first heading which has no anchor
    158             else:
    159                 anchorname = '#' + node.parent['ids'][0]
    160                 if anchorname not in self.builder.secnumbers:
    161                     anchorname = ''  # try first heading which has no anchor
    162             if self.builder.secnumbers.get(anchorname):
    163                 numbers = list(self.builder.secnumbers[anchorname])
    164                 if len(numbers) <= 3:
    165                     self.body.append('.'.join(map(str, numbers)) +
    166                                      self.secnumber_suffix)