Metadata-Version: 2.5
Name: wcwidth
Version: 0.8.4
Summary: Measures the displayed width of unicode strings in a terminal
Project-URL: Homepage, https://github.com/jquast/wcwidth
Author-email: Jeff Quast <contact@jeffquast.com>
License-Expression: MIT
License-File: LICENSE
Keywords: cjk,combining,console,eastasian,emoji,emulator,terminal,unicode,wcswidth,wcwidth,xterm
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Topic :: Software Development :: Internationalization
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Localization
Classifier: Topic :: Terminals
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/x-rst

|pypi_downloads| |codecov| |license|

============
Introduction
============

This Python library is mainly for CLI/TUI programs that carefully produce output for Terminals.

See page libwcwidth_ about the portable C11 library.

Installation
------------

The stable version of this package is maintained on pypi, install or upgrade, using pip::

    pip install --upgrade wcwidth

Problem
-------

All Python string-formatting functions, `textwrap.wrap()`_, `str.ljust()`_, `str.rjust()`_, and
`str.center()`_ **incorrectly** measure the displayed width of a string as equal to the number of
their codepoints.

Some examples of **incorrect results**:

.. code-block:: python

    >>> # result consumes 16 total cells, 11 expected,
    >>> 'コンニチハ'.rjust(11, 'X')
    'XXXXXXコンニチハ'

    >>> # result consumes 5 total cells, 6 expected,
    >>> 'café'.center(6, 'X')
    'caféX'

Solution
--------

The lowest-level functions in this library are derived from POSIX.1-2001 and POSIX.1-2008
`wcwidth(3)`_ and `wcswidth(3)`_, which this library precisely copies by interface as `wcwidth()`_
and `wcswidth()`_.  These functions return -1 when C0 and C1 control codes are present.

An easy-to-use `width()`_ function is provided as a wrapper of `wcswidth()`_ that is also capable of
measuring most terminal control codes and sequences, like colors, bold, tabstops, and horizontal
cursor movement. `width()`_ argument ``term_program`` may provide more accurate terminal measurement
Corrections_ as a wrapper of `wcstwidth()`_.

Text-justification is solved by the sequence-aware functions `ljust()`_, `rjust()`_, `center()`_,
and the grapheme-aware function `wrap()`_, serving as drop-in replacements to python standard
functions.

The `clip()`_ function extracts substrings by their displayed column positions, and
`strip_sequences()`_ removes terminal escape sequences from text altogether.

The iterator functions `iter_graphemes()`_ and `iter_sequences()`_ allow for careful navigation of
grapheme and terminal control sequence boundaries as required by editors or REPLs with cursor
control.  `iter_graphemes_reverse()`_ and `grapheme_boundary_before()`_ are necessary for backward
cursor control over complex unicode.

Discrepancies
-------------

You may find that support *varies* for complex unicode sequences or codepoints.

This library may be considered to presume the terminal is enabled for DEC Private Mode 2027
("Grapheme Clustering") by default, which may require to be enabled by a TUI application but
is often the default mode for those terminals that support it.

This library does support any specific "legacy width" measurement by API, but it does provide
Corrections_ for those terminals without grapheme support.

See also:

- `terminal-unicode-core.tex`_ (2021)
- `Grapheme Clusters and Terminal Emulators`_ (2023)
- `State of Terminal Emulators in 2025`_
- `Perfecting Terminal Character Width Using Correction Tables`_ (2026)

The `jquast/ucs-detect`_ project publishes automatic results of compliance to our standard for Wide
character, Languages, grapheme clustering, complex or combining scripts, emojis, zero-width joiner,
variations, and regional indicator (flags) as a `General Tabulated Summary`_ by terminal emulator
software and version. The results of the ucs-detect project create our correction tables.

========
Overview
========

A brief overview, through examples, for all of the public API functions.

Full API Documentation at https://wcwidth.readthedocs.io/en/latest/api.html

wcwidth()
---------

Measures width of a single codepoint,

