89 lines
2.7 KiB
Python
89 lines
2.7 KiB
Python
import codecs
|
|
import itertools
|
|
import sys
|
|
|
|
|
|
def bordered(*columns: dict) -> str:
|
|
"""
|
|
credits to https://github.com/Cog-Creators/Red-DiscordBot/blob/V3/develop/redbot/core/utils/chat_formatting.py
|
|
|
|
Get two blocks of text in a borders.
|
|
|
|
Note
|
|
----
|
|
This will only work with a monospaced font.
|
|
|
|
Parameters
|
|
----------
|
|
*columns : `sequence` of `str`
|
|
The columns of text, each being a list of lines in that column.
|
|
|
|
Returns
|
|
-------
|
|
str
|
|
The bordered text.
|
|
|
|
"""
|
|
encoder = codecs.getencoder(sys.stdout.encoding)
|
|
try:
|
|
encoder("┌┐└┘─│") # border symbols
|
|
except UnicodeEncodeError:
|
|
ascii_border = True
|
|
else:
|
|
ascii_border = False
|
|
|
|
borders = {
|
|
"TL": "+" if ascii_border else "┌", # Top-left
|
|
"TR": "+" if ascii_border else "┐", # Top-right
|
|
"BL": "+" if ascii_border else "└", # Bottom-left
|
|
"BR": "+" if ascii_border else "┘", # Bottom-right
|
|
"HZ": "-" if ascii_border else "─", # Horizontal
|
|
"VT": "|" if ascii_border else "│", # Vertical
|
|
}
|
|
|
|
sep = " " * 4 # Separator between boxes
|
|
widths = tuple(
|
|
max(len(row) for row in column.get("rows")) + 9 for column in columns
|
|
) # width of each col
|
|
cols_done = [False] * len(columns) # whether or not each column is done
|
|
lines = [""]
|
|
|
|
for i, column in enumerate(columns):
|
|
lines[0] += (
|
|
"{TL}"
|
|
+ "{HZ}"
|
|
+ column.get("title")
|
|
+ "{HZ}" * (widths[i] - len(column.get("title")) - 1)
|
|
+ "{TR}"
|
|
+ sep
|
|
)
|
|
|
|
for line in itertools.zip_longest(*[column.get("rows") for column in columns]):
|
|
row = []
|
|
for colidx, column in enumerate(line):
|
|
width = widths[colidx]
|
|
done = cols_done[colidx]
|
|
if column is None:
|
|
if not done:
|
|
# bottom border of column
|
|
column = "{HZ}" * width
|
|
row.append("{BL}" + column + "{BR}")
|
|
cols_done[colidx] = True # mark column as done
|
|
else:
|
|
# leave empty
|
|
row.append(" " * (width + 2))
|
|
else:
|
|
column += " " * (width - len(column)) # append padded spaces
|
|
row.append("{VT}" + column + "{VT}")
|
|
|
|
lines.append(sep.join(row))
|
|
|
|
final_row = []
|
|
for width, done in zip(widths, cols_done):
|
|
if not done:
|
|
final_row.append("{BL}" + "{HZ}" * width + "{BR}")
|
|
else:
|
|
final_row.append(" " * (width + 2))
|
|
lines.append(sep.join(final_row))
|
|
|
|
return "\n".join(lines).format(**borders)
|