Source code for echofilter.ui.formatters

"""
Provides extensions to argparse.
"""

# This file is part of Echofilter.
#
# Copyright (C) 2020-2022  Scott C. Lowe and Offshore Energy Research Association (OERA)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

import argparse


[docs]class DedentTextHelpFormatter(argparse.HelpFormatter): """ Help message formatter. Retains formatting of all help text, except from indentation. Leading new lines are also stripped. """ def _split_lines(self, text, width): import textwrap return textwrap.dedent(text.lstrip("\n")).splitlines() def _fill_text(self, text, width, indent): import textwrap return "".join( indent + line for line in textwrap.dedent(text.lstrip("\n")).splitlines(keepends=True) )
[docs]class FlexibleHelpFormatter(argparse.HelpFormatter): """ Help message formatter which can handle different formatting specifications. The following formatters are supported: ``"R|"`` Raw. will be left as is, processed using ``argparse.RawTextHelpFormatter``. ``"d|"`` Raw except for indentation. Will be dedented and leading newlines stripped only, processed using ``argparse.RawTextHelpFormatter``. The format specifier will be stripped from the text. Notes ----- Based on https://stackoverflow.com/a/22157266/1960959 and https://sourceforge.net/projects/ruamel-std-argparse/. """ def _split_lines(self, text, *args, **kwargs): if len(text) < 2 or text[1] != "|": return super()._split_lines(text, *args, **kwargs) if text[0] == "R": return argparse.RawTextHelpFormatter._split_lines( self, text[2:], *args, **kwargs ) if text[0] == "d": return DedentTextHelpFormatter._split_lines(self, text[2:], *args, **kwargs) raise ValueError("Invalid format code: {}".format(text[0])) def _fill_text(self, text, *args, **kwargs): if len(text) < 2 or text[1] != "|": return super()._fill_text(text, *args, **kwargs) if text[0] == "R": return argparse.RawTextHelpFormatter._fill_text( self, text[2:], *args, **kwargs ) if text[0] == "d": return DedentTextHelpFormatter._fill_text(self, text[2:], *args, **kwargs) raise ValueError("Invalid format code: {}".format(text[0]))
[docs]def format_parser_for_sphinx(parser): """ Pre-format parser help for sphinx-argparse processing. Parameters ---------- parser : argparse.ArgumentParser Initial argument parser. Returns ------- parser : argparse.ArgumentParser The same argument parser, but with raw help text touched up so it renders correctly when passed through sphinx-argparse. """ for action_group in parser._action_groups: for action in action_group._group_actions: # Get the help text for this action help = action.help # Remove quotes around default strings, to prevent double-marking. help = help.replace('"%(default)s"', "%(default)s") help = help.replace("'%(default)s'", "%(default)s") # Wrap any default values in `` so they are rendered as code. help = help.replace("%(default)s", "``%(default)s``") # But also ensure we don't add backticks around backticks help = help.replace("````", "``") # Remove flexible formatter indictor, if present if ( parser.formatter_class == FlexibleHelpFormatter and len(help) > 1 and help[1] == "|" ): help = help[2:] # Overwrite the help text action.help = help return parser