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