منصوبے کے بارے میں
Pretext is a pure JavaScript/TypeScript library for measuring multiline text and computing line layout. It avoids DOM measurement APIs like `getBoundingClientRect` and `offsetHeight`, which force layout reflow, and instead performs its own measurement using the browser's canvas `measureText` as ground truth. This makes it useful for virtualization, custom layout engines, canvas/SVG rendering, and development-time overflow checks.
## Installation
```sh
npm install @chenglou/pretext
```
## Main use cases
### 1. Measuring paragraph height without touching the DOM
```ts
import { prepare, layout } from '@chenglou/pretext'
const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter')
const { height, lineCount } = layout(prepared, 320, 20)
```
`prepare()` does one-time work: whitespace normalization, text segmentation, glue rule application, and canvas-based measurement. `layout()` is then a cheap pure-arithmetic operation over cached widths, so it can be re-run on resize without re-preparing.
Options for `prepare()` include `whiteSpace: 'pre-wrap'` for textarea-like behavior, `wordBreak: 'keep-all'` for CSS-like `word-break: keep-all`, and `letterSpacing` for CSS `letter-spacing`.
### 2. Manual line layout
`prepareWithSegments()` returns a richer structure for custom layout. The following APIs are available:
- `layoutWithLines()` — returns all lines at a fixed max width, including text and measured widths.
- `walkLineRanges()` — calls a callback per line with width and start/end cursors, without building line strings.
- `measureLineStats()` — returns line count and widest line width without allocations.
- `measureNaturalWidth()` — returns the widest forced line when width is not the cause of wrapping.
- `layoutNextLine()` / `layoutNextLineRange()` — iterator-style APIs for laying out lines one at a time with potentially different widths, useful for flowing text around floats or dynamic containers.
- `materializeLineRange()` — converts a layout range back into a full line string.
These enable rendering to Canvas, SVG, WebGL, and eventually server-side environments. Demos are included in the repository and at chenglou.me/pretext.
## Rich inline helper
A separate helper at `@chenglou/pretext/rich-inline` supports basic rich-text inline flow with mixed fonts, atomic items (e.g. chips and mentions), and caller-owned extra width for pill chrome. It is intentionally narrow: inline-only, `white-space: normal` only, and not a general CSS inline formatting engine.
## API glossary highlights
- `PreparedText` is the opaque fast-path handle; `PreparedTextWithSegments` is the richer manual-layout handle.
- `LayoutCursor` uses segment/grapheme indices, not raw string offsets.
- `layout()` on an empty string returns `{ lineCount: 0, height: 0 }`; browsers size empty blocks to one `line-height`, so callers may want to clamp.
- Soft hyphens are supported: they act as optional break points and materialize as a trailing `-` when chosen.
- `clearCache()` clears shared internal caches; `setLocale()` sets the locale for future preparation calls.
- The richer handle includes approximate `segLevels` for custom bidi-aware rendering, but Pretext does not implement the full Unicode Bidirectional Algorithm.
## Caveats
Pretext is not a full font rendering engine. It targets common CSS text setups:
- `white-space: normal` and `pre-wrap`
- `word-break: normal` and `keep-all`
- `overflow-wrap: break-word`
- `line-break: auto`
- `letter-spacing` as a numeric pixel value
- Tabs follow default `tab-size: 8`
Notable limitations:
- `system-ui` and `-apple-system` are unsafe on macOS for `layout()` accuracy; a named font is recommended.
- Emoji next to punctuation may wrap differently from the browser.
- Some fonts, such as Shantell Sans, may produce different line breaks in long words.
- Runtime requires `Intl.Segmenter`, Canvas 2D text measurement, and Unicode property escapes.
- CSS font features outside the canvas `font` shorthand are not modeled separately.
Overall, Pretext is positioned as a focused library for multiline text measurement that gives web developers a fast, deterministic alternative to browser layout queries.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.