.. code-block:: python

    >>> # '♀' narrow emoji
    >>> wcwidth.wcwidth('\u2640')
    1

Use function `wcwidth()`_ to determine the length of a *single unicode character*.

See specification_ of character measurements. Note that ``-1`` is returned for control codes.

wcswidth()
----------

Measures width of a string, returns -1 for control codes.

.. code-block:: python

    >>> # '♀️' emoji w/vs-16
    >>> wcwidth.wcswidth('\u2640\ufe0f')
    2

Use function `wcswidth()`_ to determine the length of many, a *string of unicode characters*.

See specification_ of character measurements. Note that ``-1`` is returned if control codes occurs
anywhere in the string.

wcstwidth()
-----------

Same behavior as `wcswidth()`_ with automatic terminal-specific Corrections_, reading
``TERM_PROGRAM`` or ``TERM`` when ``True`` (default), or caller can provide terminal query
XTVERSION_ or ENQ_ response:

.. code-block:: python

    >>> # '♀️' emoji w/vs-16, uncorrected:
    >>> wcwidth.wcswidth('\u2640\ufe0f')
    2
    >>> # corrected,
    >>> wcwidth.wcstwidth('\u2640\ufe0f', term_program='vte')
    1

width()
-------

Use function `width()`_ to measure a string with improved handling of ``control_codes`` and
measurement Corrections_ through ``term_program``:

.. code-block:: python

    >>> # same support as wcswidth(), eg. regional indicator flag:
    >>> wcwidth.width('\U0001F1FF\U0001F1FC')
    2
    >>> # set term_program=True to use wcstwidth()
    >>> wcwidth.width('\U0001F1FF\U0001F1FC', term_program=True)
    1
    >>> # or set term_program for measurement of a specific terminal
    >>> wcwidth.width('\U0001F1FF\U0001F1FC', term_program='contour')
    2
    >>> # but also supports sequences, like SGR colored text, "WARN", followed by reset
    >>> wcwidth.width('\x1b[38;2;255;150;100mWARN\x1b[0m')
    4
    >>> # tabs are measured as though the string begins at a tabstop,
    >>> wcwidth.width('\t', tabsize=4)
    4
    >>> # or, all control characters can be ignored (including tab)
    >>> wcwidth.width('\t\n\a\r', control_codes='ignore')
    0
    >>> # sequences with "indeterminate" effects like Home + Clear are zero-width
    >>> wcwidth.width('\x1b[H\x1b[2J')
    0
    >>> # horizontal cursor movements are parsed,
    >>> wcwidth.width('hello\b\b\b\b\bworld')
    5
    >>> wcwidth.width('hello\x1b[5Dworld')
    5
    >>> # or ignored,
    >>> wcwidth.width('hello\x1b[5Dworld', control_codes='ignore')
    10
    >>> # Measure width of text using kitty text sizing protocol (OSC 66),
    >>> width('\x1b]66;w=2;XY\x07')
    2
    >>> # Scaled text sizing: each grapheme occupies 'scale' cells
    >>> width('\x1b]66;s=2;ABC\x07')
    6

Use ``control_codes='ignore'`` when the input is known not to contain any control characters or
terminal sequences for slightly improved performance. Note that TAB (``'\t'``) is a control
character and is also ignored, you may want to use `str.expandtabs()`_, first.

Use ``control_codes='strict'`` when input is known to contain some control sequences, such as
SGR color, bold, hyperlinks and cursor movement. Any sequence that cannot be accurately parsed
for horizontal measurement, such as clearing the screen, vertical, or absolute cursor movement will
raise ``ValueError``:

.. code-block:: python

    >>> # or, raise ValueError for "indeterminate" effects using control_codes='strict'
    >>> wcwidth.width('\n', control_codes='strict')
    Traceback (most recent call last):
    ...
    ValueError: Vertical movement character 0xa at position 0


    >>> wcwidth.width('\x1b[H\x1b[2J', control_codes='strict')
    Traceback (most recent call last):
    ...
    ValueError: Indeterminate cursor sequence at position 0, '\x1b[H'


    >>> # cursor left movement beyond string start raises in strict mode,
    >>> wcwidth.width('a\x1b[5Da', control_codes='strict')
    Traceback (most recent call last):
    ...
    ValueError: Cursor left movement at position 1 would move 5 cells left from column 1, exceeding string start

