#!/usr/bin/env python
"""
Generate the table of all terms for the sphinx documentation.
"""
import os
import sys
from optparse import OptionParser
import pyparsing as pp
import numpy as nm
sys.path.append('.')
import sfepy.discrete.fem # Hack: fix circular dependency, as terms.pyx imports
# from sfepy.discrete.fem
from sfepy.terms import term_table
[docs]def set_section(sec):
def action(str, loc, toks):
if toks:
sec[0] = toks[0][1:-1]
return toks
return action
[docs]def to_list(slist, sec):
def action(str, loc, toks):
if toks:
slist.append((sec[0], toks[0]))
return toks
return action
[docs]def create_parser(slist, current_section):
colon = pp.Literal(':')
section = pp.Combine(colon
+ pp.Word(pp.alphas, pp.alphanums + '_ ')
+ colon)
section.setParseAction(set_section(current_section))
section.setName('section')
text = pp.SkipTo(section | pp.StringEnd())
text.setParseAction(to_list(slist, current_section))
text.setName('text')
doc = pp.StringStart()\
+ pp.Optional(text) + pp.ZeroOrMore(section + text)\
+ pp.StringEnd()
return doc
header = """
.. tabularcolumns:: |p{0.2\linewidth}|p{0.2\linewidth}|p{0.6\linewidth}|
.. list-table:: Table of all terms.
:widths: 20 20 60
:header-rows: 1
* - name/class
- arguments
- definition
"""
table_row = """ * - %s
:class:`%s <%s.%s>`
- %s
- %s
"""
[docs]def typeset_to_indent(txt, indent0, indent, width):
if not len(txt): return txt
txt_lines = txt.strip().split('\n')
ispaces = ' ' * indent
text = (' ' * indent0) + txt_lines[0] + '\n' + ispaces
can_newline = False
pos = indent0
for line in txt_lines[1:]:
for word in line.split():
text, pos, can_newline = format_next(text, word, pos, can_newline,
width, ispaces)
return text
[docs]def typeset_term_syntax(term_class):
if ((len(term_class.arg_types) > 1) and not
isinstance(term_class.arg_types[0], str)):
arg_types = [', '.join(['<%s>' % arg for arg in arg_type])
for arg_type in term_class.arg_types]
arg_types = [' ``%s``' % arg_type for arg_type in arg_types]
text = '\n\n '.join(arg_types)
else:
text = ', '.join(['<%s>' % arg for arg in term_class.arg_types])
text = '``%s``' % text
return text
[docs]def typeset_term_table(fd, table):
"""Terms are sorted by name without the d*_ prefix."""
sec_list = []
current_section = ['']
parser = create_parser(sec_list, current_section)
fd.write(header)
keys = table.keys()
sort_keys = [key[key.find('_'):] for key in keys]
iis = nm.argsort(sort_keys)
for ii in iis:
key = keys[ii]
item_class = table[key]
doc = item_class.__doc__
if doc is not None:
sec_list[:] = []
current_section[0] = ''
parser.parseString(doc)
dd = [x[1] for x in sec_list if x[0].lower() == 'definition']
if len(dd):
dd = dd[0]
else:
dd = ''
dds = dd.strip().split('\n\n')
definition = '\n\n'.join(typeset_to_indent(dd, 7, 11, 65)
for dd in dds)[7:]
fd.write(table_row % (item_class.name,
item_class.__name__,
item_class.__module__,
item_class.__name__,
typeset_term_syntax(item_class),
definition))
fd.write('\n')
[docs]def typeset(filename):
"""Utility function called by sphinx. """
fd = open(filename, 'w')
typeset_term_table(fd, term_table)
fd.close()
[docs]def gen_term_table(app):
typeset(os.path.join(app.builder.srcdir, 'term_table.rst'))
[docs]def setup(app):
app.connect('builder-inited', gen_term_table)
usage = '%prog [options]\n' + __doc__.rstrip()
helps = {
'output_filename' :
'output file name',
}
parser = OptionParser(usage=usage, version="%prog")
parser.add_option("-o", "--output", metavar='output_filename',
action="store", dest="output_filename",
default="term_table.rst", help=helps['output_filename'])
(options, args) = parser.parse_args()
typeset(options.output_filename)
if __name__ == '__main__':
main()