Skip to content

Commit

Permalink
refactor: Improve CLI help reST markup stripping
Browse files Browse the repository at this point in the history
- Change: Monkey-patch neccesary `argparse` classes to strip markup upon
  attribute reference.
- Add: De-monkey-patch `argparse` classes when builing the docs.
  • Loading branch information
AnonymouX47 committed Apr 7, 2023
1 parent 885a876 commit f740e55
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 16 deletions.
9 changes: 9 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

import argparse

from docutils.parsers.rst import directives
from docutils.statemachine import StringList
from sphinx_toolbox import confval

from termvisage import parsers # noqa: F401

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
Expand Down Expand Up @@ -101,3 +105,8 @@ class ConfigValue(confval.ConfigurationValue, ConfigValueSibling):


confval.ConfigurationValue = ConfigValue

# # -- CLI Parser (do not strip reST markup) -------------------------------------
del argparse.ArgumentParser.epilog
del argparse.Action.help
del argparse._ArgumentGroup.description
43 changes: 27 additions & 16 deletions src/termvisage/parsers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""CLI argument parsers"""

import argparse
import re
import sys
from argparse import Action, ArgumentParser, RawDescriptionHelpFormatter, _ArgumentGroup

from term_image.image import ITerm2Image, Size

Expand All @@ -11,24 +11,27 @@
from .config import config_options


class ReSTHelpArgumentParser(argparse.ArgumentParser):
"""Description, argument help and epilog may use reStructuredText.
reST markup is strip from the help text after it has been formatted.
"""
def strip_markup(string: str) -> str:
"""Strip selected reST markup from the *string*."""
if string:
string = string.replace("``", "`")
for pattern, repl in (
(r":(\w+):`(.+?)( <.+>)?`", r"\2"),
(r"\*\*(.+)\*\*", r"\1"),
(r"\*(.+)\*", r"\1"),
(r" \[.+\]_", ""),
):
string = re.sub(pattern, repl, string)

def format_help(self) -> str:
help_text = super().format_help().replace("``", "`")
help_text = re.sub(r":(\w+):`(.+?)( <.+>)?`", r"\2", help_text)
help_text = re.sub(r"\*\*(.+)\*\*", r"\1", help_text)
help_text = re.sub(r"\*(.+)\*", r"\1", help_text)
help_text = re.sub(r" \[.+\]_", "", help_text)
return string

return help_text

# Parser epilog, group descriptions and argument help may use reStructuredText markup.
# Ensure any markup used is stripped in `strip_markup()`.

parser = ReSTHelpArgumentParser(
parser = ArgumentParser(
prog="termvisage",
formatter_class=argparse.RawDescriptionHelpFormatter,
formatter_class=RawDescriptionHelpFormatter,
description="Display/Browse images in a terminal",
epilog=""" \
Expand Down Expand Up @@ -544,7 +547,7 @@ def format_help(self) -> str:
),
)

kitty_parser = argparse.ArgumentParser(add_help=False)
kitty_parser = ArgumentParser(add_help=False)
kitty_options = kitty_parser.add_argument_group(
"Kitty Style Options",
"These options apply only when the *kitty* :term:`render style` is used",
Expand Down Expand Up @@ -575,7 +578,7 @@ def format_help(self) -> str:
),
)

iterm2_parser = argparse.ArgumentParser(add_help=False)
iterm2_parser = ArgumentParser(add_help=False)
iterm2_options = iterm2_parser.add_argument_group(
"iTerm2 Style Options",
"These options apply only when the *iterm2* :term:`render style` is used",
Expand Down Expand Up @@ -641,3 +644,11 @@ def format_help(self) -> str:
parser._option_string_actions.update(style_parser._option_string_actions)
parser._action_groups.extend(style_parser._action_groups)
parser._mutually_exclusive_groups.extend(style_parser._mutually_exclusive_groups)

# Setup reST markup to be Striped from epilog, group descriptions and argument help.
# Anything patched here must be unpatched in the docs config script.
ArgumentParser.epilog = property(lambda self: strip_markup(vars(self)["epilog"]))
Action.help = property(lambda self: strip_markup(vars(self)["help"]))
_ArgumentGroup.description = property(
lambda self: strip_markup(vars(self)["description"])
)

0 comments on commit f740e55

Please sign in to comment.