4 पॉइंट द्वारा GN⁺ 2026-03-30 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Pretext एक शुद्ध JavaScript/TypeScript लाइब्रेरी है जो DOM access के बिना मल्टीलाइन टेक्स्ट की ऊंचाई और लाइन लेआउट की गणना करती है, और browser तथा server दोनों environments को support करती है
  • यह getBoundingClientRect जैसे DOM measurement API का उपयोग नहीं करती, इसलिए layout reflow cost को हटाती है, और font engine-आधारित अपनी measurement logic से accuracy सुनिश्चित करती है
  • prepare() / layout() API के जरिए टेक्स्ट को preprocess किया जाता है, और cached width data का उपयोग करके शुद्ध arithmetic operations से तेज height calculation किया जाता है
  • यह emoji, mixed-direction text (bidi), और कई भाषाओं को support करती है, तथा Canvas·SVG·WebGL·server rendering में भी एक जैसे परिणाम देती है
  • यह high-performance text engine है, जिसे virtualized scroll, text overflow validation, floating text placement जैसे सटीक UI layout implementations में उपयोग किया जा सकता है

अवलोकन

  • Pretext मल्टीलाइन टेक्स्ट माप और लेआउट के लिए एक शुद्ध JavaScript/TypeScript लाइब्रेरी है, जो DOM, Canvas, SVG, और server-side rendering तक support करती है
  • यह DOM measurement API (getBoundingClientRect, offsetHeight आदि) का उपयोग नहीं करती, इसलिए layout reflow cost को हटाती है
  • browser के font engine पर आधारित अपनी measurement logic के जरिए यह सटीक और तेज performance प्रदान करती है
  • यह सभी भाषाओं, emoji, mixed-direction text (bidi) को support करती है, और browser के बीच के अंतर भी संभालती है

इंस्टॉलेशन और डेमो

मुख्य फीचर्स

  • Pretext दो मुख्य usage patterns प्रदान करता है
  • 1. DOM access के बिना paragraph height मापना

    • prepare() टेक्स्ट को preprocess करता है, whitespace normalization·segment separation·glue rules application·canvas-आधारित measurement करता है, और एक opaque handle लौटाता है
    • layout() cached width data का उपयोग करके शुद्ध arithmetic operations से height और line count की गणना करता है
    • समान टेक्स्ट और settings में prepare() को बार-बार call करने की जरूरत नहीं होती, और resize होने पर केवल layout() फिर से चलाना होता है
    • { whiteSpace: 'pre-wrap' } option के साथ whitespace, tab(\t), line break(\n) को जस का तस रखा जा सकता है
    • benchmark परिणाम: prepare() लगभग 19ms (500 टेक्स्ट के आधार पर), layout() लगभग 0.09ms
    • लौटाई गई height value का उपयोग निम्न UI फीचर्स में किया जा सकता है
      • virtualization और occlusion handling में सटीक height calculation
      • JS-आधारित layout systems (जैसे masonry, flexbox-जैसी संरचना)
      • AI-आधारित text overflow validation
      • text load होने पर scroll position बनाए रखना
  • 2. मैन्युअल paragraph layout बनाना

    • prepareWithSegments() से segment-स्तर का data बनाया जाता है
    • layoutWithLines() fixed width पर हर line का text और width information लौटाता है
    • walkLineRanges() text string बनाए बिना हर line की width और cursor range पर iterate करता है
      • उदाहरण: कई widths को test करके उपयुक्त line count और height खोजने के लिए binary-search शैली का layout adjustment संभव है
    • layoutNextLine() जब हर line की width अलग हो तब line-by-line क्रमिक layout करता है
      • उदाहरण: image के आसपास text flow कराने के लिए floating text placement
    • यह तरीका Canvas, SVG, WebGL, server-side rendering पर भी समान रूप से लागू होता है

API सारांश

  • बेसिक measurement API

    • prepare(text, font, options?): टेक्स्ट का analysis और measurement, layout() को देने के लिए handle लौटाता है
    • layout(prepared, maxWidth, lineHeight): दी गई width और line height के अनुसार text height और line count की गणना
  • मैन्युअल layout API

    • prepareWithSegments(text, font, options?): segment-स्तर का data लौटाता है
    • layoutWithLines(prepared, maxWidth, lineHeight): हर line के text, width, cursor information सहित
    • walkLineRanges(prepared, maxWidth, onLine): हर line की width और cursor range को callback के जरिए देता है
    • layoutNextLine(prepared, start, maxWidth): iterator के रूप में line-स्तर layout करता है
    • LayoutLine, LayoutLineRange, LayoutCursor type definitions शामिल हैं
  • अन्य utilities

    • clearCache(): internal cache initialize करता है
    • setLocale(locale?): locale सेट करता है और cache initialize करता है (मौजूदा state पर असर नहीं)

