diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:18:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-14 20:18:28 +0000 |
commit | f8363b456f1ab31ee56abad579b215af195093d5 (patch) | |
tree | b1500c675c2e0a55fb75721a854e1510acf7c862 /tools/make_terminal_widths.py | |
parent | Initial commit. (diff) | |
download | rich-upstream.tar.xz rich-upstream.zip |
Adding upstream version 9.11.0.upstream/9.11.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | tools/make_terminal_widths.py | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/tools/make_terminal_widths.py b/tools/make_terminal_widths.py new file mode 100644 index 0000000..850f67a --- /dev/null +++ b/tools/make_terminal_widths.py @@ -0,0 +1,90 @@ +import subprocess +from typing import List, Tuple +import sys + +from rich.progress import Progress + +from wcwidth import wcwidth + + +progress = Progress() + + +def make_widths_table() -> List[Tuple[int, int, int]]: + table: List[Tuple[int, int, int]] = [] + append = table.append + + make_table_task = progress.add_task("Calculating table...") + + widths = ( + (codepoint, wcwidth(chr(codepoint))) + for codepoint in range(0, sys.maxunicode + 1) + ) + + _widths = [(codepoint, width) for codepoint, width in widths if width != 1] + iter_widths = iter(_widths) + + endpoint, group_cell_size = next(iter_widths) + start_codepoint = end_codepoint = endpoint + for codepoint, cell_size in progress.track( + iter_widths, task_id=make_table_task, total=len(_widths) - 1 + ): + if cell_size != group_cell_size or codepoint != end_codepoint + 1: + append((start_codepoint, end_codepoint, group_cell_size)) + start_codepoint = end_codepoint = codepoint + group_cell_size = cell_size + else: + end_codepoint = codepoint + append((start_codepoint, end_codepoint, group_cell_size)) + return table + + +def get_cell_size(table: List[Tuple[int, int, int]], character: str) -> int: + + codepoint = ord(character) + lower_bound = 0 + upper_bound = len(table) - 1 + index = (lower_bound + upper_bound) // 2 + while True: + start, end, width = table[index] + if codepoint < start: + upper_bound = index - 1 + elif codepoint > end: + lower_bound = index + 1 + else: + return width + if upper_bound < lower_bound: + break + index = (lower_bound + upper_bound) // 2 + return 1 + + +def test(widths_table): + for codepoint in progress.track( + range(0, sys.maxunicode + 1), description="Testing..." + ): + character = chr(codepoint) + width1 = get_cell_size(widths_table, character) + width2 = wcwidth(character) + if width1 != width2: + print(f"{width1} != {width2}") + break + + +def run(): + with progress: + widths_table = make_widths_table() + test(widths_table) + table_file = f"""# Auto generated by make_terminal_widths.py + +CELL_WIDTHS = {widths_table!r} + +""" + with open("../rich/_cell_widths.py", "wt") as fh: + fh.write(table_file) + + subprocess.run("black ../rich/_cell_widths.py", shell=True) + + +if __name__ == "__main__": + run() |