click_extra.sphinx package¶
Helpers and utilities for Sphinx.
Note
The MkDocs counterpart lives in click_extra.mkdocs, which achieves the same
ANSI color rendering by patching pymdownx.highlight’s formatter classes.
- click_extra.sphinx.MYST_NATIVE_ALERTS_VERSION = <Version('5.1.0')>¶
First
myst-parserrelease that ships the native"alert"syntax extension.Below this version,
click_extra.sphinx.alertspatches GitHub alert syntax into MyST admonitions via asource-read/include-readhook. At or above this version, the converter is skipped atsetup()time and projects should add"alert"tomyst_enable_extensionsinstead.
- click_extra.sphinx.EXEC_DIRECTIVES_OPT_IN = 'click_extra_enable_exec_directives'¶
Name of the
conf.pyconfig flag that gates every code-execution directive.Default is
False. A project that addsclick_extra.sphinxto itsextensionslist gets the ANSI Pygments formatter unconditionally, plus the GitHub-alerts converter whenmyst-parseris belowMYST_NATIVE_ALERTS_VERSION(seealertsfor the deprecation rationale), but does not gain access to either theclick:*or thepython:*directive families until the maintainer opts in explicitly. Both familiesexecuser-supplied Python at build time with full Sphinx-process privileges; gating them behind a single explicit flag keeps a transitive import or a doc-only pull request from silently expanding the build’s attack surface.
- click_extra.sphinx.RUN_CAPTURE_CONFIG = 'click_extra_run_capture'¶
Name of the
conf.pyvalue selecting the stream-capture mode for the CLIs thatclick:runandclick:treeexecute.Maps to the
captureparameter of Click’sCliRunner,"sys"or"fd"(added in Click 8.4). Defaults to"fd"so a command writing throughsys.stdout.fileno()is captured at the file-descriptor level and renders, instead of aborting the build withio.UnsupportedOperation. Ignored on Click releases older than 8.4, which lack the parameter.
- click_extra.sphinx.setup(app)[source]¶
Register extensions to Sphinx.
Always-on features (no execution surface):
The ANSI-capable HTML formatter for Pygments (replaces
sphinx.highlighting.PygmentsBridgewith one that renders ANSI colors in code blocks).GitHub-flavored alert syntax (
> [!NOTE], etc.) in included and regular source files, converted to MyST/reST admonitions. Registered only when the installedmyst-parseris belowMYST_NATIVE_ALERTS_VERSION(5.1.0). On newer versions, the converter is skipped and a one-shot info message points users atmyst-parser’s native"alert"extension. Seeclick_extra.sphinx.alertsfor the deprecation plan.The
matrixdirective, which renders a package’s compatibility grid ({matrix} pythonor{matrix} <distribution>) from its git tag history. It runs a canned generator rather than user-supplied Python, so it carries no execution surface and needs no opt-in. Seeclick_extra.sphinx.matrix.
Opt-in features (gated behind
click_extra_enable_exec_directives):click:source/click:runto define and execute Click CLIs at build time.python:source/python:runto execute arbitrary Python at build time and render its source or capturedstdout.python:render/python:render-myst/python:render-rstto execute arbitrary Python and parse the capturedstdoutas live document content.
All directives in the opt-in group execute user-supplied Python with the same privileges as the Sphinx process. They are therefore disabled by default. Set
click_extra_enable_exec_directives = Trueinconf.pyto register them.Caution
This function forces the Sphinx app to use
sphinx.highlighting.PygmentsBridgeinstead of the default HTML formatter to add support for ANSI colors in code blocks.- Return type:
ExtensionMetadata
Submodules¶
click_extra.sphinx.alerts module¶
Utilities to convert GitHub alerts into MyST admonitions for Sphinx.
Deprecated since version 7.16.0: myst-parser 5.1+ ships a native "alert" syntax extension that
renders GitHub alerts as Sphinx admonitions, covering the same ground
as this regex-based converter. click_extra.sphinx.setup() only
wires the converter into Sphinx when the installed myst-parser
is below 5.1.0 (see
click_extra.sphinx.MYST_NATIVE_ALERTS_VERSION); on newer
releases the hook is skipped at setup time and a log message points
projects at myst-parser’s native extension, which they enable by
adding "alert" to myst_enable_extensions. I plan to remove
the module entirely once the myst-parser floor moves to
>=5.1.
See also
GitHub documentation for `alerts syntax
<https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts>`_. - Announcement for alert support starting 2023-12-14. - MyST-parser “alert” syntax extension added in version 5.1.0.
- click_extra.sphinx.alerts.GITHUB_ALERT_PATTERN = re.compile('^\\s*\\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\\]\\s*$')¶
Regex pattern to match GitHub alert type declaration (without leading >).
- click_extra.sphinx.alerts.QUOTE_PREFIX_PATTERN = re.compile('^(\\s*)((?:>\\s*)+)(.*)$')¶
Regex pattern to extract indent, quote markers, and content.
- click_extra.sphinx.alerts.CODE_FENCE_PATTERN = re.compile('^(\\s*)(`{3,}|~{3,})(.*)$')¶
Regex pattern to match code fence opening/closing lines.
- click_extra.sphinx.alerts.INDENTED_CODE_BLOCK_PATTERN = re.compile('^( {4}|\\t)')¶
Regex pattern to match indented code block lines (4 spaces or 1 tab).
- class click_extra.sphinx.alerts.Alert(alert_type, indent, depth, has_nested=False, opening_line_index=0)[source]¶
Bases:
objectRepresents a GitHub alert being processed.
- class click_extra.sphinx.alerts.FenceState(char, length, indent, is_code_block)[source]¶
Bases:
objectTracks code fence state.
- class click_extra.sphinx.alerts.ParserState(result=<factory>, alert_stack=<factory>, fence_stack=<factory>, prev_line_blank=True, modified=False, just_opened_fence_directive=False)[source]¶
Bases:
objectMutable state for the alert parser.
- fence_stack: list[FenceState]¶
- click_extra.sphinx.alerts.check_colon_fence(app: Sphinx) None[source]¶
Check that colon_fence support is enabled for MyST.
- Raises:
ConfigError – If
colon_fenceis not inmyst_enable_extensions.- Return type:
- click_extra.sphinx.alerts.count_quote_depth(line)[source]¶
Parse a line to extract indent, quote depth, and content.
- click_extra.sphinx.alerts.process_fence(state, indent, chars, after)[source]¶
Process a fence line, updating fence stack.
- Return type:
- click_extra.sphinx.alerts.close_alerts_to_depth(state, target_depth)[source]¶
Close all alerts deeper than target_depth.
When the alert has no body content (just the directive line, like a bare
> [!TIP]), inject a MyST comment placeholder before the closing fence. Sphinx silently drops admonitions with an empty body, but myst-parser 5.1+’s native"alert"extension renders a title-only admonition for that input. The MyST comment is consumed at parse time, so the rendered HTML matches the upstream output:<div class="admonition tip"><p class="admonition-title">Tip</p></div>.- Return type:
- click_extra.sphinx.alerts.mark_parent_nested(state)[source]¶
Mark the parent alert as having a nested alert and update its opening.
- Return type:
- click_extra.sphinx.alerts.open_alert(state, alert_type, indent, depth)[source]¶
Open a new alert at the given depth.
- Return type:
- click_extra.sphinx.alerts.process_quoted_line(state, line)[source]¶
Process a line that starts with quote markers.
Returns True if the line was handled as part of an alert.
- Return type:
click_extra.sphinx.click module¶
Sphinx rendering of CLI based on Click Extra.
See also
These directives are based on Pallets’ Sphinx Themes, released under a BSD-3-Clause license.
Compared to the latter, it:
Add support for MyST syntax.
Adds rendering of ANSI codes in CLI results.
Has better error handling and reporting which helps you pinpoint the failing code in your documentation.
Removes the
printlnfunction which was used to explicitly print a blank line. This is no longer needed as it is now handled natively.
- click_extra.sphinx.click.RST_INDENT = ' '¶
The indentation used for rST code blocks lines.
- class click_extra.sphinx.click.TerminatedEchoingStdin(input, output)[source]¶
Bases:
EchoingStdinLike
click.testing.EchoingStdinbut adds a visible^Din place of the EOT character ().ClickRunner.invoke()addswhenterminate_input=True.
- click_extra.sphinx.click.patch_subprocess()[source]¶
Patch subprocess to work better with
ClickRunner.invoke().subprocess.calloutput is redirected toclick.echoso it shows up in the example output.Caution
The replacement is installed on the
subprocessmodule itself (not thread-local), so for the duration of thewithblock any other code in the same process that callssubprocess.callsees the patched version. Withparallel_read_safe = Truedeclared onClickDomain, a parallel reader running concurrently on a different document gets the patchedsubprocess.calltoo. The redirection is benign (output goes toclick.echo) but the race is real, and the parallel-safe claim is weaker than it looks for documents that themselves shell out viasubprocess.call.
- class click_extra.sphinx.click.ClickRunner(capture=None)[source]¶
Bases:
CliRunnerA sub-class of
click.testing.CliRunnerfor Sphinx directive execution.Produces unfiltered ANSI codes so that the
Directivesub-classes below can render colors in the HTML output. Because Click Extra executes the documented command here,invoke()forces color across both color systems a CLI might use:color=Truecovers Click’s (should_strip_ansi), andforced_color()setsFORCE_COLORfor Rich’s (whichrich-clickuses andcolor=Truenever reaches). The MkDocs plugin shares the latter lever but cannot passcolor=True, since it patches a renderer it never executes.On Click 8.4+ the runner defaults to
capture="fd"on Unix (overridable through theclick_extra_run_captureconf.pyvalue) so a documented command that writes throughsys.stdout.fileno()is captured and rendered, instead of aborting the build withio.UnsupportedOperation. On Windows, where fd-backed streams are not supported, the default falls back tocapture="sys".- isolation(*args, **kwargs)[source]¶
A context manager that sets up the isolation for invoking of a command line tool. This sets up <stdin> with the given input data and os.environ with the overrides from the given dictionary. This also rebinds some internals in Click to be mocked (like the prompt functionality).
This is automatically done in the
invoke()method.- Parameters:
input – the input stream to put into sys.stdin.
env – the environment overrides as dictionary.
color – whether the output should contain color codes. The application can still override this explicitly.
Added in version 8.2: An additional output stream is returned, which is a mix of <stdout> and <stderr> streams.
Changed in version 8.2: Always returns the <stderr> stream.
Changed in version 8.0: <stderr> is opened with
errors="backslashreplace"instead of the default"strict".Changed in version 4.0: Added the
colorparameter.
- invoke(cli, args=None, prog_name=None, input=None, terminate_input=False, env=None, _output_lines=None, **extra)[source]¶
Like
CliRunner.invokebut displays what the user would enter in the terminal for env vars, command arguments, and prompts.- Parameters:
terminate_input – Whether to display
^Dafter a list of input._output_lines – A list used internally to collect lines to be displayed.
- Return type:
- execute_source(directive)[source]¶
Execute the given code, adding it to the runner’s namespace.
- Return type:
- run_cli(directive)[source]¶
Execute the given
source_code.Returns a simulation of terminal execution, including a mix of input, output, prompts and tracebacks.
The execution context is augmented, so you can refer directly to these functions in the provided
source_code:invoke(): which is the same asClickRunner.invoke()isolated_filesystem(): A context manager that changes to a temporary directory while executing the block.
If any local variable in the provided
source_codeconflicts with these functions, aRuntimeErroris raised to help you pinpoint the issue.
- class click_extra.sphinx.click.ClickDirective(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]¶
Bases:
SphinxDirective- has_content = True¶
May the directive have content?
- required_arguments = 0¶
Number of required directive arguments.
- optional_arguments = 1¶
The optional argument overrides the default Pygments language to use.
- final_argument_whitespace = False¶
May the final argument contain whitespace?
- option_spec: ClassVar[OptionSpec] = {'caption': <function unchanged_required>, 'class': <function class_option>, 'dedent': <function optional_int>, 'emphasize-lines': <function unchanged_required>, 'emphasize-result-lines': <function unchanged_required>, 'force': <function flag>, 'hide-results': <function flag>, 'hide-source': <function flag>, 'language': <function unchanged_required>, 'lineno-start': <class 'int'>, 'linenos': <function flag>, 'name': <function unchanged>, 'show-results': <function flag>, 'show-source': <function flag>}¶
Options supported by this directive.
Support the same options as
sphinx.directives.code.CodeBlock, and some specific to Click directives.The standard
emphasize-linesoption applies to the source block only. Useemphasize-result-linesto highlight specific lines in the captured output block, with the same syntax (like:emphasize-result-lines: 1,3-5).
- default_language: str¶
Default highlighting language to use to render the code block.
All Pygments’ languages short names are recognized.
- show_source_by_default: bool = True¶
Whether to render the source code of the example in the code block.
- show_results_by_default: bool = True¶
Whether to render the results of the example in the code block.
- runner_method: str¶
The name of the method to call on the
ClickRunnerinstance.
- runner_attr: ClassVar[str] = 'click_runner'¶
Name of the attribute holding the runner on the doctree.
Subclasses (like
PythonDirective) override this so the Click and Python runners don’t collide on the same document.
- runner_factory¶
Class to instantiate for the per-document runner.
Defaults to
ClickRunnerinClickDirective(set after the class definition to break the forward reference).alias of
ClickRunner
- property runner¶
Get or create the per-document runner.
Creates one runner per document, keyed by
runner_attr.
- property language: str[source]¶
Short name of the Pygments lexer used to highlight the code block.
Returns, in order of precedence, the language specified in the :language: directive options, the first argument of the directive (if any), or the default set in the directive class.
- code_block_options(target='source')[source]¶
Render the options supported by Sphinx’ native
code-blockdirective.targetselects which block these options will be attached to:"source"for the directive’s input source code,"results"for the captured output.emphasize-linesroutes to the source block;emphasize-result-linesis rewritten asemphasize-lineson the results block, so authors can highlight different lines in each.
- property show_source: bool[source]¶
Whether to show the source code of the example in the code block.
The last occurrence of either
show-sourceorhide-sourceoptions wins. If neither is set, the default is taken fromshow_source_by_default.
- property show_results: bool[source]¶
Whether to show the results of running the example in the code block.
The last occurrence of either
show-resultsorhide-resultsoptions wins. If neither is set, the default is taken fromshow_results_by_default.
- render_code_block(lines, language, target='source')[source]¶
Render the code block with the source code or results.
targetis forwarded tocode_block_options()so theemphasize-lines/emphasize-result-linessplit routes the right highlighting to each block.
- class click_extra.sphinx.click.SourceDirective(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]¶
Bases:
ClickDirectiveDirective to declare a Click CLI source code.
This directive is used to declare a Click CLI example in the documentation. It renders the source code of the example in a Python code block.
- default_language: str = 'python'¶
Default highlighting language to use to render the code block.
All Pygments’ languages short names are recognized.
- show_source_by_default: bool = True¶
Whether to render the source code of the example in the code block.
- show_results_by_default: bool = False¶
Whether to render the results of the example in the code block.
- runner_method: str = 'execute_source'¶
The name of the method to call on the
ClickRunnerinstance.
- class click_extra.sphinx.click.RunDirective(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]¶
Bases:
ClickDirectiveDirective to run a Click CLI example.
This directive is used to run a Click CLI example in the documentation. It renders the results of running the example in a shell session code block supporting ANSI colors.
- default_language: str = 'ansi-shell-session'¶
Default highlighting language to use to render the code block.
All Pygments’ languages short names are recognized.
- show_source_by_default: bool = False¶
Whether to render the source code of the example in the code block.
- show_results_by_default: bool = True¶
Whether to render the results of the example in the code block.
- runner_method: str = 'run_cli'¶
The name of the method to call on the
ClickRunnerinstance.
- class click_extra.sphinx.click.TreeDirective(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]¶
Bases:
ClickDirectiveRender a complete CLI reference for a Click command and all its subcommands.
Walks the Click command tree at build time and emits, in MyST syntax:
A GFM summary table linking each command to its section anchor.
A heading +
click:run--helpblock for the root command.One heading +
click:run--helpblock per subcommand, nested by depth.
Designed to replace per-project hand-rolled generators (like repomatic’s
docs_update.py::cli_reference()) with a single declarative directive that walks the live command tree on every build.The required argument is a Python expression evaluated in the per-document runner namespace; it must yield a
click.Command. The optional directive body is Python preamble exec’d in the same namespace before evaluation, so authors may either import the CLI in a priorclick:source :hide-source:block or inline the import here.Note
Currently MyST-only. Use the directive in a
.mddocument withmyst_parserenabled.- has_content = True¶
May the directive have content?
- required_arguments = 1¶
Number of required directive arguments.
- optional_arguments = 0¶
The optional argument overrides the default Pygments language to use.
- final_argument_whitespace = False¶
May the final argument contain whitespace?
- option_spec: ClassVar[OptionSpec] = {'anchor-prefix': <function unchanged>, 'heading-offset': <function nonnegative_int>, 'label-prefix': <function unchanged>, 'max-depth': <function positive_int>, 'no-root': <function flag>, 'no-table': <function flag>, 'root-label': <function unchanged>}¶
Recognized directive options.
max-depthcaps the recursion into nestedclick.Groupcommands (default:10).heading-offsetshifts all generated headings down by N levels. When unset, the directive readsstate.memo.section_leveland uses the surrounding section depth so the root nests one level below the enclosing section: inside the document’sh1title this yields1(root ath2); inside anh3section it yields3(root ath4). Override only when the auto-detected depth is wrong for the page layout.anchor-prefixandlabel-prefixoverride the slug and display prefix used for anchors and labels; both default to the CLI’sclick.Command.name.root-labelsets the heading text for the root help block (default:"Help screen").no-tableskips the summary table;no-rootskips the root--helpblock.
- class click_extra.sphinx.click.ConfigDirective(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]¶
Bases:
ClickDirectiveRender the configuration reference of a CLI’s
config_schema.Introspects a configuration schema dataclass at build time and expands, in MyST syntax:
A GFM summary table linking each option to its section anchor, with its one-line summary and default value.
One heading per option, with its docstring, type, default, and a TOML example pinned to the default value.
Option metadata comes from
schema_field_infos(): dotted kebab-case keys, type annotations, defaults from a pristine schema instance, and attribute docstrings (which are parsed as the host document’s markup). Designed to replace per-project hand-rolled generators (like repomatic’sdocs_update.py::config_deflist()) with a single declarative directive that documents the live schema on every build.The required argument is a Python expression evaluated in the per-document runner namespace; it must yield either a
click.Commandwhoseconfig_schemais set (the schema is pulled off itsConfigOption), or a schema dataclass directly. The optional directive body is Python preamble exec’d in the same namespace before evaluation, so authors may either import the CLI in a priorclick:source:hide-source:block or inline the import here.Caution
Attribute docstrings are recovered from the schema’s source file, so a schema defined inside an exec’d
click:sourceblock documents its options without descriptions. Import the schema from a real module instead (seefield_docstrings()).Note
Currently MyST-only. Use the directive in a
.mddocument withmyst_parserenabled.- has_content = True¶
May the directive have content?
- required_arguments = 1¶
Number of required directive arguments.
- optional_arguments = 0¶
The optional argument overrides the default Pygments language to use.
- final_argument_whitespace = False¶
May the final argument contain whitespace?
- option_spec: ClassVar[OptionSpec] = {'heading-offset': <function nonnegative_int>, 'no-examples': <function flag>, 'no-table': <function flag>, 'section': <function unchanged>}¶
Recognized directive options.
heading-offsetshifts all generated headings down by N levels; when unset, the surrounding section depth is used (same behavior asclick:tree).sectionoverrides the TOML table header shown in the per-option examples: it defaults totool.{cli-name}when the argument is a CLI (matching how click-extra and its downstream CLIs read their section frompyproject.toml), and to no header at all for a bare schema; an explicitly empty:section:suppresses the header.no-tableskips the summary table;no-examplesskips the TOML example blocks.
- class click_extra.sphinx.click.ClickDomain(env)[source]¶
Bases:
StatelessDomainSetup new directives under the same
clicknamespace:click:sourcewhich renders a Click CLI source codeclick:runwhich renders the results of running a Click CLIclick:treewhich walks a Click command tree and renders the full--helpreference for every subcommand, with a summary table on topclick:configwhich documents a CLI’sconfig_schema: a summary table plus one section per option, with types, defaults, and TOML examples
- directives: ClassVar[dict] = {'config': <class 'click_extra.sphinx.click.ConfigDirective'>, 'run': <class 'click_extra.sphinx.click.RunDirective'>, 'source': <class 'click_extra.sphinx.click.SourceDirective'>, 'tree': <class 'click_extra.sphinx.click.TreeDirective'>}¶
directive name -> directive class
- click_extra.sphinx.click.cleanup_runner(app, doctree)¶
Drop the
ClickRunnerfrom the doctree once the document is read.- Return type:
click_extra.sphinx.manpages module¶
Sphinx integration to render roff man pages alongside the HTML build.
A project that adds click_extra.sphinx to its extensions list and
declares one or more entries in click_extra_manpages gets its Click
command tree(s) emitted as .1 files into <outdir>/<output_dir>/ on
every HTML build, with no project-local helper script. Pages mirror what
click_extra.man_page.write_manpages() produces from a CLI invocation,
so the docs site, the release pipeline, and downstream packagers all share
one generator.
When mandoc or groff is available on PATH, each .1 file is
also rendered to a browser-viewable .html sibling. Browsers download
raw .1 files rather than display them, so the HTML pass is what makes
Sphinx’s :manpage: role useful when manpages_url points at this
hook’s output.
The hook only fires for HTML-class builders (html, dirhtml,
singlehtml). Non-HTML builders (linkcheck, man, epub,
coverage, etc.) skip it: they typically have different output
semantics, and writing roff into a linkcheck output/ directory
serves no purpose.
Configuration shape:
click_extra_manpages = [
{
"script": "meta_package_manager.cli:mpm", # required
"prog_name": "mpm", # optional, see below
"output_dir": "man", # optional, defaults to "man"
"render_html": True, # optional, see below
},
]
scriptis resolved byclick_extra.cli_wrapper.resolve_target_command()exactly as it would be from theclick-extra manCLI: aconsole_scriptsentry-point name, amodule:functionpath, a.pyfile, or a plain module name.prog_nameis the basename used for both the man-page.THheader and the generated filenames. When omitted, it falls back to the resolved Click command’s ownnameattribute (mpmfor themeta_package_manager.cli:mpmtarget), matching the default theclick-extra man --output-dirCLI uses.output_diris a relative path underapp.outdir. It is created on demand and reused across builds.render_htmltoggles the HTML sibling pass. Defaults toTrue. When no renderer is onPATH, the build still produces the.1files and logs a single info-level notice; setrender_htmltoFalseto suppress that notice.
An empty (or absent) click_extra_manpages list disables the feature,
which is the default for every project pulling in the extension.
Cross-referencing the generated pages from prose¶
To make :manpage:`myprog(1)` resolve to the HTML sibling this hook
emits, set Sphinx’s manpages_url to the same output_dir:
manpages_url = "man/{page}.{section}.html"
Sphinx’s role provides {page}, {section} and {path}
placeholders; the file layout produced here is {page}.{section} plus
the optional .html extension, so the template above matches every
file regardless of how deep the subcommand tree goes.
- click_extra.sphinx.manpages.MANPAGES_CONFIG_KEY = 'click_extra_manpages'¶
Name of the
conf.pyconfig flag holding the man-page emit list.
- click_extra.sphinx.manpages.DEFAULT_OUTPUT_DIR = 'man'¶
Subdirectory under
app.outdirwhere.1files land when the caller omits theoutput_direntry. Picked to match the URL fragment projects typically publish their man pages under (likehttps://example.com/<project>/man/<cli>.1).
- click_extra.sphinx.manpages.HTML_BUILDER_NAMES = frozenset({'dirhtml', 'html', 'singlehtml'})¶
Builder names that get the man-page emit hook.
Restricted to HTML-family builders because they are the ones whose output directory becomes the published docs site. Other builders (
linkcheck,man,epub,coverage) have different output semantics, and writing roff into their build trees would either be redundant or confusing.
- click_extra.sphinx.manpages.HTML_RENDERERS: tuple[tuple[str, tuple[str, ...]], ...] = (('mandoc', ('-Thtml',)), ('groff', ('-Thtml', '-mandoc')))¶
External roff → HTML renderers, tried in order.
mandocis preferred: its HTML output ships semanticidanchors on every section and option (#NAME,#SYNOPSIS,#config…), which makes deep-linking from prose work.groff -Thtml -mandocis the GNU fallback. If neither is onPATH, the HTML pass is skipped and only the.1files are emitted.
- click_extra.sphinx.manpages.MANPAGE_LIST_DIRECTIVE = 'click-extra-manpages'¶
Name of the directive that renders an auto-generated index of every man page declared in
MANPAGES_CONFIG_KEY. The hyphenated form mirrors theclick_extra_manpagesconfig key it surfaces.
- class click_extra.sphinx.manpages.ManpageListDirective(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]¶
Bases:
SphinxDirectiveRender a bullet list with one link per emitted man page.
The directive walks every entry in
MANPAGES_CONFIG_KEYand, for each, callsiter_command_contexts()to discover the (sub)command tree. Each list item links to the corresponding.1.htmlfile written by the emit hook.Link targets are computed relative to the directive’s enclosing document so the list works whether it appears at the docs root or in a nested page. The directive takes no arguments and no content: it surfaces whatever the config declares at the time the doc is built.
- has_content = False¶
May the directive have content?
- required_arguments = 0¶
Number of required directive arguments.
- optional_arguments = 0¶
Number of optional arguments after the required arguments.
- click_extra.sphinx.manpages.setup(app)[source]¶
Register the man-page emit hook and the index directive on
app.Called from
click_extra.sphinx.setup()so projects only need to list"click_extra.sphinx"in theirextensions. The hook is a no-op whenclick_extra_manpagesis unset or empty, and the directive renders nothing in that case.- Return type:
click_extra.sphinx.matrix module¶
Release compatibility matrices derived from a project’s git history.
Walk every vX.Y.Z tag in a project’s git repository, extract each release’s
declared support for some axis, group consecutive tags that agree, and render a
GitHub-flavored markdown matrix suitable for a project’s install.md.
Two axes are supported:
Python (
{matrix} python): per-tag support comes from theProgramming Language :: Python :: X.Yclassifier list inpyproject.toml(the explicit tested grid), falling back in priority order to PEP 621requires-python, Poetry[tool.poetry.dependencies].python, andsetup.py’spython_requires. A floor-only declaration is capped at the latest Python released while the range was current, so the✅set does not over-claim support for Pythons that did not yet exist.A dependency (
{matrix} <distribution>, like{matrix} click): the per-tag constraint is that distribution’s requirement specifier; columns are auto-derived from the specifier boundaries plus theuv.lockresolved version, and each ✅ / ❌ cell is computed withpackaging.
The rendered tables back the always-on matrix Sphinx directive (see
MatrixDirective), so a project’s install.md can embed a live matrix
kept current by the click-extra refresh-directives command instead of a
static table maintained by hand. The generation functions shell out to git;
they carry no runtime CLI relevance and are kept out of the click_extra
public API.
- click_extra.sphinx.matrix.PYTHON_RELEASE_DATES: dict[str, str] = {'2.7': '2010-07-03', '3.0': '2008-12-03', '3.1': '2009-06-27', '3.10': '2021-10-04', '3.11': '2022-10-24', '3.12': '2023-10-02', '3.13': '2024-10-07', '3.14': '2025-10-07', '3.2': '2011-02-20', '3.3': '2012-09-29', '3.4': '2014-03-16', '3.5': '2015-09-13', '3.6': '2016-12-23', '3.7': '2018-06-27', '3.8': '2019-10-14', '3.9': '2020-10-05'}¶
ISO release date of each
X.YPython final release.Used to cap
✅cells when a release range’s Python support is derived from arequires-python-style floor rather than an explicit classifier list: a floor without upper bound would otherwise over-claim support for Pythons that did not yet exist while the range was current. Update this table each October when a new final release ships.
- click_extra.sphinx.matrix.DEFAULT_TAG_PATTERN: str = '^v\\d+\\.\\d+\\.\\d+$'¶
Default regex for release tags (
vMAJOR.MINOR.PATCH).
- click_extra.sphinx.matrix.DEFAULT_TAGS_SORT: str = 'version:refname'¶
Default
git tag --sortargument.
- class click_extra.sphinx.matrix.PythonMatrixGroup(first_tag: str, last_tag: str, first_date: str, python_versions: tuple[str, ...])[source]¶
Bases:
NamedTupleA contiguous run of release tags sharing the same Python support set.
Create new instance of PythonMatrixGroup(first_tag, last_tag, first_date, python_versions)
- click_extra.sphinx.matrix.python_versions_released_by(cutoff_date, release_dates=None)[source]¶
Return Python
X.Yversions released on or beforecutoff_date.
- click_extra.sphinx.matrix.parse_python_spec(spec)[source]¶
Parse a Python version spec into
(floor, ceiling, excluded).Supports:
PEP 440:
>=3.10,>=3.10,<3.14,>=2.7, !=3.0.*, !=3.1.*.Poetry caret:
^3.7expands to>=3.7, <4.0.Poetry tilde:
~3.7expands to>=3.7, <3.8.setup.py’spython_requires(uses the same PEP 440 syntax asrequires-python).
- Return type:
- Returns:
(floor, ceiling, excluded)where each offloorandceilingis a bare"X.Y"string (empty if unspecified) andexcludedis the set of bare"X.Y"values one per!=X.Y.*clause. The ceiling is exclusive:<3.14means 3.14 itself is not supported. Returns("", "", set())when no floor is found.
- click_extra.sphinx.matrix.python_matrix_groups(project_root, *, tag_pattern='^v\\\\d+\\\\.\\\\d+\\\\.\\\\d+$', tags_sort='version:refname', version_floor='', release_dates=None)[source]¶
Walk every release tag in
project_rootand group consecutive releases that declare the same effective set of Python versions.- Parameters:
project_root (
Path) – git working tree to walk.tag_pattern (
str) – regex matching release tags. Defaults toDEFAULT_TAG_PATTERN(vMAJOR.MINOR.PATCH).tags_sort (
str) – value passed togit tag --sort. Defaults toDEFAULT_TAGS_SORT(version:refname).version_floor (
str) – drop every release tag below this bare version ("4.9.0","4.9"). Empty (the default) keeps all tags. Applied before grouping so the oldest surviving group starts at the floor.release_dates (
dict[str,str] |None) – Python-version release-date table used for the cap. Defaults toPYTHON_RELEASE_DATES.
- Return type:
- Returns:
List of
PythonMatrixGroup, in chronological order. Tags with no Python declaration in any recognized form are skipped.
- click_extra.sphinx.matrix.python_matrix_table(project_root, label, *, tag_pattern='^v\\\\d+\\\\.\\\\d+\\\\.\\\\d+$', tags_sort='version:refname', python_floor='', version_floor='', release_dates=None)[source]¶
Render the Python compatibility matrix as a GitHub-flavored markdown table.
Newest releases sit on top so the supported-version streak progresses from the upper-left toward the lower-right corner over time.
- Parameters:
project_root (
Path) – git working tree to walk.label (
str) – the header column name (usually the package name, like"click-extra"or"repomatic"). Rendered in backticks.tag_pattern (
str) – passed topython_matrix_groups().tags_sort (
str) – passed topython_matrix_groups().python_floor (
str) – drop every PythonX.Ycolumn below this bare version ("3.9"). Empty (the default) keeps all columns. Trims columns only; combine withversion_floorto also drop the old release rows that supported nothing above the floor.version_floor (
str) – passed topython_matrix_groups()to drop release rows below a bare package version.release_dates (
dict[str,str] |None) – passed topython_matrix_groups().
- Return type:
- Returns:
rendered markdown table, or the empty string when no group was collected.
- class click_extra.sphinx.matrix.DependencyMatrixGroup(first_tag: str, last_tag: str, first_date: str, spec: str)[source]¶
Bases:
NamedTupleA contiguous run of release tags declaring the same dependency spec.
Create new instance of DependencyMatrixGroup(first_tag, last_tag, first_date, spec)
- click_extra.sphinx.matrix.dependency_matrix_groups(project_root, dep_name, *, tag_pattern='^v\\\\d+\\\\.\\\\d+\\\\.\\\\d+$', tags_sort='version:refname', version_floor='')[source]¶
Group consecutive release tags declaring the same
dep_namespec.- Parameters:
dep_name (
str) – the distribution whose requirement specifier is tracked (like"click").- Return type:
- Returns:
DependencyMatrixGrouplist in chronological order; tags with no declared requirement fordep_nameare skipped.
- click_extra.sphinx.matrix.dependency_matrix_table(project_root, label, dep_name, *, show_spec=False, tag_pattern='^v\\\\d+\\\\.\\\\d+\\\\.\\\\d+$', tags_sort='version:refname', version_floor='')[source]¶
Render the
dep_namecompatibility matrix as a markdown table.Columns are auto-derived from the requirement specifiers across history (see
_dependency_columns()) plus theuv.lockresolved version; each ✅ / ❌ cell is computed withpackaging. Consecutive ranges whose cells coincide are re-merged into one row.
- class click_extra.sphinx.matrix.MatrixDirective(name, arguments, options, content, lineno, content_offset, block_text, state, state_machine)[source]¶
Bases:
SphinxDirectiveRender a package’s compatibility matrix for a given axis.
{matrix} pythonrenders the interpreter matrix (release ranges × Python versions).{matrix} <distribution>(like{matrix} click) renders a dependency matrix (release ranges × that dependency’s versions, from its requirement specifier across the git history). Both emit a GitHub-flavored table parsed by the host document’s parser, so it lands as a real<table>.The table normally lives inside the block as its content, kept current by the offline updater (
update_matrix_blocks(), exposed as theclick-extra refresh-directivescommand). Rendering that embedded copy needs no git access at build time, so shallow clones and read-only build hosts still show the matrix. An empty block falls back to generating from the working tree’s git tags, so a freshly authored block renders before its first refresh.Argument: the axis,
pythonor a distribution name.Options:
:package:— header column label. Defaults to the repository name.:path:— git working tree to walk, absolute or relative to the documented project’s git root. Defaults to that git root.:version-floor:— drop release rows below this package version.:tag-pattern:— regex selecting release tags. Defaults toDEFAULT_TAG_PATTERN.:python-floor:— (python axis) drop Python columns belowX.Y.:show-spec:— (dependency axis) add a raw-specifierSpeccolumn.
The git fallback is resilient: a missing git binary, a non-repository path, or a tag-less repository logs a build warning and renders nothing rather than aborting the build.
- has_content = True¶
May the directive have content?
- required_arguments = 1¶
Number of required directive arguments.
- optional_arguments = 0¶
Number of optional arguments after the required arguments.
- click_extra.sphinx.matrix.setup(app)[source]¶
Register the always-on
matrixdirective onapp.Called from
click_extra.sphinx.setup()so projects only need to list"click_extra.sphinx"in theirextensions. Unlike theclick:*/python:*families, the directive is registered unconditionally: it runs a canned matrix generator, not user-supplied Python, so it needs no opt-in.- Return type:
- click_extra.sphinx.matrix.update_matrix_blocks(paths, *, check=False)[source]¶
Refresh every
{matrix}block in the given Markdown sources.Walks
paths(files, or directories recursed for*.md), regenerates each block’s table from its axis and options, and rewrites the file when its content changed. Incheckmode nothing is written; the return value still lists the files that would change, so a caller can exit non-zero to flag stale documentation in CI.