This function will take a list of tuples and transform it into a list of string representing the data as a ReST Sphinx table.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | import string
def as_rest_table(data, full=False):
"""
>>> from report_table import as_rest_table
>>> data = [('what', 'how', 'who'),
... ('lorem', 'that is a long value', 3.1415),
... ('ipsum', 89798, 0.2)]
>>> print as_rest_table(data, full=True)
+-------+----------------------+--------+
| what | how | who |
+=======+======================+========+
| lorem | that is a long value | 3.1415 |
+-------+----------------------+--------+
| ipsum | 89798 | 0.2 |
+-------+----------------------+--------+
>>> print as_rest_table(data)
===== ==================== ======
what how who
===== ==================== ======
lorem that is a long value 3.1415
ipsum 89798 0.2
===== ==================== ======
"""
data = data if data else [['No Data']]
table = []
# max size of each column
sizes = map(max, zip(*[[len(str(elt)) for elt in member]
for member in data]))
num_elts = len(sizes)
if full:
start_of_line = '| '
vertical_separator = ' | '
end_of_line = ' |'
line_marker = '-'
else:
start_of_line = ''
vertical_separator = ' '
end_of_line = ''
line_marker = '='
meta_template = vertical_separator.join(['{{{{{0}:{{{0}}}}}}}'.format(i)
for i in range(num_elts)])
template = '{0}{1}{2}'.format(start_of_line,
meta_template.format(*sizes),
end_of_line)
# determine top/bottom borders
if full:
to_separator = string.maketrans('| ', '+-')
else:
to_separator = string.maketrans('|', '+')
start_of_line = start_of_line.translate(to_separator)
vertical_separator = vertical_separator.translate(to_separator)
end_of_line = end_of_line.translate(to_separator)
separator = '{0}{1}{2}'.format(start_of_line,
vertical_separator.join([x*line_marker for x in sizes]),
end_of_line)
# determine header separator
th_separator_tr = string.maketrans('-', '=')
start_of_line = start_of_line.translate(th_separator_tr)
line_marker = line_marker.translate(th_separator_tr)
vertical_separator = vertical_separator.translate(th_separator_tr)
end_of_line = end_of_line.translate(th_separator_tr)
th_separator = '{0}{1}{2}'.format(start_of_line,
vertical_separator.join([x*line_marker for x in sizes]),
end_of_line)
# prepare result
table.append(separator)
# set table header
titles = data[0]
table.append(template.format(*titles))
table.append(th_separator)
for d in data[1:-1]:
table.append(template.format(*d))
if full:
table.append(separator)
table.append(template.format(*data[-1]))
table.append(separator)
return '\n'.join(table)
|