diff --git a/mkdocs_click/_docs.py b/mkdocs_click/_docs.py index a1d19d9..a18c7a1 100644 --- a/mkdocs_click/_docs.py +++ b/mkdocs_click/_docs.py @@ -1,7 +1,7 @@ # (C) Datadog, Inc. 2020-present # All rights reserved # Licensed under the Apache license (see LICENSE) -from typing import Iterator, List, Optional, cast +from typing import Iterator, List, Optional, cast, Iterable import click @@ -102,17 +102,40 @@ def _make_usage(ctx: click.Context) -> Iterator[str]: def _make_options(ctx: click.Context) -> Iterator[str]: """Create the Markdown lines describing the options for the command.""" - formatter = ctx.make_formatter() - click.Command.format_options(ctx.command, ctx, formatter) - # First line is redundant "Options" - # Last line is `--help` - option_lines = formatter.getvalue().splitlines()[1:-1] - if not option_lines: + + def backquote(opts: Iterable[str]) -> List[str]: + return [f"`{opt}`" for opt in opts] + + def format_possible_value(opt: click.Option) -> str: + param_type = opt.type + + if isinstance(param_type, click.Choice): + return f"{param_type.name.upper()} ({' | '.join(backquote(param_type.choices))})" + elif isinstance(param_type, click.DateTime): + return f"{param_type.name.upper()} ({' | '.join(backquote(param_type.formats))})" + elif isinstance(param_type, (click.IntRange, click.FloatRange)): + if param_type.min is not None and param_type.max is not None: + return f"{param_type.name.upper()} (between `{param_type.min}` and `{param_type.max}`)" + elif param_type.min is not None: + return f"{param_type.name.upper()} (`{param_type.min}` and above)" + else: + return f"{param_type.name.upper()} (`{param_type.max}` and below)" + else: + return param_type.name.upper() + + params = [param for param in ctx.command.get_params(ctx) if isinstance(param, click.Option)] + + if params[0].opts[0] == "--help": return - yield "Options:" + yield "**Options:**" yield "" - yield "```" - yield from option_lines - yield "```" + yield "| Name | Type | Description | Default |" + yield "| ------ | ---- | ----------- | ------- |" + for param in params[:-1]: + options = f"{', '.join(backquote(param.opts))}{'/{}'.format(', '.join(backquote(param.secondary_opts))) if param.secondary_opts != [] else ''}" # noqa: E501 + value_type = format_possible_value(param) + description = param.help if param.help is not None else "No description given" + default = f"`{param.default}`" if param.default is not None else "_required_" + yield f"| {options} | {value_type} | {description} | {default} |" yield "" diff --git a/tests/app/expected.md b/tests/app/expected.md index 95b47a0..ec02ee2 100644 --- a/tests/app/expected.md +++ b/tests/app/expected.md @@ -28,12 +28,12 @@ Usage: cli bar hello [OPTIONS] ``` -Options: +**Options:** -``` - --count INTEGER Number of greetings. - --name TEXT The person to greet. -``` +| Name | Type | Description | Default | +| ------ | ---- | ----------- | ------- | +| `--count` | INTEGER | Number of greetings. | `1` | +| `--name` | TEXT | The person to greet. | _required_ | ## foo diff --git a/tests/unit/test_docs.py b/tests/unit/test_docs.py index f145777..b47ddbf 100644 --- a/tests/unit/test_docs.py +++ b/tests/unit/test_docs.py @@ -28,12 +28,11 @@ def hello(): hello [OPTIONS] ``` - Options: - - ``` - -d, --debug TEXT Include debug output - ``` + **Options:** + | Name | Type | Description | Default | + | ------ | ---- | ----------- | ------- | + | `-d`, `--debug` | TEXT | Include debug output | _required_ | """ ).strip() @@ -90,11 +89,11 @@ def test_custom_multicommand(): multi hello [OPTIONS] ``` - Options: + **Options:** - ``` - -d, --debug TEXT Include debug output - ``` + | Name | Type | Description | Default | + | ------ | ---- | ----------- | ------- | + | `-d`, `--debug` | TEXT | Include debug output | _required_ | """ ).lstrip()