Man-page

Generating man pages

Every man-page section is produced mechanically by click_extra.man_page from the command itself. It works on any Click command object (no console_scripts entry point required) and walks the command tree, discovering subcommands dynamically, into one roff page per command. Literal tokens (command and option names) are set bold and replaceable tokens (metavars, operands) italic, following the literal and replaceable slots split; Click’s \b no-rewrap marker becomes a roff .nf / .fi block.

The @man_option decorator adds a --man flag that prints a command’s man page and exits:

import click

from click_extra import man_option

@click.command
@man_option
@click.option("--name", help="Who to greet.")
def greet(name):
    """Greet someone."""
    click.echo(f"Hello, {name}!")
$ greet --man
.\" Generated by Click Extra 7.20.0.dev0 <https://github.com/kdeldycke/click-extra>. Do not edit by hand.
.TH "GREET" "1" "2026-06-15" "" ""
.SH NAME
greet \- Greet someone.
.SH SYNOPSIS
\fBgreet\fR \fI[OPTIONS]\fR
.SH DESCRIPTION
Greet someone.
.SH OPTIONS
.TP
\fB\-\-man\fR
Show the command's man page (roff) and exit.
.TP
\fB\-\-name\fR \fITEXT\fR
Who to greet.
.TP
\fB\-\-help\fR
Show this message and exit.
.SH "EXIT STATUS"
.TP
\fB0\fR
Success.
.TP
\fB1\fR
A runtime error, or an aborted prompt (Ctrl\-C, a declined confirmation).
.TP
\fB2\fR
A usage error: unknown option, invalid value, missing operand, or an unparsable configuration file.

The quickest way to produce a man page is the man subcommand: click-extra man SCRIPT resolves the target, loads the Click command, and prints its roff page to stdout. Trailing arguments drill into subcommands (click-extra man flask run). With uvx nothing needs to be installed up front:

$ uvx --from click-extra --with flask click-extra man flask > flask.1

Multiple pages

For multi-command CLIs, --output-dir DIR writes the whole command tree as one .1 file per (sub)command into DIR (created if missing). The output replaces stdout, so this is the right form for a release pipeline or a distributor’s build phase:

$ uvx --from click-extra --with flask click-extra man --output-dir /tmp/man flask
/tmp/man/flask.1
/tmp/man/flask-run.1
/tmp/man/flask-routes.1
/tmp/man/flask-shell.1

--output-dir must appear before SCRIPT, since arguments after SCRIPT navigate into nested subcommands. Mixing --output-dir with a SUBCOMMAND argument is rejected: the flag always emits the whole tree of SCRIPT.

Target resolution

SCRIPT is accepted in four forms, tried in this order. The example above uses the first; the others reach the same Click command from a different starting point:

  1. A console_scripts entry point exposed by an installed package, the form shown above (flask ships one in the flask distribution).

  2. module:function notation pointing straight at a Click command object. Useful when the entry point is a wrapper rather than the command itself, or when the command isn’t exposed as a console script at all:

    $ uvx --from click-extra --with flask click-extra man flask.cli:cli > flask.1
    
  3. A .py file path. The file is imported in place, with no install step required, which is the right hook for source trees that don’t ship a Python build system (Autotools, Meson, Bazel):

    $ click-extra man path/to/my_cli.py > my_cli.1
    
  4. A bare Python module name invocable via python -m. The resolver imports the module and picks up the Click command from its top-level attributes:

    $ click-extra man my_package.cli > my_package.1
    

The same resolver is shared with wrap and show-params, so any of these forms works with all three subcommands.

Programmatic API

Three entry points cover the Python API, from one-shot rendering up to writing the whole tree. Dates honor SOURCE_DATE_EPOCH for reproducible builds:

  1. render_manpage(cli) returns one page’s roff as a string. Use it when you want to pipe to groff or post-process the output before writing it:

    from click_extra import render_manpage
    
    print(render_manpage(cli))
    
  2. render_manpages(cli) returns a {filename: roff} mapping covering the whole command tree. Use it when you need to filter, rename, or splice pages before writing them:

    from pathlib import Path
    from click_extra import render_manpages
    
    for filename, roff in render_manpages(cli).items():
        Path("man", filename).write_text(roff)
    
  3. write_manpages(cli, target_dir) writes one .1 file per command directly to disk: the build-system hook. A Debian package wires it into debian/rules from its override_dh_installman:

    override_dh_installman:
    	python -c "from myapp.cli import cli; from click_extra import write_manpages; write_manpages(cli, 'debian/tmp/manpages')"
    	dh_installman -O--buildsystem=pybuild
    

