Motore di impaginazione open source · v1.33.9

Il compositore tipografico programmabile per il web

Postext prende Markdown semantico e applica regole editoriali secolari (giustificazione Knuth-Plass, colonne bilanciate, elementi flottanti che sanno stare al loro posto) per produrre pagine di qualità editoriale in HTML, canvas o PDF pronto per la stampa.

Ogni pagina viene calcolata nel tuo browser

Postext

In breve

Postext è un software libero e open source che impagina le pagine di libri, riviste e relazioni. Scrivi il testo con pochi segni semplici, e Postext lo trasforma in pagine finite, come quelle di un libro stampato. Segue regole che i tipografi usano da secoli, così il testo è facile da leggere. Le pagine possono finire su un sito web, in un’app o in un PDF pronto per la stampa. È pensato per autori, editori, grafici e sviluppatori.

Trascrizione

Tutto ciò che dice la voce narrante, con una descrizione di ciò che appare sullo schermo.

  1. 0:00

    Sullo schermoUna scheda scura riporta «MAINZ · 1455» sopra un sottile filetto dorato. Dietro il titolo «For five centuries, print learned to set a page.» («Per cinque secoli la stampa ha imparato a comporre una pagina.»), l’anno scorre da 1455 a 2026 in enormi cifre contornate, e attorno si posano termini di tipografia, in inglese: giustificazione, crenatura (Kerning), vedove e orfane, colonne bilanciate, interlinea, griglia della linea di base, sillabazione (scritta «hy·phen·a·tion»), giustezza, elementi flottanti, testatine, canali di bianco. La telecamera si tuffa nel punto finale, che inonda lo schermo d’oro.

    NarrazionePer cinque secoli la stampa ha imparato a comporre una pagina.

  2. 0:05

    Sullo schermoTitolo: «The web learned to lay out interfaces. It never learned to set a page.» («Il web ha imparato a impaginare interfacce. Non ha mai imparato a comporre una pagina.») Una finestra del browser aperta su example.com/longform/article contiene un articolo giustificato su tre colonne, «Why the web can’t set a page» («Perché il web non sa comporre una pagina»); etichette rosse segnalano canali di bianco, una vedova, un’orfana, un’immagine che cade sul testo e un’ultima colonna sbilanciata. Accanto, un riquadro di codice mostra «column-count: 3;», poi «…and little else.» («…e poco altro.») e un elenco barrato degli stessi cinque difetti. La finestra si disturba e crolla.

    NarrazioneIl web ha imparato a impaginare interfacce. Mai pagine. Così il testo lungo si rompe ancora: canali di bianco, vedove, orfane, collisioni.

  3. 0:18

    Sullo schermoDopo un lampo bianco e una passata di strisce blu, oro e rosse, il logo e il nome di Postext salgono al loro posto con lo slogan «The programmable typesetter for the web» («Il compositore programmabile per il web»). Sotto: OPEN SOURCE · MIT LICENCE · v1.7.0 · RUNS IN YOUR BROWSER (open source, licenza MIT, funziona nel tuo browser).

    NarrazioneEcco Postext: il compositore programmabile per il web.

  4. 0:24

    Sullo schermoSezione 01 di 07, «Content in» («Entra il contenuto»): «Markdown says what things are.» («Il Markdown dice che cosa sono le cose.») Un file Markdown, 03-why-postext.md, si scrive da solo: una direttiva di parte, il titolo «Why Postext» con un sommario, un paragrafo che rimanda alla figura fig-flow con :ref, una riga ::resource e un blocco :::callout. Accanto, config.ts chiama buildDocument con un’impaginazione a due colonne, il testo corrente giustificato e la sillabazione en-us, sotto la frase «Configuration decides how they look. Nothing about layout lives in the text.» («La configurazione decide il loro aspetto. Nulla dell’impaginazione vive nel testo.»)

    NarrazioneScrivi Markdown semantico, che dice che cosa sono le cose. Una configurazione decide il loro aspetto.

  5. 0:32

    Sullo schermoSezione 02, «Pretext measures» («Pretext misura»): «Measured without touching the DOM.» («Misurato senza toccare il DOM.») Un titolo, un paragrafo e un riquadro vengono scansionati uno dopo l’altro, e linee di quota ne danno l’altezza in punti; un pannello di codice mostra prepare(text, '25px Lora') e layout(prepared, width, 38), che restituiscono un’altezza e un numero di righe. Due barre gareggiano su 10.000 paragrafi: «Browser reflow · DOM» (il ricalcolo del layout nel browser) si muove appena, mentre «Pretext · canvas metrics + arithmetic» (metriche del canvas e aritmetica) si riempie in un attimo, e un contatore sale fino a 600× sopra «faster text measurement than the DOM, so a whole book reflows as you type» («una misurazione del testo più veloce del DOM, così un libro intero si ricompone mentre scrivi») e «Powered by @chenglou/pretext».

    NarrazioneOgni paragrafo viene misurato senza toccare il DOM, fino a seicento volte più in fretta, grazie a Pretext, la libreria che lo ha reso possibile.

  6. 0:42

    Sullo schermoSezione 03, «Postext decides» («Postext decide»): «Every line placed before a pixel is drawn.» («Ogni riga al suo posto prima che si disegni un pixel.») Un anello di sette segmenti si accende a turno, Structure, Measure, Place, Float, Refine, Balance e Rhythm (strutturare, misurare, collocare, far flottare, rifinire, bilanciare, dare ritmo), ognuno con una descrizione di una riga, mentre accanto si compone una pagina a due colonne della guida di Postext: blocchi etichettati volano nelle loro colonne, una figura scivola al suo posto sotto la nota «:ref{id="fig-flow"} → column foot» (piede della colonna), la fascia d’apertura scende, compaiono le righe, le colonne si pareggiano e una griglia della linea di base scorre dall’alto in basso. L’anello ripete le iterazioni da 1 a 3 e mostra «Settled in 3 iterations» («Stabile in 3 iterazioni») con un segno di spunta; un fumetto indica il riquadro di delimitazione e la linea di base di una riga.

    NarrazionePoi Postext decide. Sette passate collocano ogni riga, fanno flottare ogni figura e bilanciano ogni colonna, e ripetono finché nulla si muove più.

  7. 0:54

    Sullo schermoSezione 04, «The virtual document» («Il documento virtuale»): «Change a word. Only what changed is set again.» («Cambia una parola. Si ricompone solo ciò che è cambiato.»), con la nota «Like React’s virtual DOM, but for pages: the VDT, a virtual document tree.» («Come il DOM virtuale di React, ma per le pagine: il VDT, un albero virtuale del documento.») Sette pagine, da p. 7 a p. 13, stanno in fila; un cursore segna una modifica a pagina 11, il resto di quella colonna diventa oro con la scritta DIRTY (da rifare) e un filo di testo trabocca a pagina 12, che riceve un segno di spunta e SETTLED (stabile), mentre le pagine precedenti riportano SKIPPED (saltata) e quelle successive UNTOUCHED (intatta). Tre punti enunciano la regola, e un pannello intitolato renderToHtmlIndexed() segna come PATCHED (aggiornati) i nodi modificati dell’albero del documento.

    NarrazioneTutto vive in un documento virtuale, come il DOM virtuale di React. Cambia una parola, e si ricompone solo ciò che è cambiato.

  8. 1:03

    Sullo schermo«A long document? Only what’s on screen gets painted.» («Un documento lungo? Si dipinge solo ciò che è sullo schermo.») Una colonna di pagine di libro scorre dentro una cornice dorata con la scritta VIEWPORT (area visibile), con un margine di 200 pixel sopra e sotto: le pagine all’interno sono disegnate per intero, quelle all’esterno sono contorni tratteggiati. Un grande contatore mostra quante delle 48 pagine sono dipinte in quel momento (IntersectionObserver · +200 px), accanto a «Geometry: every page. Pixels: only what you see.» («Geometria: ogni pagina. Pixel: solo ciò che vedi.»)

    NarrazioneE in un libro lungo si dipingono soltanto le pagine sullo schermo.

  9. 1:10

    Sullo schermoSezione 05, «Knuth–Plass justification» («Giustificazione Knuth–Plass»): «Every way to break the paragraph. At once.» («Tutti i modi di dividere il paragrafo. In una volta.») A sinistra, un paragrafo sulla divisione in righe è composto con il primo adattamento, come fa un browser, e le sue righe più larghe diventano rosse. Sotto, ogni parola diventa un punto su una linea: archi rossi segnano gli a capo greedy, tenui archi blu provano ogni a capo possibile e un percorso dorato sceglie l’insieme migliore. A destra, la versione Knuth–Plass ha una spaziatura uniforme, con la badness di ogni riga, la formula «(1 + badness + penalty)²» e un totale di demeriti più basso.

    NarrazioneUn browser va a capo in modo greedy, una riga alla volta. Postext usa Knuth–Plass, l’algoritmo di TeX. Valuta tutti i modi di dividere l’intero paragrafo e tiene il più uniforme.

  10. 1:24

    Sullo schermoSezione 06, «One layout, five outputs» («Un’impaginazione, cinque output»): «What you see is what goes to press.» («Quello che vedi è quello che va in stampa.») Sotto la riga di codice const vdt = buildDocument(content, config); una pagina si divide in cinque. Canvas (renderToCanvas(), bitmap precise al pixel) riceve una lente d’ingrandimento sulla sua griglia di pixel; HTML (renderToHtml(), testo selezionabile, attento al ridimensionamento) vede ogni blocco contornato ed etichettato <h1>, <p>, <figure> e così via; PDF (renderToPdf(), pronto per la stampa, PDF/UA, CMYK) fa scivolare quattro lastre di colore fino al registro, poi compaiono i segni di taglio e una scala colori. EPUB 3 (renderToEpub(), libro digitale, fisso o fluido) mostra la pagina in un lettore di e-book con l’etichetta «Fixed layout» (layout fisso); lo schermo si restringe alle dimensioni di un telefono, il testo si ricompone e l’etichetta diventa «Reflowable» (fluido). Folio (postext-folio, un libro in 3D, con pagine che si sfogliano) apre la pagina in una doppia pagina e gira un foglio sopra il dorso.

    NarrazioneUn’impaginazione, cinque output: canvas, HTML, PDF pronto per la stampa, EPUB 3, fisso o fluido, e un libro in 3D. Quello che vedi è quello che va in stampa.

  11. 1:41

    Sullo schermoSezione 07, «Why an open standard» («Perché uno standard aperto»): «LaTeX set the bar for print. Publishing now lives on every screen, too.» («LaTeX ha fissato l’asticella per la stampa. Ora l’editoria vive anche su ogni schermo.») Due schede: LaTeX, 1984, con delle croci accanto a «Built for the printed page» (pensato per la pagina stampata), «Builds tied to one machine’s fonts & packages» (compilazioni legate ai font e ai pacchetti di una macchina), «Compile, wait, repeat» (compila, aspetta, ripeti) e «No editorial layout on the responsive web» (nessuna impaginazione editoriale sul web responsive); Postext, 2026, con dei segni di spunta accanto a «Web, print-ready PDF & EPUB 3 from one layout» (web, PDF pronto per la stampa ed EPUB 3 da un’unica impaginazione), «One portable .postext file carries it all» (un solo file .postext portabile contiene tutto), «Reflows live, as you type» (si ricompone dal vivo, mentre scrivi) e «Runs in any browser · zero servers · MIT» (funziona in qualunque browser, senza server, con licenza MIT). La scheda di Postext si illumina.

    NarrazioneLaTeX ha fissato lo standard per la stampa. Ma oggi l’editoria vive su ogni schermo.

  12. 1:48

    Sullo schermoOcchiello «One file, the whole book» («Un file, tutto il libro»), titolo «An open standard for publishing, beyond where LaTeX reaches.» («Uno standard aperto per l’editoria, che arriva dove LaTeX non arriva.») L’icona di un file .postext si apre in cinque parti: preset.json (configurazione e progetto grafico), chapters/*.md (un file Markdown per capitolo), fonts/*.woff2 (i caratteri stessi), images/ · SVG (ogni immagine, incorporata) e resources (tabelle, figure e didascalie). Didascalia: «A plain ZIP: open, documented, MIT-licensed. Any tool can read and write it.» («Un semplice ZIP: aperto, documentato, con licenza MIT. Qualunque strumento può leggerlo e scriverlo.»)

    NarrazionePostext è uno standard aperto: un unico file portabile, documentato e con licenza MIT, che qualunque strumento può leggere e scrivere.

  13. 1:58

    Sullo schermo«The showcase · set by the real engine» («La vetrina, composta dal vero motore»): un muro di pagine di libro si allontana in prospettiva mentre un contatore arriva a 48 pagine. Testo: «12 chapters, 3 parts, a cover, laid out in about half a second. Every page of the Postext guide, computed in a browser by postext v1.7.0 for this film. Nothing placed by hand.» («12 capitoli, 3 parti, una copertina, impaginati in circa mezzo secondo. Ogni pagina della guida di Postext, calcolata in un browser da postext v1.7.0 per questo filmato. Niente è collocato a mano.») Seguono delle etichette: Textbooks, Magazines, Literary editions, Catalogues (libri di testo, riviste, edizioni letterarie, cataloghi).

    NarrazionePer questo può impaginare libri di centinaia di pagine in pochi decimi di secondo.

  14. 2:05

    Sullo schermoScheda finale: il logo di Postext con lo slogan «The programmable typesetter for the web» («Il compositore programmabile per il web»), l’indirizzo postext.dev, una riga di terminale che digita «$ pnpm add postext», e il piede «Open source · MIT · github.com/drnachio/postext».

    NarrazionePostext. Open source, su postext.dev.

Capitolo 1 · Perché Postext

Impaginazione editoriale, calcolata per il web

La tipografia a stampa ha impiegato cinque secoli a imparare come comporre una pagina; i browser hanno imparato a disporre un’interfaccia. Postext porta la prima nei secondi.

Il CSS ti dà un layout responsivo: flexbox, grid, colonne. Ma non sa bilanciare le colonne, tenere un titolo con il suo paragrafo, evitare vedove e orfane o far flottare una figura in testa alla colonna successiva. Sono decisioni editoriali, affinate in secoli di stampa.

Postext colma questa distanza. Gli dai Markdown semantico e un oggetto di configurazione. Misura il testo da 300 a 600 volte più in fretta del DOM grazie a @chenglou/pretext (si apre in una nuova scheda), poi calcola la geometria completa della pagina (ogni riga, elemento flottante e didascalia) e la restituisce attraverso i backend HTML, canvas o PDF pronto per la stampa.

Markdown in ingresso

:::part{number="I" title="Fondamenti"
  palette="band=#2b4acb"}
:::

# Perché Postext {lead="La tipografia
a stampa ha impiegato cinque secoli…"}

Postext è un **motore di
impaginazione open source** che
porta sul web il mestiere della
tipografia a stampa, come mostra
:ref{id="fig-flusso"}.

:::callout{type="try"}
Cambia una parola: la pagina
si ricompone.
:::

Pagine in uscita

Figura 1.1 Lo stesso Markdown prima e dopo il motore: un’apertura di capitolo, due colonne bilanciate e una figura spostata in testa a una colonna.

In cifre

più veloce del DOM nel misurare il testo, così un libro intero si ricompone mentre scrivi
300–600×più veloce del DOM nel misurare il testo, così un libro intero si ricompone mentre scrivi
output da un’unica impaginazione: HTML, canvas, PDF pronto per la stampa ed EPUB 3
4output da un’unica impaginazione: HTML, canvas, PDF pronto per la stampa ed EPUB 3
output PDF accessibile e con tag, con segnalibri e colori CMYK
PDF/UAoutput PDF accessibile e con tag, con segnalibri e colori CMYK
server: il motore gira interamente nel browser, con licenza MIT
0server: il motore gira interamente nel browser, con licenza MIT

Capitolo 2 · Funzionalità

Quello che i compositori tipografici hanno sempre saputo

Sei cose di cui una pagina ha bisogno e che il CSS non è mai stato pensato per decidere: le calcola il motore, ogni volta allo stesso modo.

  1. 2.1

    Giustificazione Knuth-Plass

    Lo stesso algoritmo ottimale di divisione in righe usato da TeX, con sillabazione a pattern TeX e controllo delle orfane: blocchi di testo composti in modo uniforme, senza canali di bianco, ben oltre ciò che il CSS sa esprimere.

    Leggi nella documentazione
  2. 2.2

    Risorse e rimandi

    Figure, diagrammi SVG e tabelle flottano in cima o in fondo a colonne e pagine, come gli elementi flottanti della stampa, con numerazione per tipo e rimandi :ref sempre aggiornati.

    Leggi nella documentazione
  3. 2.3

    Tabelle e didascalie

    Tabelle con tipografia indipendente per corpo e intestazione, divise tra le pagine con intestazioni ripetute, e didascalie che seguono la tua configurazione: numerate e collocate accanto alla risorsa che descrivono.

    Leggi nella documentazione
  4. 2.4

    Diagrammi a un solo inchiostro

    Ricolora i diagrammi SVG in tinte di un solo inchiostro in base alla luminanza, così ogni illustrazione si accorda al tuo progetto grafico: pronta per la stampa a colori speciali.

    Leggi nella documentazione
  5. 2.5

    Formule LaTeX

    Equazioni in linea e in display scritte in LaTeX, misurate e composte dal motore in modo che poggino sulla griglia della linea di base insieme al testo.

    Leggi nella documentazione
  6. 2.6

    Web, PDF pronto per la stampa ed EPUB

    Un motore di impaginazione, quattro output. Le stesse pagine calcolate diventano HTML, canvas o PDF pronto per la stampa (con segnalibri, colori CMYK e output PDF/UA accessibile e con tag) ed escono come e-book EPUB 3, pagina per pagina o a layout fluido.

    Leggi nella documentazione
Ogni pagina della guida di Postext, copertina, indice e pagine di parte comprese, è composta da Postext, nel tuo browser, mentre la leggi.
— Colophon della guida integrata

Vetrina

Libri veri, composti nel tuo browser

Un manuale, una rivista, un poema epico annotato, un catalogo di mostra, un classico cinese in 120 capitoli, Le mille e una notte in arabo, un romanzo giapponese composto in verticale, un fumetto in dieci lingue. Aprine uno qualsiasi nella Sandbox, cambia una regola e guarda ogni pagina ricomporsi.

Capitolo 3 · Flusso di lavoro

Tre passi verso un’impaginazione di qualità editoriale

Contenuti in Markdown, progetto grafico in un oggetto di configurazione, pagine da una sola chiamata di funzione.

  1. 3.1

    Scrivi Markdown semantico

    Scrivi i tuoi contenuti in Markdown arricchito: titoli, elenchi, tabelle, formule, riquadri e rimandi :ref alle tue figure. Nessuna preoccupazione di impaginazione, solo contenuti.

  2. 3.2

    Configura le regole di impaginazione

    Definisci formato della pagina, colonne, tipografia, stili dei titoli, testatine e collocazione degli elementi flottanti in un oggetto PostextConfig, oppure progettali visivamente nella Sandbox.

  3. 3.3

    Esporta in HTML, canvas o PDF

    Chiama buildDocument e ricevi la geometria completa dell’impaginazione, poi restituiscila con il backend HTML, canvas o PDF pronto per la stampa.

API

Una funzione, pieno controllo

Chiama buildDocument con i tuoi contenuti e un oggetto di configurazione. Ottieni la geometria completa delle pagine: disegna qualsiasi pagina come immagine con renderPage, oppure componi l’intero libro come PDF pronto per la stampa con renderToPdf.

book.ts
import { buildDocument, renderPage } from "postext";
import { renderToPdf } from "postext-pdf";

const doc = buildDocument(
  { markdown },
  {
    page: { sizePreset: "21x28" },
    layout: { layoutType: "double" },
    bodyText: {
      fontSize: { value: 12, unit: "pt" },
      textAlign: "justify",
      hyphenation: { enabled: true, locale: "en-us" },
    },
  }
);

// Ogni pagina come immagine…
const cover = renderPage(doc.pages[0], doc);
cover.toBlob((png) => save(png, "cover.png"));

// …oppure l’intero libro come PDF pronto per la stampa
// fontProvider: byte TTF per famiglia e peso (vedi la documentazione)
const pdf = await renderToPdf(doc, { fontProvider });

Capitolo 4 · Formato aperto

Un file, il libro intero

Un file .postext contiene tutto ciò che serve per comporre di nuovo un documento, su qualsiasi macchina: un formato aperto e modificabile che chiunque può adottare.

Quasi tutti i formati editoriali disperdono un progetto. La compilazione di un documento LaTeX dipende dai font e dai pacchetti installati su una macchina, e i file nativi dei principali programmi di impaginazione rimandano a immagini e caratteri conservati fuori da essi. Sposti il progetto e qualcosa va perso. Abbiamo incontrato questi limiti con LaTeX in prima persona.

Un .postext è un semplice archivio ZIP che chiunque può aprire, leggere e modificare: un manifest JSON, un file Markdown per capitolo, e i file dei font e le immagini stessi. La Sandbox lo esporta, la skill per agenti postext-port lo scrive e postext/bundle lo apre in qualsiasi programma per comporre di nuovo le stesse pagine. Il formato è documentato e con licenza MIT, pronto perché qualsiasi strumento lo legga e lo scriva.

Dentro postext-guide.postext
  1. 4.1preset.json

    Configurazione. Pagina, griglia, caratteri, stili di titolo e di paragrafo, colori e testatine, in JSON leggibile.

  2. 4.2chapters/<lang>/*.md

    Capitoli. Un file Markdown per capitolo: qui 14 capitoli in 2 lingue.

  3. 4.3fonts/*.woff2

    Caratteri. I file dei font, non solo i loro nomi: 18 file di Lora, Fraunces, Geist e Bricolage Grotesque.

  4. 4.4preset.json › resources

    Risorse. Didascalie, numerazione, collocazione e contenuto delle tabelle per le 26 figure e tabelle a cui il testo rimanda.

  5. 4.5resources/*.svg

    Immagini. Le illustrazioni stesse, SVG o bitmap, con la versione di ogni lingua: 38 file.

Figura 4.1 Il .postext della guida, 847 KB: tutto ciò che serve al libro, e niente che debba scaricare.

Prova

Apri la guida, ottieni le sue pagine

Il primo esempio della Sandbox, la guida di Postext, è un solo file .postext. Aprilo nel browser e trasforma ogni pagina in un’immagine: caratteri, figure e tabelle vengono dal file stesso.

Scarica la guidapostext-guide.postext · 847 KB
open-guide.js
import { openBundle, loadBundleFonts, registerBundleImages,
  buildBundle, renderPageToCanvas } from "postext";

// La guida della Sandbox: configurazione, capitoli, font e immagini
const file = await fetch("postext-guide.postext").then((r) => r.blob());
const book = await openBundle(file, { locale: "en" });

await loadBundleFonts(book);      // i suoi caratteri
await registerBundleImages(book); // le sue figure

// Ogni pagina di ogni capitolo, come immagine
for (const doc of buildBundle(book))
  for (const page of doc.pages) {
    const canvas = document.createElement("canvas");
    renderPageToCanvas(page, doc, canvas, { scale: 0.5 });
    document.body.append(canvas);
  }

Installazione

Comincia in meno di un minuto

Un pacchetto, nessun server, nessuna dipendenza nativa. Aggiungi postext-pdf quando ti serve la stampa.

quick-start.ts
// Avvio rapido
import { buildDocument, renderPage } from "postext";
import { renderToPdf } from "postext-pdf";

const doc = buildDocument({
  markdown: "# Hello World\n\nYour content here.",
});

// La prima pagina, disegnata su un canvas
document.body.append(renderPage(doc.pages[0], doc));

// L’intero documento come PDF
const pdf = await renderToPdf(doc, { fontProvider });