Skip to content

Commit

Permalink
Add option to show usage before description (#148)
Browse files Browse the repository at this point in the history
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
mayrholu and pre-commit-ci[bot] authored Feb 18, 2024
1 parent ddc99fa commit 2aa99ca
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 19 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Within the reStructuredText files use the `sphinx_argparse_cli` directive that t
| description | (optional) when provided, overwrites the description and when empty, will not be included |
| epilog | (optional) when provided, overwrites the epilog and when empty, will not be included |
| usage_width | (optional) how large should usage examples be - defaults to 100 character |
| usage_first | (optional) show usage before description |
| group_title_prefix | (optional) groups subsections title prefixes, accepts the string `{prog}` as a replacement for the program name - defaults to `{prog}` |
| group_sub_title_prefix | (optional) subcommands groups subsections title prefixes, accepts replacement of `{prog}` and `{subcommand}` for program and subcommand name - defaults to `{prog} {subcommand}` |
| no_default_values | (optional) suppresses generation of `default` entries |
Expand Down
49 changes: 30 additions & 19 deletions src/sphinx_argparse_cli/_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class SphinxArgparseCli(SphinxDirective):
"description": unchanged,
"epilog": unchanged,
"usage_width": positive_int,
"usage_first": flag,
"group_title_prefix": unchanged,
"group_sub_title_prefix": unchanged,
"no_default_values": unchanged,
Expand All @@ -89,6 +90,7 @@ def __init__( # noqa: PLR0913
super().__init__(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)
self._parser: ArgumentParser | None = None
self._std_domain: StandardDomain = cast(StandardDomain, self.env.get_domain("std"))
self._raw_format: bool = False

@property
def parser(self) -> ArgumentParser:
Expand All @@ -114,6 +116,8 @@ def parser(self) -> ArgumentParser:

if "prog" in self.options:
self._parser.prog = self.options["prog"]

self._raw_format = self._parser.formatter_class == RawDescriptionHelpFormatter
return self._parser

def load_sub_parsers(self) -> Iterator[tuple[list[str], str, ArgumentParser]]:
Expand Down Expand Up @@ -148,18 +152,16 @@ def run(self) -> list[Node]:
else:
home_section = section("", title("", Text(title_text)), ids=[make_id(title_text)], names=[title_text])

raw_format = self.parser.formatter_class == RawDescriptionHelpFormatter
if "usage_first" in self.options:
home_section += self._mk_usage(self.parser)

if description := self._pre_format(self.options.get("description", self.parser.description)):
home_section += description

if "usage_first" not in self.options:
home_section += self._mk_usage(self.parser)

description = self.options.get("description", self.parser.description)
if description:
if raw_format and "\n" in description:
lit = literal_block("", Text(description))
lit["language"] = "none"
home_section += lit
else:
home_section += paragraph("", Text(description))
# construct groups excluding sub-parsers
home_section += self._mk_usage(self.parser)
for group in self.parser._action_groups: # noqa: SLF001
if not group._group_actions or group is self.parser._subparsers: # noqa: SLF001
continue
Expand All @@ -168,17 +170,20 @@ def run(self) -> list[Node]:
for aliases, help_msg, parser in self.load_sub_parsers():
home_section += self._mk_sub_command(aliases, help_msg, parser)

epilog = self.options.get("epilog", self.parser.epilog)
if epilog:
if raw_format and "\n" in epilog:
lit = literal_block("", Text(epilog))
lit["language"] = "none"
home_section += lit
else:
home_section += paragraph("", Text(epilog))
if epilog := self._pre_format(self.options.get("epilog", self.parser.epilog)):
home_section += epilog

return [home_section]

def _pre_format(self, block: None | str) -> None | paragraph | literal_block:
if block is None:
return None
if self._raw_format and "\n" in block:
lit = literal_block("", Text(block))
lit["language"] = "none"
return lit
return paragraph("", Text(block))

def _mk_option_group(self, group: _ArgumentGroup, prefix: str) -> section:
sub_title_prefix: str = self.options["group_sub_title_prefix"]
title_prefix = self.options["group_title_prefix"]
Expand Down Expand Up @@ -313,11 +318,17 @@ def _mk_sub_command(self, aliases: list[str], help_msg: str, parser: ArgumentPar
group_section = section("", title("", Text(title_text)), ids=[ref_id], names=[title_ref])
self._register_ref(ref_id, title_ref, group_section)

if "usage_first" in self.options:
group_section += self._mk_usage(parser)

command_desc = (parser.description or help_msg or "").strip()
if command_desc:
desc_paragraph = paragraph("", Text(command_desc))
group_section += desc_paragraph
group_section += self._mk_usage(parser)

if "usage_first" not in self.options:
group_section += self._mk_usage(parser)

for group in parser._action_groups: # noqa: SLF001
if not group._group_actions: # do not show empty groups # noqa: SLF001
continue
Expand Down
7 changes: 7 additions & 0 deletions tests/test_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ def test_usage_width_custom(build_outcome: str) -> None:
assert "complex second [-h] [--flag] [--root]\n" in build_outcome


@pytest.mark.sphinx(buildername="text", testroot="complex")
@pytest.mark.prepare(directive_args=[":usage_first:"])
def test_set_usage_first(build_outcome: str) -> None:
assert "complex [-h]" in build_outcome.split("argparse tester")[0]
assert "complex first [-h]" in build_outcome.split("a-first-desc")[0]


@pytest.mark.sphinx(buildername="text", testroot="suppressed-action")
def test_suppressed_action(build_outcome: str) -> None:
assert "--activities-since" not in build_outcome
Expand Down

0 comments on commit 2aa99ca

Please sign in to comment.