Sphinx integration

Projects already using the click_extra.sphinx extension can publish the same pages alongside their HTML docs with a single click_extra_manpages entry in conf.py: see Man pages. The Sphinx hook reuses write_manpages under the hood and optionally renders a browser-viewable HTML sibling next to each .1 so the standard :manpage: role can link to them.

Index

The list below is auto-generated by the click-extra-manpages directive: one link per (sub)command declared in this project’s click_extra_manpages config, pointing at the HTML sibling rendered alongside the docs.

Directive call
```{click-extra-manpages}
```

Layout

Unix tools are conventionally documented with the section layout of man-pages(7): a one-line NAME, a SYNOPSIS, a prose DESCRIPTION, an itemized OPTIONS list, then ENVIRONMENT, FILES, and EXIT STATUS. A Click Extra command already carries everything those sections need. This page documents one small CLI top-to-bottom in that order, with each section backed by output rendered live from the running command.

from click_extra import Choice, argument, command, echo, option


@command(context_settings={"show_envvar": True})
@argument("city", help="Name of the city to report on.")
@option(
    "--units",
    type=Choice(["celsius", "fahrenheit"]),
    default="celsius",
    help="Temperature scale to display.",
)
def weather(city, units):
    """Report the current temperature for a city."""
    echo(f"{city}: 21 degrees {units}.")

NAME

A man page opens with a single name - one-line description line, the one apropos and whatis index. Click has no dedicated slot for it: the equivalent is the program name paired with the first line of the command’s docstring, which Click also uses as the command’s short help. For this CLI the pairing reads:

weather - report the current temperature for a city

SYNOPSIS

The Usage: line is the synopsis. Click Extra styles its tokens along the same typographic split a man page draws between bold literal text and italic replaceable text, documented in literal and replaceable slots: the literal command name weather against the replaceable CITY operand and the [OPTIONS] placeholder.

Click prints the synopsis as the first line of the help screen. The rest of that screen, dissected in the two sections below, supplies the DESCRIPTION and the OPTIONS list:

$ weather --help
Usage: weather [OPTIONS] CITY

  Report the current temperature for a city.

Positional arguments:
  CITY  Name of the city to report on.

Options:
  --units [celsius|fahrenheit]  Temperature scale to display.  [env var:
                                WEATHER_UNITS; default: celsius]
  --time / --no-time            Measure and print elapsed execution time.  [env
                                var: WEATHER_TIME; default: no-time]
  --config CONFIG_PATH          Location of the configuration file. Supports
                                local path with glob patterns or remote URL.
                                [env var: WEATHER_CONFIG; default: ~/.config/wea
                                ther/{*.toml,*.yaml,*.yml,*.json,*.json5,*.jsonc
                                ,*.hjson,*.ini,*.xml,pyproject.toml}]
  --no-config                   Ignore all configuration files and only use
                                command line parameters and environment
                                variables.  [env var: WEATHER_CONFIG]
  --validate-config FILE        Validate the configuration file and exit.  [env
                                var: WEATHER_VALIDATE_CONFIG]
  --accessible                  Accessibility mode: disable colors and render
                                tables in a plain, screen-reader-friendly
                                format.  [env var: WEATHER_ACCESSIBLE]
  --color, --ansi / --no-color, --no-ansi
                                Strip out all colors and all ANSI codes from
                                output.  [env var: WEATHER_COLOR; default:
                                color]
  --theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]
                                Color theme used for help screens.  [env var:
                                WEATHER_THEME; default: dark]
  --show-params                 Show all CLI parameters, their provenance,
                                defaults and value, then exit.  [env var:
                                WEATHER_SHOW_PARAMS]
  --table-format [aligned|asciidoc|colon-grid|csv|csv-excel|csv-excel-tab|csv-unix|double-grid|double-outline|fancy-grid|fancy-outline|github|grid|heavy-grid|heavy-outline|hjson|html|jira|json|json5|jsonc|latex|latex-booktabs|latex-longtable|latex-raw|mediawiki|mixed-grid|mixed-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded-grid|rounded-outline|rst|simple|simple-grid|simple-outline|textile|toml|tsv|unsafehtml|vertical|xml|yaml|youtrack]
                                Rendering style of tables.  [env var:
                                WEATHER_TABLE_FORMAT; default: rounded-outline]
  --verbosity LEVEL             Either CRITICAL, ERROR, WARNING, INFO, DEBUG.
                                [env var: WEATHER_VERBOSITY; default: WARNING]
  -v, --verbose                 Increase the default WARNING verbosity by one
                                level for each additional repetition of the
                                option.  [env var: WEATHER_VERBOSE; default: 0]
  --man                         Show the command's man page (roff) and exit.
                                [env var: WEATHER_MAN]
  --version                     Show the version and exit.  [env var:
                                WEATHER_VERSION]
  -h, --help                    Show this message and exit.