iter_sequences()
----------------

Iterates through text, segmented by terminal sequence,

.. code-block:: python

    >>> list(wcwidth.iter_sequences('hello'))
    [('hello', False)]
    >>> list(wcwidth.iter_sequences('\x1b[31mred\x1b[0m'))
    [('\x1b[31m', True), ('red', False), ('\x1b[0m', True)]

Use `iter_sequences()`_ to split text into segments of plain text and escape sequences. Each tuple
contains the segment string and a boolean indicating whether it is an escape sequence (``True``) or
text (``False``).

iter_graphemes()
----------------

Use `iter_graphemes()`_ to iterate over *grapheme clusters* of a string.

.. code-block:: python

    >>> from wcwidth import iter_graphemes
    >>> # ok + Regional Indicator 'Z', 'W' (Zimbabwe)
    >>> list(wcwidth.iter_graphemes('ok\U0001F1FF\U0001F1FC'))
    ['o', 'k', '🇿🇼']

    >>> # cafe + combining acute accent
    >>> list(wcwidth.iter_graphemes('cafe\u0301'))
    ['c', 'a', 'f', 'é']

    >>> # ok + Emoji Man + ZWJ + Woman + ZWJ + Girl
    >>> list(wcwidth.iter_graphemes('ok\U0001F468\u200D\U0001F469\u200D\U0001F467'))
    ['o', 'k', '👨\u200d👩\u200d👧']

A grapheme cluster is what a user perceives as a single character, even if it is composed of
multiple Unicode codepoints. This function implements `Unicode Standard Annex #29`_ grapheme cluster
boundary rules.

ljust()
-------

Use `ljust()`_ as replacement of `str.ljust()`_:

.. code-block:: python

    >>> 'コンニチハ'.ljust(11, '*')             # don't do this
    'コンニチハ******'
    >>> wcwidth.ljust('コンニチハ', 11, '*')    # do this!
    'コンニチハ*'

rjust()
-------

Use `rjust()`_ as replacement of `str.rjust()`_:

.. code-block:: python

    >>> 'コンニチハ'.rjust(11, '*')             # don't do this
    '******コンニチハ'
    >>> wcwidth.rjust('コンニチハ', 11, '*')    # do this!
    '*コンニチハ'

center()
--------

Use `center()`_ as replacement of `str.center()`_:

.. code-block:: python

    >>> 'cafe\u0301'.center(6, '*')             # don't do this
    'café*'
    >>> wcwidth.center('cafe\u0301', 6, '*')
    '*café*'                                    # do this!

wrap()
------

Use function `wrap()`_ to wrap text containing terminal sequences, Unicode grapheme
clusters, and wide characters to a given display width.

.. code-block:: python

    >>> from wcwidth import wrap
    >>> # Basic wrapping
    >>> wrap('hello world', 5)
    ['hello', 'world']

    >>> # Wrapping CJK text (each character is 2 cells wide)
    >>> wrap('コンニチハ', 4)
    ['コン', 'ニチ', 'ハ']

    >>> # Text with ANSI color sequences - SGR codes are propagated by default
    >>> # Each line ends with reset, next line starts with restored style
    >>> wrap('\x1b[1;31mhello world\x1b[0m', 5)
    ['\x1b[1;31mhello\x1b[0m', '\x1b[1;31mworld\x1b[0m']

clip()
------

Use `clip()`_ to extract a substring by column positions, preserving terminal sequences.