सीमाएँ और सावधानियाँ

  • Pretext पूर्ण font rendering engine नहीं है
  • डिफ़ॉल्ट target CSS properties
    • white-space: normal
    • word-break: normal
    • overflow-wrap: break-word
    • line-break: auto
  • { whiteSpace: 'pre-wrap' } इस्तेमाल करने पर whitespace, tab, line break को बनाए रखता है और tab-size: 8 लागू करता है
  • macOS पर system-ui font, layout() accuracy के लिए उपयुक्त नहीं है, इसलिए explicit font name का उपयोग recommended है
  • overflow-wrap: break-word के कारण बहुत संकरी width पर शब्द के भीतर भी line break हो सकता है, लेकिन यह केवल grapheme unit के आधार पर ही विभाजित होता है

डेवलपमेंट से जुड़ी जानकारी

  • development environment और commands के लिए DEVELOPMENT.md देखें

योगदान और पृष्ठभूमि

  • Sebastian Markbage के text-layout प्रोजेक्ट से विचार आगे बढ़ाए गए हैं
  • canvas measureText-आधारित shaping, pdf.js की bidi processing, और streaming line breaking डिज़ाइन को आगे विकसित किया गया है

1 टिप्पणियां

 
GN⁺ 2026-03-30
Hacker News की राय
  • यह प्रोजेक्ट सच में प्रभावशाली है
    यह वेबपेज पर टेक्स्ट को वास्तव में render किए बिना line-break हुए टेक्स्ट की ऊंचाई को efficiently calculate करने की समस्या हल करता है
    यह शब्द-आधारित segments की width और height को cache करता है, और browser के line-breaking algorithm को खुद implement करता है
    hyphen, emoji, Chinese जैसी अलग-अलग character handling और browsers के बीच rendering differences (Safari सहित) की वजह से यह बहुत कठिन काम है
    असली browser के साथ comparison testing के लिए corpora dataset और accuracy test page का उपयोग किया गया है

    • मैंने भी कुछ ऐसा ही बनाया था। uWrap.js नाम का 2KB का simple version, और वह AI के बिना implement किया था
      ASCII टेक्स्ट के आधार पर मेरा code 80ms लेता है, जबकि pretext 2200ms लेता है
      accuracy अभी test नहीं की, लेकिन आज रात करने वाला हूँ
      issue #18 में performance improvement PRs पहले से खुले हुए हैं
    • text layout engine वाकई बदनाम रूप से कठिन होते हैं
      मैंने भी पहले canvas पर multiline text render करने की कोशिश में बहुत संघर्ष किया था
      यह प्रोजेक्ट DOM से सीधे जुड़ा हुआ है, इसलिए कहीं ज्यादा उपयोगी है
      उदाहरण: Scrawl demo
    • विवरण पढ़कर लगता है कि वास्तव में यह segments को canvas पर render करके measure करता है
      यह native API से धीमा हो सकता है, और इसकी गारंटी नहीं कि browser के non-canvas rendering जैसा ही logic इस्तेमाल करता हो
    • असल में इसने browser के text rendering algorithm को सीधे implement नहीं किया है
      यह canvas पर render करके measure करता है, और बस text layout analysis के लिए API देने के स्तर पर है
    • Remotion video के लिए dynamic subtitles बनाते समय text height calculate करने में मुझे बहुत परेशानी हुई थी, यह library बहुत मददगार लगती है
  • यह सच में बहुत समय से इंतजार किया गया feature है
    पहले responsive accordion जैसी चीजें ठीक से implement करना मुश्किल था
    वेब का विकास पैटर्न हमेशा ① complex requirements का आना → ② JS/CSS hacks → ③ standardization रहा है
    इस बार यह hack नहीं, बल्कि एक सही 2nd stage जैसा लगता है
    RESEARCH.md देखें, तो इसमें browser-wise emoji measurement differences तक का बारीक अध्ययन किया गया है
    maintenance मुश्किल होगा, लेकिन यह वेब विकास के लिए बड़ा turning point बन सकता है

    • responsive accordion अब CSS से संभव है, लेकिन फिर भी इस तरह की API की जरूरत थी
      इस बार यह भी रोचक है कि AI को development process में actively use किया गया। लगता है कि Cursor agent की मदद से इसका अधिकांश implementation हुआ
  • library author के अनुसार, Claude Code और Codex को browser का ground truth data सिखाकर कई हफ्तों तक iterative measurements कराए गए
    संबंधित ट्वीट देखें
    लगता है Autoresearch का भी कुछ हिस्सा उपयोग हुआ

  • shape-based reflow example मुझे खास तौर पर पसंद आया
    इसे Ensō(enso.sonnet.io) में apply करना चाहता था, लेकिन simplicity बनाए रखने के लिए रुक गया
    accordion example CSS के interpolate-size से भी implement किया जा सकता है
    Josh Comeau का लेख देखें
    text bubble example को text-wrap: balance | pretty से मिलते-जुलते तरीके से implement किया जा सकता है

    • लेकिन balance या pretty पूरी तरह समाधान नहीं हैं
      बहुत बार line lengths को बराबर बनाना वांछित नहीं होता
      संबंधित CSSWG issue: #191
    • text-wrap हर line में शब्दों की संख्या संतुलित करने में मदद करता है, लेकिन right margin की समस्या फिर भी बनी रहती है
  • pretext canvas.measureText को सीधे इस्तेमाल नहीं करता, बल्कि अगर आप text और properties को JS API में दें तो यह अपने-आप layout calculate कर देता है
    पहले measureText को सीधे इस्तेमाल करना पड़ता था या harfbuzz को browser में port करना पड़ता था
    यह technical breakthrough कम, और मौजूदा elements के अच्छे संयोजन का परिणाम ज्यादा लगता है
    फिर भी Skia-wasm / Canvaskit से इसका अंतर जानने की उत्सुकता है

    • अंतर सादगी का है। pretext wasm नहीं है
    • Skia एक विशाल rendering engine है। Flutter की तरह device-independent rendering API देता है
      pretext की अलग बात यह है कि AI की मदद से pure Typescript-based glyph rendering implement की गई है
      यह कुछ वैसा फर्क लगता है जैसा ffmpeg को सीधे C में implement करने और Dart से call करने में होता है
      इस तरह की कोशिश client-side FOSS की नई संभावनाएँ दिखाती है
    • अगर author सही हैं, तो यह web GUI frameworks और rich text editors में बड़ा बदलाव ला सकता है
  • पिछले साल मैंने HTML में print brochure typesetting system बनाया था, जहां line breaks और widow prevention के लिए Selection API से box boundaries को बार-बार calculate करना पड़ा
    वह आज भी ठीक चलता है, लेकिन उसमें एक ऐसा off-by-one hack है जिसका कारण मुझे नहीं पता
    pretext का iterative line generation feature सच में स्वागतयोग्य है

  • Fedora + Firefox environment में demo पूरी तरह टूटा हुआ दिख रहा है
    उदाहरण: screenshot

    • यह दिखाता है कि इस तरह के प्रोजेक्ट आखिरकार अनंत edge cases को track करने की निरंतर प्रक्रिया होते हैं
  • ऐसी functionality वास्तव में browser standard API के रूप में उपलब्ध होनी चाहिए
    W3C में feature request कैसे की जाए, या community voting जैसी कोई चीज संभव है या नहीं, यह जानने की जिज्ञासा है

    • पहले से Font Metrics API proposal मौजूद है
      लेकिन browser vendors इसे प्राथमिकता नहीं दे रहे
      अभी Chrome AI-संबंधित APIs पर ज्यादा केंद्रित है
  • Sciter engine में पहले से Graphics.Text functionality है
    यह canvas-based text rendering element है, जिस पर CSS styles सीधे apply किए जा सकते हैं

  • browser का text search (Ctrl+F) virtual scroll lists में सही तरह काम नहीं करता
    इस तरह की समस्या हल करने के लिए शायद JS नहीं, बल्कि एक नई “Search” API चाहिए होगी

    • Virtual Scroller API थी, लेकिन उसमें लगभग कोई प्रगति नहीं हुई
      संबंधित प्रोजेक्ट: Display Locking, MDN दस्तावेज़
    • native search केवल DOM में मौजूद nodes को ही खोजता है
      virtualized list के offscreen items DOM में नहीं होते, इसलिए उन्हें खोजा नहीं जा सकता
      इसे हल करने के लिए selection, focus, scroll position, और match navigation तक को जोड़ने वाला नया browser contract चाहिए
      लेकिन sites इसे consistently अपनाएँगी, इसकी संभावना कम है)