DESCRIPTION

The DESCRIPTION explains what the program does and, in prose, what its operands mean. Click Extra sources it from the command’s docstring, rendered just under the synopsis above: “Report the current temperature for a city.” The CITY operand is the city to report on.

When an argument carries a help= string, Click Extra also itemizes operands in a dedicated Positional arguments: block (the CITY entry above). That is a structured take on operands that goes beyond what man-pages(7) prescribes, which keeps their meaning in the prose description rather than in a list.

OPTIONS

The OPTIONS section is the formal, per-item description of each option, rendered as the Options: block above. Every entry pairs the option’s literal name (--units) and its replaceable metavar ([celsius|fahrenheit]) with the help text and a trailing bracket field carrying the option’s environment variable and default. Click Extra injects its own options into the same list (--config, --verbosity, --version, --help, …), so a CLI built on it gets a complete, conventional options section without extra work.

When a CLI sorts its options into groups with @option_group, each group becomes a .SS subsection of OPTIONS; the options left ungrouped, including the ones Click Extra injects, gather under a trailing Other options heading. This is the same split the --help screen draws:

from click_extra import command, option, option_group


@command
@option_group(
    "Location",
    option("--city", help="City to report on."),
    option("--country", help="Two-letter country code."),
)
@option("--fahrenheit", is_flag=True, help="Report in the Fahrenheit scale.")
def forecast(city, country, fahrenheit):
    """Report a multi-day forecast."""