.. code-block:: python

    >>> from wcwidth import clip
    >>> # Wide characters split to Narrow boundaries using fillchar=' '
    >>> clip('中文字', 0, 3)
    '中 '
    >>> clip('中文字', 1, 5, fillchar='.')
    '.文.'

    >>> # 'end' defaults to -1, meaning "to the end of the line"
    >>> clip('中文字', 1)
    ' 文字'
    >>> clip('\x1b[1;31mHello world\x1b[0m', 6)
    '\x1b[1;31mworld\x1b[0m'

    >>> # SGR codes are propagated by default - result begins with active style
    >>> # and ends with reset if styles are active
    >>> clip('\x1b[1;31mHello world\x1b[0m', 6, 11)
    '\x1b[1;31mworld\x1b[0m'

    >>> # Disable SGR propagation to preserve sequence order outside of clip boundary
    >>> clip('\x1b[31m中文\x1b[32m', 0, 3, propagate_sgr=False)
    '\x1b[31m中 \x1b[32m'

    >>> # Cursor-left overwrites previous text (painter's algorithm)
    >>> clip('hello\x1b[2DXY', 0, 5)
    'helXY'
    >>> # Carriage return resets to column 0, overwriting earlier cells
    >>> clip('abc\rXY', 0, 5)
    'XYc'

    >>> # even OSC 8 hyperlink text may be clipped, 'Click This link' -> 'is link' !
    >>> clip('\x1b]8;;http://example.com\x07Click This link\x1b]8;;\x07', 8, 15)
    '\x1b]8;;http://example.com\x07is link\x1b]8;;\x07'

    >>> # and OSC 66 kitty text sizing, supporting width and scale, 'Look' -> '...ook'
    >>> clip('\x1b]66;w=4:s=4;Look\x07', 1, 16, fillchar='.')
    '...\x1b]66;s=4:w=3;ook\x07'

Use ``overtyping=False`` when the input is known not to contain any cursor movement characters
(``\b``, ``\r``, ``CSI C``, ``CSI D``, ``CSI G``) for improved performance.  When
``overtyping=None`` (default), a slower "Painter's algorithm" may be used after testing for the
presence of these characters. ``overtyping`` has no effect when ``control_codes='ignore'``.

strip_sequences()
-----------------

Use `strip_sequences()`_ to remove all terminal escape sequences from text.

.. code-block:: python

    >>> from wcwidth import strip_sequences
    >>> strip_sequences('\x1b[31mred\x1b[0m')
    'red'

.. _ambiguous_width:

Ambiguous Width
---------------

Some Unicode characters have "East Asian Ambiguous" (A) width. These characters display as 1 cell by
default, matching Western terminal contexts, but many CJK (Chinese, Japanese, Korean) environments
may have a preference for 2 cells.  This is often found as boolean option, "Ambiguous width as wide"
in Terminal Emulator software preferences.

The ``ambiguous_width`` parameter is available on all width-measuring functions: `wcwidth()`_,
`wcswidth()`_, `width()`_, `ljust()`_, `rjust()`_, `center()`_, `wrap()`_, and `clip()`_.

By default, wcwidth treats ambiguous characters as narrow (width 1). For CJK environments where your
terminal is configured to display ambiguous characters as double-width, pass ``ambiguous_width=2``:

.. code-block:: python

    >>> # CIRCLED DIGIT ONE - ambiguous width
    >>> wcwidth.width('\u2460')
    1
    >>> wcwidth.width('\u2460', ambiguous_width=2)
    2

**Terminal Detection**

The most reliable method to detect whether a terminal profile is set for "Ambiguous width as wide"
mode is to display an ambiguous character surrounded by a pair of Cursor Position Report (CPR)
queries with a terminal in cooked or raw mode, and to parse the responses for their ``(y, x)``
locations and measure the difference ``x``.

This code should also be careful to check whether it is attached to a terminal and be careful of
possible timeout, slow network, or non-response when working with "dumb terminals" like a CI build.

`jquast/blessed`_ library provides such a helping `Terminal.detect_ambiguous_width()`_ method:

