#!/usr/bin/env python
"""
Generate available fields table for ReST documentation.
"""
import os.path as op
import sys
from argparse import ArgumentParser
sys.path.append('.')
import sfepy
from sfepy import get_paths
from sfepy.base.base import load_classes
from sfepy.discrete import Field
field_files = [ii for ii
               in get_paths('sfepy/discrete/fem/fields*.py')
               if 'fields_base.py' not in ii]
field_files += get_paths('sfepy/discrete/structural/fields*.py')
field_files += get_paths('sfepy/discrete/iga/fields*.py')
field_files += get_paths('sfepy/discrete/dg/fields.py')
field_table = load_classes(field_files, [Field], ignore_errors=True,
                           name_attr='family_name')
header = """
.. tabularcolumns:: |l|l|l|p{0.55\linewidth}|
.. list-table:: Fields
   :widths: 5 15 15 65
   :header-rows: 1
   * - space
     - basis
     - region kind
     - description
"""
table_row = """   * - %s
     - %s
     - %s
     - %s
"""
class_link = ':class:`{short} <{full}>`'
translate_rtype = {'volume' : 'cell', 'surface' : 'facet'}
[docs]
def typeset_field_table(fd, field_table):
    fd.write('.. _field_table:\n')
    fd.write(header)
    rows = {}
    for key, cls in field_table.items():
        rtype, space, *basis = key.split('_')
        rtype = translate_rtype[rtype]
        basis = '_'.join(basis)
        doc = cls.__doc__
        if doc is not None:
            desc = doc.strip().splitlines()[0]
        else:
            desc = ''
        sdata = rows.setdefault(space, {})
        row = sdata.setdefault(basis, ([], desc))
        name = cls.__module__ + '.' + cls.__name__
        row[0].append(class_link.format(short=rtype, full=name))
        if row[1] is None:
            row[1] = desc
    for space, sdata in rows.items():
        for basis, (rtypes, desc) in sorted(sdata.items(), key=lambda x: x[0]):
            rtype = ', '.join(rtypes)
            fd.write(table_row % (space, basis, rtype, desc))
    fd.write('\n') 
[docs]
def typeset(fd):
    """
    Utility function called by Sphinx.
    """
    fd = open(fd, 'w')
    typeset_field_table(fd, field_table)
    fd.close() 
[docs]
def gen_field_table(app):
    typeset(op.join(app.builder.srcdir, 'field_table.rst')) 
[docs]
def setup(app):
    app.connect('builder-inited', gen_field_table) 
[docs]
def main():
    parser = ArgumentParser(description=__doc__)
    parser.add_argument('-v', '--version', action='version',
                        version='%(prog)s ' + sfepy.__version__)
    parser.add_argument('-o', '--output', metavar='output_filename',
                        action='store', dest='output_filename',
                        default='field_table.rst')
    options = parser.parse_args()
    typeset(options.output_filename) 
if __name__ == '__main__':
    main()