createdoc.py
author Sandro Knauß <knauss@netzguerilla.net>
Mon, 23 Apr 2012 21:38:30 +0200
branchdevel
changeset 271 b218238e76b9
parent 251 3caa803a2dec
child 277 f65edc0382cc
permissions -rwxr-xr-x
creadoc: switching to rst syntax doc/tmpl: switching to english

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*- 

from genshi.template import TemplateLoader
from genshi import Markup
loader = TemplateLoader('doc/tmpl', auto_reload=True)

import inspect
from docutils.core import publish_doctree
import docutils

#--
from docutils import core
from docutils.writers.html4css1 import Writer,HTMLTranslator

class NoHeaderHTMLTranslator(HTMLTranslator):
    def __init__(self, document):
        HTMLTranslator.__init__(self,document)
        self.body_prefix = []
        self.body_suffix = []

_w = Writer()
_w.translator_class = NoHeaderHTMLTranslator
_w.visitor_attributes = ("html_body",)

def d():
    subs = _w.interpolation_dict()
    return "%(html_body)s"%subs

_w.apply_template = d

def reSTify(s):
    d =docutils.utils.new_document("")
    if s.tagname == "paragraph":
        d.append(s[0])
    else:
        d.append(s)

    return core.publish_from_doctree(d, writer=_w)

from iro.view.xmlrpc import TwistedInterface as Current 

from createerm import createSchemaPlot, tables, tables_cls

class Link():
    def __init__(self,name,title):
        self.name=name
        self.title=title

    def getLink(self):
        return self.name

    def __getitem__(self,name):
        if name == "link":
            return self.getLink()
        return AttributeError(name)

class Site(Link):
    pass

class Keyword():
    def __init__(self, name=None, typ=None, description=None):
        self.name=name
        self.typ=typ
        self.description=description

    def __repr__(self):
        return '<Keyword("%s", "%s", "%s")>'%(self.name, self.typ, self.description)

def keywords(f):
    NORMAL = 0
    TYPE = 1
    pd = publish_doctree(f.__doc__.decode('utf8'))

    kws={}
    for child in pd[1][0]:
        kw = Keyword()
        ftyp = NORMAL
        for sc in child:
            if sc.tagname == "field_name":
                p = sc.astext().split()
                if p[0] in ["param",]:
                    if len(p) == 3:             #param typ name
                        kw.name = p[2]
                        kw.typ = p[1]
                    if len(p) == 2:
                        kw.name = p[1]
                elif p[0] == "type":
                    kw = kws[p[1]]
                    ftyp=TYPE
                elif p[0] in ["return","rtyp"]:
                    break
                else:
                    raise Exception("Unknown field_name: %s"%(p[0]))
            if sc.tagname == "field_body":
                if ftyp == NORMAL:
                    kw.description = Markup(reSTify(sc[0]))
                if ftyp == TYPE:
                    kw.typ = sc[0][0]
        else:
            kws[kw.name] = kw
    return kws

def ret(f):
    NORMAL = 0
    TYPE = 1
    
    pd = publish_doctree(f.__doc__.decode('utf8'))
    for child in pd[1][0]:
        kw = Keyword(name="return")
        ftyp = NORMAL
        for sc in child:
            if sc.tagname == "field_name":
                p = sc.astext().split()
                if p[0] == "return":
                    if len(p) == 2:
                        kw.typ = p[1]
                elif p[0] == "rtype":
                    ftyp=TYPE
                elif p[0] in ["param","type"]:
                    break
                else:
                    raise Exception("Unknown field_name: %s"%(p[0]))
            if sc.tagname == "field_body":
                if ftyp == NORMAL:
                    kw.description = Markup(reSTify(sc[0]))
                if ftyp == TYPE:
                    kw.typ = sc[0][0]
        else:
            return kw
    
    raise Exception("no return description")
 
class Arg():
    def __init__(self,name,f):
        self.name=name
        k = keywords(f)
        kwd=k[name]
        self.typ=kwd.typ
        self.description=kwd.description

class Method(Link):
    def __init__(self,name,methods):
        title=name[0].upper()+name[1:]
        Link.__init__(self,name,title)
        m=methods[name]
        (args, varargs, keywords, defaults)=inspect.getargspec(m)
        a=[]
        for b in args:
            if b in ("self","session"):
                continue
            else:
                a.append(b)
        
        args = a
        self.func_line=inspect.formatargspec(args, varargs, keywords, defaults)
        pd = publish_doctree(m.__doc__)
        if pd[0].tagname == "paragraph":
            self.description = pd[0].astext()
        self.args=[Arg(a,m) for a in args]
        self.rets=[ret(m)]

class Table(Link):
    def __init__(self,cls):
        name=cls.__name__
        self.tablename=cls.__tablename__
        title=self.tablename[0].upper()+self.tablename[1:]
        Link.__init__(self,name,title)
        
        self.description = Markup(core.publish_string(cls.__doc__,writer=_w))


def main():
    sites=[Site("index.html","Iro"),
           Site("current.html","API Documentation"),
           Site("database.html","Datenbase Schema"),
           Site("about.html","About us"),
           ]

    current_methods = dict(inspect.getmembers(Current()))
    current=[ Method(i,current_methods) for i in Current().listMethods() if i  != "listMethods" ]
    
    t = [Table(tables_cls[str(f)]) for f in tables]
    createSchemaPlot('doc/images/db-schema.svg')

    for site in sites:
        print("generiere %s" % site.name)
        tmpl = loader.load(site.name)
        def a(s):
            if s == site:
                return {"class":"menu active"}
        stream = tmpl.generate(sites=sites, active=a, current=current, tables=t)
        with open('doc/'+site.name, "w") as g:
            g.write(stream.render('html', doctype='html'))

if __name__ == '__main__':
    main()