"""Module containing various formatting related utilities."""## (C) Pywikibot team, 2015-2023## Distributed under the terms of the MIT license.#from__future__importannotationsimportmathimportrefrompywikibot.loggingimportinfofrompywikibot.toolsimportdeprecatedfrompywikibot.userinterfacesimportterminal_interface_base
[docs]classSequenceOutputter:"""A class formatting a list of items. It is possible to customize the appearance by changing ``format_string`` which is used by ``str.format`` with ``index``, ``width`` and ``item``. Each line is joined by the separator and the complete text is surrounded by the prefix and the suffix. All three are by default a new line. The index starts at 1 and for the width it's using the width of the sequence's length written as a decimal number. So a length of 100 will result in a with of 3 and a length of 99 in a width of 2. It is iterating over ``self.sequence`` to generate the text. That sequence can be any iterator but the result is better when it has an order. """format_string=' {index:>{width}} - {item}'separator='\n'prefix='\n'suffix='\n'def__init__(self,sequence)->None:"""Create a new instance with a reference to the sequence."""super().__init__()self.sequence=sequence@propertydefout(self):"""Create the text with one item on each line."""ifself.sequence:# Width is only defined when the length is greater 0width=int(math.log10(len(self.sequence)))+1content=self.separator.join(self.format_string.format(index=i,item=item,width=width)fori,iteminenumerate(self.sequence,start=1))else:content=''returnself.prefix+content+self.suffix
[docs]@deprecated('pywikibot.info(SequenceOutputter.out)',since='9.0.0')defoutput(self)->None:"""Output the text of the current sequence. .. deprecated:: 9.0 Use :func:`pywikibot.info()<pywikibot.logging.info>` with :attr:`out` property. """info(self.out)
[docs]@deprecated('New color format pattern like <<color>>colored text<<default>>',since='7.2.0')defcolor_format(text:str,*args,**kwargs)->str:r"""Do ``str.format`` without having to worry about colors. It is automatically adding \\03 in front of color fields so it's unnecessary to add them manually. Any other \\03 in the text is disallowed. You may use a variant {color} by assigning a valid color to a named parameter color. .. deprecated:: 7.2 new color format pattern like ``f'<<{color}>>colored text<<default>>'`` can be used instead. :param text: The format template string :return: The formatted string :raises ValueError: Wrong format string or wrong keywords """colors=set(terminal_interface_base.colors)# Dot.product of colors to create all possible combinations of foreground# and background colors.colors|={f'{c1};{c2}'forc1incolorsforc2incolors}col_pat='|'.join(colors)text=re.sub(f'(?:\03)?{{({col_pat})}}',r'<<\1>>',text)replace_color=kwargs.get('color')ifreplace_colorincolors:text=text.replace('{color}',f'<<{replace_color}>>')if'\03'intext:raiseValueError('\\03 pattern found in color format')intersect=colors.intersection(kwargs)# kwargs use colorsifintersect:raiseValueError('Keyword argument(s) use valid color(s): '+'", "'.join(intersect))try:text=text.format(*args,**kwargs)exceptKeyErrorase:ifstr(e).strip("'")incolors:raiseValueError(f'Color field "{e}" in "{text}" uses conversion 'f'information or format spec')raisereturntext