wcwidth 0.9.1__tar.gz → 0.9.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wcwidth-0.9.1 → wcwidth-0.9.3}/PKG-INFO +6 -5
- {wcwidth-0.9.1 → wcwidth-0.9.3}/README.rst +5 -4
- {wcwidth-0.9.1 → wcwidth-0.9.3}/docs/history.rst +28 -6
- {wcwidth-0.9.1 → wcwidth-0.9.3}/docs/intro.rst +5 -4
- {wcwidth-0.9.1 → wcwidth-0.9.3}/docs/libwcwidth.rst +16 -4
- {wcwidth-0.9.1 → wcwidth-0.9.3}/docs/specs.rst +60 -45
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/Makefile +2 -2
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/align.h +5 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/utf8.h +23 -4
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/wcwidth_config.h +2 -2
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/align.c +13 -3
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/textwrap.c +10 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/utf8.c +27 -24
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/wcstwidth.c +1 -1
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/width.c +5 -4
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_align.c +36 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_clip.c +13 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_textwrap.c +21 -0
- wcwidth-0.9.3/libwcwidth/tests/test_utf8.c +177 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/pyproject.toml +4 -5
- {wcwidth-0.9.1 → wcwidth-0.9.3}/requirements-update.txt +1 -1
- wcwidth-0.9.3/requirements-wheels.in +4 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/requirements-wheels.txt +7 -16
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_check_release.py +1 -1
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_clip.py +28 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_hyperlink.py +6 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_term_overrides.py +26 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_textwrap.py +32 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_width.py +5 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tox.ini +8 -7
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/__init__.py +1 -1
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/_clip.py +9 -2
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/_wcswidth.py +1 -1
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/_width.py +1 -1
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/align.py +61 -3
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/hyperlink.py +1 -1
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/textwrap.py +22 -17
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth.egg-info/PKG-INFO +6 -5
- wcwidth-0.9.1/libwcwidth/tests/test_utf8.c +0 -76
- wcwidth-0.9.1/requirements-wheels.in +0 -3
- {wcwidth-0.9.1 → wcwidth-0.9.3}/.gitignore +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/.pylintrc +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/LICENSE +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/MANIFEST.in +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/bin/check-release.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/bin/update-docs.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/bin/update-tables.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/bin/verify-table-integrity.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/bin/wcwidth-browser.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/bin/wcwidth-libc-comparator.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/api_c.rst.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/c_gcb_class.c.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/c_table.c.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/c_term_programs.c.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/c_terminal_overrides.c.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/grapheme_override_per_terminal.py.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/grapheme_override_table.py.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/grapheme_registry.py.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/grapheme_table.c.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/grapheme_table.py.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/python_table.py.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/table_overrides.py.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/tables.h.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/term_programs.py.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/unicode_version.rst.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/unicode_versions.py.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/code_templates/wcwidth_config.h.j2 +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/docs/api.rst +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/docs/conf.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/docs/developing.rst +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/docs/index.rst +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/docs/related.rst +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/docs/unicode_version.rst +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/.clang-format +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/CMakeLists.txt +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/LICENSE +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/README.rst +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/cmake/libwcwidth-config.cmake.in +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/examples/align.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/examples/textwrap.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/examples/width.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/clip.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/escape.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/grapheme.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/sgr.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/table_types.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/tables.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/terminal_override.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/text_sizing.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/textwrap.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/unicode.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/wcwidth.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/include/wcwidth/width.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/bisearch.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/clip.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/escape.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/grapheme.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/sgr.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/tables/table_ambiguous.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/tables/table_gcb_class.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/tables/table_grapheme.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/tables/table_mc.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/tables/table_term_programs.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/tables/table_terminal_overrides.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/tables/table_vs15.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/tables/table_vs16.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/tables/table_wide.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/tables/table_zero.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/terminal_override.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/text_sizing.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/wcswidth.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/src/wcwidth.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_common.h +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_escape.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_gcb_class.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_grapheme.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_sgr.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_text_sizing.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_wcswidth.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_wcwidth.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/libwcwidth/tests/test_width.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/requirements-develop.txt +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/requirements-docs.in +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/requirements-tests39.in +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/requirements-tests39.txt +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/requirements-update.in +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/setup.cfg +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/setup.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/__init__.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/conftest.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_ambiguous.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_benchmarks.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_clip_cjk_emoji.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_clip_overtyping.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_core.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_emojis.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_fastcall_args.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_grapheme.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_justify.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_setup.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_sgr_state.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_text_sizing.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/tests/test_ucslevel.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/_constants.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/_wcwidth.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/_wcwidth_c.c +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/_wcwidth_c.pyi +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/bisearch.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/control_codes.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/escape_sequences.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/grapheme.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/py.typed +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/sgr_state.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_ambiguous.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/__init__.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_058c7585.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_2148ff29.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_244dc88b.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_336a71a1.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_33ac73f2.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_3a1895d5.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_59180a0d.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_65c6beb5.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_78f828e8.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_8c2ae14d.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_900356bf.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_97904ece.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_a5880eeb.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_b6d33cf4.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_c57c295b.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_cf02297d.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_e18ac6a7.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_e2b75ee3.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_fb5fd79b.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_known_fdc99132.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_grapheme_overrides/_registry.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_mc.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_overrides.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_term_programs.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_vs15.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_vs16.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_wide.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/table_zero.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/text_sizing.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/unicode_versions.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth/wcwidth.py +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth.egg-info/SOURCES.txt +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth.egg-info/dependency_links.txt +0 -0
- {wcwidth-0.9.1 → wcwidth-0.9.3}/wcwidth.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wcwidth
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.3
|
|
4
4
|
Summary: Measures the displayed width of unicode strings in a terminal
|
|
5
5
|
Author-email: Jeff Quast <contact@jeffquast.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/jquast/wcwidth
|
|
@@ -97,8 +97,9 @@ This library may be considered to presume the terminal is enabled for DEC Privat
|
|
|
97
97
|
("Grapheme Clustering") by default, which may require to be enabled by a TUI application but
|
|
98
98
|
is often the default mode for those terminals that support it.
|
|
99
99
|
|
|
100
|
-
This library does support any specific "legacy width" measurement by API, but it does provide
|
|
101
|
-
Corrections_ for
|
|
100
|
+
This library does not support any specific "legacy width" measurement by API, but it does provide
|
|
101
|
+
Corrections_ for terminals using "legacy width" measurements or are without basic emoji or grapheme
|
|
102
|
+
support.
|
|
102
103
|
|
|
103
104
|
See also:
|
|
104
105
|
|
|
@@ -154,7 +155,7 @@ anywhere in the string.
|
|
|
154
155
|
wcstwidth()
|
|
155
156
|
-----------
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
`wcstwidth()`_ is a variant of `wcswidth()`_ that provides terminal-specific Corrections_, reading
|
|
158
159
|
``TERM_PROGRAM`` or ``TERM`` when ``True`` (default), or caller can provide terminal query
|
|
159
160
|
XTVERSION_ or ENQ_ response:
|
|
160
161
|
|
|
@@ -550,7 +551,7 @@ https://wcwidth.readthedocs.io/en/latest/related.html
|
|
|
550
551
|
.. _`str.rjust()`: https://docs.python.org/3/library/stdtypes.html#str.rjust
|
|
551
552
|
.. _`str.center()`: https://docs.python.org/3/library/stdtypes.html#str.center
|
|
552
553
|
.. _`str.expandtabs()`: https://docs.python.org/3/library/stdtypes.html#str.expandtabs
|
|
553
|
-
.. _`General Tabulated Summary`: https://ucs-detect.readthedocs.io/results.html#tabulated-
|
|
554
|
+
.. _`General Tabulated Summary`: https://ucs-detect.readthedocs.io/results.html#general-tabulated-summary
|
|
554
555
|
.. _`wcwidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcwidth
|
|
555
556
|
.. _`wcswidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcswidth
|
|
556
557
|
.. _`wcstwidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcstwidth
|
|
@@ -66,8 +66,9 @@ This library may be considered to presume the terminal is enabled for DEC Privat
|
|
|
66
66
|
("Grapheme Clustering") by default, which may require to be enabled by a TUI application but
|
|
67
67
|
is often the default mode for those terminals that support it.
|
|
68
68
|
|
|
69
|
-
This library does support any specific "legacy width" measurement by API, but it does provide
|
|
70
|
-
Corrections_ for
|
|
69
|
+
This library does not support any specific "legacy width" measurement by API, but it does provide
|
|
70
|
+
Corrections_ for terminals using "legacy width" measurements or are without basic emoji or grapheme
|
|
71
|
+
support.
|
|
71
72
|
|
|
72
73
|
See also:
|
|
73
74
|
|
|
@@ -123,7 +124,7 @@ anywhere in the string.
|
|
|
123
124
|
wcstwidth()
|
|
124
125
|
-----------
|
|
125
126
|
|
|
126
|
-
|
|
127
|
+
`wcstwidth()`_ is a variant of `wcswidth()`_ that provides terminal-specific Corrections_, reading
|
|
127
128
|
``TERM_PROGRAM`` or ``TERM`` when ``True`` (default), or caller can provide terminal query
|
|
128
129
|
XTVERSION_ or ENQ_ response:
|
|
129
130
|
|
|
@@ -519,7 +520,7 @@ https://wcwidth.readthedocs.io/en/latest/related.html
|
|
|
519
520
|
.. _`str.rjust()`: https://docs.python.org/3/library/stdtypes.html#str.rjust
|
|
520
521
|
.. _`str.center()`: https://docs.python.org/3/library/stdtypes.html#str.center
|
|
521
522
|
.. _`str.expandtabs()`: https://docs.python.org/3/library/stdtypes.html#str.expandtabs
|
|
522
|
-
.. _`General Tabulated Summary`: https://ucs-detect.readthedocs.io/results.html#tabulated-
|
|
523
|
+
.. _`General Tabulated Summary`: https://ucs-detect.readthedocs.io/results.html#general-tabulated-summary
|
|
523
524
|
.. _`wcwidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcwidth
|
|
524
525
|
.. _`wcswidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcswidth
|
|
525
526
|
.. _`wcstwidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcstwidth
|
|
@@ -2,11 +2,24 @@
|
|
|
2
2
|
History
|
|
3
3
|
=======
|
|
4
4
|
|
|
5
|
+
0.9.3 *unreleased*
|
|
6
|
+
* **Bugfix** libwcwidth no longer has undefined behavior on NULL or empty input in the UTF-8 and
|
|
7
|
+
alignment functions, `PR #293`_, `PR #294`_.
|
|
8
|
+
* **Changed** `HyperlinkParams.parse()`_ now rejects trailing text, `PR #296`_.
|
|
9
|
+
* **Bugfix** `wrap()`_ should keep a link's own OSC 8 params across a line break, `PR #299`_.
|
|
10
|
+
|
|
11
|
+
0.9.2 *2026-10-04*
|
|
12
|
+
* **Bugfix** `wrap()`_ should omit an empty line as output, like `textwrap.wrap()`_ `PR #291`_.
|
|
13
|
+
* **Bugfix** `clip()`_ when using non-default argument, ``tabsize=0``, `PR #288`_.
|
|
14
|
+
* **Bugfix** regional-indicator pairs (flags) when corrected for terminals that show lone regional
|
|
15
|
+
indicators as narrow (xterm, wezterm, VTE, and others) in `wcstwidth()`_ and `width()`_, `PR
|
|
16
|
+
#284`.
|
|
17
|
+
|
|
5
18
|
0.9.1 *2026-09-23*
|
|
6
|
-
* **Bugfix**
|
|
7
|
-
|
|
8
|
-
* **Performance** improvement of ~15% for
|
|
9
|
-
|
|
19
|
+
* **Bugfix** `width()`_ in Python and libwcwidth mis-measured CSI sequences over 64 bytes, a 0.9.0
|
|
20
|
+
release regression! `PR #272`_.
|
|
21
|
+
* **Performance** improvement of ~15% for many Python API functions when using default arguments
|
|
22
|
+
like ``ambiguous_width`` and ``term_program``. `PR #273`_
|
|
10
23
|
|
|
11
24
|
0.9.0 *2026-09-23*
|
|
12
25
|
* **New** Optional CPython extension using libwcwidth_, improving performance 10-58x `PR #248`_.
|
|
@@ -239,7 +252,7 @@ https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c::
|
|
|
239
252
|
* for any purpose and without fee is hereby granted. The author
|
|
240
253
|
* disclaims all warranties with regard to this software.
|
|
241
254
|
|
|
242
|
-
.. _`Spacing Combining Mark`: https://www.unicode.org/versions/latest/
|
|
255
|
+
.. _`Spacing Combining Mark`: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153
|
|
243
256
|
.. _`specification`: https://wcwidth.readthedocs.io/en/latest/specs.html
|
|
244
257
|
.. _`prospector`: https://github.com/landscapeio/prospector
|
|
245
258
|
.. _`combining`: https://en.wikipedia.org/wiki/Combining_character
|
|
@@ -305,8 +318,16 @@ https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c::
|
|
|
305
318
|
.. _`PR #253`: https://github.com/jquast/wcwidth/pull/253
|
|
306
319
|
.. _`PR #259`: https://github.com/jquast/wcwidth/pull/259
|
|
307
320
|
.. _`PR #262`: https://github.com/jquast/wcwidth/pull/262
|
|
308
|
-
.. _`PR #
|
|
321
|
+
.. _`PR #272`: https://github.com/jquast/wcwidth/pull/272
|
|
309
322
|
.. _`PR #273`: https://github.com/jquast/wcwidth/pull/273
|
|
323
|
+
.. _`PR #281`: https://github.com/jquast/wcwidth/pull/281
|
|
324
|
+
.. _`PR #284`: https://github.com/jquast/wcwidth/pull/284
|
|
325
|
+
.. _`PR #288`: https://github.com/jquast/wcwidth/pull/288
|
|
326
|
+
.. _`PR #291`: https://github.com/jquast/wcwidth/pull/291
|
|
327
|
+
.. _`PR #293`: https://github.com/jquast/wcwidth/pull/293
|
|
328
|
+
.. _`PR #294`: https://github.com/jquast/wcwidth/pull/294
|
|
329
|
+
.. _`PR #296`: https://github.com/jquast/wcwidth/pull/296
|
|
330
|
+
.. _`PR #299`: https://github.com/jquast/wcwidth/pull/299
|
|
310
331
|
.. _`Issue #101`: https://github.com/jquast/wcwidth/issues/101
|
|
311
332
|
.. _`Issue #155`: https://github.com/jquast/wcwidth/issues/155
|
|
312
333
|
.. _`Issue #211`: https://github.com/jquast/wcwidth/issues/211
|
|
@@ -332,6 +353,7 @@ https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c::
|
|
|
332
353
|
.. _`iter_sequences()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.iter_sequences
|
|
333
354
|
.. _`list_versions()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.list_versions
|
|
334
355
|
.. _`list_term_programs()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.list_term_programs
|
|
356
|
+
.. _`HyperlinkParams.parse()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.HyperlinkParams
|
|
335
357
|
.. _`parity padding`: https://jazcap53.github.io/pythons-eccentric-strcenter.html
|
|
336
358
|
.. _`kitty text sizing protocol`: https://sw.kovidgoyal.net/kitty/text-sizing-protocol/
|
|
337
359
|
.. _Corrections: https://wcwidth.readthedocs.io/en/latest/intro.html#corrections
|
|
@@ -66,8 +66,9 @@ This library may be considered to presume the terminal is enabled for DEC Privat
|
|
|
66
66
|
("Grapheme Clustering") by default, which may require to be enabled by a TUI application but
|
|
67
67
|
is often the default mode for those terminals that support it.
|
|
68
68
|
|
|
69
|
-
This library does support any specific "legacy width" measurement by API, but it does provide
|
|
70
|
-
Corrections_ for
|
|
69
|
+
This library does not support any specific "legacy width" measurement by API, but it does provide
|
|
70
|
+
Corrections_ for terminals using "legacy width" measurements or are without basic emoji or grapheme
|
|
71
|
+
support.
|
|
71
72
|
|
|
72
73
|
See also:
|
|
73
74
|
|
|
@@ -123,7 +124,7 @@ anywhere in the string.
|
|
|
123
124
|
wcstwidth()
|
|
124
125
|
-----------
|
|
125
126
|
|
|
126
|
-
|
|
127
|
+
`wcstwidth()`_ is a variant of `wcswidth()`_ that provides terminal-specific Corrections_, reading
|
|
127
128
|
``TERM_PROGRAM`` or ``TERM`` when ``True`` (default), or caller can provide terminal query
|
|
128
129
|
XTVERSION_ or ENQ_ response:
|
|
129
130
|
|
|
@@ -519,7 +520,7 @@ https://wcwidth.readthedocs.io/en/latest/related.html
|
|
|
519
520
|
.. _`str.rjust()`: https://docs.python.org/3/library/stdtypes.html#str.rjust
|
|
520
521
|
.. _`str.center()`: https://docs.python.org/3/library/stdtypes.html#str.center
|
|
521
522
|
.. _`str.expandtabs()`: https://docs.python.org/3/library/stdtypes.html#str.expandtabs
|
|
522
|
-
.. _`General Tabulated Summary`: https://ucs-detect.readthedocs.io/results.html#tabulated-
|
|
523
|
+
.. _`General Tabulated Summary`: https://ucs-detect.readthedocs.io/results.html#general-tabulated-summary
|
|
523
524
|
.. _`wcwidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcwidth
|
|
524
525
|
.. _`wcswidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcswidth
|
|
525
526
|
.. _`wcstwidth()`: https://wcwidth.readthedocs.io/en/latest/api.html#wcwidth.wcstwidth
|
|
@@ -137,16 +137,23 @@ address:
|
|
|
137
137
|
String length conventions
|
|
138
138
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
139
139
|
|
|
140
|
-
Every string function
|
|
140
|
+
Every string function reads exactly the length you pass:
|
|
141
141
|
|
|
142
142
|
``_u32`` functions
|
|
143
143
|
count codepoints in the array,
|
|
144
144
|
``_u8`` functions
|
|
145
145
|
count bytes.
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
Pass ``strlen(text)`` when the text is a C string. A NUL counts as an ordinary zero-width character
|
|
148
|
+
in any position. Transform functions copy it through and report the full length in ``*out_len``.
|
|
149
|
+
|
|
150
|
+
Pointer contract
|
|
151
|
+
~~~~~~~~~~~~~~~~
|
|
152
|
+
|
|
153
|
+
Input pointers and the ``count`` / ``out_len`` out-length pointers must not be NULL.
|
|
154
|
+
|
|
155
|
+
``stack`` accepts NULL to select the heap path. ``wcwidth_utf8_decode_single()`` accepts
|
|
156
|
+
NULL as ``cp_out``, reporting the length of the next character.
|
|
150
157
|
|
|
151
158
|
Alternate encodings
|
|
152
159
|
~~~~~~~~~~~~~~~~~~~
|
|
@@ -302,6 +309,11 @@ returns a ``malloc``\ 'd NUL-terminated string the caller must ``free``:
|
|
|
302
309
|
/* "*café*" */
|
|
303
310
|
free(out);
|
|
304
311
|
|
|
312
|
+
Tabs are measured as though text begins at column 0. ``wcwidth_rjust_u8()`` and
|
|
313
|
+
``wcwidth_center_u8()`` insert padding to the left of the ``text`` which move tabstops and return
|
|
314
|
+
an incorrect result, always expand tabs or call `wcwidth_clip_u8()`_ to ``opts->dest_width`` first,
|
|
315
|
+
which expands tabs before using these alignment functions.
|
|
316
|
+
|
|
305
317
|
.. _libwcwidth-clip:
|
|
306
318
|
|
|
307
319
|
wcwidth_clip_u8()
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
Specification
|
|
5
5
|
=============
|
|
6
6
|
|
|
7
|
-
This document defines how
|
|
8
|
-
a string. This is not meant to an official standard, but as a terse
|
|
9
|
-
API functions :func:`wcwidth.wcwidth` and
|
|
10
|
-
functions :func:`wcwidth.width
|
|
7
|
+
This document defines how the Python wcwidth and C11 libwcwidth_ libraries measure the printable
|
|
8
|
+
width of characters of a string. This is not meant to be an official standard, but as a terse
|
|
9
|
+
description of the lowest level API functions :func:`wcwidth.wcwidth` and :func:`wcwidth.wcswidth`
|
|
10
|
+
and their relation to higher level functions :func:`wcwidth.width`, :func:`wcwidth.wcstwidth` and
|
|
11
|
+
:func:`wcwidth.iter_graphemes`.
|
|
11
12
|
|
|
12
13
|
Scope
|
|
13
14
|
-----
|
|
@@ -19,10 +20,19 @@ its docstring and specifications of related control codes, `XTerm Control Sequen
|
|
|
19
20
|
Text Sizing Protocol`_.
|
|
20
21
|
|
|
21
22
|
Each string yielded by :func:`wcwidth.iter_graphemes` may be mapped to :func:`wcwidth.wcswidth` to
|
|
22
|
-
accurately measure the width of a grapheme.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
accurately measure the width of a grapheme. :func:`wcwidth.iter_graphemes` implements the `Unicode
|
|
24
|
+
Standard Annex #29`_ rules of Unicode 18.0, the version of this library's tables, while
|
|
25
|
+
`unicodedata.iter_graphemes()`_, new in Python 3.15, implements Unicode 17.0. They also differ in
|
|
26
|
+
return value: :func:`wcwidth.iter_graphemes` yields only strings, while
|
|
27
|
+
:func:`unicodedata.iter_graphemes` yields ``unicodedata.Segment`` class objects.
|
|
28
|
+
|
|
29
|
+
Tamil, Kannada and Sinhala text is measured differently than it is segmented, so
|
|
30
|
+
:func:`wcwidth.clip` and :func:`wcwidth.wrap` do not measure these scripts correctly. See `Virama
|
|
31
|
+
Conjunct Formation`_.
|
|
32
|
+
|
|
33
|
+
The C11 library libwcwidth_ implements this specification through parallel entry points:
|
|
34
|
+
``wcswidth_u32()`` and ``wcswidth_u8()`` for :func:`wcwidth.wcswidth`, ``wcstwidth_u8()`` for
|
|
35
|
+
:func:`wcwidth.wcstwidth`, and ``wcwidth_width_u8()`` for :func:`wcwidth.width`; see the `C11 API`_.
|
|
26
36
|
|
|
27
37
|
Width of -1
|
|
28
38
|
-----------
|
|
@@ -30,39 +40,38 @@ Width of -1
|
|
|
30
40
|
The following have a column width of -1 for function :func:`wcwidth.wcwidth`
|
|
31
41
|
|
|
32
42
|
- ``C0`` control characters (`U+0001`_ through `U+001F`_).
|
|
33
|
-
- ``C1`` control characters and ``DEL`` (`U+007F`_ through `U+
|
|
43
|
+
- ``C1`` control characters and ``DEL`` (`U+007F`_ through `U+009F`_).
|
|
34
44
|
|
|
35
45
|
If any character in sequence contains ``C0`` or ``C1`` control characters, the final
|
|
36
|
-
return value of :func:`wcwidth.wcswidth` is -1
|
|
46
|
+
return value of :func:`wcwidth.wcswidth` is -1, except a control character immediately following
|
|
47
|
+
ZWJ (`U+200D`_), which `Width of 0`_ consumes.
|
|
37
48
|
|
|
38
49
|
Width of 0
|
|
39
50
|
----------
|
|
40
51
|
|
|
41
52
|
Any characters with the `Default_Ignorable_Code_Point`_ property in
|
|
42
|
-
`DerivedCoreProperties.txt`_
|
|
43
|
-
|
|
53
|
+
`DerivedCoreProperties.txt`_, excluding `U+00AD`_ SOFT HYPHEN (width 1) and
|
|
54
|
+
`U+115F`_ HANGUL CHOSEONG FILLER (width 2).
|
|
44
55
|
|
|
45
|
-
Any characters defined by `General Category`_ codes in `DerivedGeneralCategory.txt`_
|
|
56
|
+
Any characters defined by `General Category`_ codes in `DerivedGeneralCategory.txt`_:
|
|
46
57
|
|
|
47
|
-
- 'Me': `Enclosing Mark`_
|
|
48
|
-
- 'Mn': `Nonspacing Mark`_
|
|
58
|
+
- 'Me': `Enclosing Mark`_.
|
|
59
|
+
- 'Mn': `Nonspacing Mark`_.
|
|
49
60
|
- 'Cf': `Format`_ control characters excluding `U+00AD`_ SOFT HYPHEN and
|
|
50
|
-
`Prepended_Concatenation_Mark`_ characters
|
|
61
|
+
`Prepended_Concatenation_Mark`_ characters.
|
|
51
62
|
- 'Zl': `U+2028`_ LINE SEPARATOR only
|
|
52
63
|
- 'Zp': `U+2029`_ PARAGRAPH SEPARATOR only
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
an emoji base character in sequence; see `Width of 2`_ for standalone.
|
|
64
|
+
|
|
65
|
+
`Emoji Modifier`_ Fitzpatrick symbols (`U+1F3FB`_ through `U+1F3FF`_) are zero-width
|
|
66
|
+
only when following an emoji base character in sequence; see `Width of 2`_ for standalone.
|
|
57
67
|
|
|
58
68
|
The NULL character (`U+0000`_).
|
|
59
69
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
of `Unicode Standard Annex #29`_.
|
|
64
|
-
|
|
65
|
-
is measured normally.
|
|
70
|
+
ZWJ (`U+200D`_) is zero-width, and in sequence by :func:`wcwidth.wcswidth` or
|
|
71
|
+
:func:`wcwidth.width` the codepoint immediately following it is consumed as zero-width.
|
|
72
|
+
For emoji (`Extended_Pictographic`_ property) and `Regional Indicator`_ sequences this follows the
|
|
73
|
+
grapheme cluster boundary rules of `Unicode Standard Annex #29`_. After a virama, the following
|
|
74
|
+
consonant continues the conjunct, see `Virama Conjunct Formation`_.
|
|
66
75
|
|
|
67
76
|
The second `Regional Indicator`_ symbol (`U+1F1E6`_ through `U+1F1FF`_) in a
|
|
68
77
|
consecutive pair, when measured in sequence by :func:`wcwidth.wcswidth` or
|
|
@@ -71,9 +80,9 @@ consecutive pair, when measured in sequence by :func:`wcwidth.wcswidth` or
|
|
|
71
80
|
`Hangul Jamo`_ Jungseong and "Extended-B" code blocks, `U+1160`_ through
|
|
72
81
|
`U+11FF`_ and `U+D7B0`_ through `U+D7FF`_.
|
|
73
82
|
|
|
74
|
-
Any characters of category ``Mc`` (`Spacing Combining Mark`_),
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
Any characters of category ``Mc`` (`Spacing Combining Mark`_), for the
|
|
84
|
+
single-character function :func:`wcwidth.wcwidth`. When measured in sequence by
|
|
85
|
+
:func:`wcwidth.wcswidth`, see `Width of 2`_.
|
|
77
86
|
|
|
78
87
|
Width of 1
|
|
79
88
|
----------
|
|
@@ -93,8 +102,9 @@ Width of 2
|
|
|
93
102
|
----------
|
|
94
103
|
|
|
95
104
|
Any character defined by `East Asian`_ (`Unicode Standard Annex #11`_) Fullwidth
|
|
96
|
-
(``F``) or Wide (``W``) properties in `EastAsianWidth.txt`_
|
|
97
|
-
|
|
105
|
+
(``F``) or Wide (``W``) properties in `EastAsianWidth.txt`_, except those that
|
|
106
|
+
are defined by the Category codes of `Nonspacing Mark`_ (``Mn``) or `Spacing
|
|
107
|
+
Combining Mark`_ (``Mc``).
|
|
98
108
|
|
|
99
109
|
`Regional Indicator`_ symbols (`U+1F1E6`_ through `U+1F1FF`_). Though
|
|
100
110
|
classified as Neutral in `EastAsianWidth.txt`_, terminals universally render
|
|
@@ -106,7 +116,7 @@ measured standalone (not following an emoji base character). When following
|
|
|
106
116
|
an emoji base, they combine with the base and add 0 to total width.
|
|
107
117
|
|
|
108
118
|
Any characters of `Modifier Symbol`_ category, ``'Sk'`` where ``'FULLWIDTH'`` is
|
|
109
|
-
present in comment of `UnicodeData.txt`_
|
|
119
|
+
present in comment of `UnicodeData.txt`_.
|
|
110
120
|
|
|
111
121
|
Any character with `U+FE0F`_ (Variation Selector 16) defined as ``emoji style``
|
|
112
122
|
in `emoji-variation-sequences.txt`_, per `UTS #51`_ and `Unicode Standard
|
|
@@ -116,13 +126,14 @@ making the pair width 2. Wide characters are unchanged.
|
|
|
116
126
|
Any character of non-zero width followed by an ``Mc`` (`Spacing Combining Mark`_)
|
|
117
127
|
character when measured in sequence by :func:`wcwidth.wcswidth` or
|
|
118
128
|
:func:`wcwidth.width`. The ``Mc`` character caps the cluster width at 2,
|
|
119
|
-
reflecting its *positive advance width* as defined in `General Category`_
|
|
120
|
-
|
|
121
|
-
|
|
129
|
+
reflecting its *positive advance width* as defined in the `General Category Values`_
|
|
130
|
+
table. Zero-width combining marks (``Mn``) between the base character and the ``Mc``
|
|
131
|
+
do not break the association. For example, a consonant followed
|
|
122
132
|
by a Nukta (``Mn``) and then a vowel sign (``Mc``) is measured as a cluster of
|
|
123
133
|
width 2.
|
|
124
134
|
|
|
125
|
-
Any grapheme cluster width is limited to 2 cells since 0.8.0, `PR #224`_
|
|
135
|
+
Any grapheme cluster width is limited to 2 cells since 0.8.0, `PR #224`_, which prevents the ``Mc``
|
|
136
|
+
rule and the virama conjunct sum from exceeding 2 cells.
|
|
126
137
|
|
|
127
138
|
Virama Conjunct Formation
|
|
128
139
|
-------------------------
|
|
@@ -145,16 +156,19 @@ described in the Virama section header).
|
|
|
145
156
|
- ZWJ (`U+200D`_) after a virama is consumed without breaking conjunct state,
|
|
146
157
|
supporting explicit half-form requests (virama + ZWJ + consonant).
|
|
147
158
|
|
|
148
|
-
See also: `L2/
|
|
159
|
+
See also: `L2/23-107`_ "Proper Complex Script Support in Text Terminals", the 2023 project
|
|
160
|
+
proposal that records the missing terminal-width standard, and `L2/25-263`_ for the Text Terminal
|
|
161
|
+
Working Group's latest report.
|
|
149
162
|
|
|
150
|
-
.. _`Hyperlinks in Terminal Emulators`: https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
|
|
151
163
|
.. _`Kitty Text Sizing Protocol`: https://sw.kovidgoyal.net/kitty/text-sizing-protocol/
|
|
152
164
|
.. _`XTerm Control Sequences`: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
|
|
165
|
+
.. _`C11 API`: https://wcwidth.readthedocs.io/en/latest/api_c.html
|
|
166
|
+
.. _libwcwidth: https://wcwidth.readthedocs.io/en/latest/libwcwidth.html
|
|
153
167
|
.. _`U+0000`: https://codepoints.net/U+0000
|
|
154
168
|
.. _`U+0001`: https://codepoints.net/U+0001
|
|
155
169
|
.. _`U+001F`: https://codepoints.net/U+001F
|
|
156
170
|
.. _`U+007F`: https://codepoints.net/U+007F
|
|
157
|
-
.. _`U+
|
|
171
|
+
.. _`U+009F`: https://codepoints.net/U+009F
|
|
158
172
|
.. _`U+00AD`: https://codepoints.net/U+00AD
|
|
159
173
|
.. _`U+1160`: https://codepoints.net/U+1160
|
|
160
174
|
.. _`U+11FF`: https://codepoints.net/U+11FF
|
|
@@ -172,12 +186,13 @@ See also: `L2/2023/23107`_ "Proper Complex Script Support in Text Terminals".
|
|
|
172
186
|
.. _`Prepended_Concatenation_Mark`: https://www.unicode.org/reports/tr44/#Prepended_Concatenation_Mark
|
|
173
187
|
.. _`Default_Ignorable_Code_Point`: https://www.unicode.org/reports/tr44/#Default_Ignorable_Code_Point
|
|
174
188
|
.. _`General Category`: https://www.unicode.org/reports/tr44/#General_Category
|
|
189
|
+
.. _`General Category Values`: https://www.unicode.org/reports/tr44/#GC_Values_Table
|
|
175
190
|
.. _`Spacing Combining Mark`: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153
|
|
176
191
|
.. _`Enclosing Mark`: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153
|
|
177
192
|
.. _`Format`: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153
|
|
178
193
|
.. _`Modifier Symbol`: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153
|
|
179
194
|
.. _`Hangul Jamo`: https://www.unicode.org/charts/PDF/U1100.pdf
|
|
180
|
-
.. _`U+D7FF`: https://
|
|
195
|
+
.. _`U+D7FF`: https://www.unicode.org/charts/PDF/UD7B0.pdf
|
|
181
196
|
.. _`UnicodeData.txt`: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt
|
|
182
197
|
.. _`East Asian`: https://www.unicode.org/reports/tr11/
|
|
183
198
|
.. _`Unicode Standard Annex #11`: https://www.unicode.org/reports/tr11/
|
|
@@ -187,18 +202,18 @@ See also: `L2/2023/23107`_ "Proper Complex Script Support in Text Terminals".
|
|
|
187
202
|
.. _`U+1F3FF`: https://codepoints.net/U+1F3FF
|
|
188
203
|
.. _`Regional Indicator`: https://www.unicode.org/charts/PDF/U1F100.pdf
|
|
189
204
|
.. _`Emoji Modifier`: https://unicode.org/reports/tr51/#Emoji_Modifiers
|
|
190
|
-
.. _`Extended_Pictographic`: https://www.unicode.org/
|
|
205
|
+
.. _`Extended_Pictographic`: https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt
|
|
191
206
|
.. _`UTS #51`: https://www.unicode.org/reports/tr51/
|
|
192
207
|
.. _`Nonspacing Mark`: https://www.unicode.org/versions/latest/core-spec/chapter-4/#G134153
|
|
193
208
|
.. _`IndicSyllabicCategory.txt`: https://www.unicode.org/Public/UCD/latest/ucd/IndicSyllabicCategory.txt
|
|
194
|
-
.. _`Indic_Syllabic_Category`: https://www.unicode.org/reports/tr44/#Indic_Syllabic_Category
|
|
195
209
|
.. _`Invisible_Stacker`: https://www.unicode.org/Public/UCD/latest/ucd/IndicSyllabicCategory.txt
|
|
196
210
|
.. _`Brahmic scripts`: https://en.wikipedia.org/wiki/Brahmic_scripts
|
|
197
211
|
.. _`Virama`: https://www.unicode.org/glossary/#virama
|
|
198
212
|
.. _`conjunct`: https://www.unicode.org/glossary/#consonant_conjunct
|
|
199
213
|
.. _`aksara`: https://www.unicode.org/glossary/#aksara
|
|
200
|
-
.. _`L2/
|
|
214
|
+
.. _`L2/23-107`: https://www.unicode.org/L2/L2023/23107-terminal-suppt.pdf
|
|
215
|
+
.. _`L2/25-263`: https://www.unicode.org/L2/L2025/25263-ttwg-report-utc185.pdf
|
|
201
216
|
.. _`Unicode Standard Annex #29`: https://www.unicode.org/reports/tr29/
|
|
202
|
-
.. _`Unicode Standard Section 23.4`: https://www.unicode.org/versions/
|
|
203
|
-
.. _`
|
|
217
|
+
.. _`Unicode Standard Section 23.4`: https://www.unicode.org/versions/latest/core-spec/chapter-23/#G19053
|
|
218
|
+
.. _`unicodedata.iter_graphemes()`: https://docs.python.org/3.15/library/unicodedata.html#unicodedata.iter_graphemes
|
|
204
219
|
.. _`PR #224`: https://github.com/jquast/wcwidth/pull/224
|
|
@@ -13,8 +13,8 @@ CFLAGS ?= -std=c11 -Wall -Wextra -O2 -g
|
|
|
13
13
|
INCLUDE = -Iinclude
|
|
14
14
|
BUILD = build
|
|
15
15
|
|
|
16
|
-
ASAN_CFLAGS = -std=c11 -Wall -Wextra -O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer
|
|
17
|
-
UBSAN_CFLAGS = -std=c11 -Wall -Wextra -O2 -g -fsanitize=undefined -fno-omit-frame-pointer
|
|
16
|
+
ASAN_CFLAGS = -std=c11 -Wall -Wextra -O1 -g -fsanitize=address,undefined -fno-sanitize-recover=all -fno-omit-frame-pointer
|
|
17
|
+
UBSAN_CFLAGS = -std=c11 -Wall -Wextra -O2 -g -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer
|
|
18
18
|
|
|
19
19
|
LIB_SRCS = $(wildcard src/*.c) $(wildcard src/tables/*.c)
|
|
20
20
|
LIB_OBJS = $(patsubst %.c,$(BUILD)/%.o,$(LIB_SRCS))
|
|
@@ -48,6 +48,11 @@ extern const wcwidth_align_opts_t WCWIDTH_ALIGN_OPTS_DEFAULT;
|
|
|
48
48
|
* opts: alignment options, or NULL for defaults.
|
|
49
49
|
* out_len: output: byte length of result (excluding NUL); may be NULL.
|
|
50
50
|
* error: output: wcwidth_error_t, WCWIDTH_ERROR_NONE on success.
|
|
51
|
+
*
|
|
52
|
+
* Tabs are measured as though text begins at column 0. 'rjust' and 'center' operations insert
|
|
53
|
+
* padding to the left of the ``text`` which move tabstops and return an incorrect result, always
|
|
54
|
+
* expand tabs or clip to ``opts->dest_width``, which expands tabs before using those alignment
|
|
55
|
+
* functions.
|
|
51
56
|
*/
|
|
52
57
|
char *wcwidth_ljust_u8(const char *text, size_t text_len, wcwidth_control_mode_t mode,
|
|
53
58
|
const wcwidth_align_opts_t *opts, size_t *out_len, int *error);
|
|
@@ -17,6 +17,9 @@ extern "C" {
|
|
|
17
17
|
* U+FFFD and the return value is the number of bytes to skip (1 for a bad
|
|
18
18
|
* leading byte, the remaining length for a truncated sequence, or 0 when
|
|
19
19
|
* *len* is 0).
|
|
20
|
+
*
|
|
21
|
+
* *s* must not be NULL. *cp_out* may be NULL to consume the sequence and
|
|
22
|
+
* query the length of the next character.
|
|
20
23
|
*/
|
|
21
24
|
size_t wcwidth_utf8_decode_single(const char *s, size_t len, uint32_t *cp_out);
|
|
22
25
|
|
|
@@ -28,15 +31,26 @@ size_t wcwidth_utf8_decode_single(const char *s, size_t len, uint32_t *cp_out);
|
|
|
28
31
|
* is undefined behavior. Sets *count* and returns NULL on allocation
|
|
29
32
|
* failure.
|
|
30
33
|
*
|
|
34
|
+
* *utf8* and *count* must not be NULL; *count* is required because the
|
|
35
|
+
* returned array carries no terminator. A *stack* of NULL forces the heap
|
|
36
|
+
* path. When *n* is 0 and *stack* is NULL, the result is a freeable array
|
|
37
|
+
* with *count* set to 0.
|
|
38
|
+
*
|
|
31
39
|
* The result type allows a plain free() release, matching wcwidth_encode_u32()
|
|
32
40
|
* below. Treat the contents as read-only.
|
|
41
|
+
*
|
|
42
|
+
* Decoding reads exactly *n* bytes. A NUL byte counts as an ordinary
|
|
43
|
+
* zero-width codepoint in any position; pass strlen(utf8) for a C string.
|
|
33
44
|
*/
|
|
34
45
|
uint32_t *wcwidth_decode_u32(const char *utf8, size_t n, uint32_t *stack, size_t stack_cap,
|
|
35
46
|
size_t *count);
|
|
36
47
|
|
|
37
48
|
/*
|
|
38
49
|
* Decode *utf8* into a malloc'd codepoint array (one free()). Returns the
|
|
39
|
-
* array and sets *count*, or NULL on allocation failure.
|
|
50
|
+
* array and sets *count*, or NULL on allocation failure. An *n* of 0 returns
|
|
51
|
+
* a freeable array with *count* set to 0.
|
|
52
|
+
*
|
|
53
|
+
* Follows the length and NUL semantics of wcwidth_decode_u32().
|
|
40
54
|
*/
|
|
41
55
|
uint32_t *wcwidth_decode_u32_heap(const char *utf8, size_t n, size_t *count);
|
|
42
56
|
|
|
@@ -46,10 +60,15 @@ uint32_t *wcwidth_decode_u32_heap(const char *utf8, size_t n, size_t *count);
|
|
|
46
60
|
* in *stack* (no allocation), otherwise a heap buffer is allocated. The
|
|
47
61
|
* caller must free() the result only when it is not *stack*; freeing *stack*
|
|
48
62
|
* is undefined behavior. Sets *out_len* and returns NULL on allocation
|
|
49
|
-
* failure.
|
|
63
|
+
* failure. An *n* of 0 returns a freeable buffer with *out_len* set to 0.
|
|
64
|
+
*
|
|
65
|
+
* *codepoints* and *out_len* must not be NULL; *out_len* is required because
|
|
66
|
+
* the returned bytes carry no terminator. A *stack* of NULL forces the heap
|
|
67
|
+
* path.
|
|
50
68
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
69
|
+
* Encoding writes exactly *n* codepoints: a U+0000 becomes a NUL byte, so the
|
|
70
|
+
* output can contain embedded NUL bytes. Invalid codepoints (lone surrogates
|
|
71
|
+
* and values above U+10FFFF) are encoded as U+FFFD.
|
|
53
72
|
*/
|
|
54
73
|
char *wcwidth_encode_u32(const uint32_t *codepoints, size_t n, char *stack, size_t stack_cap,
|
|
55
74
|
size_t *out_len);
|
|
@@ -18,8 +18,8 @@ extern "C" {
|
|
|
18
18
|
|
|
19
19
|
#define WCWIDTH_VERSION_MAJOR 0
|
|
20
20
|
#define WCWIDTH_VERSION_MINOR 9
|
|
21
|
-
#define WCWIDTH_VERSION_PATCH
|
|
22
|
-
#define WCWIDTH_VERSION "0.9.
|
|
21
|
+
#define WCWIDTH_VERSION_PATCH 3
|
|
22
|
+
#define WCWIDTH_VERSION "0.9.3"
|
|
23
23
|
|
|
24
24
|
/* Unicode version the library tables were generated from. */
|
|
25
25
|
#define WCWIDTH_UNICODE_VERSION "18.0.0"
|
|
@@ -87,6 +87,10 @@ fill_repeat(char *dst, const char *fillchar, size_t fillchar_len, size_t count)
|
|
|
87
87
|
{
|
|
88
88
|
size_t i;
|
|
89
89
|
|
|
90
|
+
if (fillchar_len == 0) {
|
|
91
|
+
return dst;
|
|
92
|
+
}
|
|
93
|
+
|
|
90
94
|
for (i = 0; i < count; i++) {
|
|
91
95
|
memcpy(dst, fillchar, fillchar_len);
|
|
92
96
|
dst += fillchar_len;
|
|
@@ -133,7 +137,9 @@ ljust_impl(const char *text, size_t text_len, size_t dest_width, const char *fil
|
|
|
133
137
|
return NULL;
|
|
134
138
|
}
|
|
135
139
|
|
|
136
|
-
|
|
140
|
+
if (text_len > 0) {
|
|
141
|
+
memcpy(result, text, text_len);
|
|
142
|
+
}
|
|
137
143
|
fill_repeat(result + text_len, fillchar, fillchar_len, padding);
|
|
138
144
|
result[total] = '\0';
|
|
139
145
|
|
|
@@ -184,7 +190,9 @@ rjust_impl(const char *text, size_t text_len, size_t dest_width, const char *fil
|
|
|
184
190
|
|
|
185
191
|
fill_repeat(result, fillchar, fillchar_len, padding);
|
|
186
192
|
/* add_fill_bytes() above already proved this product cannot wrap. */
|
|
187
|
-
|
|
193
|
+
if (text_len > 0) {
|
|
194
|
+
memcpy(result + padding * fillchar_len, text, text_len);
|
|
195
|
+
}
|
|
188
196
|
result[total] = '\0';
|
|
189
197
|
|
|
190
198
|
if (out_len != NULL) {
|
|
@@ -246,7 +254,9 @@ center_impl(const char *text, size_t text_len, size_t dest_width, const char *fi
|
|
|
246
254
|
|
|
247
255
|
{
|
|
248
256
|
char *dst = fill_repeat(result, fillchar, fillchar_len, left_pad);
|
|
249
|
-
|
|
257
|
+
if (text_len > 0) {
|
|
258
|
+
memcpy(dst, text, text_len);
|
|
259
|
+
}
|
|
250
260
|
fill_repeat(dst + text_len, fillchar, fillchar_len, right_pad);
|
|
251
261
|
}
|
|
252
262
|
result[total] = '\0';
|
|
@@ -806,6 +806,16 @@ _wrap_chunks(chunklist_t *chunks, const wcwidth_wrap_opts_t *opts, lines_t *line
|
|
|
806
806
|
lc.len = rstrip_len(lc.data, lc.len);
|
|
807
807
|
if (lc.data != NULL)
|
|
808
808
|
lc.data[lc.len] = '\0';
|
|
809
|
+
if (lc.len == 0) {
|
|
810
|
+
/*
|
|
811
|
+
* The line held only whitespace, which dropping has now emptied. Skip
|
|
812
|
+
* it and leave `first` unchanged so initial_indent still applies to the
|
|
813
|
+
* first line with content, as stdlib textwrap and wcwidth.textwrap do.
|
|
814
|
+
*/
|
|
815
|
+
sbuf_free(&lc);
|
|
816
|
+
cl_free(&cur);
|
|
817
|
+
continue;
|
|
818
|
+
}
|
|
809
819
|
}
|
|
810
820
|
sbuf_t fl;
|
|
811
821
|
sbuf_init(&fl);
|