À propos du projet

Pretext est une bibliothèque pure JavaScript/TypeScript pour mesurer le texte multiligne et calculer la mise en page des lignes. Elle évite les API de mesure du DOM comme `getBoundingClientRect` et `offsetHeight`, qui provoquent un reflow de mise en page, et effectue plutôt sa propre mesure en utilisant la mesure de texte du canvas du navigateur comme référence. Cela la rend utile pour la virtualisation, les moteurs de mise en page personnalisés, le rendu canvas/SVG, et les vérifications de débordement en temps de développement. ## Installation ```sh npm install @chenglou/pretext ``` ## Cas d'utilisation principaux ### 1. Mesure de la hauteur d'un paragraphe sans toucher au DOM ```ts import { prepare, layout } from '@chenglou/pretext' const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter') const { height, lineCount } = layout(prepared, 320, 20) ``` `prepare()` effectue un travail ponctuel : normalisation des espaces blancs, segmentation du texte, application des règles de colle, et mesure basée sur le canvas. `layout()` est ensuite une opération purement arithmétique bon marché sur les largeurs mises en cache, ce qui permet de la réexécuter lors d'un redimensionnement sans avoir à préparer à nouveau. Les options pour `prepare()` incluent `whiteSpace: 'pre-wrap'` pour un comportement similaire à une zone de texte, `wordBreak: 'keep-all'` pour un comportement CSS similaire à `word-break: keep-all`, et `letterSpacing` pour la propriété CSS `letter-spacing`. ### 2. Mise en page manuelle des lignes `prepareWithSegments()` retourne une structure plus riche pour une mise en page personnalisée. Les API suivantes sont disponibles : - `layoutWithLines()` — retourne toutes les lignes à une largeur maximale fixe, incluant le texte et les largeurs mesurées. - `walkLineRanges()` — appelle un rappel par ligne avec la largeur et les curseurs de début/fin, sans construire les chaînes de lignes. - `measureLineStats()` — retourne le nombre de lignes et la largeur de la ligne la plus large sans allocations. - `measureNaturalWidth()` — retourne la largeur de la ligne forcée la plus large lorsque la largeur n'est pas la cause du retour à la ligne. - `layoutNextLine()` / `layoutNextLineRange()` — API de style itérateur pour disposer les lignes une à une avec potentiellement différentes largeurs, utile pour faire flotter le texte autour de flottants ou dans des conteneurs dynamiques. - `materializeLineRange()` — convertit une plage de mise en page en une chaîne de ligne complète. Ces fonctionnalités permettent le rendu vers Canvas, SVG, WebGL, et éventuellement des environnements côté serveur. Des démonstrations sont incluses dans le dépôt et sur chenglou.me/pretext. ## Assistant d'enrichissement en ligne Un assistant distinct situé à `@chenglou/pretext/rich-inline` prend en charge un flux en ligne de texte enrichi de base avec des polices mixtes, des éléments atomiques (par exemple des puces et des mentions), et une largeur supplémentaire appartenant à l'appelant pour le chrome de pilule. Il est délibérément restreint : uniquement en ligne, `white-space: normal` uniquement, et ne constitue pas un moteur général de mise en forme en ligne CSS. ## Points forts du glossaire API - `PreparedText` est le handle opaque du chemin rapide ; `PreparedTextWithSegments` est le handle plus riche pour la mise en page manuelle. - `LayoutCursor` utilise des indices de segment/grapheme, et non des décalages de chaîne bruts. - `layout()` sur une chaîne vide retourne `{ lineCount: 0, height: 0 }` ; les navigateurs dimensionnent les blocs vides à une hauteur de ligne, donc les appelants peuvent vouloir limiter. - Les tirets doux sont pris en charge : ils agissent comme des points de rupture optionnels et se matérialisent sous la forme d'un tiret trailing `-` lorsqu'ils sont choisis. - `clearCache()` vide les caches internes partagés ; `setLocale()` définit la locale pour les appels futurs de préparation. - Le handle plus riche inclut des niveaux de segment approximatifs `segLevels` pour un rendu personnalisé conscient de la bidirectionnalité, mais Pretext ne met pas en œuvre l'algorithme complet de bidirectionnalité Unicode. ## Mises en garde Pretext n'est pas un moteur de rendu de polices complet. Il cible les configurations courantes de texte CSS : - `white-space: normal` et `pre-wrap` - `word-break: normal` et `keep-all` - `overflow-wrap: break-word` - `line-break: auto` - `letter-spacing` comme valeur numérique en pixels - Les tabulations suivent la valeur par défaut `tab-size: 8` Limitations notables : - `system-ui` et `-apple-system` sont dangereux sur macOS pour la précision de `layout()` ; une police nommée est recommandée. - Les emojis situés à côté de la ponctuation peuvent présenter un retour à la ligne différent de celui du navigateur. - Certaines polices, telles que Shantell Sans, peuvent produire des sauts de ligne différents dans de longs mots. - L'exécution nécessite `Intl.Segmenter`, la mesure de texte du canvas 2D, et les échappements de propriétés Unicode. - Les fonctionnalités de police CSS situées en dehors du raccourci `font` du canvas ne sont pas modélisées séparément. Dans l'ensemble, Pretext se positionne comme une bibliothèque ciblée pour la mesure du texte multiligne qui offre aux développeurs web une alternative rapide et déterministe aux requêtes de mise en page du navigateur.