| 541 | |
| 542 | |
| 543 | class _EastAsianTextAdjustment(_TextAdjustment): |
| 544 | def __init__(self) -> None: |
| 545 | super().__init__() |
| 546 | if get_option("display.unicode.ambiguous_as_wide"): |
| 547 | self.ambiguous_width = 2 |
| 548 | else: |
| 549 | self.ambiguous_width = 1 |
| 550 | |
| 551 | # Definition of East Asian Width |
| 552 | # https://unicode.org/reports/tr11/ |
| 553 | # Ambiguous width can be changed by option |
| 554 | self._EAW_MAP = {"Na": 1, "N": 1, "W": 2, "F": 2, "H": 1} |
| 555 | |
| 556 | def len(self, text: str) -> int: |
| 557 | """ |
| 558 | Calculate display width considering unicode East Asian Width |
| 559 | """ |
| 560 | if not isinstance(text, str): |
| 561 | return len(text) |
| 562 | |
| 563 | return sum( |
| 564 | self._EAW_MAP.get(east_asian_width(c), self.ambiguous_width) for c in text |
| 565 | ) |
| 566 | |
| 567 | def justify( |
| 568 | self, texts: Iterable[str], max_len: int, mode: str = "right" |
| 569 | ) -> list[str]: |
| 570 | # re-calculate padding space per str considering East Asian Width |
| 571 | def _get_pad(t: str) -> int: |
| 572 | return max_len - self.len(t) + len(t) |
| 573 | |
| 574 | if mode == "left": |
| 575 | return [x.ljust(_get_pad(x)) for x in texts] |
| 576 | elif mode == "center": |
| 577 | return [x.center(_get_pad(x)) for x in texts] |
| 578 | else: |
| 579 | return [x.rjust(_get_pad(x)) for x in texts] |
| 580 | |
| 581 | |
| 582 | def get_adjustment() -> _TextAdjustment: |