Sobre o projeto

Pretext é uma biblioteca JavaScript/TypeScript pura para medir texto multilinha e calcular o layout de linhas. Ela evita APIs de medição do DOM como `getBoundingClientRect` e `offsetHeight`, que forçam o reflow do layout, e em vez disso realiza sua própria medição usando o `measureText` do canvas do navegador como referência. Isso a torna útil para virtualização, mecanismos de layout personalizados, renderização em canvas/SVG e verificações de overflow em tempo de desenvolvimento. ## Instalação ```sh npm install @chenglou/pretext ``` ## Principais casos de uso ### 1. Medir a altura de um parágrafo sem tocar no DOM ```ts import { prepare, layout } from '@chenglou/pretext' const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter') const { height, lineCount } = layout(prepared, 320, 20) ``` `prepare()` faz o trabalho único: normalização de espaços em branco, segmentação de texto, aplicação de regras de cola e medição baseada em canvas. `layout()` é então uma operação puramente aritmética e barata sobre larguras em cache, podendo ser reexecutada em redimensionamentos sem preparar novamente. As opções de `prepare()` incluem `whiteSpace: 'pre-wrap'` para comportamento semelhante a textarea, `wordBreak: 'keep-all'` para `word-break: keep-all` semelhante ao CSS, e `letterSpacing` para `letter-spacing` do CSS. ### 2. Layout manual de linhas `prepareWithSegments()` retorna uma estrutura mais rica para layout personalizado. As seguintes APIs estão disponíveis: - `layoutWithLines()` — retorna todas as linhas em uma largura máxima fixa, incluindo texto e larguras medidas. - `walkLineRanges()` — chama um callback por linha com largura e cursores de início/fim, sem construir strings de linha. - `measureLineStats()` — retorna a contagem de linhas e a largura da linha mais larga sem alocações. - `measureNaturalWidth()` — retorna a linha forçada mais larga quando a largura não é a causa da quebra. - `layoutNextLine()` / `layoutNextLineRange()` — APIs no estilo iterador para dispor linhas uma a uma com larguras potencialmente diferentes, útil para fluir texto ao redor de floats ou contêineres dinâmicos. - `materializeLineRange()` — converte um intervalo de layout de volta em uma string de linha completa. Essas APIs permitem renderização em Canvas, SVG, WebGL e, eventualmente, ambientes do lado do servidor. Demos estão incluídas no repositório e em chenglou.me/pretext. ## Helper inline rico Um helper separado em `@chenglou/pretext/rich-inline` suporta fluxo inline básico de rich text com fontes mistas, itens atômicos (por exemplo, chips e menções) e largura extra de responsabilidade do chamador para o chrome de pills. Ele é intencionalmente restrito: apenas inline, apenas `white-space: normal`, e não é um mecanismo geral de formatação inline do CSS. ## Destaques do glossário da API - `PreparedText` é o handle opaco do caminho rápido; `PreparedTextWithSegments` é o handle mais rico para layout manual. - `LayoutCursor` usa índices de segmento/grapheme, não offsets brutos de string. - `layout()` em uma string vazia retorna `{ lineCount: 0, height: 0 }`; navegadores dimensionam blocos vazios para um `line-height`, então os chamadores podem querer limitar. - Hífens suaves são suportados: atuam como pontos de quebra opcionais e se materializam como um `-` final quando escolhidos. - `clearCache()` limpa caches internos compartilhados; `setLocale()` define o locale para chamadas futuras de preparação. - O handle mais rico inclui `segLevels` aproximados para renderização personalizada com reconhecimento de bidi, mas Pretext não implementa o algoritmo bidirecional completo do Unicode. ## Ressalvas Pretext não é um mecanismo completo de renderização de fontes. Ele tem como alvo configurações comuns de texto CSS: - `white-space: normal` e `pre-wrap` - `word-break: normal` e `keep-all` - `overflow-wrap: break-word` - `line-break: auto` - `letter-spacing` como um valor numérico em pixels - Tabs seguem o padrão `tab-size: 8` Limitações notáveis: - `system-ui` e `-apple-system` são inseguros no macOS para a precisão de `layout()`; uma fonte nomeada é recomendada. - Emoji próximo de pontuação pode quebrar de forma diferente do navegador. - Algumas fontes, como Shantell Sans, podem produzir quebras de linha diferentes em palavras longas. - O runtime requer `Intl.Segmenter`, medição de texto em Canvas 2D e escapes de propriedades Unicode. - Recursos de fonte CSS fora do atalho `font` do canvas não são modelados separadamente. No geral, Pretext se posiciona como uma biblioteca focada para medição de texto multilinha que oferece aos desenvolvedores web uma alternativa rápida e determinística às consultas de layout do navegador.