From 47ed711743f66fd4cabeb270952405674ef985ba Mon Sep 17 00:00:00 2001 From: Wu Xiaotian Date: Sun, 17 Sep 2023 07:08:38 +0800 Subject: Support CJK text alignment (#2012) * Add functions for unicode string alignment * use unicode alignment function to show menu * Allow table content to support unicode text alignment --- archinstall/lib/menu/abstract_menu.py | 21 ++------------------ archinstall/lib/output.py | 37 ++++++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/archinstall/lib/menu/abstract_menu.py b/archinstall/lib/menu/abstract_menu.py index f12d2b73..306c500a 100644 --- a/archinstall/lib/menu/abstract_menu.py +++ b/archinstall/lib/menu/abstract_menu.py @@ -1,32 +1,15 @@ from __future__ import annotations -import unicodedata from typing import Callable, Any, List, Iterator, Tuple, Optional, Dict, TYPE_CHECKING from .menu import Menu, MenuSelectionType from ..output import error +from ..output import unicode_ljust from ..translationhandler import TranslationHandler, Language if TYPE_CHECKING: _: Any -def count_cjk_chars(string): - "Count the total number of CJK characters contained in a string" - return sum(unicodedata.east_asian_width(c) in 'FW' for c in string) - -def cjkljust(string, width, fillbyte=' '): - """Support left alignment of Chinese, Japanese, Korean text - >>> cjkljust('Hello', 15, '*') - 'Hello**********' - >>> cjkljust('你好', 15, '*') - '你好***********' - >>> cjkljust('안녕하세요', 15, '*') - '안녕하세요*****' - >>> cjkljust('こんにちは', 15, '*') - 'こんにちは*****' - """ - return string.ljust(width - count_cjk_chars(string), fillbyte) - class Selector: def __init__( self, @@ -145,7 +128,7 @@ class Selector: if current: padding += 5 - description = cjkljust(str(self._description), padding, ' ') + description = unicode_ljust(str(self._description), padding, ' ') current = current else: description = self._description diff --git a/archinstall/lib/output.py b/archinstall/lib/output.py index 9f2a2ae3..63d9c1fb 100644 --- a/archinstall/lib/output.py +++ b/archinstall/lib/output.py @@ -1,6 +1,7 @@ import logging import os import sys +import unicodedata from enum import Enum from pathlib import Path @@ -83,7 +84,7 @@ class FormattedOutput: if capitalize: key = key.capitalize() - key_list.append(key.ljust(width)) + key_list.append(unicode_ljust(key, width)) output += ' | '.join(key_list) + '\n' output += '-' * len(output) + '\n' @@ -99,9 +100,9 @@ class FormattedOutput: value = '*' * width if isinstance(value, (int, float)) or (isinstance(value, str) and value.isnumeric()): - obj_data.append(str(value).rjust(width)) + obj_data.append(unicode_rjust(str(value), width)) else: - obj_data.append(str(value).ljust(width)) + obj_data.append(unicode_ljust(str(value), width)) output += ' | '.join(obj_data) + '\n' @@ -326,3 +327,33 @@ def log( if level != logging.DEBUG or storage.get('arguments', {}).get('verbose', False): sys.stdout.write(f"{text}\n") sys.stdout.flush() + +def _count_wchars(string: str) -> int: + "Count the total number of wide characters contained in a string" + return sum(unicodedata.east_asian_width(c) in 'FW' for c in string) + +def unicode_ljust(string: str, width: int, fillbyte: str = ' ') -> str: + """Return a left-justified unicode string of length width. + >>> unicode_ljust('Hello', 15, '*') + 'Hello**********' + >>> unicode_ljust('你好', 15, '*') + '你好***********' + >>> unicode_ljust('안녕하세요', 15, '*') + '안녕하세요*****' + >>> unicode_ljust('こんにちは', 15, '*') + 'こんにちは*****' + """ + return string.ljust(width - _count_wchars(string), fillbyte) + +def unicode_rjust(string: str, width: int, fillbyte: str = ' ') -> str: + """Return a right-justified unicode string of length width. + >>> unicode_rjust('Hello', 15, '*') + '**********Hello' + >>> unicode_rjust('你好', 15, '*') + '***********你好' + >>> unicode_rjust('안녕하세요', 15, '*') + '*****안녕하세요' + >>> unicode_rjust('こんにちは', 15, '*') + '*****こんにちは' + """ + return string.rjust(width - _count_wchars(string), fillbyte) -- cgit v1.2.3-54-g00ecf