reddit-image-wall-getter/reddit_imgs/system/table_fmt.py

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