diff --git a/.gitignore b/.gitignore index a5d525b..a60b090 100644 --- a/.gitignore +++ b/.gitignore @@ -65,3 +65,6 @@ ChangeLog # Intellij .idea + +# VSCode +.vscode diff --git a/releasenotes/notes/print-usage-c83518ec412eca7c.yaml b/releasenotes/notes/print-usage-c83518ec412eca7c.yaml new file mode 100644 index 0000000..df171aa --- /dev/null +++ b/releasenotes/notes/print-usage-c83518ec412eca7c.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Add a "Usage" label (rubric) before printing the command's usage format. diff --git a/sphinx_click/ext.py b/sphinx_click/ext.py index 0c4d804..92b15ff 100644 --- a/sphinx_click/ext.py +++ b/sphinx_click/ext.py @@ -358,15 +358,20 @@ def _format_command( # usage - for line in _format_usage(ctx): + lines = list(_format_usage(ctx)) + if lines: + # we use rubric to provide some separation without exploding the table + # of contents + yield '.. rubric:: Usage' + yield '' + + for line in lines: yield line # options lines = list(_format_options(ctx)) if lines: - # we use rubric to provide some separation without exploding the table - # of contents yield '.. rubric:: Options' yield '' diff --git a/tests/test_extension.py b/tests/test_extension.py index 4dfd12d..1377e31 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -20,8 +20,9 @@ def test_basics(make_app, rootdir): # section: # title: # paragraph: + # rubric: (Usage) # literal_block: - # rubric: + # rubric: (Commands) # index: # desc: # desc_signature: @@ -38,16 +39,18 @@ def test_basics(make_app, rootdir): assert section[0].astext() == 'greet' assert isinstance(section[1], nodes.paragraph) assert section[1].astext() == 'A sample command group.' - assert isinstance(section[2], nodes.literal_block) + assert isinstance(section[2], nodes.rubric) + assert section[2].astext() == 'Usage' + assert isinstance(section[3], nodes.literal_block) - assert isinstance(section[3], nodes.rubric) - assert section[3].astext() == 'Commands' - assert isinstance(section[4], sphinx_nodes.index) - assert isinstance(section[5], sphinx_nodes.desc) - assert section[5].astext() == 'hello\n\nGreet a user.' - assert isinstance(section[6], sphinx_nodes.index) - assert isinstance(section[7], sphinx_nodes.desc) - assert section[7].astext() == 'world\n\nGreet the world.' + assert isinstance(section[4], nodes.rubric) + assert section[4].astext() == 'Commands' + assert isinstance(section[5], sphinx_nodes.index) + assert isinstance(section[6], sphinx_nodes.desc) + assert section[6].astext() == 'hello\n\nGreet a user.' + assert isinstance(section[7], sphinx_nodes.index) + assert isinstance(section[8], sphinx_nodes.desc) + assert section[8].astext() == 'world\n\nGreet the world.' def test_commands(make_app, rootdir): @@ -66,8 +69,9 @@ def test_commands(make_app, rootdir): # section: # title: # paragraph: + # rubric: (Usage) # literal_block: - # rubric: + # rubric: (Commands) # index: # desc: # desc_signature: @@ -80,14 +84,16 @@ def test_commands(make_app, rootdir): assert section[0].astext() == 'greet' assert isinstance(section[1], nodes.paragraph) assert section[1].astext() == 'A sample command group.' - assert isinstance(section[2], nodes.literal_block) + assert isinstance(section[2], nodes.rubric) + assert section[2].astext() == 'Usage' + assert isinstance(section[3], nodes.literal_block) # we should only show a single command, 'world' - assert isinstance(section[3], nodes.rubric) - assert section[3].astext() == 'Commands' - assert isinstance(section[4], sphinx_nodes.index) - assert isinstance(section[5], sphinx_nodes.desc) - assert section[5].astext() == 'world\n\nGreet the world.' + assert isinstance(section[4], nodes.rubric) + assert section[4].astext() == 'Commands' + assert isinstance(section[5], sphinx_nodes.index) + assert isinstance(section[6], sphinx_nodes.desc) + assert section[6].astext() == 'world\n\nGreet the world.' def test_nested_full(make_app, rootdir): @@ -106,15 +112,18 @@ def test_nested_full(make_app, rootdir): # section: # title: # paragraph: + # rubric: (Usage) # literal_block: # section: # title # paragraph + # rubric: (Usage) # literal_block # ... # section: # title # paragraph + # rubric: (Usage) # literal_block section = content[0][1] @@ -124,23 +133,29 @@ def test_nested_full(make_app, rootdir): assert section[0].astext() == 'greet' assert isinstance(section[1], nodes.paragraph) assert section[1].astext() == 'A sample command group.' - assert isinstance(section[2], nodes.literal_block) + assert isinstance(section[2], nodes.rubric) + assert section[2].astext() == 'Usage' + assert isinstance(section[3], nodes.literal_block) - subsection_a = section[3] + subsection_a = section[4] assert isinstance(subsection_a, nodes.section) assert isinstance(subsection_a[0], nodes.title) assert subsection_a[0].astext() == 'hello' assert isinstance(subsection_a[1], nodes.paragraph) assert subsection_a[1].astext() == 'Greet a user.' - assert isinstance(subsection_a[2], nodes.literal_block) + assert isinstance(subsection_a[2], nodes.rubric) + assert subsection_a[2].astext() == 'Usage' + assert isinstance(subsection_a[3], nodes.literal_block) # we don't need to verify the rest of this: that's done elsewhere - subsection_b = section[4] + subsection_b = section[5] assert isinstance(subsection_b, nodes.section) assert isinstance(subsection_b[0], nodes.title) assert subsection_b[0].astext() == 'world' assert isinstance(subsection_b[1], nodes.paragraph) assert subsection_b[1].astext() == 'Greet the world.' - assert isinstance(subsection_b[2], nodes.literal_block) + assert isinstance(subsection_b[2], nodes.rubric) + assert subsection_b[2].astext() == 'Usage' + assert isinstance(subsection_b[3], nodes.literal_block) diff --git a/tests/test_formatter.py b/tests/test_formatter.py index a10ce0b..7a84e51 100644 --- a/tests/test_formatter.py +++ b/tests/test_formatter.py @@ -31,6 +31,8 @@ def foobar(): A sample command. .. program:: foobar + .. rubric:: Usage + .. code-block:: shell foobar [OPTIONS] @@ -79,6 +81,8 @@ def foobar(bar): A sample command. .. program:: foobar + .. rubric:: Usage + .. code-block:: shell foobar [OPTIONS] ARG @@ -152,6 +156,8 @@ def foobar(bar): A sample command. .. program:: foobar + .. rubric:: Usage + .. code-block:: shell foobar [OPTIONS] @@ -197,6 +203,8 @@ def foobar(bar): A sample command. .. program:: foobar + .. rubric:: Usage + .. code-block:: shell foobar [OPTIONS] ARG ARG_NO_HELP @@ -261,6 +269,8 @@ def foobar(bar): A sample command. .. program:: foobar + .. rubric:: Usage + .. code-block:: shell foobar [OPTIONS] @@ -313,6 +323,8 @@ def foobar(): A sample command. .. program:: foobar + .. rubric:: Usage + .. code-block:: shell foobar [OPTIONS] @@ -374,6 +386,8 @@ def hello(name): my_cli hello --name "Jack" .. program:: hello + .. rubric:: Usage + .. code-block:: shell hello [OPTIONS] @@ -428,6 +442,8 @@ def foobar(): dash of bold and even some underlined words. .. program:: foobar + .. rubric:: Usage + .. code-block:: shell foobar [OPTIONS] @@ -495,6 +511,8 @@ def cli(): :param click.core.Context ctx: Click context. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] @@ -564,6 +582,8 @@ def cli(): that will be rewrapped again. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] @@ -621,6 +641,8 @@ def cli(): A sample command group. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] COMMAND [ARGS]... @@ -652,6 +674,8 @@ def cli(): A sample command group. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] ARG COMMAND [ARGS]... @@ -724,6 +748,8 @@ def test_nested_short(self): A sample command group. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] COMMAND [ARGS]... @@ -753,6 +779,8 @@ def test_nested_full(self): A sample command group. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] COMMAND [ARGS]... @@ -776,6 +804,8 @@ def test_nested_none(self): A sample command group. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] COMMAND [ARGS]... @@ -818,6 +848,8 @@ def test_no_commands(self): A sample command group. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] COMMAND [ARGS]... @@ -840,6 +872,8 @@ def test_order_of_commands(self): A sample command group. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] COMMAND [ARGS]... @@ -902,6 +936,8 @@ def get_command(self, ctx, name): A sample custom multicommand. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] COMMAND [ARGS]... @@ -960,6 +996,8 @@ def get_command(self, ctx, name): A sample custom multicommand. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] COMMAND [ARGS]... @@ -1017,6 +1055,8 @@ def world(): A simple CommandCollection. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] COMMAND [ARGS]... @@ -1033,6 +1073,8 @@ def world(): A simple CommandCollection. .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS] COMMAND [ARGS]... @@ -1083,6 +1125,8 @@ def cli_with_auto_envvars(): A simple CLI with auto-env vars . .. program:: cli + .. rubric:: Usage + .. code-block:: shell cli [OPTIONS]