Leith.Text 59.0.0
Leith.Text
Standards-based Unicode text semantics for .NET: grapheme segmentation and navigation, Unicode Character Database lookups, streaming state, and a deliberately separate terminal-cell-width policy.
Leith.Text is designed as a general-purpose library, not as a private implementation detail of
the Leith applications. Leith.Editor, Leith.Term, and Leith.Commander are consumers of its public
contracts; they do not define those contracts. A proposed API should make sense to a .NET user who has
never seen another Leith repository.
Grapheme segmentation is universal Unicode text semantics. Terminal column width is a console
policy — separate from GUI/font shaping width and kept isolated under Leith.Text.Terminal.
Why
string.Length and naive enumeration are not enough for anything user-facing: a single
character a user can select or delete is often several UTF-16 code units, or several code
points joined by a zero-width joiner (family emoji, flags, skin-tone modifiers). If you are
building a text editor, terminal emulator, TUI, chat application, log viewer, protocol decoder,
or any other Unicode-aware .NET component, this library provides reusable text-level semantics:
- Validated, not just implemented. Grapheme segmentation is tested against the official
Unicode UAX #29 conformance corpus (
GraphemeBreakTest.txt), not hand-picked examples. - Zero dependencies beyond
System.Memoryonnetstandard2.0. Nothing Leith-specific leaks into the public API. - Multi-targeted:
netstandard2.0,net8.0,net9.0,net10.0— usable from .NET Framework 4.6.1+ through current .NET. - Standards-pinned data. Unicode properties are generated from a pinned UCD version and the generated tables are verified in CI.
- Universal semantics and consumer policy stay distinct. Grapheme segmentation (UAX #29) is
universal; terminal column width (
TerminalCellWidth) is a separate, opinionated console policy.
Scope
The project owns reusable Unicode text semantics: operations and properties that can be specified, tested, and consumed independently of a particular editor, terminal, renderer, or application model.
A feature is a good fit when it:
- represents a reusable property, boundary, transformation, or state machine over Unicode text;
- has a standards-based or otherwise explicit semantic contract;
- can be tested independently of rendering, document storage, terminal grids, or application state;
- is useful to consumers outside the Leith workspace; and
- does not introduce Leith-specific concepts into the public API.
The project intentionally does not own font shaping or rendering, GUI layout, terminal screen-grid placement, editor document models, syntax highlighting, language parsing, or application-specific text policy.
See Docs/scope-and-roadmap.md for the project boundary and roadmap, and
Docs/research/text-semantics.md for the research gate applied before
expanding into additional Unicode semantics.
Layout
Leith.Text
├── Unicode/ UCD 17.0.0 properties and tables
├── Graphemes/ UTF-16 grapheme boundaries and navigation
└── Terminal/ terminal cell width measurement and truncation
One NuGet package (Leith.Text), three namespaces.
Used internally by
| Consumer | Uses |
|---|---|
| Leith.Editor | GraphemeNavigator for caret, Backspace/Delete, selection, wrapping normalization |
| Leith.Term | grapheme segmentation, streaming state, terminal width |
| Leith.Commander | mostly via Editor; optional filename/path helpers |
Extraction from Leith.Term is complete; Leith.Editor and Leith.Term consume this
package as the UAX #29 source of truth, the same way any other .NET consumer would.
API sketch
using Leith.Text.Graphemes;
using Leith.Text.Terminal;
using Leith.Text.Unicode;
// Universal grapheme operations (UTF-16 offsets)
foreach (var cluster in Grapheme.Enumerate(line))
{
...
}
var count = Grapheme.Count("👨👩👧👦abc"); // 4
var previous = Grapheme.PreviousBoundary(line, caret);
var containing = Grapheme.GetContainingRange(line, caret);
// Unicode data
var widthClass = UnicodeProperties.GetEastAsianWidth(0x3042);
// Terminal policy (not GUI width)
var columns = TerminalCellWidth.Measure("🇵🇱");
var cjkColumns = TerminalCellWidth.Measure("·", TerminalWidthPolicy.WideAmbiguous);
var clipped = TerminalCellWidth.Truncate(filename, 30);
Document offsets stay UTF-16; GraphemeNavigator snaps and steps across legal grapheme boundaries.
Build
dotnet build Leith.Text.slnx -c Release
dotnet test --solution Leith.Text.slnx -c Release
Unicode table regeneration
Pinned UCD inputs: unicode/17.0.0/. Generator: tools/Leith.Text.UnicodeGenerator/.
# First-time or UCD bump
pwsh scripts/fetch-ucd.ps1 -Version 17.0.0
# Regenerate committed *.g.cs
pwsh scripts/regenerate-unicode-tables.ps1
CI reruns the generator and fails when src/Text/Internal/Generated/*.g.cs drift from the
pinned UCD (git diff --exit-code).
Tests use xunit.v3 4.x with Microsoft.Testing.Platform (global.json). The test suite itself
targets net10.0; the library targets netstandard2.0;net8.0;net9.0;net10.0.
Status
UCD 17.0.0 tables, allocation-free UTF-16 enumeration, GraphemeStreamState for incremental
join state, GraphemeNavigator editor helpers, and terminal width under
TerminalCellWidth. Consumed by Leith.Term (segmentation + width) and Leith.Editor
(caret navigation). Multi-targeted netstandard2.0/net8.0/net9.0/net10.0; version
0.5.0.
The next phase is contract stabilization and research, not feature accumulation: establish the long-term Unicode/versioning policy, harden the existing API, and evaluate additional text semantics against the project scope before committing them to the roadmap.
Showing the top 20 packages that depend on Leith.Text.
| Packages | Downloads |
|---|---|
|
Leith.Term
Leith VT/xterm-class terminal engine (.NET 10). See https://github.com/buchmiet/Leith.Term.Engine.
|
34 |
|
Leith.Term.Kernel
Leith.Term kernel. Internal implementation of the shipping Terminal facade; not a public product API.
|
33 |
|
Leith.Term
Leith VT/xterm-class terminal engine (.NET 10). See https://github.com/buchmiet/Leith.Term.Engine.
|
3 |
|
Leith.Term.Presentation.Rendering.Skia
Skia rendering and font-metrics backend for Leith.Term.Presentation.
|
0 |
|
Leith.Term
Leith VT/xterm-class terminal engine (.NET 10). See https://github.com/buchmiet/Leith.Term.Engine.
|
0 |
|
Leith.Term.Kernel
Leith.Term kernel. Internal implementation of the shipping Terminal facade; not a public product API.
|
0 |
.NET 10.0
- No dependencies.
.NET 8.0
- No dependencies.
.NET 9.0
- No dependencies.
.NET Standard 2.0
- System.Memory (>= 4.5.5)
| Version | Downloads | Last updated |
|---|---|---|
| 59.0.0 | 72 | 09/28/2026 |