Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor the extension to use a Sphinx Domain #34

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ repos:
language: system
entry: mypy
types: [python]
exclude: ^docs/
exclude: ^(docs|test/roots)/
28 changes: 28 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,34 @@
Change log
**********

0.5.0
#####

The following enhancements to the HTML output are described on the [Usage](https://sphinx-argparse.readthedocs.io/en/latest/usage.html) page.

* Optional command index.
* Optional ``:index-groups:`` field to the directive for an command-by-group index.
* A ``full_subcommand_name`` option to print fully-qualified sub-command headings.
This option helps when more than one sub-command offers a ``create`` or ``list`` or other
repeated sub-command.
* Each command heading is a domain-specific link target.
You can link to commands and sub-commands with the ``:ref:`` role, but this
release adds support for the domain-specific role like
``:commands:command:`sample-directive-opts A` ``.
The ``:commands:command:`` role supports linking from other projects through the
intersphinx extension.

Changes

* Previously, common headings such as **Positional Arguments** were subject to a
process that made them unique but adding a ``_repeatX`` suffix to the HREF target.
This release continues to support those HREF targets as secondary targets so that
bookmarks continue to work.
However, this release prefers using fully-qualified HREF targets like
``sample-directive-opts-positional-arguments`` as the primary HREF so that customers
are less likely to witness the ``_repeatX`` link in URLs.


0.4.0
#####

Expand Down
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.coverage',
'sphinx.ext.intersphinx',
'sphinx.ext.viewcode',
'sphinxarg.ext',
]
Expand Down
127 changes: 126 additions & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
===========
Basic usage
===========

Expand Down Expand Up @@ -67,6 +68,11 @@ working dir.

That's it. Directives will render positional arguments, options and sub-commands.

.. _about-subcommands:

About Sub-Commands
==================

Sub-commands are limited to one level. But, you can always output help for subcommands separately::

.. argparse::
Expand All @@ -87,7 +93,7 @@ Nesting level is unlimited::


Other useful directives
-----------------------
=======================

:nodefault: Do not show any default values.

Expand All @@ -100,3 +106,122 @@ Other useful directives
:nodescription: Do not parse the description, which can be useful if it contains text that could be incorrectly parse as reStructuredText.

:passparser: This can be used if you don't have a function that returns an argument parser, but rather adds commands to it (`:func:` is then that function).

:index-groups: This option is related to grouping related commands in an index.


Printing Fully Qualified Sub-Command Headings
=============================================

By default, when a command has sub-commands, such as ``fancytool install`` shown in the
:ref:`about-subcommands` section, the heading for the sub-command does not include the command name.
For instance, the the heading is **install** rather than **fancytool install**.

If you prefer to show the full command, **fancytool install**, then you can enable
the option in the ``conf.py`` for your project:

.. code-block:: python

sphinx_argparse_conf = {
"full_subcommand_name": True,
}


Indices
=======

The extension supports two types of optional indices.
The first type of index is a simple index that provides a list of all the commands in the project by fully qualified name and a link to each command.
The second type of index enables you to group related commands into groups and then provide a list of the commands and a link to each command.
By default, no index is created.

Simple Command Index
--------------------

To enable the simple command index, add the following to the project ``conf.py`` file:

.. code-block:: python

sphinx_argparse_conf = {
"build_commands_index": True,
"commands_index_in_toctree": True,
}

The first option, ``build_commands_index``, instructs the extension to create the index.
For an HTML build, the index is created with the file name ``commands-index.html`` in the output directory.
You can reference the index from other files with the ``:ref:`commands-index``` markup.

The second option, ``commands_index_in_toctree``, enables you to reference the the index in a ``toctree`` directive.
By default, you cannot reference indices generated by extensions in a ``toctree``.
When you enable this option, the extension creates a temporary file that is named ``commands-index.rst`` in the source directory of your project.
Sphinx locates the temporary file and that makes it possible to reference the file in the ``toctree``.
When the Sphinx build finishes, the extension removes the temporary file from the source directory.

Commands by Group Index
-----------------------

To enable the more complex index, add the following to the project ``conf.py`` file:

.. code-block:: python

sphinx_argparse_conf = {
"build_commands_by_group_index": True,
"commands_by_group_index_in_toctree": True,
}

Add the ``:index-groups:`` option to the ``argparse`` directive in your documentation files.
Specify one or more groups that the command belongs to (comma-separated).

.. code-block:: reStructuredText

.. argparse::
:filename: ../test/sample.py
:func: parser
:prog: sample
:index-groups: Basic Commands

For an HTML build, the index is created with the file name ``commands-by-group.html`` in the output directory.
You can cross reference the index from other files with the ``:ref:`commands-by-group``` role.

Like the simple index, the ``commands_by_group_index_in_toctree`` option enables you to reference the index in ``toctree`` directives.

This index has two more options.

.. code-block:: python

sphinx_argparse_conf = {
"commands_by_group_index_in_toctree": True,
"commands_by_group_index_file_suffix": "by-service",
"commands_by_group_index_title": "Commands by Service",
}

The ``commands_by_group_index_file_suffix`` option overrides the default index name of ``commands-by-group.html``.
The value ``commands-`` is concatenated with the value you specify.
In the preceding sample, the index file name is created as ``commands-by-service.html``.
If you specify this option, the default reference of ``:ref:`commands-by-group``` is overridden with the value that you create.

The ``commands_by_group_index_title`` option overides the default first-level heading for the file.
The default heading is "Commands by Group".
The value you specify replaces the default value.

Customizing the Indices
-----------------------

By default, indices are created with the ``domainindex.html`` template.
If you want to customize the appearance of an index, copy the default ``domainindex.html`` file for your theme to the ``_templates`` directory in your project and modify it.

If you want to customize both indices, but one template cannot accommodate both of them, you can create an additional index template, such as ``customindex.html``.
You can configure Sphinx to use the additional template for an index by modifying the ``conf.py`` for the project like the following example.

.. code-block:: python

def page_template(app: "Sphinx", pagename, templatename, context, doctree) -> str:
if pagename == "commands-by-group":
return "customindex.html"
else:
return templatename

def setup(app: "Sphinx"):
app.connect('html-page-context', page_template)

For more information, refer to the Sphinx documentation for :ref:`sphinx:templating` and the :doc:`sphinx:extdev/appapi`.
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ classifiers = [
]
dependencies = [
"sphinx>=4.0.0",
"CommonMark>=0.9.1",
]
dynamic = ["version"]


[project.optional-dependencies]
markdown = [
"CommonMark>=0.5.6"
Expand Down Expand Up @@ -98,6 +98,7 @@ multi_line_output = 3
[tool.mypy]
files = ["sphinxarg", "test"]
python_version = "3.10"
exclude = '''(?x)( ^test/roots | ^docs )'''

[[tool.mypy.overrides]]
module = [
Expand Down
Loading
Loading