87 lines
2.6 KiB
Python
87 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
# -*- encoding: utf-8 -*-
|
|
|
|
from typing import Any, List, Optional, Union
|
|
|
|
|
|
def table_fmt(labels: List[str],
|
|
table: List[List[Any]],
|
|
title: Optional[str] = None,
|
|
alignment: Optional[Union[str, List[str]]] = None,
|
|
divide_last_line: bool = False
|
|
) -> str:
|
|
lbl: List[str] = list(map(str, labels))
|
|
tbl: List[List[str]] = list(map(lambda l: list(map(str, l)), table))
|
|
lbl_sz = len(lbl)
|
|
for line in tbl:
|
|
line_sz = len(line)
|
|
if line_sz != lbl_sz:
|
|
raise ValueError(
|
|
"A table line does not match its cell count to the number of labels."
|
|
)
|
|
algnmt: List[str] = list()
|
|
if alignment is None:
|
|
algnmt = ['<']*lbl_sz
|
|
else:
|
|
if len(alignment) != lbl_sz:
|
|
raise ValueError(
|
|
"Table alignment does not match its rule count to the number of labels."
|
|
)
|
|
algnmt = list(alignment)
|
|
acceptable_rules = ('<', '^', '>')
|
|
for rl in algnmt:
|
|
if rl not in acceptable_rules:
|
|
raise ValueError(
|
|
"Table alignment rule %r is not one of %r" %
|
|
(rl, acceptable_rules)
|
|
)
|
|
tbl_sz = len(tbl)
|
|
tbl_szs: List[List[int]] = (
|
|
[list(map(len, lbl))] +
|
|
list(map(lambda l: list(map(len, l)), tbl))
|
|
)
|
|
row_widths: List[int] = list(map(max, zip(*tbl_szs)))
|
|
print(row_widths)
|
|
labels_tpl = (
|
|
'| ' +
|
|
' | '.join([f'{{{e}:^{l}}}' for e, l in enumerate(row_widths)]) +
|
|
' |'
|
|
)
|
|
data_tpl = (
|
|
'| ' +
|
|
' | '.join([f'{{{e}:{algnmt[e]}{l}}}' for e, l in enumerate(row_widths)]) +
|
|
' |'
|
|
)
|
|
lastlinesep = (
|
|
'|.' +
|
|
'.|.'.join(['.'*w for w in row_widths]) +
|
|
'.|'
|
|
)
|
|
title_tpl = '| {0:^%d} |\n' % (sum(row_widths)+3*(lbl_sz-1))
|
|
linesep_total_sz = (4+sum(row_widths)+3*(lbl_sz-1))
|
|
hugelinesep = '='*linesep_total_sz
|
|
linesep = '-'*linesep_total_sz
|
|
s = ''
|
|
# title section
|
|
s += hugelinesep + '\n'
|
|
if title:
|
|
s += title_tpl.format(title)
|
|
s += hugelinesep + '\n'
|
|
# row label section
|
|
s += labels_tpl.format(*lbl) + '\n'
|
|
s += linesep + '\n'
|
|
# data section
|
|
for seq, line in enumerate(tbl):
|
|
if seq+1 == tbl_sz and divide_last_line:
|
|
s+= lastlinesep + '\n'
|
|
s += data_tpl.format(*line) + '\n'
|
|
# row label section
|
|
s += linesep + '\n'
|
|
s += labels_tpl.format(*lbl) + '\n'
|
|
# title section
|
|
s += hugelinesep + '\n'
|
|
if title:
|
|
s += title_tpl.format(title)
|
|
s += hugelinesep + '\n'
|
|
return s
|