.. code-block:: python

    >>> import blessed, functools
    >>> # Detect terminal ambiguous width as wide (2) or narrow (1)
    >>> ambiguous_width = blessed.Terminal().detect_ambiguous_width()
    >>> # Define a new 'width' function with this argument
    >>> awidth = functools.partial(wcwidth.width, ambiguous_width=ambiguous_width)
    >>> # result depends on attached terminal mode
    >>> awidth('\u2460')
    1

Corrections
-----------

Corrections may be automatically applied depending on the detected or given terminal software name
beginning with wcwidth release 0.8.0. This allows to correct widths for terminal software that
differs from the python wcwidth specification_.  These corrections are sourced from the
`jquast/ucs-detect`_ project.

The ``term_program`` parameter is available on all width-measuring functions: `wcstwidth()`_,
`width()`_, `ljust()`_, `rjust()`_, `center()`_, `wrap()`_, and `clip()`_.

`wcstwidth()`_ defaults to ``term_program=True``, auto-detecting the terminal from the
``TERM_PROGRAM`` or ``TERM`` environment variable.  All other functions default to
``term_program=False``, disabling corrections.  Use ``term_program=True`` for automatic
detection by environment values of ``TERM`` and ``TERM_PROGRAM``.

.. code-block:: python

    # VTE terminals (Gnome Terminal Et al.) still render trigrams as narrow (1 cell), but their
    # definition was changed to wide in Unicode 16 (September 2024).
    >>> wcwidth.wcswidth('\u2630')
    2
    >>> wcwidth.wcstwidth('\u2630', term_program='vte')
    1

    # account for Alacritty non-support of emoji ZWJ:
    # man + ZWJ + woman + ZWJ + girl + ZWJ + boy
    >>> family = '\U0001F468\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466'
    >>> wcwidth.wcswidth(family)
    2
    >>> wcwidth.wcstwidth(family, term_program='alacritty')
    8

Only detectable_ terminals are included: those that identify themselves by XTVERSION_, ENQ_, any
``TERM_PROGRAM`` or a unique ``TERM`` environment value.  For the most accurate correction tables,
query the terminal's software version via XTVERSION_ (``CSI > q``) using a higher-level interactive
terminal library like `jquast/blessed`_:

.. code-block:: python

    >>> import blessed, wcwidth
    >>> term = blessed.Terminal()
    >>> sw_ver = term.get_software_version()
    >>> print(sw_ver)
    SoftwareVersion(name='VTE', version='7600')
    >>> wcwidth.width('\u2630', term_program=sw_ver.name)
    1

This is important because ``TERM_PROGRAM`` is not forwarded for remote hosts, like SSH, and many
terminals may only be identified using XTVERSION_ or ENQ_.  Use `list_term_programs()`_ to see all
recognized names:

.. BEGIN_LIST_TERM_PROGRAMS
.. code-block:: python

    >>> wcwidth.list_term_programs()
    ('absolutetelnet/ssh', 'alacritty', 'apple_terminal', 'bobcat', 'contour',
     'extraterm', 'foot', 'ghostty', 'hyper', 'iterm.app', 'iterm2', 'kitty',
     'konsole', 'mintty', 'mlterm', 'pterm', 'putty', 'rio', 'rxvt',
     'rxvt-unicode-256color', 'st', 'st-256color', 'tabby', 'terminology',
     'urxvt', 'vscode', 'vte', 'warp', 'warpterminal', 'wezterm', 'xterm',
     'xterm-ghostty', 'xterm-kitty', 'xterm.js')

.. END_LIST_TERM_PROGRAMS

``term_program=False`` (the default for `width()`_, `ljust()`_, `rjust()`_, `center()`_,
`wrap()`_, and `clip()`_) disables terminal corrections.

For automatic tests and other purposes that require cross-environment consistency, set static values
or unset ``TERM`` and ``TERM_PROGRAM`` environment values, such as in ``conftest.py`` with pytest:

