Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
_wcswidth.py151 linesDownload Raw Back to wcwidth
1"""This is a python implementation of wcswidth()."""2 3from __future__ import annotations4 5from typing import Optional6 7# local8from ._wcwidth import wcwidth9from .bisearch import bisearch10from ._constants import (_EMOJI_ZWJ_SET,11                         _ISC_VIRAMA_SET,12                         _CATEGORY_MC_TABLE,13                         _FITZPATRICK_RANGE,14                         _REGIONAL_INDICATOR_SET)15from .table_vs16 import VS16_NARROW_TO_WIDE16from .table_grapheme import ISC_CONSONANT17 18 19def wcswidth(20    pwcs: str,21    n: Optional[int] = None,22    unicode_version: str = 'auto',23    ambiguous_width: int = 1,24) -> int:25    """26    Given a unicode string, return its printable length on a terminal.27 28    See :ref:`Specification` for details of cell measurement.29 30    This implementation differs from Markus Khun's original POSIX C implementation, in that this31    ``wcswidth()`` processes graphemes strings yielded by :func:`wcwidth.iter_graphemes` defined by32    `Unicode Standard Annex #29`_. POSIX wcswidth(3) is not grapheme-aware and does not measure many33    kinds of Emojis or complex scripts correctly.34 35    :param pwcs: Measure width of given unicode string.36    :param n: When ``n`` is None (default), return the length of the entire37        string, otherwise only the first ``n`` characters are measured.38 39    :param unicode_version: Ignored. Retained for backwards compatibility.40 41        .. deprecated:: 0.3.042           Only the latest Unicode version is now shipped.43 44    :param ambiguous_width: Width to use for East Asian Ambiguous (A)45        characters. Default is ``1`` (narrow). Set to ``2`` for CJK contexts.46    :returns: The width, in cells, needed to display the first ``n`` characters47        of the unicode string ``pwcs``.  Returns ``-1`` for C0 and C1 control48        characters!49 50    .. _`Unicode Standard Annex #29`: https://www.unicode.org/reports/tr29/51    """52    # pylint: disable=unused-argument,too-many-locals,too-many-statements53    # pylint: disable=too-complex,too-many-branches,duplicate-code54    # This function intentionally keeps all logic inline for performance.55 56    # Fast path: pure ASCII printable strings are always width == length57    if n is None and pwcs.isascii() and pwcs.isprintable():58        return len(pwcs)59 60    # Select wcwidth call pattern for best lru_cache performance61    _wcwidth = wcwidth if ambiguous_width == 1 else lambda c: wcwidth(c, 'auto', ambiguous_width)62 63    end = len(pwcs) if n is None else n64    total_width = 065    idx = 066 67    # grapheme-clustering state68    last_measured_idx = -269    last_measured_ucs = -170    last_was_virama = False71    conjunct_pending = False72 73    while idx < end:74        char = pwcs[idx]75        ucs = ord(char)76 77        # ZWJ (U+200D)78        if ucs == 0x200D:79            if last_was_virama:80                idx += 181            elif idx + 1 < end:82                last_was_virama = False83                idx += 284            else:85                last_was_virama = False86                idx += 187            continue88 89        # VS16 (U+FE0F): converts preceding narrow character to wide.90        if ucs == 0xFE0F and last_measured_idx >= 0:91            total_width += bisearch(92                ord(pwcs[last_measured_idx]),93                VS16_NARROW_TO_WIDE['9.0.0'],94            )95            last_measured_idx = -2  # prevent double application96            idx += 197            continue98 99        # Regional Indicator & Fitzpatrick (both above BMP)100        if ucs > 0xFFFF:101            if ucs in _REGIONAL_INDICATOR_SET:102                ri_before = 0103                j = idx - 1104                while j >= 0 and ord(pwcs[j]) in _REGIONAL_INDICATOR_SET:105                    ri_before += 1106                    j -= 1107                if ri_before % 2 == 1:108                    last_measured_ucs = ucs109                    idx += 1110                    continue111            elif (_FITZPATRICK_RANGE[0] <= ucs <= _FITZPATRICK_RANGE[1]112                  and last_measured_ucs in _EMOJI_ZWJ_SET):113                idx += 1114                continue115 116        # Virama conjunct formation117        if last_was_virama and bisearch(ucs, ISC_CONSONANT):118            last_measured_idx = idx119            last_measured_ucs = ucs120            last_was_virama = False121            conjunct_pending = True122            idx += 1123            continue124 125        # Normal character: measure with wcwidth126        w = _wcwidth(char)127        if w < 0:128            # C0/C1 control character129            return -1130        if w > 0:131            if conjunct_pending:132                total_width += 1133                conjunct_pending = False134            total_width += w135            last_measured_idx = idx136            last_measured_ucs = ucs137            last_was_virama = False138        elif last_measured_idx >= 0 and bisearch(ucs, _CATEGORY_MC_TABLE):139            # Spacing Combining Mark (Mc) following a base character adds 1140            total_width += 1141            last_measured_idx = -2142            last_was_virama = False143            conjunct_pending = False144        else:145            last_was_virama = ucs in _ISC_VIRAMA_SET146        idx += 1147 148    if conjunct_pending:149        total_width += 1150    return total_width151 
codekingpro/portable-devtools · Team Ai