Last active
February 5, 2022 10:44
-
-
Save kkew3/3dde88ec52df12d7cc855ffeb2091a7c to your computer and use it in GitHub Desktop.
Pretty print list of strings like BSD `ls`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
import itertools | |
import shutil | |
# https://gist.github.com/kkew3/8bb9aa225a6c82ae5e1a0fa609c9a65a | |
import cjkjust | |
def calc_layout(n_strings, total_width, column_width, width_between_cols): | |
# expected_ncols * column_width + | |
# (expected_ncols - 1) * width_between_cols <= total_width | |
# | |
# -> expected_ncols <= (total_width + width_between_cols) / | |
# (column_width + width_between_cols) | |
# | |
# Therefore, expected_ncols is at most the floor of the RHS | |
expected_ncols = math.floor((total_width + width_between_cols) / | |
(column_width + width_between_cols)) | |
expected_ncols = max(expected_ncols, 1) | |
actual_nrows = math.ceil(n_strings / expected_ncols) | |
actual_ncols = (n_strings - 1) // actual_nrows + 1 | |
return actual_nrows, actual_ncols | |
def pprint(strings, total_width=None, width_between_cols=1, file=None) -> None: | |
""" | |
Pretty print list of strings like ``ls``. | |
:param strings: list of strings | |
:param total_width: the disposable total width, default to terminal width | |
:param width_between_cols: width between columns, default to 1 | |
:param file: file handle to which to print, default to stdout | |
""" | |
total_width = total_width or shutil.get_terminal_size().columns | |
assert total_width >= 1, total_width | |
assert width_between_cols >= 1, width_between_cols | |
if not strings: | |
return | |
column_width = max(map(cjkjust.cjklen, strings)) | |
nrows, ncols = calc_layout( | |
len(strings), total_width, column_width, width_between_cols) | |
columns = [[] for _ in range(ncols)] | |
for i, s in enumerate(strings): | |
columns[i // nrows].append(s) | |
for row in itertools.zip_longest(*columns): | |
padded_row = (cjkjust.cjkljust(s or '', column_width) for s in row) | |
print((' ' * width_between_cols).join(padded_row), file=file) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment