""" Outputs web.py docs as html version 2.0: documents all code, and indents nicely. By Colin Rothwell (TheBoff) """ import inspect import sys import markdown from web.net import websafe sys.path.insert(0, "..") ALL_MODULES = [ "web.application", "web.contrib.template", "web.db", "web.debugerror", "web.form", "web.http", "web.httpserver", "web.net", "web.session", "web.template", "web.utils", "web.webapi", "web.wsgi", ] item_start = '' item_end = "" indent_amount = 30 doc_these = ( # These are the types of object that should be docced "module", "classobj", "instancemethod", "function", "type", "property", ) not_these_names = ( # Any particular object names that shouldn't be doced "fget", "fset", "fdel", "storage", # These stop the lower case versions getting docced "memoize", "iterbetter", "capturesstdout", "profile", "threadeddict", "d", # Don't know what this is, but only only conclude it shouldn't be doc'd ) css = """ """ indent_start = '

' indent_end = "
" header = """ """ def type_string(ob): return str(type(ob)).split("'")[1] def ts_css(text): """applies nice css to the type string""" return '%s' % text def arg_string(func): """Returns a nice argstring for a function or method""" return inspect.formatargspec(*inspect.getargspec(func)) def recurse_over(ob, name, indent_level=0): ts = type_string(ob) if ts not in doc_these: return # stos what shouldn't be docced getting docced if indent_level > 0 and ts == "module": return # Stops it getting into the stdlib if name in not_these_names: return # Stops things we don't want getting docced indent = indent_level * indent_amount # Indents nicely ds_indent = indent + (indent_amount / 2) if indent_level > 0: print(indent_start % indent) argstr = "" if ts.endswith(("function", "method")): argstr = arg_string(ob) elif ts in {"classobj", "type"}: if ts == "classobj": ts = "class" if hasattr(ob, "__init__"): if type_string(ob.__init__) == "instancemethod": argstr = arg_string(ob.__init__) else: argstr = "(self)" if ts == "instancemethod": ts = "method" # looks much nicer ds = inspect.getdoc(ob) if ds is None: ds = "" ds = markdown.Markdown(ds) mlink = '' % name if ts == "module" else "" mend = "" if ts == "module" else "" print( "".join( ( "

", ts_css(ts), item_start % ts, " ", mlink, name, websafe(argstr), mend, item_end, "
", ) ) ) print("".join((indent_start % ds_indent, ds, indent_end, "

"))) # Although ''.join looks weird, it's a lot faster is string addition members = "" if hasattr(ob, "__all__"): members = ob.__all__ else: members = [item for item in dir(ob) if not item.startswith("_")] if "im_class" not in members: for name in members: recurse_over(getattr(ob, name), name, indent_level + 1) if indent_level > 0: print(indent_end) def main(modules=None): modules = modules or ALL_MODULES print("
") # Stops markdown vandalising my html. print(css) print(header) print("") for name in modules: try: mod = __import__(name, {}, {}, "x") recurse_over(mod, name) except ImportError as e: print(f"Unable to import module {name} (Error: {e})", file=sys.stderr) pass print("
") if __name__ == "__main__": main(sys.argv[1:])