doc2html.py

'''\
Create HTML Documentation from __DOC__ Attributes.

Developer@Sonnack.com
May 2012
'''
####################################################################################################
from __future__ import print_function
from sys import stdout, stderr, argv, path as syspath
from os import path
from datetime import datetime
from xml.sax.saxutils import escape
####################################################################################################

JobSpecs = {
    'test':{
        'htmlpath':'C:/CJS/prj/Python/docs',
        'indexname':'demo.html',
        'modpaths':[],
        'modlist':['files', 'filelist', 'datelist', 'htmlpage', 'img', 'logger', 'xml2tree']
    },
    'default':{
        'htmlpath':'C:/CJS/www/root/cjs/python',
        'indexname':'index.html',
        'modpaths':[
            'C:/CJS/prj/Python/app',
            'C:/CJS/prj/Python/app/maze',
            'C:/CJS/prj/Python/ws/chess',
            'C:/CJS/prj/Python/ws/ftp',
            'C:/CJS/prj/Python/ws/img',
            'C:/CJS/data/mx/py',
            'C:/CJS/www/bin',
            'C:/CJS/www/bin/pageinfo',
            'C:/CJS/www/bin/thumbx',
        ],
        'modlist':[
            'b64', 'bnode', 'colors', 'datelist', 'db', 'dbsql',
            'env', 'filelist', 'files', 'grid', 'htget', 'htmlpage', 'html_cal',
            'img', 'lexer', 'logger', 'point2', 'point3', 'properties',
            'uid', 'webpage', 'xml_grep', 'xml_sax',
            'zoo',
            'doc2html', 'grep', 'L26', 'relays', 'subdirs', 'pf',
            'bj', 'bj_objects', 'bj_rulz',
            'lep', 'lep_objects', 'lep_parser',
            'maze-maker-2', 'maze_gif', 'maze_img', 'maze_nav', 'maze_obj', 'maze_gen', 'maze_sol', 'maze_xml', 'maze_cgi',
            'chessboard', 'plasma',
            'eml2txt', 'eml2txt_followers', 'eml2txt_likes', 'chart_followers',
            'thumbx', 'htmlpageinfo', 'fcatalog',
            'ls_dilbert', 'ls_strngmttr', 'ls_calv-hobb'
        ]
    },
    'baseball':{
        'htmlpath':'C:/CJS/www/root/cjs/python/baseball',
        'indexname':'index_modules.html',
        'modpaths':[
            'C:/CJS/prj/Python/baseball',
            'C:/CJS/prj/Python/baseball/etc',
            'C:/CJS/prj/Python/baseball/sql',
        ],
        'modlist':[
            'gameday', 'gameday_url', 'gameday_misc',
            'gameday_msb', 'gameday_epg',
            'gameday_boxscore', 'gameday_linescore', 'gameday_events', 'gameday_innings', 'gameday_game',
            'gameday_player', 'gameday_players',
            'gd', 'gd_players',
            'team_games', 'team_stats', 'team_table',
            'teams', 'teams_progress', 'teams_schedule', 'teams_win_loss', 'teams_xref',
            'twins', 'twins_batter', 'twins_pitcher',
            'page_team_starters_rpt', 'post_season',
            'bbdb', 'db_all_teams_stats', 'db_season_elimination',
            'chart_maker',
            'http404',
            'db_app','db_baseball','pfx_app','pitchfx',
            'tblGames','tblGamesCharts','tblBoxScores',
            'tblFranchise','tblPlayers','tblAttendance','tblGameLogs',
            'util',
        ]
    },
    'bool':{
        'htmlpath':'C:/CJS/www/root/cjs/python/bool',
        'indexname':'index.html',
        'modpaths':['C:/CJS/prj/Python/ws/bool'],
        'modlist':[
            'bool_m','bool_obj','bool_rte','bool_sys',
            'x_act', 'x_act_lib', 'x_act_sys', 'x_act_usr',
            'x_environ', 'x_impl',
            'x_mdl', 'x_mdl_bool', 'x_mdl_date', 'x_mdl_float', 'x_mdl_int', 'x_mdl_list', 'x_mdl_string',
            'x_obj', 'x_system',
        ]
    },

} # end JobSpecs

####################################################################################################
def PrintPageHead (fp):
    ''' Page Head. '''
    print('<html><head>', file=fp)
    print('<title>Sonnack.Python.Docs</title>', file=fp)
    print('<link rel="stylesheet" type="text/css" href="/basic.css">', file=fp)
    print('<link rel="stylesheet" type="text/css" href="docs.css">', file=fp)
    print('</head><body>', file=fp)
    print('<div id="PageHead">', file=fp)
    print('<h1>Sonnack/Python</h1>', file=fp)
    print('<h2>Module Docs</h2>', file=fp)
    print('</div>', file=fp)
    print('<div id="PageBody">', file=fp)

