X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FN2VC.git;a=blobdiff_plain;f=modules%2Flibjuju%2Fdocs%2F_extensions%2Fautomembersummary.py;fp=modules%2Flibjuju%2Fdocs%2F_extensions%2Fautomembersummary.py;h=898da626d8c07a7b637ceab5c2a199e6eb473c9b;hp=0000000000000000000000000000000000000000;hb=68858c1915122c2dbc8999a5cd3229694abf5f3a;hpb=032a71b2a6692b8b4e30f629a1f906d246f06736 diff --git a/modules/libjuju/docs/_extensions/automembersummary.py b/modules/libjuju/docs/_extensions/automembersummary.py new file mode 100644 index 0000000..898da62 --- /dev/null +++ b/modules/libjuju/docs/_extensions/automembersummary.py @@ -0,0 +1,114 @@ +# Copyright 2014-2015 Canonical Limited. +# +# This file is part of charm-helpers. +# +# charm-helpers is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 as +# published by the Free Software Foundation. +# +# charm-helpers is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with charm-helpers. If not, see . + + +import importlib +import inspect +import textwrap + +from docutils import nodes +from docutils.statemachine import ViewList +from sphinx.errors import SphinxError +from sphinx.util.compat import Directive +from sphinx.util.nodes import nested_parse_with_titles + + +class AutoMemberSummary(Directive): + required_arguments = 1 + + def run(self): + module_name = self.arguments[0] + + try: + module = importlib.import_module(module_name) + except ImportError: + raise SphinxError("Unable to generate reference docs for %s, " + "could not import" % (module_name)) + + divider = '+{:-<80}+'.format('') + row = '| {:<78} |'.format + lines = [] + for member_name, member in inspect.getmembers(module): + if not self._filter(module_name, member_name, member): + continue + summary = textwrap.wrap(self._get_summary(member), 78) or [''] + link = '`{} <#{}>`_'.format(member_name, + '.'.join([module_name, + member_name])) + methods = ['* `{} <#{}>`_'.format(n, + '.'.join([module_name, + member_name, + n])) + for n, m in inspect.getmembers(member) + if not n.startswith('_') and inspect.isfunction(m)] + + lines.append(divider) + lines.append(row(link)) + lines.append(divider) + for line in summary: + lines.append(row(line)) + if methods: + lines.append(row('')) + lines.append(row('Methods:')) + lines.append(row('')) + for i, method in enumerate(methods): + lines.append(row(method)) + lines.append(divider) + content = '\n'.join(lines) + + result = self._parse(content, '') + return result + + def _get_summary(self, member): + doc = (member.__doc__ or '').splitlines() + + # strip any leading blank lines + while doc and not doc[0].strip(): + doc.pop(0) + + # strip anything after the first blank line + for i, piece in enumerate(doc): + if not piece.strip(): + doc = doc[:i] + break + + return " ".join(doc).strip() + + def _filter(self, module_name, member_name, member): + if member_name.startswith('_'): + return False + if hasattr(member, '__module__'): + # skip imported classes & functions + return member.__module__.startswith(module_name) + elif hasattr(member, '__name__'): + # skip imported modules + return member.__name__.startswith(module_name) + else: + return False # skip instances + return True + + def _parse(self, rst_text, annotation): + result = ViewList() + for line in rst_text.split("\n"): + result.append(line, annotation) + node = nodes.paragraph() + node.document = self.state.document + nested_parse_with_titles(self.state, result, node) + return node.children + + +def setup(app): + app.add_directive('automembersummary', AutoMemberSummary)