diff --git a/cliff/sphinxext.py b/cliff/sphinxext.py index 89f41c03..7312b428 100644 --- a/cliff/sphinxext.py +++ b/cliff/sphinxext.py @@ -35,6 +35,17 @@ def _indent(text): return ''.join(prefixed_lines()) +def _format_description(parser): + """Get parser description. + + We parse this as reStructuredText, allowing users to embed rich + information in their help messages if they so choose. + """ + for line in statemachine.string2lines( + parser.description, tab_width=4, convert_whitespace=True): + yield line + + def _format_usage(parser): """Get usage without a prefix.""" fmt = argparse.HelpFormatter(parser.prog) @@ -64,6 +75,17 @@ def _format_usage(parser): return [parser.prog] + [_indent(x) for x in parts] +def _format_epilog(parser): + """Get parser epilog. + + We parse this as reStructuredText, allowing users to embed rich + information in their help messages if they so choose. + """ + for line in statemachine.string2lines( + parser.epilog, tab_width=4, convert_whitespace=True): + yield line + + def _format_positional_action(action): """Format a positional action.""" if action.help == argparse.SUPPRESS: @@ -109,13 +131,17 @@ def _format_parser(parser): Given the following parser:: >>> import argparse - >>> parser = argparse.ArgumentParser(prog='hello-world') + >>> parser = argparse.ArgumentParser(prog='hello-world', \ + description='This is my description.', + epilog='This is my epilog') >>> parser.add_argument('name', help='User name', metavar='') >>> parser.add_argument('--language', action='store', dest='lang', \ help='Greeting language') Returns the following:: + This is my description. + .. program:: hello-world .. code:: shell @@ -132,7 +158,14 @@ def _format_parser(parser): .. option:: -h, --help Show this help message and exit + + This is my epilog. """ + if parser.description: + for line in _format_description(parser): + yield line + yield '' + yield '.. program:: {}'.format(parser.prog) yield '.. code-block:: shell' @@ -156,6 +189,11 @@ def _format_parser(parser): yield line yield '' + if parser.epilog: + for line in _format_epilog(parser): + yield line + yield '' + class AutoprogramCliffDirective(rst.Directive): """Auto-document a subclass of `cliff.command.Command`.""" @@ -199,8 +237,6 @@ class AutoprogramCliffDirective(rst.Directive): """ command = command_class(None, None) parser = command.get_parser(command_name) - description = command.get_description() - epilog = command.get_epilog() ignored_opts = ignored_opts or [] # Drop the automatically-added help action @@ -210,10 +246,6 @@ class AutoprogramCliffDirective(rst.Directive): del parser._actions[parser._actions.index(action)] break - # Title - - # We build this with plain old docutils nodes - section = nodes.section( '', nodes.title(text=title), @@ -223,38 +255,11 @@ class AutoprogramCliffDirective(rst.Directive): source_name = '<{}>'.format(command.__class__.__name__) result = statemachine.ViewList() - # Description - - # We parse this as reStructuredText, allowing users to embed rich - # information in their help messages if they so choose. - - if description: - for line in statemachine.string2lines( - description, tab_width=4, convert_whitespace=True): - result.append(line, source_name) - - result.append('', source_name) - - # Summary - - # We both build and parse this as reStructuredText - for line in _format_parser(parser): result.append(line, source_name) self.state.nested_parse(result, 0, section) - # Epilog - - # Like description, this is parsed as reStructuredText - - if epilog: - result.append('', source_name) - - for line in statemachine.string2lines( - epilog, tab_width=4, convert_whitespace=True): - result.append(line, source_name) - return [section] def run(self): diff --git a/cliff/tests/test_sphinxext.py b/cliff/tests/test_sphinxext.py index f9f0de06..288149b5 100644 --- a/cliff/tests/test_sphinxext.py +++ b/cliff/tests/test_sphinxext.py @@ -62,6 +62,30 @@ class TestSphinxExtension(base.TestBase): user name """).lstrip(), output) + def test_description_epilog(self): + """Handle a parser description, epilog.""" + parser = argparse.ArgumentParser(prog='hello-world', add_help=False, + description='A "Hello, World" app.', + epilog='What am I doing down here?') + parser.add_argument('name', action='store') + parser.add_argument('--language', dest='lang') + + output = '\n'.join(sphinxext._format_parser(parser)) + self.assertEqual(textwrap.dedent(""" + A "Hello, World" app. + + .. program:: hello-world + .. code-block:: shell + + hello-world [--language LANG] name + + .. option:: --language + + .. option:: name + + What am I doing down here? + """).lstrip(), output) + def test_flag(self): """Handle a boolean argparse action.""" parser = argparse.ArgumentParser(prog='hello-world', add_help=False)