####################################################################################################
def PrintPageFoot (fp):
    ''' Page Foot. '''
    print('</div>', file=fp)
    print('<div id="PageFoot">', file=fp)
    print('<div class="Rt">created: %s</div>' % datetime.today(), file=fp)
    print('<br>', file=fp)
    print('</div>', file=fp)
    print('</body></html>', file=fp)


####################################################################################################
def document_module (bag, moduleName):
    ''' Document Module. '''

    m = __import__(moduleName)
    h = m.__doc__ if hasattr(m,'__doc__') else None
    h = escape(h.strip()) if h else '(no Module Doc)'

    # For each key in the Module's Dictionary...
    d = []
    for k in m.__dict__:
        # Use the key to get Module Object...
        obj = m.__dict__[k]

        # If the Object has a Module (name) attribute, the Module name
        # must match this Module (otherwise it's an imported object)...
        mod_name = obj.__module__ if hasattr(obj,'__module__') else ''
        if mod_name != m.__name__:
            continue

        # Get Object attributes (if they exist)...
        obj_name = obj.__name__ if hasattr(obj,'__name__') else ''
        obj_doc  = obj.__doc__ if hasattr(obj,'__doc__') else ''
        obj_type = type(obj).__name__
        if obj_name == '<lambda>':
            obj_type = 'lambda'

        # Add to collection...
        t = (k, obj_type, obj_name, obj_doc)
        d.append(t)

    # Open file...
    fn = path.join(bag['htmlpath'], '%s.html' % moduleName)
    fp = open(fn, 'w')
    try:
        html_h3 = '<h3>%s</h3>'
        html_h4 = '<h4 class="%s"><span style="color:#666666;font-weight:normal;">%s</span> %s</h4>'
        # Page Head...
        PrintPageHead(fp)
        # Page Body...
        print(html_h3 % moduleName, file=fp)
        print('<pre class="ModuleDoc">%s</pre>' % h, file=fp)
        for t in sorted(d, cmp=lambda a,b: cmp(b[1],a[1]) or cmp(a[0],b[0])):
            print(html_h4 % (t[1], t[1], t[0]), file=fp)
            if t[1] not in ['function','type']:
                continue
            if t[3]:
                print('<pre class="ObjectDoc">%s</pre>' % escape(t[3].strip()), file=fp)
        # Page Foot...
        PrintPageFoot(fp)
    except Exception as e:
        print(e, file=stderr)
    finally:
        # Close file...
        fp.close()

    ix = h.find('.')
    if 0 < ix:
        h = h[:ix]
    return h

####################################################################################################
def document_module_list (bag):
    syspath.extend(bag['modpaths'])

    # Open output file...
    fn = path.join(bag['htmlpath'], bag['indexname'])
    fp = open(fn, 'w')
    try:
        html_h3 = '<h3>Module Index</h3>'
        html_li = '<li><a href="%s.html">%s</a> %s</li>'
        # Page Head...
        PrintPageHead(fp)

        # Page Body...
        print(html_h3, file=fp)
        print('<ul>', file=fp)
        for mod_name in bag['modlist']:
            print(mod_name)
            s = document_module(bag, mod_name)
            print(html_li % (mod_name, mod_name, s), file=fp)
        print('</ul>', file=fp)

        # Page Foot...
        PrintPageFoot(fp)
    except Exception as e:
        print(e, file=stderr)
        raise
    finally:
        fp.close()


##================================================================================================##
def do_main (*args):
    print('main/parameters: %s' % str(args))
    grp_bag = JobSpecs[args[0]]
    document_module_list(grp_bag)
    return 'Done!'
####################################################################################################
def dispatch (cmd, *args):
    print('command: %s' % cmd)
    print('arguments: %s' % str(args))
    if cmd == 'bool': return do_main('bool')
    if cmd == 'baseball': return do_main('baseball')
    if cmd == 'default': return do_main('default')
    if cmd == 'main': return do_main(*args)
    return 'Nothing to do!'
####################################################################################################
if __name__ == '__main__':
    print('autorun: %s' % argv[0])
    cmd = argv[1] if 1 < len(argv) else ''
    etc = argv[2:] if 2 < len(argv) else []
    obj = dispatch(cmd, *etc)
    print(obj)
####################################################################################################
'''eof'''