$ forecast --man
.\" Generated by Click Extra 7.20.0.dev0 <https://github.com/kdeldycke/click-extra>. Do not edit by hand.
.TH "FORECAST" "1" "2026-06-15" "" ""
.SH NAME
forecast \- Report a multi\-day forecast.
.SH SYNOPSIS
\fBforecast\fR \fI[OPTIONS]\fR
.SH DESCRIPTION
Report a multi\-day forecast.
.SH OPTIONS
.SS "Location"
.TP
\fB\-\-city\fR \fITEXT\fR
City to report on.
.TP
\fB\-\-country\fR \fITEXT\fR
Two\-letter country code.
.SS "Other options"
.TP
\fB\-\-fahrenheit\fR
Report in the Fahrenheit scale.
.TP
\fB\-\-time\fR / \fB\-\-no\-time\fR
Measure and print elapsed execution time.
.TP
\fB\-\-config\fR \fICONFIG_PATH\fR
Location of the configuration file. Supports local path with glob patterns or remote URL.
.TP
\fB\-\-no\-config\fR
Ignore all configuration files and only use command line parameters and environment variables.
.TP
\fB\-\-validate\-config\fR \fIFILE\fR
Validate the configuration file and exit.
.TP
\fB\-\-accessible\fR
Accessibility mode: disable colors and render tables in a plain, screen\-reader\-friendly format.
.TP
\fB\-\-color\fR / \fB\-\-ansi\fR / \fB\-\-no\-color\fR / \fB\-\-no\-ansi\fR
Strip out all colors and all ANSI codes from output.
.TP
\fB\-\-theme\fR \fI[dark|dracula|light|manpage|monokai|nord|solarized_dark]\fR
Color theme used for help screens.
.TP
\fB\-\-show\-params\fR
Show all CLI parameters, their provenance, defaults and value, then exit.
.TP
\fB\-\-table\-format\fR \fI[aligned|asciidoc|colon\-grid|csv|csv\-excel|csv\-excel\-tab|csv\-unix|double\-grid|double\-outline|fancy\-grid|fancy\-outline|github|grid|heavy\-grid|heavy\-outline|hjson|html|jira|json|json5|jsonc|latex|latex\-booktabs|latex\-longtable|latex\-raw|mediawiki|mixed\-grid|mixed\-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded\-grid|rounded\-outline|rst|simple|simple\-grid|simple\-outline|textile|toml|tsv|unsafehtml|vertical|xml|yaml|youtrack]\fR
Rendering style of tables.
.TP
\fB\-\-verbosity\fR \fILEVEL\fR
Either CRITICAL, ERROR, WARNING, INFO, DEBUG.
.TP
\fB\-\-verbose\fR / \fB\-v\fR \fIINTEGER RANGE\fR
.TP
\fB\-\-man\fR
Show the command's man page (roff) and exit.
.TP
\fB\-\-version\fR
Show the version and exit.
.TP
\fB\-\-help\fR / \fB\-h\fR
Show this message and exit.
.SH ENVIRONMENT
.TP
\fBFORECAST_CITY\fR
City to report on.
.TP
\fBFORECAST_COUNTRY\fR
Two\-letter country code.
.TP
\fBFORECAST_FAHRENHEIT\fR
Report in the Fahrenheit scale.
.TP
\fBFORECAST_TIME\fR
Measure and print elapsed execution time.
.TP
\fBFORECAST_CONFIG\fR
Location of the configuration file. Supports local path with glob patterns or remote URL.
.TP
\fBFORECAST_VALIDATE_CONFIG\fR
Validate the configuration file and exit.
.TP
\fBFORECAST_ACCESSIBLE\fR
Accessibility mode: disable colors and render tables in a plain, screen\-reader\-friendly format.
.TP
\fBFORECAST_COLOR\fR
Strip out all colors and all ANSI codes from output.
.TP
\fBFORECAST_THEME\fR
Color theme used for help screens.
.TP
\fBFORECAST_SHOW_PARAMS\fR
Show all CLI parameters, their provenance, defaults and value, then exit.
.TP
\fBFORECAST_TABLE_FORMAT\fR
Rendering style of tables.
.TP
\fBFORECAST_VERBOSITY\fR
Either CRITICAL, ERROR, WARNING, INFO, DEBUG.
.TP
\fBFORECAST_VERBOSE\fR
.TP
\fBFORECAST_MAN\fR
Show the command's man page (roff) and exit.
.TP
\fBFORECAST_VERSION\fR
Show the version and exit.
.TP
\fBFORECAST_HELP\fR
Show this message and exit.
.SH FILES
.nf
\fI~/.config/forecast/{*.toml,*.yaml,*.yml,*.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproject.toml}\fR
.fi
.SH "EXIT STATUS"
.TP
\fB0\fR
Success.
.TP
\fB1\fR
A runtime error, or an aborted prompt (Ctrl\-C, a declined confirmation).
.TP
\fB2\fR
A usage error: unknown option, invalid value, missing operand, or an unparsable configuration file.

ENVIRONMENT

The ENVIRONMENT section lists the variables that change the program’s behavior. Click Extra derives one per option from the command name (the WEATHER_ prefix here) and surfaces it in the help screen’s bracket field ([env var: WEATHER_UNITS; …] above) when show_envvar is enabled. The variable is live: setting it feeds the option, ranked below the command line but above the default in the precedence chain.

$ export WEATHER_UNITS=fahrenheit
$ weather Paris
Paris: 21 degrees fahrenheit.

--show-params prints the full mapping at once: every parameter, the environment variable it reads, its default, its resolved value, and the source that value came from.

