X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=modules%2Flibjuju%2Fdocs%2F_extensions%2Fautomembersummary.py;fp=modules%2Flibjuju%2Fdocs%2F_extensions%2Fautomembersummary.py;h=cfe0b84b857c51ce323f846f6e6dc70075667524;hb=e2051cca7dac12aa09f6ed33555dcc4548c4b52b;hp=0000000000000000000000000000000000000000;hpb=9d18c22a0dc9e295adda50601fc5e2f45d2c9b8a;p=osm%2FN2VC.git diff --git a/modules/libjuju/docs/_extensions/automembersummary.py b/modules/libjuju/docs/_extensions/automembersummary.py new file mode 100644 index 0000000..cfe0b84 --- /dev/null +++ b/modules/libjuju/docs/_extensions/automembersummary.py @@ -0,0 +1,112 @@ +# Copyright 2014-2015 Canonical Limited. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +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)