.. code-block:: python

    @pytest.fixture(autouse=True)
    def _clear_term_program():
        """unset TERM/TERM_PROGRAM before each test."""
        saved_term = os.environ.pop('TERM', None)
        saved_tprog = os.environ.pop('TERM_PROGRAM', None)
        yield
        if saved_term is not None:
            os.environ['TERM'] = saved_term
        if saved_tprog is not None:
            os.environ['TERM_PROGRAM'] = saved_tprog

==================
More documentation
==================

Developer documentation, for building and contributing to this project, at
https://wcwidth.readthedocs.io/en/latest/developing.html

Projects using wcwidth, and implementations in other languages, at
https://wcwidth.readthedocs.io/en/latest/related.html

.. _`specification`: https://wcwidth.readthedocs.io/en/latest/specs.html
.. _`jquast/blessed`: https://github.com/jquast/blessed
.. _`wcwidth(3)`:  https://man7.org/linux/man-pages/man3/wcwidth.3.html
.. _`wcswidth(3)`: https://man7.org/linux/man-pages/man3/wcswidth.3.html
.. _`jquast/ucs-detect`: https://github.com/jquast/ucs-detect
.. _`textwrap.wrap()`: https://docs.python.org/3/library/textwrap.html#textwrap.wrap
.. _`str.ljust()`: https://docs.python.org/3/library/stdtypes.html#str.ljust
.. _`str.rjust()`: https://docs.python.org/3/library/stdtypes.html#str.rjust
.. _`str.center()`: https://docs.python.org/3/library/stdtypes.html#str.center
.. _`str.expandtabs()`: https://docs.python.org/3/library/stdtypes.html#str.expandtabs
.. _`General Tabulated Summary`: https://ucs-detect.readthedocs.io/results.html#tabulated-results
.. _`wcwidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcwidth
.. _`wcswidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcswidth
.. _`wcstwidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcstwidth
.. _`width()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.width
.. _`iter_graphemes()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.iter_graphemes
.. _`iter_graphemes_reverse()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.iter_graphemes_reverse
.. _`grapheme_boundary_before()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.grapheme_boundary_before
.. _`ljust()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.ljust
.. _`rjust()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.rjust
.. _`center()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.center
.. _`wrap()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wrap
.. _`clip()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.clip
.. _`strip_sequences()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.strip_sequences
.. _`iter_sequences()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.iter_sequences
.. _`list_term_programs()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.list_term_programs
.. _`Unicode Standard Annex #29`: https://www.unicode.org/reports/tr29/
.. _`Terminal.detect_ambiguous_width()`: https://blessed.readthedocs.io/en/latest/api/terminal.html#blessed.terminal.Terminal.detect_ambiguous_width
.. _`Grapheme Clusters and Terminal Emulators`: https://mitchellh.com/writing/grapheme-clusters-in-terminals
.. _`terminal-unicode-core.tex`: https://github.com/contour-terminal/terminal-unicode-core/blob/master/spec/terminal-unicode-core.tex
.. _`State of Terminal Emulators in 2025`: https://www.jeffquast.com/post/state-of-terminal-emulation-2025/
.. _`Perfecting Terminal Character Width Using Correction Tables`: https://www.jeffquast.com/post/perfecting-terminal-character-width-using-correction-tables/
.. _XTVERSION: https://vtdn.dev/docs/dcs/xtversion/
.. _ENQ: https://documentation.help/PuTTY/config-answerback.html
.. _detectable: https://ucs-detect.readthedocs.io/results.html#terminal-identification
.. _libwcwidth: https://wcwidth.readthedocs.io/en/latest/libwcwidth.html
.. |pypi_downloads| image:: https://img.shields.io/pypi/dm/wcwidth.svg?logo=pypi
    :alt: Downloads
    :target: https://pypi.org/project/wcwidth/
.. |codecov| image:: https://codecov.io/gh/jquast/wcwidth/branch/master/graph/badge.svg
    :alt: codecov.io Code Coverage
    :target: https://app.codecov.io/gh/jquast/wcwidth/
.. |license| image:: https://img.shields.io/pypi/l/wcwidth.svg
    :target: https://pypi.org/project/wcwidth/
    :alt: MIT License

