README0100644001243100224340000000111207635756134010652 0ustar gregstage7Usage: pyrexdoc module1 [module2 ...] pyrexdoc generates no-frills but usable documentation for modules created with Pyrex. This utility is needed because the regular Python doco generators like epydoc, pydoc, happydoc etc lose the plot when analysing modules created with Pyrex. For instance, the other doc generators may ignore Pyrex-generated classes and/or functions, or regard class methods as instance variables, or other equally annoying behaviour. Note - the arguments above should be module *names*, not files. pyrexdoc was written by David McNab pyrexdoc.py0100644001243100224340000002504007636161173012201 0ustar gregstage7import sys,types,os,os.path from pdb import set_trace as trace def doIndent(indent): sys.stdout.write(' ' * indent) def my_import(name): mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod def analyseClass(aClass): contents = {'methods':[]} for childName in dir(aClass): if childName[0:2] == '__': continue childObj = getattr(aClass, childName) childDict = {'name':childName, 'object':childObj, 'doc':childObj.__doc__, } if type(childObj) is types.BuiltinMethodType \ or type(childObj) is types.MethodType \ or repr(type(childObj)) in ["", "", ]: contents['methods'].append(childDict) return contents def analyseModule(module): contents = {'functions':[], 'classes':[]} for childName in dir(module): if childName[0:2] == '__' and childName not in ['__init__', '__new__', '__dealloc__']: continue childObj = getattr(module, childName) childDict = {'name':childName, 'object':childObj, 'doc':childObj.__doc__, } if type(childObj) is types.ClassType or type(childObj) is types.TypeType: childDict['contents'] = analyseClass(childObj) contents['classes'].append(childDict) elif type(childObj) is types.FunctionType or type(childObj) is types.BuiltinFunctionType: contents['functions'].append(childDict) return contents def makeDir(dirName): if os.path.exists(dirName): if not os.path.isdir(dirName): print "Cannot create directory '%s': file exists" % dirName sys.exit(1) else: try: os.makedirs(dirName) except: print "Cannot create directory '%s'" % dirName sys.exit(1) def makeHtmlIndex(): fd = file("index.html", "w") fd.write(""" """) fd.write("Doco for Pyrex Modules\n") fd.write(""" Sorry - you need a frames-enabled browser to view this documentation """) fd.write("\n") fd.close() def makeHtmlModuleList(tree): fd = file("contents/modulelist.html", "w") fd.write(""" """) fd.write("\n\n") fd.write("

Modules

\n") for module in tree: fd.write("""%s
\n""" % ( module['name'], module['name'])) fd.write("\n\n") fd.close() def makeHtmlModulePaneTop(tree): fd = file("contents/modulepane.html", "w") fd.write(""" """) fd.write("\n\n") fd.write("

Documentation for Pyrex-generated modules

\n") fd.write("Please click on a link in the left pane") fd.write("\n\n") fd.close() def makeHtmlModulePane(module): oldCwd = os.getcwd() os.chdir("contents") moduleName = module['name'] contents = module['contents'] # Generate top-level module frameset fd = file("module-%s.html" % moduleName, "w") fd.write(""" """) fd.write("%s: Pyrex Module Documentation\n" % moduleName) fd.write(""" Sorry - you need a frames-enabled browser to view this documentation """ % (moduleName, moduleName)) fd.write("\n") fd.close() # Generate module list pane fd = file("module-%s-contents.html" % moduleName, "w") fd.write("""\n\n\n""") fd.write("Module %s Contents\n" % moduleName) fd.write("\n\n") fd.write("

Module
%s

\n" % moduleName) if len(contents['classes']) != 0: fd.write("

Classes

\n") for item in contents['classes']: className = item['name'] fd.write("""%s\n""" % ( moduleName, className, className)) fd.write("
\n") classContents = item['contents'] if len(classContents['methods']) > 0: for m in classContents['methods']: methodName = m['name'] # here - need to put the url's '#' component as an arg, otherwise poor doddery # old emacs loses the plot vis a vis strings fd.write("""   %s
\n""" % ( moduleName, "#", className, methodName, methodName)) fd.write("\n") fd.write("\n") else: fd.write("

No Classes

\n") fd.write("
\n") if len(contents['functions']) != 0: fd.write("

Functions

\n") for item in contents['functions']: funcName = item['name'] fd.write("""%s\n""" % ( moduleName, funcName, funcName)) fd.write("
\n") else: fd.write("

No Functions

\n") fd.write("
\n") fd.write("\n\n") fd.close() # Generate module detail pane fd = file("module-%s-detail.html" % moduleName, "w") fd.write("""\n\n\n""") fd.write("Module %s Details\n" % moduleName) fd.write("\n\n") fd.write("

Module: %s

\n" % moduleName) fd.write("
%s
\n" % module['doc']) fd.write("
\n") if len(contents['classes']) != 0: for item in contents['classes']: className = item['name'] fd.write("""""" % className) fd.write("

Class: %s

\n" % className) fd.write("
%s
\n" % item['doc']) #trace() classContents = item['contents'] if len(classContents['methods']) > 0: fd.write("

\n") fd.write("

Methods for class %s

\n" % className) fd.write("
\n") for m in classContents['methods']: methodName = m['name'] fd.write("""""" % (className, methodName)) fd.write("

%s.%s

\n" % (className, methodName)) fd.write("
%s
\n" % m['doc']) fd.write("
\n") fd.write("
\n") fd.write("
\n") if len(contents['functions']) != 0: for item in contents['functions']: funcName = item['name'] fd.write("""""" % funcName) fd.write("

Function: %s

\n" % item['name']) fd.write("
%s
\n" % item['doc']) fd.write("
\n") fd.write("\n\n") fd.close() # Done - back to old directory os.chdir(oldCwd) def makeHtml(tree): """ Generates html doco from analysed tree """ # Create and enter Doco directory makeDir("Doco") oldCwd = os.getcwd() os.chdir("Doco") makeDir("contents") # generate frameset in index.html makeHtmlIndex() # generate module list frame makeHtmlModuleList(tree) # generate empty contents pane makeHtmlModulePaneTop(tree) # generate each module's right panes for module in tree: makeHtmlModulePane(module) # Done os.chdir(oldCwd) print "Documentation successfully generated" def docgen(modlist): modules = [] if modlist == []: return # nothing to do for modName in modlist: try: modObj = my_import(modName) modProps = {'name':modName, 'object':modObj, 'doc':modObj.__doc__} modProps['contents'] = analyseModule(modObj) modules.append(modProps) except: print "ignoring unimportable module '%s'" % modName #print "docgen: modules" #print modules makeHtml(modules) def usage(): progname = sys.argv[0] print print "Usage: %s module1 [module2 ...]" % progname print print "%s generates no-frills but usable documentation for modules" % progname print "created with Pyrex." print print "This utility is needed because the regular Python doco generators" print "like epydoc, pydoc, happydoc etc lose the plot when analysing" print "modules created with Pyrex." print print "For instance, the other doc generators may ignore Pyrex-generated classes" print "and/or functions, or regard class methods as instance variables, or other" print "equally annoying behaviour." print print "Note - the arguments above should be module *names*, not files." print print "%s was written by David McNab " % progname print def main(): if '.' not in sys.path: sys.path.insert(0, '.') pushed = True else: pushed = False if len(sys.argv) <= 1 or sys.argv[1] in ['-h', '-?', '-help', '--help']: usage() docgen(sys.argv[1:]) if pushed and sys.path[0] == '.': sys.path.pop(0) if __name__ == '__main__': main() pyrexdoc0100755001243100224340000000006607635756074011567 0ustar gregstage7#!/usr/bin/env python import pyrexdoc pyrexdoc.main()