From 0a0bbae88ca41a5860d271670fc9e78262a8d1e1 Mon Sep 17 00:00:00 2001 From: Ethan Dalool Date: Mon, 20 Dec 2021 16:45:47 -0800 Subject: [PATCH] Use unicode_width instead of len, improve in_box. --- voussoirkit/niceprints.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/voussoirkit/niceprints.py b/voussoirkit/niceprints.py index fd069b1..f1c4bc7 100644 --- a/voussoirkit/niceprints.py +++ b/voussoirkit/niceprints.py @@ -12,6 +12,7 @@ these functions. import shutil from voussoirkit import dotdict +from voussoirkit import stringtools SINGLE_BOX = dotdict.DotDict( upper_left='┌', @@ -36,7 +37,7 @@ def equals_header(text): Sample text =========== ''' - return text + '\n' + ('=' * len(text)) + return text + '\n' + ('=' * stringtools.unicode_width(text)) def in_box(text, *, boxchars=SINGLE_BOX, title=''): ''' @@ -50,16 +51,27 @@ def in_box(text, *, boxchars=SINGLE_BOX, title=''): │There is breaking news about an urgent topic│ │and you'll never guess what it is │ └────────────────────────────────────────────┘ + + This function does not perform text wrapping. Wrap your text before putting + it in the box. ''' lines = text.splitlines() - longest_line = max(max(len(line) for line in lines), len(title)) - top = title + boxchars.top * (longest_line - len(title)) - bottom = boxchars.top * longest_line + widths = {line: stringtools.unicode_width(line) for line in lines} + if len(widths) == 0: + longest_line = 0 + else: + longest_line = max(widths.values()) + + box_width = max(longest_line, stringtools.unicode_width(title)) + top = title + boxchars.top * (box_width - stringtools.unicode_width(title)) + bottom = boxchars.top * box_width new_lines = [] new_lines.append(boxchars.upper_left + top + boxchars.upper_right) for line in lines: - new_lines.append(boxchars.side + line.ljust(longest_line, ' ') + boxchars.side) + space_needed = box_width - widths[line] + space = ' ' * space_needed + new_lines.append(f'{boxchars.side}{line}{space}{boxchars.side}') new_lines.append(boxchars.lower_left + bottom + boxchars.lower_right) return '\n'.join(new_lines) @@ -69,6 +81,6 @@ def solid_hash_header(text): ''' cli_width = shutil.get_terminal_size()[0] # One left hash, space, and space after text. - right_count = cli_width - (len(text) + 3) + right_count = cli_width - (stringtools.unicode_width(text) + 3) right_hashes = '#' * right_count return f'# {text} {right_hashes}'