diff --git a/tests/core/test_console_cell_width.py b/tests/core/test_console_cell_width.py index 5aa2ae1b..c8256253 100644 --- a/tests/core/test_console_cell_width.py +++ b/tests/core/test_console_cell_width.py @@ -22,3 +22,8 @@ def test_panel_pads_an_indic_label_to_the_border() -> None: Console(file=out, width=20, color_system=None).print(Panel("हिंदी")) assert out.getvalue().splitlines()[1] == "│ हिंदी" + " " * 12 + " │" + + +def test_a_virama_conjunct_shares_one_cell() -> None: + assert cell_len("हिन्दी") == 4 # न्द is one conjunct + assert cell_len("ಕನ್ನಡ") == 4 # a Kannada virama does not join, so ನ್ನ keeps two cells diff --git a/unshackle/core/console.py b/unshackle/core/console.py index 843b2fb2..2f0efac2 100644 --- a/unshackle/core/console.py +++ b/unshackle/core/console.py @@ -426,7 +426,23 @@ def _cell_size(character: str, *args: str) -> int: return 1 if unicodedata.category(character) == "Mc" else _rich_cell_size(character, *args) +# the viramas that join the next consonant into one cluster (Unicode InCB=Linker); Tamil and Kannada do not +_JOINING_VIRAMAS = frozenset("्্્୍్്") +_rich_cell_len = rich.cells._cell_len + + +def _cell_len(text: str, *args: str) -> int: + """Count a consonant joined by a virama (the न्द in हिन्दी) as no cell: terminals draw the conjunct in one.""" + width = _rich_cell_len(text, *args) + if _JOINING_VIRAMAS.isdisjoint(text): + return width + return width - sum( + prev in _JOINING_VIRAMAS and unicodedata.category(char) == "Lo" for prev, char in zip(text, text[1:]) + ) + + rich.cells.get_character_cell_size = _cell_size +rich.cells._cell_len = _cell_len rich.cells.cached_cell_len.cache_clear() console = ComfyConsole(