Indented text printing

This commit is contained in:
Tony Garnock-Jones 2022-01-12 02:02:36 +01:00
parent 3cc875bce3
commit ddfd2e24a6
2 changed files with 47 additions and 25 deletions

View File

@ -312,8 +312,10 @@ def parse_with_annotations(bs, **kwargs):
return Parser(input_buffer=bs, include_annotations=True, **kwargs).next()
class Formatter(TextCodec):
def __init__(self, format_embedded=lambda x: x):
def __init__(self, format_embedded=lambda x: x, indent=None):
super(Formatter, self).__init__()
self.indent_delta = 0 if indent is None else indent
self.indent_distance = 0
self.chunks = []
self._format_embedded = format_embedded
@ -325,6 +327,19 @@ class Formatter(TextCodec):
def contents(self):
return u''.join(self.chunks)
def is_indenting(self):
return self.indent_delta > 0
def write_indent(self):
if self.is_indenting():
self.chunks.append('\n' + ' ' * self.indent_distance)
def write_indent_space(self):
if self.is_indenting():
self.write_indent()
else:
self.chunks.append(' ')
def write_stringlike_char(self, c):
if c == '\\': self.chunks.append('\\\\')
elif c == '\x08': self.chunks.append('\\b')
@ -334,15 +349,23 @@ class Formatter(TextCodec):
elif c == '\x09': self.chunks.append('\\t')
else: self.chunks.append(c)
def write_seq(self, opener, closer, vs):
def write_seq(self, opener, closer, vs, appender):
vs = list(vs)
itemcount = len(vs)
self.chunks.append(opener)
first_item = True
for v in vs:
if first_item:
first_item = False
else:
self.chunks.append(' ')
self.append(v)
if itemcount == 0:
pass
elif itemcount == 1:
appender(vs[0])
else:
self.indent_distance = self.indent_distance + self.indent_delta
self.write_indent()
appender(vs[0])
for v in vs[1:]:
self.write_indent_space()
appender(v)
self.indent_distance = self.indent_distance - self.indent_delta
self.write_indent()
self.chunks.append(closer)
def append(self, v):
@ -366,25 +389,19 @@ class Formatter(TextCodec):
else: self.write_stringlike_char(c)
self.chunks.append('"')
elif isinstance(v, list):
self.write_seq('[', ']', v)
self.write_seq('[', ']', v, self.append)
elif isinstance(v, tuple):
self.write_seq('[', ']', v)
self.write_seq('[', ']', v, self.append)
elif isinstance(v, set):
self.write_seq('#{', '}', v)
self.write_seq('#{', '}', v, self.append)
elif isinstance(v, frozenset):
self.write_seq('#{', '}', v)
self.write_seq('#{', '}', v, self.append)
elif isinstance(v, dict):
self.chunks.append('{')
need_comma = False
for (k, v) in v.items():
if need_comma:
self.chunks.append(', ')
else:
need_comma = True
self.append(k)
def append_kv(kv):
self.append(kv[0])
self.chunks.append(': ')
self.append(v)
self.chunks.append('}')
self.append(kv[1])
self.write_seq('{', '}', v.items(), append_kv)
else:
try:
i = iter(v)
@ -393,7 +410,7 @@ class Formatter(TextCodec):
if i is None:
self.cannot_format(v)
else:
self.write_seq('[', ']', i)
self.write_seq('[', ']', i, self.append)
def cannot_format(self, v):
raise TypeError('Cannot preserves-format: ' + repr(v))

View File

@ -99,7 +99,12 @@ class Record(object):
encoder.buffer.append(0x84)
def __preserve_write_text__(self, formatter):
formatter.write_seq('<', '>', (self.key,) + self.fields)
formatter.chunks.append('<')
formatter.append(self.key)
for f in self.fields:
formatter.chunks.append(' ')
formatter.append(f)
formatter.chunks.append('>')
def __getitem__(self, index):
return self.fields[index]