sphinx-autodoc-argparse 0.0.1a8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sphinx_autodoc_argparse-0.0.1a8/.gitignore +228 -0
- sphinx_autodoc_argparse-0.0.1a8/PKG-INFO +63 -0
- sphinx_autodoc_argparse-0.0.1a8/README.md +33 -0
- sphinx_autodoc_argparse-0.0.1a8/pyproject.toml +44 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/__init__.py +137 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/cli_usage_lexer.py +120 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/compat.py +292 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/directive.py +244 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/domain.py +419 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/exemplar.py +1373 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/highlight.css +437 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/lexer.py +434 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/nodes.py +626 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/parser.py +658 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/py.typed +0 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/renderer.py +832 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/roles.py +382 -0
- sphinx_autodoc_argparse-0.0.1a8/src/sphinx_autodoc_argparse/utils.py +78 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
#uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
#poetry.lock
|
|
109
|
+
#poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
#pdm.lock
|
|
116
|
+
#pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
#pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# SageMath parsed files
|
|
135
|
+
*.sage.py
|
|
136
|
+
|
|
137
|
+
# Environments
|
|
138
|
+
.env
|
|
139
|
+
.envrc
|
|
140
|
+
.venv
|
|
141
|
+
env/
|
|
142
|
+
venv/
|
|
143
|
+
ENV/
|
|
144
|
+
env.bak/
|
|
145
|
+
venv.bak/
|
|
146
|
+
|
|
147
|
+
# Spyder project settings
|
|
148
|
+
.spyderproject
|
|
149
|
+
.spyproject
|
|
150
|
+
|
|
151
|
+
# Rope project settings
|
|
152
|
+
.ropeproject
|
|
153
|
+
|
|
154
|
+
# mkdocs documentation
|
|
155
|
+
/site
|
|
156
|
+
|
|
157
|
+
# mypy
|
|
158
|
+
.mypy_cache/
|
|
159
|
+
.dmypy.json
|
|
160
|
+
dmypy.json
|
|
161
|
+
|
|
162
|
+
# Pyre type checker
|
|
163
|
+
.pyre/
|
|
164
|
+
|
|
165
|
+
# pytype static type analyzer
|
|
166
|
+
.pytype/
|
|
167
|
+
|
|
168
|
+
# Cython debug symbols
|
|
169
|
+
cython_debug/
|
|
170
|
+
|
|
171
|
+
# PyCharm
|
|
172
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
173
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
174
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
175
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
176
|
+
#.idea/
|
|
177
|
+
|
|
178
|
+
# Abstra
|
|
179
|
+
# Abstra is an AI-powered process automation framework.
|
|
180
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
181
|
+
# Learn more at https://abstra.io/docs
|
|
182
|
+
.abstra/
|
|
183
|
+
|
|
184
|
+
# Visual Studio Code
|
|
185
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
186
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
188
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
189
|
+
# .vscode/
|
|
190
|
+
|
|
191
|
+
# Ruff stuff:
|
|
192
|
+
.ruff_cache/
|
|
193
|
+
|
|
194
|
+
# PyPI configuration file
|
|
195
|
+
.pypirc
|
|
196
|
+
|
|
197
|
+
# Cursor
|
|
198
|
+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
|
199
|
+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
|
200
|
+
# refer to https://docs.cursor.com/context/ignore-files
|
|
201
|
+
.cursorignore
|
|
202
|
+
.cursorindexingignore
|
|
203
|
+
|
|
204
|
+
# Marimo
|
|
205
|
+
marimo/_static/
|
|
206
|
+
marimo/_lsp/
|
|
207
|
+
__marimo__/
|
|
208
|
+
|
|
209
|
+
# Generated by sphinx_fonts extension (downloaded at build time)
|
|
210
|
+
docs/_static/fonts/
|
|
211
|
+
docs/_static/css/fonts.css
|
|
212
|
+
|
|
213
|
+
# Claude Code
|
|
214
|
+
**/CLAUDE.local.md
|
|
215
|
+
**/CLAUDE.*.md
|
|
216
|
+
**/.claude/settings.local.json
|
|
217
|
+
|
|
218
|
+
# Playwright MCP
|
|
219
|
+
.playwright-mcp/
|
|
220
|
+
|
|
221
|
+
# Repo-local pytest mirror (do not track — validator-only)
|
|
222
|
+
out/
|
|
223
|
+
|
|
224
|
+
# Misc
|
|
225
|
+
.vim/
|
|
226
|
+
*.lprof
|
|
227
|
+
pip-wheel-metadata/
|
|
228
|
+
monkeytype.sqlite3
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sphinx-autodoc-argparse
|
|
3
|
+
Version: 0.0.1a8
|
|
4
|
+
Summary: Modern Sphinx extension for documenting argparse-based CLI tools
|
|
5
|
+
Project-URL: Repository, https://github.com/git-pull/gp-sphinx
|
|
6
|
+
Author-email: Tony Narlock <tony@git-pull.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: argparse,cli,documentation,sphinx
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Framework :: Sphinx
|
|
11
|
+
Classifier: Framework :: Sphinx :: Domain
|
|
12
|
+
Classifier: Framework :: Sphinx :: Extension
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Documentation
|
|
22
|
+
Classifier: Topic :: Documentation :: Sphinx
|
|
23
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: <4.0,>=3.10
|
|
26
|
+
Requires-Dist: docutils
|
|
27
|
+
Requires-Dist: pygments
|
|
28
|
+
Requires-Dist: sphinx>=8.1
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# sphinx-autodoc-argparse
|
|
32
|
+
|
|
33
|
+
Modern Sphinx extension for documenting argparse-based CLI tools.
|
|
34
|
+
|
|
35
|
+
A modernized replacement for `sphinx-argparse` that:
|
|
36
|
+
- Works with Sphinx 8.x and 9.x (no `autodoc.mock` dependency)
|
|
37
|
+
- Fixes long-standing issues (TOC pollution, heading levels)
|
|
38
|
+
- Provides configurable output (rubrics vs sections, flattened subcommands)
|
|
39
|
+
- Includes Pygments lexers for argparse help output and CLI usage blocks
|
|
40
|
+
- Supports extensibility via renderer classes
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
```console
|
|
45
|
+
$ pip install sphinx-autodoc-argparse
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Usage
|
|
49
|
+
|
|
50
|
+
In your `docs/conf.py`:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
extensions = ["sphinx_autodoc_argparse"]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then use the `.. argparse::` directive:
|
|
57
|
+
|
|
58
|
+
```rst
|
|
59
|
+
.. argparse::
|
|
60
|
+
:module: myapp.cli
|
|
61
|
+
:func: create_parser
|
|
62
|
+
:prog: myapp
|
|
63
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# sphinx-autodoc-argparse
|
|
2
|
+
|
|
3
|
+
Modern Sphinx extension for documenting argparse-based CLI tools.
|
|
4
|
+
|
|
5
|
+
A modernized replacement for `sphinx-argparse` that:
|
|
6
|
+
- Works with Sphinx 8.x and 9.x (no `autodoc.mock` dependency)
|
|
7
|
+
- Fixes long-standing issues (TOC pollution, heading levels)
|
|
8
|
+
- Provides configurable output (rubrics vs sections, flattened subcommands)
|
|
9
|
+
- Includes Pygments lexers for argparse help output and CLI usage blocks
|
|
10
|
+
- Supports extensibility via renderer classes
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```console
|
|
15
|
+
$ pip install sphinx-autodoc-argparse
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
In your `docs/conf.py`:
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
extensions = ["sphinx_autodoc_argparse"]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Then use the `.. argparse::` directive:
|
|
27
|
+
|
|
28
|
+
```rst
|
|
29
|
+
.. argparse::
|
|
30
|
+
:module: myapp.cli
|
|
31
|
+
:func: create_parser
|
|
32
|
+
:prog: myapp
|
|
33
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "sphinx-autodoc-argparse"
|
|
3
|
+
version = "0.0.1a8"
|
|
4
|
+
description = "Modern Sphinx extension for documenting argparse-based CLI tools"
|
|
5
|
+
requires-python = ">=3.10,<4.0"
|
|
6
|
+
authors = [
|
|
7
|
+
{name = "Tony Narlock", email = "tony@git-pull.com"}
|
|
8
|
+
]
|
|
9
|
+
license = { text = "MIT" }
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 3 - Alpha",
|
|
12
|
+
"License :: OSI Approved :: MIT License",
|
|
13
|
+
"Framework :: Sphinx",
|
|
14
|
+
"Framework :: Sphinx :: Domain",
|
|
15
|
+
"Framework :: Sphinx :: Extension",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
|
+
"Topic :: Documentation",
|
|
24
|
+
"Topic :: Documentation :: Sphinx",
|
|
25
|
+
"Topic :: Software Development :: Documentation",
|
|
26
|
+
"Typing :: Typed",
|
|
27
|
+
]
|
|
28
|
+
readme = "README.md"
|
|
29
|
+
keywords = ["sphinx", "argparse", "cli", "documentation"]
|
|
30
|
+
dependencies = [
|
|
31
|
+
"sphinx>=8.1",
|
|
32
|
+
"pygments",
|
|
33
|
+
"docutils",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
Repository = "https://github.com/git-pull/gp-sphinx"
|
|
38
|
+
|
|
39
|
+
[build-system]
|
|
40
|
+
requires = ["hatchling"]
|
|
41
|
+
build-backend = "hatchling.build"
|
|
42
|
+
|
|
43
|
+
[tool.hatch.build.targets.wheel]
|
|
44
|
+
packages = ["src/sphinx_autodoc_argparse"]
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""sphinx_autodoc_argparse - Modern sphinx-argparse replacement.
|
|
2
|
+
|
|
3
|
+
A Sphinx extension for documenting argparse-based CLI tools that:
|
|
4
|
+
- Works with Sphinx 8.x AND 9.x (no autodoc.mock dependency)
|
|
5
|
+
- Fixes long-standing sphinx-argparse issues (TOC pollution, heading levels)
|
|
6
|
+
- Provides configurable output (rubrics vs sections, flattened subcommands)
|
|
7
|
+
- Supports extensibility via renderer classes
|
|
8
|
+
- Text processing utilities (ANSI stripping)
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import typing as t
|
|
14
|
+
|
|
15
|
+
from sphinx_autodoc_argparse.directive import ArgparseDirective
|
|
16
|
+
from sphinx_autodoc_argparse.domain import ArgparseDomain
|
|
17
|
+
from sphinx_autodoc_argparse.nodes import (
|
|
18
|
+
argparse_argument,
|
|
19
|
+
argparse_group,
|
|
20
|
+
argparse_program,
|
|
21
|
+
argparse_subcommand,
|
|
22
|
+
argparse_subcommands,
|
|
23
|
+
argparse_usage,
|
|
24
|
+
depart_argparse_argument_html,
|
|
25
|
+
depart_argparse_group_html,
|
|
26
|
+
depart_argparse_program_html,
|
|
27
|
+
depart_argparse_subcommand_html,
|
|
28
|
+
depart_argparse_subcommands_html,
|
|
29
|
+
depart_argparse_usage_html,
|
|
30
|
+
visit_argparse_argument_html,
|
|
31
|
+
visit_argparse_group_html,
|
|
32
|
+
visit_argparse_program_html,
|
|
33
|
+
visit_argparse_subcommand_html,
|
|
34
|
+
visit_argparse_subcommands_html,
|
|
35
|
+
visit_argparse_usage_html,
|
|
36
|
+
)
|
|
37
|
+
from sphinx_autodoc_argparse.utils import strip_ansi
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
"ArgparseDirective",
|
|
41
|
+
"strip_ansi",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
if t.TYPE_CHECKING:
|
|
45
|
+
from sphinx.application import Sphinx
|
|
46
|
+
|
|
47
|
+
__version__ = "0.0.1a8"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class SetupDict(t.TypedDict):
|
|
51
|
+
"""Return type for Sphinx extension setup()."""
|
|
52
|
+
|
|
53
|
+
version: str
|
|
54
|
+
parallel_read_safe: bool
|
|
55
|
+
parallel_write_safe: bool
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def setup(app: Sphinx) -> SetupDict:
|
|
59
|
+
"""Register the argparse directive and configuration options.
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
app : Sphinx
|
|
64
|
+
The Sphinx application object.
|
|
65
|
+
|
|
66
|
+
Returns
|
|
67
|
+
-------
|
|
68
|
+
SetupDict
|
|
69
|
+
Extension metadata.
|
|
70
|
+
"""
|
|
71
|
+
# Configuration options
|
|
72
|
+
app.add_config_value(
|
|
73
|
+
"argparse_group_title_prefix",
|
|
74
|
+
"",
|
|
75
|
+
"html",
|
|
76
|
+
description="Prefix for argument group titles",
|
|
77
|
+
)
|
|
78
|
+
app.add_config_value(
|
|
79
|
+
"argparse_show_defaults",
|
|
80
|
+
True,
|
|
81
|
+
"html",
|
|
82
|
+
description="Show default values in argument docs",
|
|
83
|
+
)
|
|
84
|
+
app.add_config_value(
|
|
85
|
+
"argparse_show_choices",
|
|
86
|
+
True,
|
|
87
|
+
"html",
|
|
88
|
+
description="Show choice constraints",
|
|
89
|
+
)
|
|
90
|
+
app.add_config_value(
|
|
91
|
+
"argparse_show_types",
|
|
92
|
+
True,
|
|
93
|
+
"html",
|
|
94
|
+
description="Show type information",
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Register custom nodes
|
|
98
|
+
app.add_node(
|
|
99
|
+
argparse_program,
|
|
100
|
+
html=(visit_argparse_program_html, depart_argparse_program_html),
|
|
101
|
+
)
|
|
102
|
+
app.add_node(
|
|
103
|
+
argparse_usage,
|
|
104
|
+
html=(visit_argparse_usage_html, depart_argparse_usage_html),
|
|
105
|
+
)
|
|
106
|
+
app.add_node(
|
|
107
|
+
argparse_group,
|
|
108
|
+
html=(visit_argparse_group_html, depart_argparse_group_html),
|
|
109
|
+
)
|
|
110
|
+
app.add_node(
|
|
111
|
+
argparse_argument,
|
|
112
|
+
html=(visit_argparse_argument_html, depart_argparse_argument_html),
|
|
113
|
+
)
|
|
114
|
+
app.add_node(
|
|
115
|
+
argparse_subcommands,
|
|
116
|
+
html=(visit_argparse_subcommands_html, depart_argparse_subcommands_html),
|
|
117
|
+
)
|
|
118
|
+
app.add_node(
|
|
119
|
+
argparse_subcommand,
|
|
120
|
+
html=(visit_argparse_subcommand_html, depart_argparse_subcommand_html),
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# Register the argparse domain so :argparse:program: / :argparse:option: /
|
|
124
|
+
# :argparse:subcommand: / :argparse:positional: xrefs resolve and the two
|
|
125
|
+
# auto-generated indices (argparse-programsindex, argparse-optionsindex)
|
|
126
|
+
# are available. The renderer populates this domain via note_* helpers
|
|
127
|
+
# in parallel with the existing std:cmdoption emission.
|
|
128
|
+
app.add_domain(ArgparseDomain)
|
|
129
|
+
|
|
130
|
+
# Register directive
|
|
131
|
+
app.add_directive("argparse", ArgparseDirective)
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
"version": __version__,
|
|
135
|
+
"parallel_read_safe": True,
|
|
136
|
+
"parallel_write_safe": True,
|
|
137
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"""Pygments lexer for CLI usage/help output.
|
|
2
|
+
|
|
3
|
+
This module provides a custom Pygments lexer for highlighting command-line
|
|
4
|
+
usage text typically generated by argparse, getopt, or similar libraries.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import typing as t
|
|
10
|
+
|
|
11
|
+
from pygments.lexer import RegexLexer, bygroups as _bygroups, include
|
|
12
|
+
from pygments.token import Generic, Name, Operator, Punctuation, Text, Whitespace
|
|
13
|
+
|
|
14
|
+
# Wrapper to silence mypy [no-untyped-call] - bygroups is untyped in types-pygments
|
|
15
|
+
bygroups: t.Callable[..., t.Any] = _bygroups
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CLIUsageLexer(RegexLexer):
|
|
19
|
+
"""Lexer for CLI usage/help text (argparse, etc.).
|
|
20
|
+
|
|
21
|
+
Highlights usage patterns including options, arguments, and meta-variables.
|
|
22
|
+
|
|
23
|
+
Examples
|
|
24
|
+
--------
|
|
25
|
+
>>> from pygments.token import Token
|
|
26
|
+
>>> lexer = CLIUsageLexer()
|
|
27
|
+
>>> tokens = list(lexer.get_tokens("usage: cmd [-h]"))
|
|
28
|
+
>>> tokens[0]
|
|
29
|
+
(Token.Generic.Heading, 'usage:')
|
|
30
|
+
>>> tokens[2]
|
|
31
|
+
(Token.Name.Label, 'cmd')
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
name = "CLI Usage"
|
|
35
|
+
aliases = ["cli-usage", "usage"] # noqa: RUF012
|
|
36
|
+
filenames: t.ClassVar[list[str]] = []
|
|
37
|
+
mimetypes = ["text/x-cli-usage"] # noqa: RUF012
|
|
38
|
+
|
|
39
|
+
tokens = { # noqa: RUF012
|
|
40
|
+
"root": [
|
|
41
|
+
# "usage:" at start of line
|
|
42
|
+
(r"^(usage:)(\s+)", bygroups(Generic.Heading, Whitespace)),
|
|
43
|
+
# Continuation lines (leading whitespace for wrapped usage)
|
|
44
|
+
(r"^(\s+)(?=\S)", Whitespace),
|
|
45
|
+
include("inline"),
|
|
46
|
+
],
|
|
47
|
+
"inline": [
|
|
48
|
+
# Whitespace
|
|
49
|
+
(r"\s+", Whitespace),
|
|
50
|
+
# Long options with = value (e.g., --log-level=VALUE)
|
|
51
|
+
(
|
|
52
|
+
r"(--[a-zA-Z0-9][-a-zA-Z0-9]*)(=)([A-Z][A-Z0-9_]*|[a-z][-a-z0-9]*)",
|
|
53
|
+
bygroups(Name.Tag, Operator, Name.Variable),
|
|
54
|
+
),
|
|
55
|
+
# Long options standalone
|
|
56
|
+
(r"--[a-zA-Z0-9][-a-zA-Z0-9]*", Name.Tag),
|
|
57
|
+
# Short options with space-separated value (e.g., -S socket-path)
|
|
58
|
+
(
|
|
59
|
+
r"(-[a-zA-Z0-9])(\s+)([A-Z][A-Z0-9_]*|[a-z][-a-z0-9]*)",
|
|
60
|
+
bygroups(Name.Attribute, Whitespace, Name.Variable),
|
|
61
|
+
),
|
|
62
|
+
# Short options standalone
|
|
63
|
+
(r"-[a-zA-Z0-9]", Name.Attribute),
|
|
64
|
+
# UPPERCASE meta-variables (COMMAND, FILE, PATH)
|
|
65
|
+
(r"\b[A-Z][A-Z0-9_]+\b", Name.Constant),
|
|
66
|
+
# Opening bracket - enter optional state
|
|
67
|
+
(r"\[", Punctuation, "optional"),
|
|
68
|
+
# Closing bracket (fallback for unmatched)
|
|
69
|
+
(r"\]", Punctuation),
|
|
70
|
+
# Choice separator (pipe)
|
|
71
|
+
(r"\|", Operator),
|
|
72
|
+
# Parentheses for grouping
|
|
73
|
+
(r"[()]", Punctuation),
|
|
74
|
+
# Positional/command names (lowercase with dashes)
|
|
75
|
+
(r"\b[a-z][-a-z0-9]*\b", Name.Label),
|
|
76
|
+
# Catch-all for any other text
|
|
77
|
+
(r"[^\s\[\]|()]+", Text),
|
|
78
|
+
],
|
|
79
|
+
"optional": [
|
|
80
|
+
# Nested optional bracket
|
|
81
|
+
(r"\[", Punctuation, "#push"),
|
|
82
|
+
# End optional
|
|
83
|
+
(r"\]", Punctuation, "#pop"),
|
|
84
|
+
# Contents use inline rules
|
|
85
|
+
include("inline"),
|
|
86
|
+
],
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def tokenize_usage(text: str) -> list[tuple[str, str]]:
|
|
91
|
+
"""Tokenize usage text and return list of (token_type, value) tuples.
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
text : str
|
|
96
|
+
CLI usage text to tokenize.
|
|
97
|
+
|
|
98
|
+
Returns
|
|
99
|
+
-------
|
|
100
|
+
list[tuple[str, str]]
|
|
101
|
+
List of (token_type_name, text_value) tuples.
|
|
102
|
+
|
|
103
|
+
Examples
|
|
104
|
+
--------
|
|
105
|
+
>>> result = tokenize_usage("usage: cmd [-h]")
|
|
106
|
+
>>> result[0]
|
|
107
|
+
('Token.Generic.Heading', 'usage:')
|
|
108
|
+
>>> result[2]
|
|
109
|
+
('Token.Name.Label', 'cmd')
|
|
110
|
+
>>> result[4]
|
|
111
|
+
('Token.Punctuation', '[')
|
|
112
|
+
>>> result[5]
|
|
113
|
+
('Token.Name.Attribute', '-h')
|
|
114
|
+
>>> result[6]
|
|
115
|
+
('Token.Punctuation', ']')
|
|
116
|
+
"""
|
|
117
|
+
lexer = CLIUsageLexer()
|
|
118
|
+
return [
|
|
119
|
+
(str(tok_type), tok_value) for tok_type, tok_value in lexer.get_tokens(text)
|
|
120
|
+
]
|