$ weather --show-params
╭─────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────┬──────────────────────────────────┬─────────────┬────────┬─────────┬──────────────────┬─────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────┬────────────────────┬──────────────┬──────────┬───────┬────────┬─────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────╮
│ IDSpec.ClassParam typePython typeHiddenExposedAllowed in conf?Env. vars.DefaultIs flagFlag valueIs bool flagMultipleNargsPromptConfirmation promptValueSource      │
├─────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────┼──────────────────────────────────┼─────────────┼────────┼─────────┼──────────────────┼─────────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────┼────────────────────┼──────────────┼──────────┼───────┼────────┼─────────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────────┤
│ weather.accessible--accessible                                                                                                                                                                                                                                                                                                                                                                                                                                                                  │ click_extra.accessibility.AccessibleOption │ click.types.BoolParamType        │ boolWEATHER_ACCESSIBLEFalseTrue        │ 1     │        │                    │ False                                                                                                          │ DEFAULT     │
│ weather.city            │                                                                                                                                                                                                                                                                                                                                                                                                                                                                               │ click_extra.parameters.Argument            │ click.types.StringParamType      │ str         │        │                 │                         │ Sentinel.UNSET                                                                                                 │         │                    │              │         │ 1     │        │                     │ Sentinel.UNSET                                                                                                 │ DEFAULT     │
│ weather.color--color, --ansi / --no-color, --no-ansi                                                                                                                                                                                                                                                                                                                                                                                                                                       │ click_extra.colorize.ColorOption           │ click.types.BoolParamType        │ boolWEATHER_COLORTrueTrue        │ 1     │        │                    │ True                                                                                                           │ DEFAULT     │
│ weather.config--config CONFIG_PATH                                                                                                                                                                                                                                                                                                                                                                                                                                                          │ click_extra.config.ConfigOption            │ click.types.UnprocessedParamType │ strWEATHER_CONFIG'/home/runner/.config/weather/{*.toml,*.yaml,*.yml,*.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproject.toml}'       │                    │         │ 1     │        │                    │ '/home/runner/.config/weather/{*.toml,*.yaml,*.yml,*.json,*.json5,*.jsonc,*.hjson,*.ini,*.xml,pyproject.toml}' │ DEFAULT     │
│ weather.config--no-config                                                                                                                                                                                                                                                                                                                                                                                                                                                                   │ click_extra.config.NoConfigOption          │ click.types.UnprocessedParamType │ strWEATHER_CONFIGSentinel.UNSETSentinel.NO_CONFIG        │ 1     │        │                    │ Sentinel.UNSET                                                                                                 │ DEFAULT     │
│ weather.help-h, --help                                                                                                                                                                                                                                                                                                                                                                                                                                                                    │ click.core.Option                          │ click.types.BoolParamType        │ boolWEATHER_HELPFalseTrue        │ 1     │        │                    │ False                                                                                                          │ DEFAULT     │
│ weather.man--man                                                                                                                                                                                                                                                                                                                                                                                                                                                                         │ click_extra.man_page.ManOption             │ click.types.BoolParamType        │ boolWEATHER_MANFalseTrue        │ 1     │        │                    │ False                                                                                                          │ DEFAULT     │
│ weather.show_params--show-params                                                                                                                                                                                                                                                                                                                                                                                                                                                                 │ click_extra.parameters.ShowParamsOption    │ click.types.BoolParamType        │ boolWEATHER_SHOW_PARAMSFalseTrue        │ 1     │        │                    │ True                                                                                                           │ COMMANDLINE │
│ weather.table_format--table-format [aligned|asciidoc|colon-grid|csv|csv-excel|csv-excel-tab|csv-unix|double-grid|double-outline|fancy-grid|fancy-outline|github|grid|heavy-grid|heavy-outline|hjson|html|jira|json|json5|jsonc|latex|latex-booktabs|latex-longtable|latex-raw|mediawiki|mixed-grid|mixed-outline|moinmoin|orgtbl|outline|pipe|plain|presto|pretty|psql|rounded-grid|rounded-outline|rst|simple|simple-grid|simple-outline|textile|toml|tsv|unsafehtml|vertical|xml|yaml|youtrack] │ click_extra.table.TableFormatOption        │ click_extra.types.EnumChoice     │ strWEATHER_TABLE_FORMAT'rounded-outline'       │                    │         │ 1     │        │                    │ 'rounded-outline'                                                                                              │ DEFAULT     │
│ weather.theme--theme [dark|dracula|light|manpage|monokai|nord|solarized_dark]                                                                                                                                                                                                                                                                                                                                                                                                              │ click_extra.theme.ThemeOption              │ click_extra.theme.ThemeChoice    │ strWEATHER_THEME'dark'       │                    │         │ 1     │        │                    │ 'dark'                                                                                                         │ DEFAULT     │
│ weather.time--time / --no-time                                                                                                                                                                                                                                                                                                                                                                                                                                                            │ click_extra.execution.TimerOption          │ click.types.BoolParamType        │ boolWEATHER_TIMEFalseTrue        │ 1     │        │                    │ False                                                                                                          │ DEFAULT     │
│ weather.units--units [celsius|fahrenheit]                                                                                                                                                                                                                                                                                                                                                                                                                                                  │ click_extra.parameters.Option              │ click.types.Choice               │ strWEATHER_UNITS'celsius'       │                    │         │ 1     │        │                    │ 'celsius'                                                                                                      │ DEFAULT     │
│ weather.validate_config--validate-config FILE                                                                                                                                                                                                                                                                                                                                                                                                                                                        │ click_extra.config.ValidateConfigOption    │ click.types.Path                 │ strWEATHER_VALIDATE_CONFIGSentinel.UNSET       │                    │         │ 1     │        │                    │ Sentinel.UNSET                                                                                                 │ DEFAULT     │
│ weather.verbose-v, --verbose                                                                                                                                                                                                                                                                                                                                                                                                                                                                 │ click_extra.logging.VerboseOption          │ click.types.IntRange             │ intWEATHER_VERBOSE0       │                    │         │ 1     │        │                    │ 0                                                                                                              │ DEFAULT     │
│ weather.verbosity--verbosity LEVEL                                                                                                                                                                                                                                                                                                                                                                                                                                                             │ click_extra.logging.VerbosityOption        │ click_extra.types.EnumChoice     │ strWEATHER_VERBOSITY'WARNING'       │                    │         │ 1     │        │                    │ 'WARNING'                                                                                                      │ DEFAULT     │
│ weather.version--version                                                                                                                                                                                                                                                                                                                                                                                                                                                                     │ click_extra.version.ExtraVersionOption     │ click.types.BoolParamType        │ boolWEATHER_VERSIONFalseTrue        │ 1     │        │                    │ False                                                                                                          │ DEFAULT     │
╰─────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────┴──────────────────────────────────┴─────────────┴────────┴─────────┴──────────────────┴─────────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴─────────┴────────────────────┴──────────────┴──────────┴───────┴────────┴─────────────────────┴────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴─────────────╯

