jp (common): added use_buffer argument in Table:

when use_buffer is True, the Table is not printed but put in a buffer. A unicode string can then be computed when string property is used.
This commit is contained in:
Goffi 2017-08-23 00:10:09 +02:00
commit f4761fb1cc

View file

@ -505,7 +505,7 @@ class BaseEdit(object):
class Table(object):
def __init__(self, host, data, headers=None, filters=None):
def __init__(self, host, data, headers=None, filters=None, use_buffer=False):
"""
@param data(list[list]): table data
all lines must have the same number of columns
@ -515,8 +515,10 @@ class Table(object):
the callable will get col value as argument and must return a string
if it's unicode, it will be used with .format and must countain u'{}' which will be replaced with the string
if not None, must have same number of columns as data
@param use_buffer(bool): if True, bufferise output instead of printing it directly
"""
self.host = host
self._buffer = [] if use_buffer else None
# headers are columns names/titles, can be None
self.headers = headers
# sizes fof columns without headers,
@ -559,6 +561,12 @@ class Table(object):
# the table is empty, we print headers at their lenght
self.sizes = [len(h) for h in headers]
@property
def string(self):
if self._buffer is None:
raise exceptions.InternalError(u'buffer must be used to get a string')
return u'\n'.join(self._buffer)
@staticmethod
def readDictValues(data, keys, defaults=None):
if defaults is None:
@ -626,6 +634,13 @@ class Table(object):
headers.append(rendered)
return head_sep.join(headers)
def _disp(self, data):
"""output data (can be either bufferised or printed)"""
if self._buffer is not None:
self._buffer.append(data)
else:
self.host.disp(data)
def display(self,
head_alignment = u'left',
columns_alignment = u'left',
@ -647,7 +662,7 @@ class Table(object):
bottom_left=u'└',
bottom=None,
bottom_sep=u'─┴─',
bottom_right=u'┘'
bottom_right=u'┘',
):
"""Print the table
@ -657,6 +672,8 @@ class Table(object):
@param columns_alignment(unicode): how to align columns, can be left, center or right
@param col_sep(unicode): separator betweens columns
@param head_line(unicode): character to use to make line under head
@param disp(callable, None): method to use to display the table
None to use self.host.disp
"""
col_sep_size = len(regex.ansiRemove(col_sep))
if right is None:
@ -673,7 +690,7 @@ class Table(object):
left = right = head_line_left = head_line_right = u''
# top border
if show_borders:
self.host.disp(
self._disp(
top_left
+ top_sep.join([top*size for size in self.sizes])
+ top_right
@ -681,13 +698,13 @@ class Table(object):
# headers
if show_header:
self.host.disp(
self._disp(
left
+ self._headers(head_sep, head_alignment, head_style)
+ right
)
# header line
self.host.disp(
self._disp(
head_line_left
+ head_line_sep.join([head_line*size for size in self.sizes])
+ head_line_right
@ -704,20 +721,22 @@ class Table(object):
raise exceptions.InternalError(u'bad columns alignment argument')
for row in self.rows:
self.host.disp(left + col_sep.join([alignment(idx,c) for idx,c in enumerate(row)]) + right)
self._disp(left + col_sep.join([alignment(idx,c) for idx,c in enumerate(row)]) + right)
if show_borders:
# bottom border
self.host.disp(
self._disp(
bottom_left
+ bottom_sep.join([bottom*size for size in self.sizes])
+ bottom_right
)
# we return self so string can be used after display (table.display().string)
return self
def display_blank(self, **kwargs):
"""Display table without visible borders"""
kwargs_ = {'col_sep':u' ', 'head_line_sep':u' ', 'show_borders':False}
kwargs_.update(kwargs)
self.display(self,
**kwargs_
)
return self.display(self,
**kwargs_
)