Skip to main content

cellstr

Display-width aware len, slicing, padding and truncation for terminal text: East Asian wide characters, emoji sequences, combining marks, zero-width characters and ANSI escape sequences, measured the way a terminal draws them. Typed, zero dependencies, Unicode 18.0.0.

Install

pip install cellstr

Usage

len, slicing and str.ljust count code points, so they misalign any text that carries colour codes, CJK characters, emoji or accents. cellstr counts display cells.

from cellstr import cell_len, cell_slice, fit, ljust, truncate

warn = "\x1b[31mWARN\x1b[0m"  # red "WARN"
cell_len(warn)  # -> 4
cell_len("你好")  # -> 4
cell_len("👨‍👩‍👧")  # -> 2
cell_len("🇯🇵")  # -> 2
cell_len("é")  # -> 1

cell_slice(warn, 0, 2)  # -> "\x1b[31mWA\x1b[0m"
cell_slice("a你b", 0, 2)  # -> "a"
cell_slice("x👨‍👩‍👧y", 0, 2)  # -> "x"

ljust("你", 4)  # -> "你  "
truncate("hello world", 8)  # -> "hello..."
truncate("/usr/local/lib/python", 12, position="middle")  # -> "/usr/...thon"
fit("张伟张伟", 5, suffix="")  # -> "张伟 "

What it gets right:

  • Grapheme clusters. A ZWJ family, a skin tone sequence, a flag, a keycap or a letter with accents is one unit: measured once and never split by slicing or truncation.
  • Escape sequences. SGR colours, OSC 8 hyperlinks, cursor movement and the other ECMA-48 families count as nothing and are kept in place, so styled text stays styled.
  • Ambiguous width. Greek, Cyrillic, box drawing and circled digits are one cell in Western terminals and two in CJK ones. Pass ambiguous=2 to any function.
  • Tabs. Pass tabsize=8 to measure tab stops; slicing and padding turn tabs into the spaces they cover. expand_tabs() does it on its own.
  • Real Unicode data. Tables are generated by a committed script from a committed Unicode Character Database snapshot, and the full grapheme break test suite runs.
from cellstr import cell_len, iter_cells, truncate_detailed

cell_len("αβ─", ambiguous=2)  # -> 6
cell_len("a\tb", tabsize=8)  # -> 9
[c.width for c in iter_cells("a你🇯🇵")]  # -> [1, 2, 2]
truncate_detailed("hello world", 8).truncated  # -> True

Public API: cell_len, char_width, grapheme_width, iter_graphemes, iter_cells (Cell), cell_slice, ljust, rjust, center, fit, truncate, truncate_detailed (Truncation), expand_tabs, strip_ansi, UNICODE_VERSION, and the Align and Position literal types. Every function is fully typed and documented.

Command line

$ printf 'abc\n你好\n' | cellstr measure
3
4
$ printf '/usr/local/lib/python3/site-packages\n' | cellstr truncate 16 --position middle
/usr/lo...ckages
$ printf 'id\n12345\n' | cellstr pad 8 --align right
      id
   12345

Commands: measure (--max), truncate N, pad N, fit N and slice START [STOP], all with --ambiguous and --tabsize. cellstr --help lists runnable examples.

Terminals disagree

There is no standard for how many cells a character takes, and terminals differ on ambiguous-width characters, emoji ZWJ sequences and variation selectors. cellstr follows Markus Kuhn's reference wcwidth for single code points and measures emoji sequences as one glyph, as terminals with grapheme support draw them. GUIDE.md has the exact rules, concrete examples of where terminals differ, a recipe for code point by code point measuring, and every difference from the wcwidth package.

Why

wcwidth measures plain-text width well, but it does not give you a typed, cohesive set of string operations: slicing by column that keeps escapes and graphemes intact, padding, fitting a table cell and width-aware truncation with a suffix at either end or in the middle. strip-ansi style tools remove escapes but know nothing about width. cellstr does all of it in one small, fully typed, zero-dependency package.

License

MIT. See LICENSE. The property tables in src/cellstr/_ucd_*.py are generated from the Unicode Character Database and are covered by the Unicode License v3, see LICENSE-UNICODE.

Metadata

Release files for cellstr 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cellstr 0.2.1
File Size Uploaded Provenance Actions
cellstr-0.2.1.tar.gz 42.0 kB Without provenance Details for cellstr-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cellstr 0.2.1
File Interpreter ABI Platform Actions
cellstr-0.2.1-py3-none-any.whl Python 3 none any Details for cellstr-0.2.1-py3-none-any.whl

Total release size: 66.6 kB

Release files / cellstr-0.2.1.tar.gz

Download URL cellstr-0.2.1.tar.gz
Size 42.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c96f5efa3270f11a0d5c5c11cb6af80ed7eb6cfe4b39b4caf6862230daea95f8
BLAKE2b-256 checksum
How to use checksums
998ce7a207993c4f9a65484afb068abc76cae3c417f0f521afd38cf8328b76d3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release files / cellstr-0.2.1-py3-none-any.whl

Download URL cellstr-0.2.1-py3-none-any.whl
Size 24.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6fafe5adfa054f6296af9a72c21403cb04cebebf803ebcfb2ba0c9543f8c45f1
BLAKE2b-256 checksum
How to use checksums
10c965908579ca8d03b310c513d84898f7be1563ff80958f931c3574a7238e67
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Security for cellstr 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page