FILES

The FILES section documents the files a program reads. Click Extra’s --config option resolves a per-platform search path, shown as its default in the OPTIONS block above: the application directory for weather followed by a glob over every supported format (*.toml, *.yaml, *.json, *.ini, *.xml, and pyproject.toml). See the configuration guide for the search order and the precedence rules that govern which file wins.

EXIT STATUS

The EXIT STATUS section documents the process return codes. Click Extra inherits Click’s conventional scheme:

Code

Meaning

0

Success.

1

A runtime error, or an aborted prompt (Ctrl-C, a declined confirmation).

2

A usage error: unknown option, invalid value, missing operand, or an unparsable --config file.

A successful run returns 0:

$ weather Paris
Paris: 21 degrees celsius.

An invalid choice is a usage error, so the command exits 2:

$ weather --units kelvin Paris
Usage: weather [OPTIONS] CITY
Try 'weather --help' for help.

Error: Invalid value for '--units' (env var: '('WEATHER_UNITS',)'): 'kelvin' is not one of 'celsius', 'fahrenheit'.

click_extra.man_page API

Generate roff/troff man pages from Click commands.

Produces one man page per command, mirroring the man-pages(7) section structure documented in Man-page: NAME, SYNOPSIS, DESCRIPTION, OPTIONS, COMMANDS, ENVIRONMENT, FILES and EXIT STATUS.

This is Click Extra’s answer to the unmaintained click-man package. It improves on it by:

  • working on a command object via click.Command.make_context(), so it needs no console_scripts entry point;

  • discovering subcommands dynamically through click.Group.list_commands() / click.Group.get_command() with a live context;

  • honoring Click’s \b no-rewrap marker (rendered as roff .nf / .fi);

  • rendering boolean flags (--foo / --no-foo) and skipping hidden commands and options;

  • mirroring Cloup option groups as .SS subsections of OPTIONS (ungrouped options fall under an Other options heading), matching the help screen;

  • emitting ENVIRONMENT (from auto-generated env vars), FILES (from the --config search pattern) and EXIT STATUS sections that click-man never grew.

Font selection follows the man typographic convention encoded by click_extra.theme.LITERAL_STYLES / REPLACEABLE_STYLES: literal tokens (command and option names) render bold (\fB), replaceable tokens (metavars, operands) render italic (\fI).

click_extra.man_page.INLINE_LITERAL_RE = re.compile('``([^`]+?)``')

