| 1 | |
| 2 | |
| 3 | |
| 4 |
|
| 5 | |
| 6 | Ancillary argparse HelpFormatter class that works on a similar way as
|
| 7 | argparse.RawDescriptionHelpFormatter, e.g. description maintains line
|
| 8 | breaks, but it also implement transformations to the help text. The
|
| 9 | actual transformations ar given by enrich_text(), if the output is tty.
|
| 10 |
|
| 11 | Currently, the follow transformations are done:
|
| 12 |
|
| 13 | - Positional arguments are shown in upper cases;
|
| 14 | - if output is TTY, ``var`` and positional arguments are shown prepended
|
| 15 | by an ANSI SGR code. This is usually translated to bold. On some
|
| 16 | terminals, like, konsole, this is translated into a colored bold text.
|
| 17 |
|
| 18 |
|
| 19 | import argparse
|
| 20 | import re
|
| 21 | import sys
|
| 22 |
|
| 23 | class EnrichFormatter(argparse.HelpFormatter):
|
| 24 | |
| 25 | Better format the output, making easier to identify the positional args
|
| 26 | and how they're used at the __doc__ description.
|
| 27 |
|
| 28 | def __init__(self, *args, **kwargs):
|
| 29 | |
| 30 | Initialize class and check if is TTY.
|
| 31 |
|
| 32 | super().__init__(*args, **kwargs)
|
| 33 | self._tty = sys.stdout.isatty()
|
| 34 |
|
| 35 | def enrich_text(self, text):
|
| 36 | |
| 37 | Handle ReST markups (currently, only \`\`text\`\` markups).
|
| 38 |
|
| 39 | if self._tty and text:
|
| 40 | |
| 41 | return re.sub(r'\`\`(.+?)\`\`',
|
| 42 | lambda m: f'\033[1m{m.group(1)}\033[0m', text)
|
| 43 | return text
|
| 44 |
|
| 45 | def _fill_text(self, text, width, indent):
|
| 46 | |
| 47 | Enrich descriptions with markups on it.
|
| 48 |
|
| 49 | enriched = self.enrich_text(text)
|
| 50 | return "\n".join(indent + line for line in enriched.splitlines())
|
| 51 |
|
| 52 | def _format_usage(self, usage, actions, groups, prefix):
|
| 53 | |
| 54 | Enrich positional arguments at usage: line.
|
| 55 |
|
| 56 |
|
| 57 | prog = self._prog
|
| 58 | parts = []
|
| 59 |
|
| 60 | for action in actions:
|
| 61 | if action.option_strings:
|
| 62 | opt = action.option_strings[0]
|
| 63 | if action.nargs != 0:
|
| 64 | opt += f" {action.dest.upper()}"
|
| 65 | parts.append(f"[{opt}]")
|
| 66 | else:
|
| 67 | |
| 68 | parts.append(self.enrich_text(f"``{action.dest.upper()}``"))
|
| 69 |
|
| 70 | usage_text = f"{prefix or 'usage: '} {prog} {' '.join(parts)}\n"
|
| 71 | return usage_text
|
| 72 |
|
| 73 | def _format_action_invocation(self, action):
|
| 74 | |
| 75 | Enrich argument names.
|
| 76 |
|
| 77 | if not action.option_strings:
|
| 78 | return self.enrich_text(f"``{action.dest.upper()}``")
|
| 79 |
|
| 80 | return ", ".join(action.option_strings)
|