paginateText

متن ساده را به صفحه‌هایی می‌برد که در جعبه‌ای ثابت جا شوند: یک کتاب‌خوان، یک تله‌پرامپتر، یک پیش‌نمایش چاپی.

حساب ناب: جعبه و اندازه‌های حروف را همچون عدد می‌گیرد و هرگز به DOM دست نمی‌زند. ظرف را یک بار روی رشتهٔ اصلی اندازه بگیرید و پس از آن در یک Worker، روی سرور یا درون آزمون صفحه‌بندی کنید.

API

paginateText(text, box, metrics, options?)

پارامتر توضیح نوع
text متن مبدأ؛ \r\n و \r به \n یکدست می‌شوند string
box { width, height } بر حسب پیکسل TextBox
metrics { charWidth, lineHeight, narrowRatio? } بر حسب پیکسل TextGridMetrics
options.minBox کمتر از این، جعبه هنوز چیده‌نشده به شمار می‌آید. پیش‌فرض 30 number

narrowRatio پیشرویِ یک نویسهٔ ASCII است، همچون کسری از charWidth؛ پیش‌فرض 0.5625 (۹/۱۶).

{ pages, total, charsPerLine, linesPerPage, charsPerPage } برمی‌گرداند و هر صفحه { text, start, end, index } است که جای‌گشت‌هایش بر پایهٔ متنِ یکدست‌شده است.

نمونه

import { paginateText } from 'ranuts';

const { width, height } = container.getBoundingClientRect();
const result = paginateText(book, { width, height }, { charWidth: 18.4, lineHeight: 40 });

render(result.pages[0].text);
console.log(`${result.pages.length} صفحه، ${result.charsPerLine} نویسه در هر سطر`);

یادداشت‌ها

  1. شبکه‌ای با عرض ثابت را فرض می‌گیرد: هر نویسه یک خانه پیش می‌رود (CJK، تمام‌پهنا) یا به اندازهٔ narrowRatio از آن (ASCII). برای قلمی با عرض ثابت دقیقاً درست است و برای متنی که بیشترش CJK باشد به‌قدر کافی نزدیک، اما جایگزین شکل‌دهی واقعی برای لاتینِ متناسب نیست.
  2. واژه‌های ASCII شکسته نمی‌شوند. صفحه هرگز در میانهٔ واژه پایان نمی‌یابد، مگر آنکه واژه از یک سطر بلندتر باشد که آنگاه ناچار باید شکسته شود.
  3. جای‌گشت‌ها پیوسته‌اند: pages[i].start === pages[i - 1].end، و به‌هم‌پیوستن همهٔ page.textها دقیقاً متنِ یکدست‌شده را بازمی‌سازد. همین است که می‌گذارد یادداشت را همچون جای‌گشت سراسری ذخیره کنید و پس از صفحه‌بندی دوباره هم معتبر بماند. segmentByRanges را ببینید.
  4. جعبه‌ای کوچک‌تر از minBox هیچ صفحه‌ای نمی‌دهد. وگرنه صفحه‌بندی در نخستین ترسیم، وقتی ظرف هنوز ۰ اندازه می‌گیرد، بیهوده می‌چرخید.