Match a reST inline literal ("…``”``) in a docstring.

Click stores docstrings verbatim, so any reST markup the author used to render code-like tokens in HTML docs leaks into Command.help / Command.short_help. The roff and HTML man-page paths translate these matches into the bold/literal markers their renderers understand; the Sphinx index directive translates them into nodes.literal.

click_extra.man_page.iter_inline_literals(text)[source]

Walk text and yield (segment, is_literal) pairs.

Split on INLINE_LITERAL_RE so the consumer can apply different rendering to the literal segments (bold for roff, a literal node for docutils) without re-parsing the regex.

Return type:

Iterator[tuple[str, bool]]

click_extra.man_page.CLICK_EXTRA_URL = 'https://github.com/kdeldycke/click-extra'

Click Extra’s home page, stamped into the provenance comment of every generated man page so a reader of the raw roff knows where it came from.

click_extra.man_page.MAN_SECTION = '1'

Default man page section. Section 1 is for executable programs and shell commands, which is what a Click CLI is.

click_extra.man_page.full_short_help(command)[source]

Return the command’s canonical one-line short help, untruncated.

Click’s click.Command.get_short_help_str() truncates to 45 characters by default with a trailing "..." so subcommand listings fit a terminal column. That bound is wrong for a man page: the NAME and COMMANDS sections in man-pages(7) carry the full description, and the man-page renderer (mandoc, groff, less) wraps text on its own.

The lookup mirrors Click’s order: an explicit short_help wins, otherwise the first paragraph of command.help is joined into one line. A truthy deprecated flag prepends (Deprecated) so the flag stays visible in both sections.

Return type:

str

click_extra.man_page.DEFAULT_EXIT_STATUS: tuple[tuple[str, str], ...] = (('0', 'Success.'), ('1', 'A runtime error, or an aborted prompt (Ctrl-C, a declined confirmation).'), ('2', 'A usage error: unknown option, invalid value, missing operand, or an unparsable configuration file.'))

Conventional exit codes shared by every Click Extra CLI.

Mirrors the EXIT STATUS table in Man-page. Click returns 2 for usage errors (UsageError), 1 for aborts, and 0 on success.

class click_extra.man_page.ManOptionItem(names, metavar, is_choice, help, envvars, required)[source]

Bases: object

A single OPTIONS entry, extracted from a Click option.

names: tuple[str, ...]

All literal spellings: primary opts followed by secondary_opts (so --foo / --no-foo boolean flags render both).

metavar: str | None

The rendered metavar, or None for boolean flags (which take no value).

is_choice: bool

Whether the option’s type is a click.Choice.

help: str | None

The option’s help text, possibly carrying a \b no-rewrap marker.

envvars: tuple[str, ...]

Environment variables read by the option, auto-generated one included.

required: bool

Whether the option is mandatory.

to_roff()[source]

Render this option as a roff tagged paragraph (.TP).

Return type:

list[str]

class click_extra.man_page.ManOptionGroup(options, title=None, help=None)[source]

Bases: object

A titled cluster of OPTIONS entries, mirroring a Cloup option group.

A plain Click command, or a Cloup command with no explicit @option_group, yields a single group with title=None: it renders as a flat OPTIONS list with no .SS subsection heading, identical to a man page that never grouped its options.

options: tuple[ManOptionItem, ...]

The option entries in this group.

title: str | None = None

The subsection heading, rendered as a roff .SS. None for the implicit single group of an ungrouped command (no heading emitted).

help: str | None = None

Optional group description, rendered as prose under the heading.

to_roff()[source]

Render an optional .SS heading, group help, then the options.

Return type:

list[str]

class click_extra.man_page.ManPage(name, short_help='', section='1', synopsis_pieces=(), description='', operands=(), option_groups=(), subcommands=(), environment=(), files=(), exit_status=(('0', 'Success.'), ('1', 'A runtime error, or an aborted prompt (Ctrl-C, a declined confirmation).'), ('2', 'A usage error: unknown option, invalid value, missing operand, or an unparsable configuration file.')), version=None, date='', manual=None, authors=None, copyright=None)[source]

Bases: object

A whole man page in structured form, ready to render to roff.

One ManPage maps to one command (or subcommand). Its fields are the man-pages(7) sections, in the order Man-page documents them. Build it with extract_manpage() and serialize with to_roff().

name: str

Full command path, space-joined (e.g. weather forecast).

short_help: str = ''

One-line description for the NAME section.

section: str = '1'

Man section number.

synopsis_pieces: tuple[str, ...] = ()

Usage metavars after the command name ([OPTIONS], CITY, …).

description: str = ''

The command’s full help text / docstring for the DESCRIPTION section.

operands: tuple[tuple[str, str], ...] = ()

Positional arguments as (metavar, help) pairs.

option_groups: tuple[ManOptionGroup, ...] = ()

The OPTIONS entries, partitioned into one or more groups. A command without explicit option groups carries a single untitled group.

subcommands: tuple[tuple[str, str], ...] = ()

For groups: (name, short_help) pairs for the COMMANDS section.

environment: tuple[tuple[str, str], ...] = ()

ENVIRONMENT entries as (variable_name, help) pairs.

files: tuple[str, ...] = ()

FILES entries (configuration search patterns).

exit_status: tuple[tuple[str, str], ...] = (('0', 'Success.'), ('1', 'A runtime error, or an aborted prompt (Ctrl-C, a declined confirmation).'), ('2', 'A usage error: unknown option, invalid value, missing operand, or an unparsable configuration file.'))

EXIT STATUS entries as (code, meaning) pairs.

version: str | None = None

Version string for the .TH header.

date: str = ''

Date for the .TH header (YYYY-MM-DD).

manual: str | None = None

Manual name for the .TH header (the centered footer title).

authors: str | None = None

AUTHORS section content, or None to omit the section.

copyright: str | None = None

COPYRIGHT section content, or None to omit the section.

property title: str

The .TH page title: the command path, hyphen-joined and upper-cased.

to_roff()[source]

Render the full man page as a roff/troff string.

Return type:

str

click_extra.man_page.extract_manpage(command, ctx, *, version=None, date=None, manual=None, authors=None, copyright=None)[source]

Build a ManPage from a Click command and its context.

The context must have been created for command (e.g. via click.Command.make_context() with resilient_parsing=True), so that auto-generated environment-variable prefixes resolve correctly.

Return type:

ManPage

click_extra.man_page.iter_command_contexts(command, prog_name=None, _parent=None, _path=())[source]

Walk a command tree, yielding (path, command, context) for each visible command.

Subcommands are discovered dynamically (click.Group.list_commands() / get_command()), so dynamically-registered commands are included. Hidden commands are skipped. Each context is built with resilient_parsing=True to avoid triggering required-argument errors, prompts, or eager-option side effects.

Return type:

Iterator[tuple[tuple[str, ...], Command, Context]]

click_extra.man_page.render_manpage(command, prog_name=None, ctx=None, **overrides)[source]

Render a single command’s man page as a roff string.

Reuses ctx when given (e.g. the live invocation context), otherwise builds a throwaway one with resilient_parsing=True. Keyword overrides (version, date, manual, authors, copyright) are passed through to extract_manpage().

Return type:

str

click_extra.man_page.render_manpages(command, prog_name=None, **overrides)[source]

Render the whole command tree, one man page per (sub)command.

Returns an ordered mapping of {filename: roff} where each filename is the command path joined by hyphens plus the section suffix (e.g. weather-forecast.1).

Return type:

dict[str, str]

click_extra.man_page.write_manpages(command, target_dir, prog_name=None, **overrides)[source]

Render the command tree and write each man page into target_dir.

Creates target_dir if missing. Returns the list of written paths.

Return type:

list[Path]

class click_extra.man_page.ManOption(param_decls=None, is_flag=True, expose_value=False, is_eager=True, help="Show the command's man page (roff) and exit.", **kwargs)[source]

Bases: ExtraOption

A pre-configured --man flag that prints the command’s man page (roff) to stdout and exits.

Eager and value-less, like ShowParamsOption. Part of the default option set injected by default_extra_params(), so every @extra_command and @extra_group exposes it. Use @man_option to add it to a plain Click CLI.

Note

The flag is named --man, not --show-man or --man-page.

In the POSIX, GNU and BSD traditions a program does not emit its own man page through a flag: the page is a separate file read with man <prog>, either hand-written (BSD mdoc) or generated at build time from --help output (GNU help2man). Click Extra already covers that build-time path with write_manpages(), its help2man equivalent.

The one ecosystem that exposes a runtime flag is Perl’s Pod::Usage, whose convention is --help for the brief usage and bare --man for the full manual. --man also lines up with the neighbouring --help and --version informational flags, which use bare nouns with no show- prefix. --show-man and --man-page have no precedent outside Click Extra.

print_man(ctx, param, value)[source]

Render and print the invoked command’s man page, then exit.

Return type:

None