def _parse_with_formatting(string, args, kwargs, *, recursion_depth=2, auto_arg_index=0, recursive=False): # This function re-implements Formatter._vformat() if recursion_depth < 0: raise ValueError("Max string recursion exceeded") formatter = Formatter() parser = AnsiParser() for literal_text, field_name, format_spec, conversion in formatter.parse( string): parser.feed(literal_text, raw=recursive) if field_name is not None: if field_name == "": if auto_arg_index is False: raise ValueError("cannot switch from manual field " "specification to automatic field " "numbering") field_name = str(auto_arg_index) auto_arg_index += 1 elif field_name.isdigit(): if auto_arg_index: raise ValueError("cannot switch from manual field " "specification to automatic field " "numbering") auto_arg_index = False obj, _ = formatter.get_field(field_name, args, kwargs) obj = formatter.convert_field(obj, conversion) format_spec, auto_arg_index = Colorizer._parse_with_formatting( format_spec, args, kwargs, recursion_depth=recursion_depth - 1, auto_arg_index=auto_arg_index, recursive=True, ) formatted = formatter.format_field(obj, format_spec) parser.feed(formatted, raw=True) tokens = parser.done() if recursive: return AnsiParser.strip(tokens), auto_arg_index return tokens
def formatMentions(cls, text, *args, **kwargs): """Like `str.format`, but takes tuples with a thread id and text instead. Returns a `Message` object, with the formatted string and relevant mentions. ``` >>> Message.formatMentions("Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael")) <Message (None): "Hey 'Peter'! My name is Michael", mentions=[<Mention 1234: offset=4 length=7>, <Mention 4321: offset=24 length=7>] emoji_size=None attachments=[]> >>> Message.formatMentions("Hey {p}! My name is {}", ("1234", "Michael"), p=("4321", "Peter")) <Message (None): 'Hey Peter! My name is Michael', mentions=[<Mention 4321: offset=4 length=5>, <Mention 1234: offset=22 length=7>] emoji_size=None attachments=[]> ``` """ result = "" mentions = list() offset = 0 f = Formatter() field_names = [field_name[1] for field_name in f.parse(text)] automatic = "" in field_names i = 0 for (literal_text, field_name, format_spec, conversion) in f.parse(text): offset += len(literal_text) result += literal_text if field_name is None: continue if field_name == "": field_name = str(i) i += 1 elif automatic and field_name.isdigit(): raise ValueError( "cannot switch from automatic field numbering to manual field specification" ) thread_id, name = f.get_field(field_name, args, kwargs)[0] if format_spec: name = f.format_field(name, format_spec) if conversion: name = f.convert_field(name, conversion) result += name mentions.append( Mention(thread_id=thread_id, offset=offset, length=len(name))) offset += len(name) message = cls(text=result, mentions=mentions) return message
def convert_field(self, value, conversion): if self.pretty: if value is None: return '' elif isinstance(value, list): def _str(x): if isinstance(x, unicode): return x else: return str(x) return ' '.join(map(_str, value)) return Formatter.convert_field(self, value, conversion)
def format_mentions(text, *args, **kwargs): """Like `str.format`, but takes tuples with a thread id and text instead. Return a tuple, with the formatted string and relevant mentions. >>> Message.format_mentions("Hey {!r}! My name is {}", ("1234", "Peter"), ("4321", "Michael")) ("Hey 'Peter'! My name is Michael", [Mention(thread_id=1234, offset=4, length=7), Mention(thread_id=4321, offset=24, length=7)]) >>> Message.format_mentions("Hey {p}! My name is {}", ("1234", "Michael"), p=("4321", "Peter")) ('Hey Peter! My name is Michael', [Mention(thread_id=4321, offset=4, length=5), Mention(thread_id=1234, offset=22, length=7)]) """ result = "" mentions = list() offset = 0 f = Formatter() field_names = [field_name[1] for field_name in f.parse(text)] automatic = "" in field_names i = 0 for (literal_text, field_name, format_spec, conversion) in f.parse(text): offset += len(literal_text) result += literal_text if field_name is None: continue if field_name == "": field_name = str(i) i += 1 elif automatic and field_name.isdigit(): raise ValueError( "cannot switch from automatic field numbering to manual field specification" ) thread_id, name = f.get_field(field_name, args, kwargs)[0] if format_spec: name = f.format_field(name, format_spec) if conversion: name = f.convert_field(name, conversion) result += name mentions.append( Mention(thread_id=thread_id, offset=offset, length=len(name))) offset += len(name) return result, mentions
usage='', description=''): pub = Publisher(reader, parser, writer, settings=None) pub.set_components(reader_name, parser_name, writer_name) output = pub.publish(argv, usage, description, config_section=None, enable_exit_status=True) return output formatter = Formatter() #self = self.vformat(format_string, args, kwargs) to_r = formatter.convert_field(value='3', conversion='r') formatter.format_field(value=+43000, format_spec='> 4,.0F') ALLOWED_TYPES = parse.ALLOWED_TYPES def print_types(): results = dict() for TYPE in ALLOWED_TYPES: expression = '{:' + TYPE + '}' results[TYPE] = parse.compile(expression)._expression return results extract = '[[fill]align][0][width][.precision][type]' e = parse.extract_format('3>03.2e', None)