Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

75 lines
1.8 KiB
Python

#
# Generates the dynamic parts of the ZeekControl documentation.
#
import inspect
def api(*deco_args):
if len(deco_args) == 1 and callable(deco_args[0]):
# No argument to decorator.
method = deco_args[0]
method._doc = ""
return method
else:
# Tag argument.
def _api(method):
method._doc = deco_args[0]
return method
return _api
def print_indented(text, level):
out = ""
if not isinstance(text, list):
text = text.splitlines()
for line in text:
if line:
out += "{} {}\n".format(" " * level, line)
else:
out += "\n"
out += "\n"
return out
# Prints API documentation for a class. Includes all methods tagged with
# @api(tag). (Use an unknown tag to not exclude all methods.) If header is
# False, the class's name and doc string is not included.
def print_class(cls, tag="", header=True):
out = ""
methods = {}
for key, val in cls.__dict__.items():
if not inspect.isfunction(val):
continue
if not "_doc" in val.__dict__:
continue
if val.__dict__["_doc"] == tag:
methods[key] = val
if header:
out += f".. _{cls.__name__}:\n\n"
out += f"Class ``{cls.__name__}``\n"
out += "~~~~~~~~%s~~" % ("~" * len(cls.__name__))
out += "\n\n"
out += f"class **{cls.__name__}**\n"
out += print_indented(inspect.getdoc(cls), 1)
for name in sorted(methods.keys()):
func = methods[name]
spec = inspect.getfullargspec(func)
out += print_indented(f".. _{cls.__name__}.{name}:", 1)
out += print_indented("**{}** ({})".format(name, ", ".join(spec.args)), 1)
out += print_indented(inspect.getdoc(func), 2)
return out