#!/usr/bin/env python # Copyright (C) 2020 Collin Capano # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 of the License, or (at your # option) any later version. # # 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 General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """Prints an RST table of data options for inference models. """ from io import StringIO import re import textwrap from pycbc.inference.models import data_utils # wrapper for long metavars metavar_txtwrap = textwrap.TextWrapper(width=34, break_long_words=False) # convenience class for storing row data class Row(object): def __init__(self, divider=None, lpad=0, wrap_option=True): if divider is None: divider = ' | ' self.divider = divider self.lborder = ' '*lpad + divider[1:] self.rborder = divider[:-1] self._groupmsg = '' self.wrap_option = wrap_option self._option = '' self._metavar = '' self._helpmsg = '' @property def option(self): return self._option @option.setter def option(self, option): if self.wrap_option: # add `` around option string option = '``'+option+'``' self._option = option @property def metavar(self): return self._metavar @metavar.setter def metavar(self, metavar): # text wrap if metavar is more than 34 characters wide self._metavar = '\n'.join(metavar_txtwrap.wrap(metavar)) @staticmethod def replace_doubledash(str_): """Replaces all instances of --arg with ``arg`` in a string.""" pattern = r"--\w+-?\w*" for s in re.findall(pattern, str_): rep = '``' + s.replace('--', '') + '``' str_ = re.sub(s, rep, str_) return str_ @property def helpmsg(self): return self._helpmsg @helpmsg.setter def helpmsg(self, msg): # replace all instances of --arg with ``arg`` self._helpmsg = self.replace_doubledash(msg) @property def groupmsg(self): return self._groupmsg @groupmsg.setter def groupmsg(self, msg): # replace all instances of --arg with ``arg`` self._groupmsg = self.replace_doubledash(msg) @property def isgroup(self): return self.groupmsg != '' @property def grouplen(self): return max(map(len, self.groupmsg.split('\n'))) @property def metavarlen(self): return max(map(len, self.metavar.split('\n'))) @property def helplen(self): return max(map(len, self.helpmsg.split('\n'))) def format(self, maxlen, optlen, metalen, helplen): if self.isgroup: out = ['{lbdr}{msg:<{width}}{rbdr}'.format(lbdr=self.lborder, msg=msg, width=maxlen, rbdr=self.rborder) for msg in self.groupmsg.split('\n')] else: tmplt = '{msg:<{rpad}}' out = [] metavar = self.metavar.split('\n') helpmsg = self.helpmsg.split('\n') nlines = max(len(metavar), len(helpmsg)) for ii in range(nlines): if ii == 0: optstr = self.option else: optstr = '' if ii < len(metavar): metastr = metavar[ii] else: metastr = '' if ii < len(helpmsg): helpstr = helpmsg[ii] else: helpstr = '' optstr = tmplt.format(msg=optstr, rpad=optlen) metastr = tmplt.format(msg=metastr, rpad=metalen) helpstr = tmplt.format(msg=helpstr, rpad=helplen) #rowstr = self.divider.join([optstr, helpstr, metastr]) rowstr = self.divider.join([optstr, metastr, helpstr]) # add borders rowstr = '{}{}{}'.format(self.lborder, rowstr, self.rborder) out.append(rowstr) return '\n'.join(out) def __len__(self): if self.isgroup: baselen = self.grouplen else: baselen = len(self.option) + self.metavarlen + self.helplen return baselen + 2*len(self.divider) # create a data parser that has the options parser = data_utils.create_data_parser() # dump the help message to a file buffer fp = StringIO() parser.print_help(file=fp) # Regular expressions to interpret the help message: # Lines with a "--option stuff" (i.e., a single space after the option) include # metadata. Lines with "--option msg" (i.e., multiple spaces after the # option) contain no metadata, and just go straight to the help message. regx_optmeta = re.compile( r'^\s+((-\S, )*)--(?P