From 61c2acef022ef81b043e3c10215ff3afb3a9ff80 Mon Sep 17 00:00:00 2001 From: Ofek Lev Date: Fri, 19 Nov 2021 03:43:40 -0500 Subject: [PATCH] Add ability to ignore ASCII art (#45) --- README.md | 1 + mkdocs_click/_docs.py | 29 ++++++++++++++++++++++++----- mkdocs_click/_extension.py | 8 +++++++- tests/test_docs.py | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 16fefdc..21ae5d9 100644 --- a/README.md +++ b/README.md @@ -134,3 +134,4 @@ Options: - `prog_name`: _(Optional, default: same as `command`)_ The name to display for the command. - `depth`: _(Optional, default: `0`)_ Offset to add when generating headers. - `style`: _(Optional, default: `plain`)_ Style for the options section. The possible choices are `plain` and `table`. +- `remove_ascii_art`: _(Optional, default: `False`)_ When docstrings begin with the escape character `\b`, all text will be ignored until the next blank line is encountered. diff --git a/mkdocs_click/_docs.py b/mkdocs_click/_docs.py index b4ce905..553beac 100644 --- a/mkdocs_click/_docs.py +++ b/mkdocs_click/_docs.py @@ -14,13 +14,17 @@ def make_command_docs( command: click.BaseCommand, depth: int = 0, style: str = "plain", + remove_ascii_art: bool = False, has_attr_list: bool = False, ) -> Iterator[str]: """Create the Markdown lines for a command and its sub-commands.""" for line in _recursively_make_command_docs( - prog_name, command, depth=depth, style=style, has_attr_list=has_attr_list + prog_name, command, depth=depth, style=style, remove_ascii_art=remove_ascii_art, has_attr_list=has_attr_list ): - yield line.replace("\b", "") + if line.strip() == "\b": + continue + + yield line def _recursively_make_command_docs( @@ -29,13 +33,14 @@ def _recursively_make_command_docs( parent: click.Context = None, depth: int = 0, style: str = "plain", + remove_ascii_art: bool = False, has_attr_list: bool = False, ) -> Iterator[str]: """Create the raw Markdown lines for a command and its sub-commands.""" ctx = click.Context(cast(click.Command, command), info_name=prog_name, parent=parent) yield from _make_title(ctx, depth, has_attr_list=has_attr_list) - yield from _make_description(ctx) + yield from _make_description(ctx, remove_ascii_art=remove_ascii_art) yield from _make_usage(ctx) yield from _make_options(ctx, style) @@ -103,12 +108,26 @@ def _make_title_full_command_path(ctx: click.Context, depth: int) -> Iterator[st yield "" -def _make_description(ctx: click.Context) -> Iterator[str]: +def _make_description(ctx: click.Context, remove_ascii_art: bool = False) -> Iterator[str]: """Create markdown lines based on the command's own description.""" help_string = ctx.command.help or ctx.command.short_help if help_string: - yield from help_string.splitlines() + if remove_ascii_art: + skipped_ascii_art = True + for i, line in enumerate(help_string.splitlines()): + if skipped_ascii_art is False: + if not line.strip(): + skipped_ascii_art = True + continue + elif i == 0 and line.strip() == "\b": + skipped_ascii_art = False + + if skipped_ascii_art: + yield line + else: + yield from help_string.splitlines() + yield "" diff --git a/mkdocs_click/_extension.py b/mkdocs_click/_extension.py index 489cdbf..2264c23 100644 --- a/mkdocs_click/_extension.py +++ b/mkdocs_click/_extension.py @@ -23,13 +23,19 @@ def replace_command_docs(has_attr_list: bool = False, **options: Any) -> Iterato prog_name = options.get("prog_name", None) depth = int(options.get("depth", 0)) style = options.get("style", "plain") + remove_ascii_art = options.get("remove_ascii_art", False) command_obj = load_command(module, command) prog_name = prog_name or command_obj.name or command return make_command_docs( - prog_name=prog_name, command=command_obj, depth=depth, style=style, has_attr_list=has_attr_list + prog_name=prog_name, + command=command_obj, + depth=depth, + style=style, + remove_ascii_art=remove_ascii_art, + has_attr_list=has_attr_list, ) diff --git a/tests/test_docs.py b/tests/test_docs.py index 333e68a..39168da 100644 --- a/tests/test_docs.py +++ b/tests/test_docs.py @@ -16,6 +16,31 @@ def hello(): """Hello, world!""" +@click.command() +@click.option("-d", "--debug", help="Include debug output") +def hello_escape_marker(): + """ + \b + Hello, world! + """ + + +@click.command() +@click.option("-d", "--debug", help="Include debug output") +def hello_ascii_art(): + """ + \b + ______ __ __ ______ __ ___ + / || | | | / || |/ / + | ,----'| | | | | ,----'| ' / + | | | | | | | | | < + | `----.| `----.| | | `----.| . \\ + \\______||_______||__| \\______||__|\\__\\ + + Hello, world! + """ + + HELLO_EXPECTED = dedent( """ # hello @@ -60,6 +85,16 @@ def test_style_invalid(): list(make_command_docs("hello", hello, style="invalid")) +def test_basic_escape_marker(): + output = "\n".join(make_command_docs("hello", hello_escape_marker)) + assert output == HELLO_EXPECTED + + +def test_basic_ascii_art(): + output = "\n".join(make_command_docs("hello", hello_ascii_art, remove_ascii_art=True)) + assert output == HELLO_EXPECTED + + @click.command() @click.option("-d", "--debug", help="Include debug output") @click.option("--choice", type=click.Choice(["foo", "bar"]), default="foo")