Kapitel 11 · Teil II · Das Handwerk
Konfiguration: Schriften, Farben und Ausgabe
Einheiten, Farben und die Palette, eigene Schriften, der HTML-Betrachter, PDF und Druckvorstufe, der Folio-Betrachter und die Debug-Überlagerungen
Kurz gesagt
Diese Seite behandelt die Einstellungen, die für das ganze Buch gelten, und die Einstellungen für jede Art von Ausgabe. Sie erklärt, wie Sie ein Maß und eine Farbe angeben und wie Sie die Farben einer Palette benennen. Sie zeigt, wie Sie eigene Schriften hinzufügen. Danach geht es um die Webansicht, die PDF-Datei, die Dateien, die eine Druckerei verlangt, und das 3D-Buch. Der letzte Abschnitt schaltet die Hilfslinien und Warnungen ein, die Ihnen bei der Arbeit helfen.
#Einheiten und Farben
#Maße
Alle physischen Maße in Postext verwenden den Typ Dimension – einen Wert zusammen mit einer Einheit:
interface Dimension {
value: number;
unit: DimensionUnit; // 'cm' | 'mm' | 'in' | 'pt' | 'px' | 'em' | 'rem'
}Absolute Einheiten – cm, mm, in, pt, px – werden mit der konfigurierten DPI-Zahl in Pixel umgerechnet. Bei 300 DPI entspricht 1 cm etwa 118 px.
Relative Einheiten – em, rem – skalieren mit der aktuellen Schriftgröße. Ein em bezieht sich auf die eigene Schriftgröße des Elements, rem auf die Schriftgröße des Grundtexts.
#Farben
Farben werden mit einer Hex-Darstellung und einem Zielfarbmodell gespeichert:
interface ColorValue {
hex: string; // '#ff0000', 'transparent', etc.
model: ColorModel; // 'hex' | 'rgb' | 'cmyk' | 'hsl'
cmyk?: CmykPercent; // The exact process values of a colour authored in CMYK.
}Das Feld model gibt den beabsichtigten Farbraum an. Für die Darstellung im Web sind 'hex' oder 'rgb' üblich. Für Druck-Workflows sagt 'cmyk', dass die Farbe in CMYK angegeben wurde, und cmyk bewahrt ihre Werte: Eine CMYK-Druckausgabe setzt sie unverändert, mit hex als ihrer Bildschirmdarstellung (siehe In CMYK angelegte Farben).
Weil Postext auf Ausgabe in Publikationsqualität zielt, wird die Standardfarbe des Grundtexts mit model: 'cmyk' (#000000) ausgeliefert. Die Farben von Überschriften, Fett, Kursiv und Listen sind standardmäßig an die Palettenfarbe Main Color (#295AA3, model: 'hex') gekoppelt. Seitenhintergrund und Überlagerungen der Oberfläche (Grundlinienraster, Schnittmarken, Debug-Anzeigen) haben standardmäßig model: 'hex'. Überschreiben Sie color.model in einem beliebigen Feld, wenn Sie eine andere Bedeutung für den Export brauchen.
#Transparenz
Eine Farbe kann durchscheinend sein. hex akzeptiert einen Alphakanal als #rgba oder #rrggbbaa. Es akzeptiert auch eine Farbe rgb() / rgba() in der Komma- oder der Leerzeichen-Syntax, mit dem Alphawert als Zahl oder Prozentwert. transparent ist vollständig durchsichtig:
const config: PostextConfig = {
header: {
elements: [{
kind: 'box',
id: 'veil',
placement: {
anchor: { to: 'bleed', edge: 'top-left' },
size: { width: 'fill', height: { value: 40, unit: 'mm' } },
},
style: { backgroundColor: { hex: '#ffffffb3', model: 'hex' } }, // white at 70 %
}],
},
bodyText: { color: { hex: 'rgba(0, 0, 0, 0.85)', model: 'rgb' } },
};Die drei Backends malen sie gleich. Canvas und HTML-Betrachter übernehmen den Wert als CSS-Farbe. Das PDF-Backend setzt die Deckkraft der Farbe als konstantes Alpha, einen ExtGState mit ca für Flächen und CA für Konturen. Das gilt für Text, Linien, Kästen, Tabellenflächen und -rahmen, Chips, Farbfelder und Formeln. Eine durchscheinende Farbe legt sich über alles, was vor ihr gemalt wurde. Ein Kasten in der Kopf- oder Fußzeile wird zuletzt gemalt und verschleiert daher den Text darunter; ein Kasten in einem Auftaktband wird zuerst gemalt und tönt daher die Seite unter dem Text. Wird das PDF in einen anderen Farbraum gezwungen (pdfGeneration.forceColorSpace mit colorSpace: 'cmyk' oder 'grayscale'), wird die Farbe umgerechnet und ihr Alpha bleibt erhalten. In der Sandbox schreibt der Deckkraftregler des Farbwählers diese Werte als #rrggbbaa, und der Farbwähler liest auch die anderen Formen.
#Eigene Schriften
Postext löst jede Zeichenkette fontFamily sowohl gegen den Katalog von Google Fonts als auch gegen die Liste customFonts des Dokuments auf. Bei Namensgleichheit haben eigene Schriften Vorrang – wenn Sie customFonts: [{ name: 'Roboto', … }] deklarieren, verwendet Postext Ihre hochgeladene Datei statt der „Roboto“ von Google Fonts.
Verwenden Sie eigene Schriften, wenn:
- das Dokument eine Haus- oder lizenzierte Schrift braucht, die es bei Google Fonts nicht gibt;
- die Umgebung die Schrift-CDNs nicht erreicht, also jsDelivr (woher die Sandbox die Dateien von Fontsource bezieht) oder Google Fonts (offline, Intranet, datenschutzsensibel);
- Sie die Schriftdatei privat halten müssen und sie nicht bei einem Dritten hochladen dürfen.
#Konfigurationsschema
type CustomFontFormat = 'woff2' | 'woff' | 'ttf' | 'otf';
type CustomFontStyle = 'normal' | 'italic';
interface CustomFontVariant {
weight: number; // CSS font-weight, 100..900
style: CustomFontStyle;
fileId: string; // opaque id of the binary in out-of-band storage
format: CustomFontFormat;
fileName?: string; // original upload filename (optional, shown in UI)
}
interface CustomFontFamily {
name: string; // used anywhere a Google Font family name fits
variants: CustomFontVariant[];
}
interface PostextConfig {
// ...
customFonts?: CustomFontFamily[];
}Die Binärdatei jeder Variante ist nicht in die Konfiguration selbst eingebettet. Die Konfiguration enthält nur Verweise fileId; die Bytes liegen getrennt davon. In der Sandbox heißt das IndexedDB (Schlüssel-Wert-Speicher, nur im Browser, privat für das Dokument). Wer Postext in einen anderen Host einbettet, kann fileId beliebig auflösen – über einen Server-Endpunkt, einen Service-Worker-Cache, was auch immer –, solange die Bytes den Hauptthread erreichen, bevor buildDocument läuft.
#Eigene Schriften in der Sandbox verwalten
Öffnen Sie das Bedienfeld Schriften über die linke Aktivitätsleiste (zwischen Ressourcen und Gestaltung). Seine Liste Schriften in diesem Buch zeigt jede Familie, die die Gestaltung verwendet, mit ihrer Rolle und ihrer Herkunft: Google Fonts, Fontsource (für eine Familie, die Google Fonts nicht hat), Ihre Datei oder nirgends (Nicht gefunden). Unter Ihre Schriftdateien gilt für jede Familie:
- Schriftfamilie hinzufügen – legt eine leere Familie an; benennen Sie sie direkt um.
- Variante(n) hochladen – wählen Sie eine Schriftstärke (100–900) und einen Stil (normal / kursiv) und dann eine oder mehrere Dateien
.woff2,.woff,.ttfoder.otf. Jede Datei wird zu einer eigenen Variante, gebunden an das gerade gewählte Paar (Schriftstärke, Stil); der Name der hochgeladenen Datei wird gespeichert und in der Zeile angezeigt, damit Sie Varianten unterscheiden können. Schriftstärke oder Stil einer Variante lassen sich jederzeit über ihre Auswahllisten nachstellen. - Doppelte Varianten sind erlaubt. Landen zwei Dateien auf demselben Platz (Schriftstärke, Stil), werden beide behalten, und die Warnung Doppelte Schriftvariante erscheint, damit Sie die Einstellungen der zusätzlichen Dateien eindeutig machen.
- Variante löschen oder Familie löschen – entfernt den Eintrag aus der Konfiguration und die gespeicherten Bytes aus IndexedDB.
Sobald eine Familie deklariert ist, führt jeder Schriftwähler sie in der Gruppe Eigene über der Liste von Google Fonts. Wenn Sie sie auswählen, wird die Familie in jedes Feld für Schriftfamilien eingetragen, auf das Sie sie anwenden.
#Verhalten bei der Darstellung
Unter der Haube:
- Ändert sich
customFonts, wird jede deklarierte Familie automatisch als EinträgeFontFaceindocument.fontsregistriert – so übernehmen der HTML-Betrachter, der Canvas-Viewport (der überdocument.fontsmisst) und jeder direkte CSS-Verweis die eigene Schrift, ohne dass der Benutzer zuerst den Schriftwähler öffnen muss. - Der Layout-Worker erhält dieselben ArrayBuffers über den bestehenden Übertragungsweg für Schriftdaten, sodass die Messung (
buildFontString, Pretext) genauso funktioniert wie bei einer Familie aus dem Katalog. - Wird eine Variante geändert oder entfernt, verwirft der Worker die zwischengespeicherte Schrift dieser Familie und registriert sie beim nächsten Build neu, sodass die Vorschauen mit dem aktuellen Variantensatz synchron bleiben.
- PDF-Export: Hochgeladene Binärdateien laufen durch dieselbe Pipeline
PdfFontProvider. Dateien.woff2werden dekomprimiert;.ttfund.otfwerden direkt durchgereicht..woffwird mit einer klaren Fehlermeldung abgewiesen (pdf-lib kann rohes WOFF nicht einbetten – laden Sie die Schrift als.woff2/.ttf/.otferneut hoch). OpenType mit CFF-Konturen (.otfmit der SignaturOTTO) wird ohne Teilmengenbildung eingebettet, weil der CFF-Subsetter von pdf-lib beimsave()jede Glyphe durchläuft und bei echten Schriften minutenlang hängen kann; der Verzicht auf die Teilmenge tauscht ein etwas größeres PDF gegen gleichmäßige Darstellungszeiten.
#Warnungen zu fehlenden Schriften
Das Bedienfeld Prüfungen der Sandbox listet in seiner Gruppe Schriften drei Fehlerarten, die eigene Schriften betreffen (alle über denselben Schalter debug.warnings.missingFont eingeschaltet, der schon die allgemeine Warnung „nicht geladen“ steuert):
- Unbekannte Schriftfamilie – ein
fontFamilyverweist auf einen Namen, der weder eine bekannte Google-Schrift noch eine aktuell deklarierte eigene Familie ist. Die Warnung erscheint auch sofort, wenn Sie eine eigene Familie löschen, auf die noch ein FeldfontFamilyverweist, statt zu warten, bis das DOM es bemerkt. - Schriftvariante fehlt – die Familie existiert, aber mindestens einer der Standardplätze für Schriftstärke und Stil (400 / 700, normal / kursiv) hat keine hochgeladene Datei. Die Warnung nennt die fehlenden Kombinationen.
- Doppelte Schriftvariante – zwei oder mehr hochgeladene Dateien teilen sich innerhalb einer Familie denselben Platz (Schriftstärke, Stil). Bei der Darstellung wird nur eine Datei verwendet; die Warnung erinnert Sie daran, die übrigen Einträge nachzustellen.
Ein Klick auf eine dieser Warnungen öffnet das Bedienfeld Schriften, damit Sie die fehlende Variante hochladen, die Familie wieder hinzufügen oder die Duplikate eindeutig machen können.
Sobald ein Layout existiert, listet das Bedienfeld auch die Warnung Ersatzschrift im Layout der Engine (fontFallback): eine Schrift, ohne die die Seiten gemessen wurden, weil sie fehlt oder weil der Browser sie aus einer anderen Schriftstärke oder Neigung gezeichnet hat. Eine Familie, die bereits als unbekannt oder als unvollständig gemeldet ist, wird nicht doppelt aufgeführt. Vor dem ersten Layout vertritt eine Prüfung gegen document.fonts diese Meldung.
#Farbpalette
Mit der Eigenschaft colorPalette von PostextConfig legen Sie einen wiederverwendbaren Satz benannter Farben an und verweisen von jedem ColorValue der Konfiguration darauf. Sie ist die Postext-Entsprechung von CSS Custom Properties oder dem Farbfelder-Bedienfeld von InDesign: Ändern Sie den Paletteneintrag einmal, und jede Farbe, die auf ihn zeigt, ändert sich im ganzen Dokument.
interface ColorPaletteEntry {
id: string; // stable identifier — referenced by ColorValue.paletteId
name: string; // human label shown in sandbox UIs
value: ColorValue;
}#Die Standardpalette
Postext wird mit einer Standardpalette aus einem einzigen Eintrag namens Main Color (id: 'main-color', Hex #295AA3) ausgeliefert. Mehrere Voreinstellungen – Überschriftenfarbe, Farbe für Fett und Kursiv im Grundtext, Farbe von :ref, Farben von Aufzählungszeichen und Nummern – verweisen über paletteId: 'main-color' auf diesen Eintrag; ändern Sie dieses eine Farbfeld, färben sich alle Teile des Dokuments um, die es verwenden.
Über drei Exporte können Sie die Standardpalette ansehen, klonen oder mit ihr vergleichen:
import {
DEFAULT_COLOR_PALETTE,
cloneDefaultColorPalette,
isDefaultColorPalette,
} from 'postext';
// Read-only snapshot of the shipped palette.
DEFAULT_COLOR_PALETTE;
// => [{ id: 'main-color', name: 'Main Color', value: { hex: '#295AA3', model: 'hex' } }]
// Independent copy — mutate this, not DEFAULT_COLOR_PALETTE.
const palette = cloneDefaultColorPalette();
// Detect whether a user has customised the palette at all.
isDefaultColorPalette(palette); // trueEine Palette steht auf der obersten Ebene der Konfiguration:
const config: PostextConfig = {
colorPalette: [
{ id: 'ink', name: 'Ink', value: { hex: '#0a0a0a', model: 'cmyk' } },
{ id: 'accent', name: 'Accent', value: { hex: '#b8860b', model: 'hex' } },
],
bodyText: { color: { hex: '#000000', model: 'cmyk', paletteId: 'ink' } },
headings: { color: { hex: '#000000', model: 'hex', paletteId: 'accent' } },
};#Auf einen Paletteneintrag verweisen
Jeder ColorValue der Konfiguration kann ein optionales Feld paletteId tragen, das auf einen Eintrag in colorPalette zeigt: Seitenhintergrund, Farben des Grundtexts (einschließlich der Farbe von :ref), Überschriftenfarben, Spaltenlinien, Listenfarben, die Farben von Tabellen, Legenden, Chips und Kästen (Kasten, Streifen, Symbol, Markierung, Label, Titel, Text), Farben von Schnittmarken und Grundlinienraster, Debug-Anzeigen und jede Farbe einer Gestaltung – die Kolumnentitel, die Überschriftenauftakte und Gestaltungen in der Spalte, Gestaltungen und Kolumnentitel der Überschriftenformate, die Teilseiten und die Teilzeilen des Inhaltsverzeichnisses (Text, Linie, Kastenfläche und -rahmen, Kontur, Initiale). Ist es vorhanden, haben hex / model des Paletteneintrags Vorrang vor dem daneben gespeicherten Ersatzwert hex / model. Der eingebettete Ersatzwert wird nur verwendet, wenn die Palette fehlt, leer ist oder diese ID nicht enthält – nützlich, wenn Sie eine Konfiguration ausliefern, die ein Werkzeug ohne Palettenunterstützung lesen wird.
Geändert in postext 1.5. Bis postext 1.4 erreichte die Palette nur eine feste Liste von Einstellungen: Die Farben der Gestaltungen (Kolumnentitel, Auftakte, Überschriftenformate, Teile, Zeilen des Inhaltsverzeichnisses), bodyText.referenceColor, die Label-Farben der Kästen und die Farben für Fett und Kursiv im Kastentext behielten den hex, der neben ihrer paletteId gespeichert war. Ein Dokument, dessen gespeicherter Wert vom Paletteneintrag abweicht – jedes, das nach der Änderung des Eintrags in der Sandbox bearbeitet wurde, und jedes :ref, wenn die Main Color nicht #295AA3 ist –, druckt jetzt die Palettenfarbe, wie es die Verknüpfung verlangt. Um eine Farbe so zu behalten, wie sie war, entfernen Sie ihre paletteId.
#Wie Paletten angewendet werden
buildDocument wendet die Palette an zwei Stellen an, damit verknüpfte Farben sowohl für ausdrücklich angegebene Werte als auch für später ergänzte Voreinstellungen funktionieren:
applyPaletteToConfig(config)– löst jedenColorValueder rohen Benutzerkonfiguration auf, der einepaletteIdträgt. Nützlich, wenn Sie sehen wollen, was die Engine tatsächlich erhält.applyPaletteToResolvedConfig(resolved, palette)– läuft, nachdem die Voreinstellungen aufgelöst sind, und schreibt die an die Palette gekoppelten Voreinstellungen (Überschriftenfarbe, Farbe für Fett und Kursiv im Grundtext, Farbe von:ref, Listenfarben, die Farben der Standardgestaltungen) passend zur aktiven Palette um.
Beide durchlaufen die gesamte Konfiguration, sodass keine an die Palette gekoppelte Farbe zurückbleibt. Die meisten Farben des Textflusses (Grundtext, Überschriften, Listen, Tabellen, Legenden, Chips, Kasten, Titel und Text des Kastens) kommen als einfache Werte heraus. Jede andere – die Farben der Gestaltungen, die Farbe von :ref, die Labels der Kästen – übernimmt hex / model der Palette und behält ihre paletteId. Über diese Verknüpfung überschreiben das Attribut palette eines Teils und das palette eines Überschriftenformats die Farben auf ihren Seiten (siehe Teile); sie muss daher erhalten bleiben. htmlViewer.overrides bleibt, wie es geschrieben ist: Der HTML-Betrachter führt es zuerst zusammen, und eine Palette darin gilt dann für alles, auch für die Gestaltungen.
Sie müssen diese Funktionen selten selbst aufrufen, aber beide werden exportiert, damit Sie sie untersuchen oder wiederverwenden können:
import {
applyPaletteToConfig,
applyPaletteToResolvedConfig,
resolveColorValue,
} from 'postext';
const flat = applyPaletteToConfig(config);
// Every ColorValue with a paletteId in the raw config now carries the
// palette entry's hex/model (a design colour keeps its paletteId).
// `applyPaletteToResolvedConfig` is typically handled by buildDocument; use it
// directly if you build a ResolvedConfig yourself and want the palette applied.resolveColorValue(value, palette, fallback) ist die Variante für einen einzelnen Wert, praktisch, wenn Sie Konfigurationen imperativ zusammensetzen und jeweils eine Farbe auflösen müssen.
#Die Palette bearbeiten
Eine Farbe, deren paletteId keinen Eintrag nennt, druckt ihren gespeicherten hex / model, der älter sein kann als die Farbe, die der Eintrag ihr gab. Schreiben Sie daher vor dem Entfernen eines Eintrags jeden damit verknüpften ColorValue als einfache Farbe mit dem aktuellen Wert des Eintrags um. Der Abschnitt Palette der Sandbox (Gestaltung → Farben) tut das, wenn Sie einen Eintrag löschen, wo immer die Farbe steht (Gestaltungen und Labels der Kästen eingeschlossen), und seine Bestätigung listet jede Einstellung auf, die den Eintrag verwendet: mit Namen oder mit ihrem Pfad in der Konfiguration (header.elements[2].color).
#HTML-Betrachter
Die Eigenschaft htmlViewer steuert, wie das HTML-Backend die Seiten am Bildschirm anordnet. Sie wirkt nur, wenn Sie mit renderToHtml / renderToHtmlIndexed rendern; Canvas- und PDF-Pfad ignorieren sie vollständig – sie verwenden direkt die konfigurierten page.width, page.height und page.dpi.
interface HtmlViewerConfig {
maxCharsPerLine?: number; // Target column width, in characters of the body font.
columnGap?: number; // Horizontal gap between columns in multi-column mode (px).
optimalLineBreaking?: boolean; // Use Knuth–Plass inside the HTML viewer instead of greedy.
overrides?: HtmlViewerOverrides; // Screen-only partial config merged over the document config.
}
type HtmlViewerOverrides = Omit<PostextConfig, 'htmlViewer'>;| Eigenschaft | Typ | Standard | Beschreibung |
|---|---|---|---|
maxCharsPerLine | number | 70 | Zielzeilenlänge jeder dargestellten Spalte, angegeben in Zeichen der Grundschrift. Der Viewport misst eine repräsentative Textprobe dieser Länge, um daraus die tatsächliche Breite in Pixeln abzuleiten – so passt sich das Ergebnis an jede Kombination aus Proportionalschrift und Schriftgröße an. |
columnGap | number | 50 | Horizontaler Abstand in CSS-Pixeln zwischen den Spalten, wenn der Betrachter mehrspaltig darstellt. Im einspaltigen Modus ohne Wirkung. |
optimalLineBreaking | boolean | false | Schaltet den Zeilenumbruch nach Knuth-Plass im HTML-Betrachter ein. Standardmäßig aus, weil der Betrachter das Layout bei jeder Größen- und Schriftgrößenänderung neu berechnet – der gierige First-Fit-Algorithmus ist schnell genug, um sich unmittelbar anzufühlen. Schalten Sie ihn ein, wenn Sie dieselben optimalen Umbrüche wollen, die das Canvas-Backend verwendet. |
overrides | HtmlViewerOverrides | — | Eine Teilkonfiguration des Dokuments, die nur am Bildschirm gilt. Der HTML-Betrachter führt sie vor dem Setzen über die Dokumentkonfiguration zusammen (applyHtmlViewerOverrides); Canvas und PDF ignorieren sie. Objekte werden rekursiv zusammengeführt; ein Array levels (Überschriften, Listen, Inhaltsverzeichnis) wird Eintrag für Eintrag über level zusammengeführt; jedes andere Array – die elements eines Gestaltungsplatzes, calloutStyles, colorPalette … – ersetzt das Basis-Array vollständig. Typischer Einsatz: ein Kapitelauftakt ohne die Druckbänder oder eine Teilseite, deren Titel sich am Nummernzeichen statt an einer festen Breite des Endformats umbricht. Die Sandbox bearbeitet sie als JSON. |
const config: PostextConfig = {
headings: { levels: [{ level: 1, span: 'page', breakBefore: { enabled: true } }] },
htmlViewer: {
// On screen, chapters flow on without the page-span opener.
overrides: { headings: { levels: [{ level: 1, span: 'column', breakBefore: { enabled: false } }] } },
},
};Resolver und Stripper folgen demselben Muster wie in den anderen Abschnitten:
import {
DEFAULT_HTML_VIEWER_CONFIG,
resolveHtmlViewerConfig,
stripHtmlViewerDefaults,
} from 'postext';
const resolved = resolveHtmlViewerConfig(config.htmlViewer);
// => { maxCharsPerLine: 70, columnGap: 50, optimalLineBreaking: false }
const minimal = stripHtmlViewerDefaults(config.htmlViewer);
// => undefined when everything matches the defaultsEin vollständiges Beispiel finden Sie unter Den HTML-Betrachter einbinden.
#PDF-Erzeugung (Konfiguration)
Die Eigenschaft pdfGeneration steuert, wie das PDF-Backend das fertige Dokument ausgibt. Diese Einstellungen liest das Paket postext-pdf beim Export; Canvas- und HTML-Betrachter ignorieren sie.
buildDocument trägt sie im VDT als doc.config.pdfGeneration, und renderToPdf nimmt jede Einstellung von der ersten Stelle, die sie angibt:
- aus seinen eigenen Optionen (
outlines,accessible,colorSpace); - aus
pdfGenerationdes ersten Dokuments, das es rendert (in einem Buch gelten die Einstellungen des ersten Kapitels für die ganze Datei); - aus den Voreinstellungen: Lesezeichen und Tagging an, RGB-Farbe.
renderToPdf(doc, { fontProvider }) folgt also der Konfiguration, und eine an renderToPdf übergebene Option gewinnt nur für diese eine Einstellung. forceColorSpace und colorSpace stehen zusammen für die Option colorSpace: Das colorSpace der Konfiguration gilt, solange forceColorSpace an ist, und das PDF ist RGB, solange es aus ist. Frühere Versionen von postext-pdf lasen nur die Optionen; eine Konfiguration, die pdfGeneration setzt, ändert jetzt das PDF eines Aufrufers, der keine Optionen übergibt.
type PdfColorSpace = 'rgb' | 'cmyk' | 'grayscale';
interface PdfGenerationConfig {
outlines?: boolean; // Emit PDF bookmarks from the heading tree.
forceColorSpace?: boolean; // Convert every colour to `colorSpace`.
colorSpace?: PdfColorSpace; // Target space used when `forceColorSpace` is true.
accessible?: boolean; // Tagged, PDF/UA-oriented output (structure tree, alt text, language).
}| Eigenschaft | Typ | Standard | Beschreibung |
|---|---|---|---|
outlines | boolean | true | Gibt aus der Überschriftenhierarchie PDF-Lesezeichen (Outlines) aus, damit Leser in der Seitenleiste eines PDF-Betrachters direkt zu jeder Überschrift springen können. Schalten Sie sie bei Dokumenten ab, in denen der Überschriftenbaum keinen Sinn ergibt (z. B. einseitige Plakate). |
forceColorSpace | boolean | false | Ist der Wert true, wird jede Farbe des gerenderten PDFs beim Export in colorSpace umgerechnet. Lassen Sie ihn bei PDFs für den Bildschirm aus, deren Eingangsfarben schon im gewünschten Farbraum liegen; schalten Sie ihn ein, um bei gemischten Quellen einen einzigen Farbraum sicherzustellen. |
colorSpace | 'rgb' | 'cmyk' | 'grayscale' | 'cmyk' | Zielfarbraum, wenn forceColorSpace an ist. Verwenden Sie 'cmyk' für den Offsetdruck, 'rgb' für reine Bildschirm-PDFs und 'grayscale' für Schwarz-Weiß-Andrucke. Ohne Wirkung, wenn forceColorSpace false ist. CMYK wird über das Ausgabeprofil von print (standardmäßig FOGRA39) mit dessen Schwarzbehandlung separiert, und RGB-Bilder werden ebenfalls umgerechnet; ein dort gewählter PDF/X-Standard schreibt CMYK, unabhängig von diesem Wert. |
accessible | boolean | true | Gibt ein barrierefreies, getaggtes PDF nach PDF/UA-1 aus: einen logischen Strukturbaum in Lesereihenfolge (Überschriften, die nie eine Ebene überspringen, Absätze, Listen, Blockzitate, Kästen, Tabellen mit Kopfzellen, Abbildungen mit Alternativtext und Legende, Formeln, anklickbare Verweise als Links, der Inhalt eines :::toc als ein TOC mit einem TOCI je Zeile: die Nummer der Zeile ein Lbl, Titel und Seite eine Reference, die den Link enthält), Titel und Sprache des Dokuments (das oberste locale), die PDF/UA-Kennung in den XMP-Metadaten und jedes schmückende Element (Seitenhintergrund, Linien, Grundlinienraster, Kopf- und Fußzeilen, Schnittmarken, wiederholte Tabellenköpfe, der wiederholte Titel und der Fortsetzungshinweis eines geteilten Kastens) als Artefakt markiert, damit Screenreader es überspringen. Eine Abbildung ohne altText greift auf ihre Legende zurück, dann auf ihr Label. Eine gleitende Abbildung oder Tabelle wird direkt nach dem Text gelesen, der sie zuerst zitiert, oder nach dem Text vor ihrer Zeile ::resource, und ein gleitender Kasten nach dem Text vor seinem Direktivenblock, auch wenn das Gleitobjekt auf einer späteren Seite steht; eine Liste oder das Inhaltsverzeichnis, die hinter einem Gleitobjekt weiterlaufen, bleiben ein Element. Schalten Sie es nur für Druckvorlagen ab, bei denen die zusätzliche Struktur unerwünscht ist. |
pdfGeneration: {
outlines: true,
accessible: true,
forceColorSpace: true,
colorSpace: 'cmyk',
}Resolver und Stripper entsprechen den anderen Abschnitten:
import {
DEFAULT_PDF_GENERATION_CONFIG,
resolvePdfGenerationConfig,
stripPdfGenerationDefaults,
} from 'postext';
const resolved = resolvePdfGenerationConfig(config.pdfGeneration);
// => { outlines: true, forceColorSpace: false, colorSpace: 'cmyk', accessible: true }
const minimal = stripPdfGenerationDefaults(config.pdfGeneration);
// => undefined when everything matches the defaultsDas vollständige Exportrezept finden Sie unter PDFs erzeugen.
#Druckvorstufe (Konfiguration)
Die Eigenschaft print legt fest, wie ein Buch in den Druck geht: den PDF/X-Standard der Datei, das Ausgabeprofil, mit dem ihr CMYK separiert wird, wie Schwarz druckt und die Schwellenwerte des Preflights. Das Layout ignoriert sie, ihre Änderung verschiebt also nie eine Zeile. Drei Stellen lesen sie: postext-pdf beim Schreiben der Datei, preflightDocument beim Prüfen eines gesetzten Dokuments und die Druckvorschau des Canvas- und des Folio-Betrachters.
type PdfXStandard = 'none' | 'pdfx1a' | 'pdfx4';
interface PrintConfig {
standard?: PdfXStandard; // 'none': an ordinary PDF.
outputProfile?: string; // A catalogue id ('fogra39', 'fogra51'…) or 'custom'.
customProfile?: CustomOutputProfile; // An uploaded .icc file.
renderingIntent?: 'relative' | 'perceptual';
blackPointCompensation?: boolean;
convertImages?: boolean; // Separate RGB pictures (PDF/X-1a always does).
inkLimit?: number; // Total area coverage, percent.
black?: PrintBlackConfig;
preflight?: PrintPreflightConfig;
}
interface CustomOutputProfile {
name: string; // Its description, or the file name.
fileId: string; // The stored .icc file.
registryName?: string; // The condition's ICC registry name (FOGRA51…), else 'Custom'.
inkLimit?: number;
}| Eigenschaft | Typ | Standard | Beschreibung |
|---|---|---|---|
standard | 'none' | 'pdfx1a' | 'pdfx4' | 'none' | Die PDF/X-Variante der Datei. 'pdfx1a' schreibt PDF/X-1a:2003: nur CMYK und Grau, keine Transparenz, von jeder Druckerei angenommen. 'pdfx4' schreibt PDF/X-4: Transparenz und Farbmanagement bleiben erhalten, für aktuelle Workflows. Beide separieren jede Farbe über das Ausgabeprofil, unabhängig von pdfGeneration.colorSpace. |
outputProfile | string | 'fogra39' | Die Druckbedingung, für die CMYK separiert wird: eine ID aus dem Profilkatalog oder 'custom' für customProfile. Eine ID, die der Katalog nicht kennt, oder 'custom' ohne Datei fällt auf den Standardwert zurück und erzeugt eine Konfigurationswarnung. |
customProfile | CustomOutputProfile | keiner | Ein CMYK-Ausgabeprofil, das Sie selbst liefern, nämlich das, das Ihnen Ihre Druckerei gibt (etwa PSOcoated_v3.icc der ECI). Seine Bytes werden wie eine Schrift getrennt gespeichert; renderToPdf nimmt sie als Option outputProfile. registryName wird als Kennung der Bedingung des Output Intents geschrieben. |
renderingIntent | 'relative' | 'perceptual' | 'relative' | Relativ farbmetrisch hält die Farben, die die Druckmaschine drucken kann, exakt und beschneidet die übrigen auf die nächstgelegene druckbare; wahrnehmungsorientiert staucht den ganzen Bereich, sodass Farben außerhalb des Farbumfangs ihre Verhältnisse zueinander behalten. |
blackPointCompensation | boolean | true | Bildet beim relativen Intent das Schwarz des Bildschirms auf das tiefste Schwarz ab, das die Druckmaschine druckt, sodass die dunkelsten Töne ihre Zeichnung behalten, statt zuzulaufen. |
convertImages | boolean | true | Separiert RGB-Bilder mit dem Profil nach CMYK. PDF/X-1a tut das immer. In PDF/X-4 behält false sie in RGB, über /DefaultRGB der Seiten als sRGB gekennzeichnet, damit das RIP der Druckerei sie umrechnet. CMYK- und Graustufen-JPEGs werden immer unverändert eingebettet. |
inkLimit | number | der des Profils | Die höchste Summe aus C+M+Y+K in Prozent, die der Preflight akzeptiert. Standardmäßig der Grenzwert, auf den das Profil separiert (300 % für die meisten Offsetbedingungen, 230 % für Zeitungspapier IFRA26). |
black | PrintBlackConfig | siehe Schwarz | Grautöne nur in K, Überdrucken und Tiefschwarz. |
preflight | PrintPreflightConfig | siehe Preflight | Was der Preflight prüft und seine Schwellenwerte. |
print: {
standard: 'pdfx4',
outputProfile: 'fogra51',
black: { richBlackColor: { c: 60, m: 40, y: 40, k: 100 } },
preflight: { minImageResolution: 300, safeZone: { value: 5, unit: 'mm' } },
}#Ausgabeprofile
postext liefert diese CMYK-Ausgabeprofile in seinem Ordner icc/ aus (postext/icc/<id>.icc auf jedem npm-CDN und /icc/<id>.icc auf postext.dev). Für keines sind urheberrechtliche Einschränkungen bekannt (CC0): die FOGRA-, GRACoL-, SWOP- und Zeitungsprofile von colord, erzeugt aus den Charakterisierungsdaten der jeweiligen Bedingung, sowie FOGRA51 und FOGRA52, von postext mit ArgyllCMS aus den Daten der Fogra selbst gebaut. Die Profile der ECI (ISO Coated v2, PSO Coated v3, PSO Uncoated v3) beschreiben dieselben Bedingungen, dürfen aber nicht weitergegeben werden; laden Sie sie als eigenes Profil hoch, wenn Ihre Druckerei danach fragt.
| ID | Bedingung | Registry-Name | Farbauftrag max. |
|---|---|---|---|
fogra39 | Offset, gestrichenes Papier (Bedingung ISO Coated v2) | FOGRA39 | 300 % |
fogra51 | Offset, Premium gestrichen (Bedingung PSO Coated v3) | FOGRA51 | 300 % |
fogra52 | Offset, holzfrei ungestrichen (Bedingung PSO Uncoated v3) | FOGRA52 | 300 % |
fogra47 | Offset, ungestrichen weiß (PSO Uncoated ISO 12647) | FOGRA47 | 300 % |
fogra29 | Offset, ungestrichen weiß | FOGRA29 | 300 % |
fogra30 | Offset, ungestrichen gelblich | FOGRA30 | 340 % |
fogra27 | Offset, gestrichen (ISO 12647-2:1996) | FOGRA27 | 300 % |
fogra28 | Heatset-Rollenoffset, LWC glänzend | FOGRA28 | 300 % |
fogra45 | Heatset-Rollenoffset, LWC verbessert | FOGRA45 | 300 % |
fogra40 | Heatset-Rollenoffset, SC-Papier | FOGRA40 | 340 % |
gracol2006 | GRACoL 2006, Grad 1 gestrichen | CGATS TR 006 | 300 % |
swop3 | SWOP 2006, Grad 3 gestrichen | CGATS TR 003 | 300 % |
swop5 | SWOP 2006, Grad 5 gestrichen | CGATS TR 005 | 300 % |
ifra26 | Coldset-Zeitungspapier (ISO 12647-3) | IFRA26 | 230 % |
snap2007 | Zeitungspapier SNAP 2007 | CGATS TR 002 | 320 % |
renderToPdf liest die Bytes des Profils aus seiner Option outputProfile; ohne sie lädt es die Katalogdatei von profileBaseUrl (standardmäßig https://cdn.jsdelivr.net/npm/postext/icc/). Eine PDF/X-Ausgabe, deren Profil sich nicht laden lässt, scheitert; eine einfache CMYK-Ausgabe greift mit der Warnung outputProfileUnavailable auf die Lehrbuchformel zurück.
import { readFile } from 'node:fs/promises';
import { renderToPdf } from 'postext-pdf';
const pdf = await renderToPdf(doc, {
fontProvider,
print: { standard: 'pdfx1a', outputProfile: 'fogra39' },
outputProfile: await readFile('node_modules/postext/icc/fogra39.icc'),
});#PDF/X-1a und PDF/X-4
Beide Standards schreiben:
- den Output Intent (
GTS_PDFX), der die Druckbedingung nennt und das Zielprofil einbettet; - die Kennung im Info-Dictionary (
GTS_PDFXVersion,/Trapped /False, Titel und Datumsangaben) und in den XMP-Metadaten (pdfxid:GTSPDFXVersion, die Dokument- und Versions-IDs), zusammengeführt mit der PDF/UA-Kennung, wenn die Datei getaggt ist; - auf jeder Seite eine TrimBox und eine BleedBox (die ganze Seite, wenn es keine Schnittlinien gibt);
- die
/IDim Trailer; - jede Farbe in DeviceCMYK (oder Grau) über das Profil und die Schnittmarken in Passerfarbe;
- keine Link-Annotationen: Eine Datei für die Druckmaschine enthält keine innerhalb ihrer BleedBox, daher entfallen die Links des Bildschirm-PDFs (die Lesezeichen bleiben).
PDF/X-1a:2003 ist PDF 1.4 ohne Objektströme und kennt keine Transparenz: Eine durchscheinende Farbe wird so gesetzt, wie sie auf dem Papier drucken würde, das Alpha eines Bildes wird auf Weiß verrechnet, und das Debug-Seitennegativ entfällt (mit der Warnung pageNegativeIgnored). PDF/X-4 ist PDF 1.6: Die Transparenz bleibt, jede Seite erhält eine Transparenzgruppe, die in CMYK verrechnet, und RGB-Bilder, die convertImages: false beibehält, werden über /DefaultRGB als sRGB gekennzeichnet.
Eine PDF-Druckvorlage (svg.pdfFileId) wird unverändert eingebettet, ihre Farben, Schriften und Transparenz sind also ihre eigenen; der Preflight meldet, was sie mitbringt.
#Schwarz
interface PrintBlackConfig {
kOnlyNeutrals?: boolean; // Greys and black in black ink only.
overprint?: boolean; // 100 % K overprints.
richBlack?: boolean; // Large black areas in rich black.
richBlackColor?: CmykPercent; // { c, m, y, k } in percent.
richBlackMinSize?: Dimension; // The smaller side an area needs.
}| Eigenschaft | Typ | Standard | Beschreibung |
|---|---|---|---|
kOnlyNeutrals | boolean | true | Eine neutrale Farbe (#000000, #808080 …) druckt allein mit schwarzer Farbe, ihr K so gewählt, dass die Helligkeit stimmt, nie als vierfarbiges Grau, das sich mit dem Passer verschiebt. Bilder behalten den Schwarzaufbau des Profils. |
overprint | boolean | true | Alles, was allein in 100 % K malt (schwarzer Text, Linien, Konturen, kleine schwarze Formen), überdruckt (op/OP mit OPM 1), sodass eine Druckplatte, die sich in der Maschine verschiebt, nie einen weißen Rand darum aufreißt. Alles andere spart aus; Bilder und Verläufe überdrucken nie. |
richBlack | boolean | true | Eine schwarze Fläche, deren kleinere Seite richBlackMinSize erreicht (ein Hintergrund, ein Band, ein Kasten), druckt in richBlackColor und spart aus, sodass sie tief statt dunkelgrau wirkt. Text wird nie zu Tiefschwarz. |
richBlackColor | CmykPercent | | Der Aufbau des Tiefschwarz in Prozent. Halten Sie seine Summe unter dem maximalen Farbauftrag; der Preflight prüft das. |
richBlackMinSize | Dimension | 6mm | Die kleinere Seite, die eine schwarze Fläche braucht, um in Tiefschwarz zu drucken. |
#In CMYK angelegte Farben
Eine in CMYK geschriebene Farbe behält ihre exakten Werte: ColorValue.cmyk (Prozent) wird in einer Druckausgabe unverändert gesetzt, und hex ist ihre Bildschirmdarstellung. Ein in CMYK angelegter Paletteneintrag gilt für jede mit ihm verknüpfte Farbe.
colorPalette: [
{ id: 'brand', name: 'Brand', value: { hex: '#00a0e3', model: 'cmyk', cmyk: { c: 100, m: 0, y: 0, k: 0 } } },
],#Preflight
interface PrintPreflightConfig {
enabled?: boolean;
minImageResolution?: number; // ppi at the printed size.
criticalImageResolution?: number;
minRuleWidth?: Dimension;
smallTextSize?: Dimension;
safeZone?: Dimension;
bleedSnap?: Dimension;
checkFonts?: boolean;
}| Eigenschaft | Typ | Standard | Beschreibung |
|---|---|---|---|
enabled | boolean | true | Führt die Prüfungen aus. |
minImageResolution | number | 300 | Eine platzierte Bitmap, die in ihrer Druckgröße, Beschnitt eingerechnet, unter so vielen Pixeln pro Zoll liegt, erhält eine Warnung: Abbildungen, Bilder in Tabellenzellen, Gestaltungsbilder, Comic-Panels. Eine Bitmap ohne eigene Auflösung druckt in ihrer natürlichen Größe mit page.dpi; eine Seite, die mit 150 dpi gesetzt ist, druckt jedes solche Bild also mit 150 ppi. Eine Bitmap mit Auflösung (bitmap.resolution, layout.bitmapResolution) druckt in ihrer natürlichen Größe mit dieser Auflösung. |
criticalImageResolution | number | 150 | Darunter ist die Warnung kritisch. Nie höher als minImageResolution. |
minRuleWidth | Dimension | 0.25pt | Linien, Rahmen, Spaltenlinien, Tabellenlinien und Rahmen von Comic-Panels, die dünner sind. |
smallTextSize | Dimension | 9pt | Text unter dieser Größe, der in mehr als einer Druckfarbe gesetzt ist (eine Prozessfarbe, Tiefschwarz): Er verschwimmt, wenn sich die Platten verschieben. Schwarzer Text nur in K zählt nie. |
safeZone | Dimension | 5mm | Text, der näher am Endformat steht, wo das Schneidemesser ihn treffen kann. |
bleedSnap | Dimension | 3mm | Ein Kasten oder Bild, das so nahe am Endformat endet, ohne den Anschnitt zu erreichen: Ziehen Sie es in den Anschnitt oder nach innen. |
checkFonts | boolean | true | Meldet Schriften, die ein platziertes PDF nicht einbettet (die Sandbox untersucht jede Druckvorlage mit inspectPrintMaster). Postext bettet jede Schrift ein, die es setzt. |
preflightDocument(doc, options) führt die Prüfungen an einem gesetzten Dokument aus und gibt eine Liste von Befunden zurück, jeder mit einer kind, einer severity ('critical', 'warning' oder 'info'), dem buchweiten pageIndex, dem betroffenen rect (Seitenpixel) und, wenn das Element einen hat, seinem Quellbereich. Die Arten sind lowImageResolution, declaredPixelsMismatch, rgbImage, thinRule, smallProcessText, inkLimit, safeZone und nearTrim. Ohne transform zählt eine neutrale Farbe als eine Druckfarbe und jede andere als drei, und der Farbauftrag wird nicht geprüft; mit einem sind Zählung und Farbauftrag exakt. Die Auflösung eines Bildes wird aus den Pixeln berechnet, die seine Ressource angibt, oder aus denen der Datei selbst, wenn imageSize(fileId) sie liefert (bitmapInfo auf den Bytes oder das dekodierte Bild): Eine Angabe, die mehr als ein Pixel von der Datei abweicht, wird einmal als declaredPixelsMismatch gemeldet, als Warnung, wenn sie mehr Pixel behauptet, als die Datei hat. placedImageResolutions(doc, { resources, imageSize }) listet jede platzierte Bitmap mit ihrer effektiven ppi-Zahl auf, ob der Preflight an ist oder nicht.
import { bitmapInfo, outputTransform, parseIccProfile, preflightDocument, resolvePrintConfig } from 'postext';
import { inspectPrintMaster } from 'postext-pdf';
const print = resolvePrintConfig(config.print);
const transform = outputTransform(parseIccProfile(fogra51Bytes), { intent: print.renderingIntent });
const issues = preflightDocument(doc, {
print,
transform,
resources, // pixel sizes of the bitmaps
imageSize: (fileId) => bitmapInfo(bytesOf(fileId)), // the files' real pixels
imageColor: (fileId) => colourOf(fileId), // 'rgb' | 'cmyk' | 'gray', from the file
});
if (issues.some((i) => i.severity === 'critical')) process.exit(1);
const master = await inspectPrintMaster(masterBytes);
// => { nonEmbeddedFonts: ['Helvetica'], rgb: true, transparency: false }#Druckvorschau
Eine Canvas-Seite lässt sich so malen, wie sie drucken wird. createPrintPreview(transform, print, { paper, dpi, grayscale }) baut den Softproof einer Einrichtung: Jedes Pixel wird über das Profil separiert (neutrale Farben nur in K, wie im PDF) und auf dem Bildschirm zurückgezeigt, auf dem eigenen Weiß des Papiers, wenn paper true ist; schwarze Flächen, die groß genug für Tiefschwarz sind, erscheinen als Tiefschwarz. Mit grayscale ist der Proof ein Graustufendruck – ein in Graustufen gezwungenes PDF druckt die Luminanz jeder Farbe allein in Schwarz, ohne Tiefschwarz. Übergeben Sie ihn renderPageToCanvas als printPreview. Für eine Arbeitsansicht statt eines Proofs fügt guides die Linien für Endformat, Anschnitt und Sicherheitsabstand hinzu, und marksFor umrandet Bereiche einer Seite (die rects des Preflights); die Sandbox lässt beides weg, ihre Vorschau zeigt also nur den Druck. postext-folio nimmt dasselbe Objekt als printPreview; geben Sie dem Buch bei paper: true währenddessen einen neutralen Papierton (folio.paper.shade), sonst wird das Papier doppelt getönt.
import { createPrintPreview, renderPageToCanvas } from 'postext';
const preview = createPrintPreview(transform, print, { paper: true, dpi: doc.config.page.dpi });
renderPageToCanvas(page, doc, canvas, {
printPreview: { ...preview, guides: { safeZonePx: 59 }, marksFor: () => issues.map((i) => i.rect!).filter(Boolean) },
});#Farb-Engine
Das Farbmanagement, das postext verwendet, wird für Ihre eigenen Werkzeuge exportiert. Es liest ICC-Profile der Versionen 2 und 4 (Matrix/TRC und die Lookup-Tabellen mft1, mft2, mAB, mBA) in reinem TypeScript, ohne WebAssembly.
parseIccProfile(bytes)liest ein Profil;deviceChannels(profile)gibt seine Kanalzahl an.outputTransform(profile, { intent, blackPointCompensation, preserveNeutrals })gibtfromRgb(r, g, b)(sRGB 0..1 → CMYK 0..1),toLab(cmyk, paper?)undproof(cmyk, paper?)(CMYK → Bildschirm-sRGB) zurück.cmykToLab,labToCmyk,srgbToLab,labToSrgb,deltaEundtotalAreaCoveragesind die einzelnen Umrechnungen;buildRgbLut/sampleRgbLuterzeugen und lesen dichte Lookup-Tabellen für die Arbeit an Pixeln.OUTPUT_PROFILES,outputProfileInfo(id)undloadOutputProfile(id, baseUrl?)liefern den Katalog;srgbProfileBytes()schreibt das sRGB-Profil, mit dem PDF/X-4 RGB kennzeichnet;authoredCmykColors(config)listet die Farben auf, die eine Konfiguration in CMYK angelegt hat.
Resolver und Stripper entsprechen den anderen Abschnitten: resolvePrintConfig, stripPrintDefaults und profileInkLimit(config) (der Grenzwert des Profils, das eine Konfiguration nennt, vor jeder Überschreibung durch inkLimit), mit DEFAULT_PRINT_CONFIG, DEFAULT_PRINT_BLACK_CONFIG, DEFAULT_PRINT_PREFLIGHT_CONFIG und DEFAULT_RICH_BLACK.
#Kontrastprüfung (Konfiguration)
Die Eigenschaft contrast stellt die Prüfung ein, die sagt, ob sich der Text eines Buches lesen lässt: jede Textfarbe gegen den Untergrund, auf dem sie steht. Das Layout ignoriert sie, ihre Änderung verschiebt also nie eine Zeile. contrastDocument liest sie beim Prüfen eines gesetzten Dokuments, die Sandbox listet die Befunde unter Prüfungen auf und zeigt das Verhältnis neben jedem Farbfeld, und postext check gibt sie aus.
interface ContrastConfig {
enabled?: boolean;
level?: 'AA' | 'AAA';
mode?: 'auto' | 'screen' | 'print' | 'both';
reversedText?: {
enabled?: boolean;
minSize?: Dimension;
minFineSize?: Dimension;
lightWeight?: number;
};
}| Eigenschaft | Typ | Standard | Beschreibung |
|---|---|---|---|
enabled | boolean | true | Führt die Prüfung aus. |
level | 'AA' | 'AAA' | 'AA' | Die WCAG-2-Stufe, an der die Verhältnisse gemessen werden. Siehe Schwellenwerte. |
mode | string | 'auto' | Die geprüfte Wiedergabe: 'screen', 'print', 'both' oder 'auto', das immer den Bildschirm prüft und zusätzlich den Druck bei einem Buch, das für den Druck eingerichtet ist (ein PDF/X-Standard in print.standard, ein CMYK-PDF in pdfGeneration oder Schnittmarken in page.cutLines). |
reversedText.enabled | boolean | true | Meldet negativen Text in der Druckprüfung. |
reversedText.minSize | Dimension | 8pt | Negativer Text unter dieser Größe wird gemeldet. |
reversedText.minFineSize | Dimension | 12pt | Dasselbe für Kursive und leichte Schnitte, deren Striche dünner sind. |
reversedText.lightWeight | number | 300 | Eine Schriftstärke bis einschließlich dieser gilt als leicht. |
Ein level oder ein mode, das anders geschrieben ist, wird als Standardwert gelesen und als unbekannter Einstellungswert gemeldet (siehe Konfigurationswarnungen).
#Schwellenwerte
Das Verhältnis, das ein Text erreichen muss, richtet sich wie in WCAG 2 nach Größe und Schriftstärke.
| Stufe | Text | Großer Text |
|---|---|---|
AA | 4,5:1 | 3:1 |
AAA | 7:1 | 4,5:1 |
Großer Text hat 18 pt und mehr oder 14 pt und mehr bei einer Schriftstärke ab 700. Die Größen sind die gedruckten, in Punkt. Ein hoch- oder tiefgestelltes Zeichen wird in der Größe des Texts beurteilt, zu dem es gehört.
#Bildschirm und Druck
Postext setzt dieselben Seiten für einen Bildschirm und für eine Druckmaschine, und eine Farbe wirkt auf beiden nicht gleich.
- Bildschirm ist das WCAG-2-Kontrastverhältnis der sRGB-Farben,
(L1 + 0.05) / (L2 + 0.05)über ihre relativen Luminanzen: das, was Canvas, HTML-Betrachter, ein EPUB und ein RGB-PDF zeigen. - Druck ist dieselbe Formel über die Luminanz, die jede Farbe auf Papier hat. Die Farbe wird über das Ausgabeprofil des Auftrags separiert (eine in CMYK angelegte behält ihre Werte), die Separation wird über das Profil zurückgelesen, und ihre Luminanz wird relativ zum unbedruckten Papier genommen, das das Weiß einer gedruckten Seite ist, so wie das Weiß des Displays das Weiß eines Bildschirms ist. Druckfarbe ist nie ein vollkommenes Schwarz: Volles Schwarz auf Weiß erreicht etwa 14:1 auf gestrichenem Papier (FOGRA39, FOGRA51), 8:1 auf ungestrichenem Papier (FOGRA47, FOGRA52) und 5:1 auf Zeitungspapier (IFRA26, SNAP), wo ein Bildschirm 21:1 liefert. Ein Grau, das am Bildschirm besteht, kann auf Papier durchfallen:
#767676auf Weiß hat am Bildschirm 4,54:1 und auf gestrichenem Papier etwa 3,3:1.
Das Druckverhältnis braucht die Transformation des Ausgabeprofils (options.transform, gebaut mit outputTransform). Ohne sie wird für den Druck nur der negative Text geprüft.
#Negativer Text
Heller Text, der aus einem bedruckten Untergrund ausgespart ist, läuft im Druck zu, wenn er klein ist oder seine Striche dünn sind: Die Farbe des Untergrunds breitet sich in die Buchstaben aus, und ein Untergrund aus mehreren Druckfarben hängt zudem davon ab, dass die Platten im Passer bleiben. Das Verhältnis zeigt das nicht, denn Weiß auf Dunkelblau liegt über 10:1. Die Druckprüfung meldet solchen Text eigens (reversedText), wenn er unter minSize liegt oder unter minFineSize, während er kursiv ist oder eine Schriftstärke von lightWeight oder weniger hat. Jeder Befund nennt, aus wie vielen der vier Druckfarben der Untergrund aufgebaut ist.
#Was gelesen wird
Die Prüfung liest die Zeilen jedes Blocks mit ihren Inline-Farben (fett, kursiv, Verweise, Chips), Listenzeichen, Initialen, Legenden, Anmerkungen und Tabellenzellen sowie den Text der Gestaltungsplätze: Kolumnentitel, Auftakte, Überschriftengestaltungen, Kastentitel. Der Untergrund ist die oberste Fläche unter dem Text: ein Gestaltungskasten, ein Kasten, ein Legendenbalken, eine Tabellenzelle, ein Chip, sonst die Seitenfarbe (page.backgroundColor oder das Papier, das die Palette eines Teils seinen Seiten gibt). Eine durchscheinende Farbe wird mit dem verrechnet, was unter ihr liegt. Text über einem Bild wird übersprungen, weil sein Untergrund nicht einfarbig ist, ebenso Comic-Lettering, Ruby-Lesungen und Formeln.
#Die Prüfung ausführen
contrastDocument(doc, options) gibt die Befunde eines gesetzten Dokuments zurück, das niedrigste Verhältnis zuerst. Jeder hat den buchweiten pageIndex, das rect auf dem Bogen (Seitenpixel) und den Quellbereich seines ersten Vorkommens, die beiden Farben, wie sie gemalt sind (color, background), die kleinste sizePt, in der er gesetzt ist, mit weight und italic, eine role ('body', 'heading', 'caption', 'table', 'runningHead', 'design', 'chip' oder 'marker'), den text des ersten Abschnitts und die Anzahl count der so gesetzten Abschnitte. Ein Paar wird je Schwellenwert einmal gemeldet, wie viele Zeilen es auch verwenden.
lowContrastergänztlevel,large,required, das Verhältnis in jeder geprüften Wiedergabe (screen,print) undfailing, die Wiedergaben unterrequired.reversedTextergänztreasons('small','italic','light'),minimumPtundinks.
Die Optionen sind contrast (die aufgelösten Einstellungen, wenn es nicht die des Dokuments sind), media (die Wiedergaben, unabhängig von mode) und transform.
import { contrastDocument, outputTransform, parseIccProfile } from 'postext';
const transform = outputTransform(parseIccProfile(fogra51Bytes));
for (const issue of contrastDocument(doc, { transform })) {
if (issue.kind === 'lowContrast') {
console.log(`${issue.color} on ${issue.background}: ${issue.screen}:1, ${issue.level} asks for ${issue.required}:1`);
}
}contrastPairs(doc, options) gibt jedes Paar aus Text und Untergrund zurück, das das Dokument setzt, ob es besteht oder nicht, mit seinem Verhältnis screen, seinem Verhältnis print, wenn die Transformation übergeben wird, dem geforderten Verhältnis required und den Farben, wie die Konfiguration sie schreibt (textColor, groundColor): das, was ein Gestaltungswerkzeug neben einem Farbfeld anzeigt. Sie läuft unabhängig von enabled.
Die Maße werden für Ihre eigenen Werkzeuge exportiert:
contrastRatio(a, b)undrelativeLuminance(color)liefern das WCAG-2-Verhältnis und die Luminanz von sRGB-Farben.isLargeText(sizePt, weight)undcontrastThreshold(level, large)liefern den Schwellenwert einer Größe und Schriftstärke.blendColors(top, under)liefert eine durchscheinende Farbe über einer anderen als#rrggbb.printContrastRatio(a, b, context),printLuminance(color, context)undprintSeparation(color, context)liefern dasselbe auf Papier. Der Kontext enthält dietransformund alsauthoreddas Ergebnis vonauthoredCmykColors(config).contrastMedia(doc.config, contrast)liefert die Wiedergaben, zu denenmodefür ein Dokument aufgelöst wird.
Resolver und Stripper entsprechen den anderen Abschnitten: resolveContrastConfig und stripContrastDefaults, mit DEFAULT_CONTRAST_CONFIG, DEFAULT_CONTRAST_REVERSED_TEXT_CONFIG, CONTRAST_LEVELS und CONTRAST_MODES.
#Folio-Betrachter (Konfiguration)
Die Eigenschaft folio legt fest, wie der Folio-Betrachter (postext-folio) das gedruckte Buch in 3D zeigt: den Blickwinkel, das Papier, die Bindung, die Unterlage, auf der das Buch liegt, und das Licht. Das Layout ignoriert sie, ebenso die Ausgaben Canvas, HTML und PDF. buildDocument trägt die aufgelösten Einstellungen im VDT als doc.config.folio, wenn die Konfiguration welche setzt; ein Dokument ohne sie behält also seinen Layout-Hash.
interface FolioConfig {
tilt?: number; // Degrees from straight above, 0–70.
yaw?: number; // Degrees round the book, −180–180.
paper?: {
type?: 'uncoated' | 'bookWove' | 'coatedMatte' | 'coatedSilk' | 'coatedGloss'
| 'bible' | 'newsprint' | 'cardStock' | 'board';
grammage?: number; // g/m²
bulk?: number; // cm³/g; caliper µm = grammage × bulk
finish?: 'auto' | 'uncoated' | 'matte' | 'silk' | 'gloss';
texture?: 'auto' | 'smooth' | 'vellum' | 'wove' | 'laid' | 'linen' | 'felt';
textureStrength?: number; // 0–2
shade?: ColorValue;
showThrough?: boolean;
};
binding?: {
type?: 'hardcover' | 'paperback' | 'sewn' | 'layflat' | 'saddleStitch' | 'folded';
cover?: 'case' | 'pages';
coverMaterial?: 'auto' | 'cloth' | 'paper' | 'leather';
coverColor?: ColorValue;
spineImage?: string; // resource id
};
surface?: {
type?: 'oak' | 'walnut' | 'linen' | 'felt' | 'leather' | 'marble' | 'plain' | 'none';
color?: ColorValue;
};
lighting?: {
environment?: 'studio' | 'daylight' | 'lamp' | 'overcast' | 'night';
intensity?: number; // 0.25–2
shadows?: boolean;
};
}| Eigenschaft | Typ | Standard | Beschreibung |
|---|---|---|---|
tilt | number | 22 | Neigung des Blicks gegenüber der Senkrechten von oben, in Grad, begrenzt auf 0–70. Bei 0 sieht man das aufgeschlagene Buch flach von oben; ein größerer Winkel rückt den Fuß der Seiten näher und zeigt die Tiefe des Buchblocks. |
yaw | number | 0 | Wie weit der Blick um das Buch gedreht ist, in Grad, auf −180–180 gebracht. Bei 0 sieht man das Buch vom Fuß seiner Seiten her; ein positiver Winkel führt das Auge nach rechts herum, ein negativer nach links. Zusammen mit tilt ist es die Ansicht, mit der der Betrachter öffnet und zu der resetView() sanft zurückkehrt. |
paper.type | FolioPaperType | 'uncoated'; 'newsprint' bei einem Zeitungsformat | Die Papiersorte. Sie liefert die Standardwerte der fünf Felder darunter (siehe die Tabelle der Sorten). cardStock ist Umschlagkarton; board ist starre Pappe wie in einem Pappbilderbuch, und ihre Blätter wenden sich, ohne sich zu biegen. |
paper.grammage | number | der der Sorte | Flächengewicht in Gramm pro Quadratmeter, 20–2500. Schwereres Papier ist dicker, steifer und undurchsichtiger: Ein Blatt biegt sich in einem weiteren Bogen und zeigt weniger von der Rückseite. |
paper.bulk | number | der der Sorte | Dicke je Gewichtseinheit (Volumen) in cm³/g, 0,5–3. Die Dicke eines Blattes in Mikrometern ist Flächengewicht × Volumen, und die Dicke des Buchblocks ergibt sich daraus und aus der Seitenzahl. |
paper.finish | FolioPaperFinish | 'auto' | Ungestrichen (Faser, kein Glanz) oder gestrichen und satiniert zu matt, seidenmatt (ein sanfter Glanz) oder glänzend. Eine glänzende Seite spiegelt in Folio das Blatt, das sich über ihr wendet. 'auto' übernimmt den Wert der Sorte. |
paper.texture | FolioPaperTexture | 'auto' | Das Relief der Oberfläche: smooth (satiniert), vellum (eine feine Körnung), wove (die gleichmäßige Struktur der meisten Buchpapiere, auf einem gewebten Sieb gebildet), laid (dichte Rippen, gekreuzt von weiter auseinanderliegenden Stegen, vom Egoutteur hinterlassen), linen (eine geprägte Leinenstruktur), felt (unregelmäßige Filzmarkierungen). 'auto' übernimmt den Wert der Sorte. |
paper.textureStrength | number | 1 | Wie stark die Struktur im Licht hervortritt, 0–2. |
paper.shade | ColorValue | der der Sorte | Die Farbe des Papiers vor dem Druck (weiß, naturweiß, chamois). Die Seiten werden darauf gedruckt. |
paper.showThrough | boolean | true | Die Rückseite einer Seite scheint durch dünnes Papier schwach durch. Nach Dünndruckpapier zeigt Zeitungspapier sie am stärksten: Seine Druckfarbe zieht in den Bogen ein. |
binding.type | FolioBindingType | 'hardcover'; 'folded' bei einem Zeitungsformat | hardcover: Hardcover mit Buchdecke, die Deckel etwas größer als die Seiten. paperback: Klebebindung (gefräst und geleimt), öffnet sich weniger flach. sewn: ein Softcover mit fadengehefteten Lagen. layflat: öffnet sich flach, ohne Senke am Bund. saddleStitch: gefalzte Bogen, durch den Falz geheftet, wie bei einer Zeitschrift oder Broschüre; kein flacher Rücken. folded (seit postext 1.18): eine Zeitung, einmal gefalzte Bogen, ineinandergelegt, ohne dass etwas sie hält; keine Heftklammern, kein Rücken und kein Deckel, und die erste Seite ist die Titelseite. Ein Abschnitt :::paper mit einem shade druckt einen Zeitungsteil, etwa den Wirtschaftsteil, auf lachsfarbenem Zeitungspapier. |
binding.cover | FolioCoverSource | 'case' | Die Umschläge. 'case' zeichnet eine Buchdecke um die Seiten. 'pages' nimmt die erste Seite des Buches als Vorderdeckel und seine letzte Seite, wenn sie eine linke Seite ist, als Rückdeckel: Das Buch liegt geschlossen, bis der Umschlag umgeschlagen wird, die Deckel wenden sich steif (bei einer Rückstichheftung ist der Umschlag ein Bogen, etwas schwerer als die Seiten, und wendet sich wie sie), und es wird keine Buchdecke gezeichnet. |
binding.coverMaterial | FolioCoverMaterial | 'auto' | 'auto' ist Leinen bei einem Hardcover und Karton ('paper') bei den anderen Bindungen. |
binding.coverColor | ColorValue | Dunkelblau (#2c3e57) | Die Farbe des Bezugsmaterials. |
binding.spineImage | string | keiner | Die ID einer Bitmap- oder SVG-Ressource, die auf den Rücken gedruckt wird: der Rücken, wie man ihn beim stehenden Buch sieht, Kopf oben und der Vorderdeckel rechts. Sie wird zentriert so eingepasst, dass sie den Rücken bedeckt. Bei Rückstichheftung und bei gefalzter Bindung ohne Wirkung. |
surface.type | FolioSurfaceType | 'oak' | Worauf das Buch liegt. 'none' lässt den Hintergrund des Hosts stehen. |
surface.color | ColorValue | keiner | Tönt die Unterlage; bei 'plain' ist es die Farbe der Unterlage. |
lighting.environment | FolioEnvironment | 'studio' | Die Umgebung, die gestrichenes und glänzendes Papier spiegeln, zusammen mit dem Hauptlicht, das die Schatten wirft. |
lighting.intensity | number | 1 | Belichtung, 0,25–2. |
lighting.shadows | boolean | true | Vom Hauptlicht geworfene Schatten. |
Die Sorten und die Werte, die sie liefern (FOLIO_PAPER_STOCKS), typisch für die Datenblätter der Papierfabriken:
| Sorte | Flächengewicht | Volumen | Dicke | Oberfläche | Struktur | Papierton |
|---|---|---|---|---|---|---|
uncoated (holzfreies Offsetpapier) | 90 g/m² | 1,25 | 113 µm | ungestrichen | Velin | #fcfbf8 |
bookWove (chamois, hohes Volumen) | 80 g/m² | 1,6 | 128 µm | ungestrichen | Velin | #f6efdc |
coatedMatte | 115 g/m² | 1,0 | 115 µm | matt | glatt | #fdfdfc |
coatedSilk | 115 g/m² | 0,9 | 104 µm | seidenmatt | glatt | #ffffff |
coatedGloss | 115 g/m² | 0,8 | 92 µm | glänzend | glatt | #ffffff |
bible | 40 g/m² | 1,1 | 44 µm | ungestrichen | Vellum | #f9f6ee |
newsprint | 48 g/m² | 1,5 | 72 µm | ungestrichen | Velin | #ebe7dc |
cardStock | 250 g/m² | 1,2 | 300 µm | ungestrichen | Vellum | #fbfaf6 |
board | 1250 g/m² | 1,6 | 2000 µm | seidenmatt | glatt | #ffffff |
Ein Roman auf chamoisfarbenem Werkdruckpapier, als Paperback gebunden, auf einem Nussbaumschreibtisch unter einer Leselampe:
folio: {
paper: { type: 'bookWove' },
binding: { type: 'paperback', coverColor: { hex: '#8a2b1f', model: 'hex' } },
surface: { type: 'walnut' },
lighting: { environment: 'lamp' },
}Eine Seite in einem Zeitungsformat (page.sizePreset 'broadsheet', 'berliner', 'tabloid' oder 'compact') wird als Zeitung gezeigt, wenn die Konfiguration weder Sorte noch Bindung nennt: Papier newsprint und Bindung folded (seit postext 1.18). Eine Sorte oder Bindung, die die Konfiguration nennt, bleibt erhalten; paper: { type: 'uncoated' } druckt ein Tabloid also auf Offsetpapier. Papierfelder, die ohne Sorte gesetzt sind (ein grammage, ein shade), gelten für das Zeitungspapier. Resolver und Stripper nehmen das Format als zweites Argument, und folioForTrim(folio, sizePreset) schreibt die beiden Standardwerte in die Konfiguration:
resolveFolioConfig({ tilt: 30 }, 'tabloid');
// => { tilt: 30, paper: { type: 'newsprint', grammage: 48, bulk: 1.5, … }, binding: { type: 'folded', coverMaterial: 'paper', … }, … }
stripFolioDefaults({ paper: { type: 'newsprint' }, binding: { type: 'folded' } }, 'tabloid');
// => undefinedDie Farben folgen Palettenverknüpfungen wie jede andere Farbe der Konfiguration (paletteId). Resolver und Stripper entsprechen den anderen Abschnitten; der Stripper entfernt Papierwerte, die denen der gewählten Sorte gleichen:
import { FOLIO_PAPER_STOCKS, DEFAULT_FOLIO_CONFIG, resolveFolioConfig, stripFolioDefaults } from 'postext';
resolveFolioConfig({ paper: { type: 'bible' } }).paper;
// => { type: 'bible', grammage: 40, bulk: 1.1, finish: 'uncoated', texture: 'vellum', textureStrength: 1, shade: { hex: '#f9f6ee', … }, showThrough: true }
stripFolioDefaults({ paper: { type: 'bible', grammage: 40 } });
// => { paper: { type: 'bible' } }In der Sandbox bilden diese Einstellungen die Gruppe Folio des Bedienfelds Gestaltung (Gestaltung → Folio → Folio-Betrachter (3D)), und der Tab Folio zeigt Änderungen sofort, ohne das Buch neu zu setzen. Zum Betrachter selbst siehe Ein 3D-Buch, und zu einer Seitenfolge auf einer anderen Papiersorte Dokumentformat › :::paper.
#Debug
Die Eigenschaft debug fasst zwei Arten von Hilfen beim Schreiben zusammen: visuelle Überlagerungen, die den Quelltext und das gesetzte Layout synchron halten, und eine Reihe von Warnungen, die typografische oder strukturelle Probleme im Bedienfeld Prüfungen der Sandbox anzeigen. Keine von beiden wirkt sich auf die exportierte Ausgabe aus.
| Eigenschaft | Typ | Beschreibung |
|---|---|---|
cursorSync | SyncIndicatorConfig | In das gesetzte Layout gespiegelte Einfügemarke – siehe Visuelle Überlagerungen. |
selectionSync | SyncIndicatorConfig | Auf der Seite hervorgehobene Auswahl im Quelltext – siehe Visuelle Überlagerungen. |
looseLineHighlight | LooseLineHighlightConfig | Überlagerung auf zu lockeren Zeilen im Blocksatz – siehe Visuelle Überlagerungen. |
pageNegative | | Kontrastreiches Negativ der Seite – siehe Visuelle Überlagerungen. |
warnings | WarningsToggleConfig | Ein boolescher Wert je Art von Warnung, die der Editor beim Schreiben anzeigt – siehe Warnungen. |
#Visuelle Überlagerungen
| Eigenschaft | Typ | Standard | Beschreibung |
|---|---|---|---|
cursorSync.enabled | boolean | true | Zeigt im gesetzten Layout eine Einfügemarke, die die Cursorposition im Quelltext spiegelt. |
cursorSync.color | ColorValue | #2563eb | Farbe dieser Einfügemarke. |
selectionSync.enabled | boolean | true | Hebt den gesetzten Bereich hervor, der der Auswahl im Quelltext entspricht. |
selectionSync.color | ColorValue | #fde04780 | Farbe der Hervorhebung – standardmäßig ein durchscheinendes Gelb. |
looseLineHighlight.enabled | boolean | false | Legt eine Überlagerung auf Zeilen im Blocksatz, deren Wortabstand das threshold-Fache der normalen Wortzwischenraumbreite übersteigt. |
looseLineHighlight.color | ColorValue | #ff000040 | Farbe dieser Überlagerung. |
looseLineHighlight.threshold | number | 3 | Vielfaches der normalen Wortzwischenraumbreite, ab dem eine Zeile im Blocksatz als zu locker gilt. Die Warnung looseLines verwendet denselben Schwellenwert. Eine Zeile im Blocksatz, deren Zwischenräume über das Dreifache hinaus gedehnt würden, wird im Flattersatz gesetzt; beim Standardwert finden Überlagerung und Warnung im laufenden Text daher fast nichts. Senken Sie den Wert (1,5 oder 2), um Zeilen zu sehen, die locker, aber noch im Blocksatz sind. |
pageNegative.enabled | boolean | false | Legt ein kontrastreiches Negativ über die Seite – nützlich, um die Gesamtform einer Doppelseite (Textdichte, Spaltenausgleich, Weißraum) auf einen Blick zu prüfen, ohne von den Einzelheiten der Glyphen abgelenkt zu werden. |
Jede SyncIndicatorConfig ist { enabled: boolean; color?: ColorValue }. LooseLineHighlightConfig ist { enabled: boolean; color?: ColorValue; threshold?: number }. pageNegative ist ein minimaler Schalter { enabled: boolean }.
debug: {
cursorSync: { enabled: true, color: { hex: '#ff0066', model: 'hex' } },
selectionSync: { enabled: false, color: { hex: '#fde04780', model: 'hex' } },
looseLineHighlight: { enabled: true, color: { hex: '#ff000040', model: 'hex' }, threshold: 3 },
pageNegative: { enabled: true },
}Diese Überlagerungen zeichnet die Sandbox über ihre Canvas-Vorschau. Sie gehören nicht zur Seite: renderPage, die HTML-Ausgabe und das PDF malen sie nie.
#Zu lockere Zeilen im eigenen Canvas
Die Engine exportiert die Hervorhebung zu lockerer Zeilen als zwei Hilfsfunktionen für eine Seite, die Sie selbst malen:
import { buildDocument, renderPageToCanvas, drawLooseLines, findLooseLines } from 'postext';
const doc = buildDocument(content, config);
const canvas = document.querySelector('canvas')!;
renderPageToCanvas(doc.pages[0], doc, canvas, { scale: 0.5 });
drawLooseLines(canvas.getContext('2d')!, doc.pages[0], doc, { threshold: 2.5 });
// The same lines as data: a report, an SVG overlay, a count per page.
for (const { ratio, line, block } of findLooseLines(doc, { threshold: 2.5 })) {
console.log(`page ${block.pageIndex + 1}: ${ratio.toFixed(2)}× — ${line.text}`);
}findLooseLines(doc, { threshold?, pageIndex? })gibt in Lesereihenfolge jede Zeile im Blocksatz zurück, deren Wortabstandthresholdübersteigt:{ block, line, ratio, x, y, width, height }.ratioistlineWordSpacing(line): der Abstand so, wieminWordSpacingundmaxWordSpacingihn begrenzen (justifiedSpaceLimitRatio, wenn die Zeile Zwischenräume eines anderen Schnitts enthält, sonstjustifiedSpaceRatio); eine Zeile, die an der Grenze gesetzt ist und einen fetten Zwischenraum enthält, wird bei einem Schwellenwert gleichmaxWordSpacingalso nicht gemeldet. Das Rechteck in Seitenpixeln ist der Streifen, den die Hervorhebung abdeckt: die volle Breite des Blocks über die Zeile hinweg. Es sind die Zeilen, die die Sandbox hervorhebt und in ihrem Bedienfeld Prüfungen alslooseLinemeldet.drawLooseLines(ctx, page, doc, { threshold?, color? })füllt diese Streifen für eine Seite und gibt die gemalten Zeilen zurück. Sie zeichnet in Seitenpixeln unter der aktuellen Transformation des Kontexts; rufen Sie sie also direkt nachrenderPageoderrenderPageToCanvasauf demselben Canvas auf: Beide hinterlassen den Kontext auf die Seite skaliert.colorist ein beliebiger Füllstil des Canvas.- Standardwerte. Beide Hilfsfunktionen verwenden den Standardschwellenwert (3) und die Standardfarbe (
#ff000040), nichtdebug.looseLineHighlightdes Dokuments: Diese Einstellung gehört der Sandbox. Um einer Konfiguration zu folgen, übergeben SieresolveDebugConfig(config.debug).looseLineHighlight.thresholdund.color.hex.
#Warnungen
debug.warnings legt fest, welche Probleme beim Schreiben im Bedienfeld Prüfungen der Sandbox erscheinen (bearbeitet unter Gestaltung → Erweitert → Warnungen). Jeder Schlüssel ist ein unabhängiger boolescher Schalter; setzen Sie einen auf false, um genau diese Warnung stummzuschalten, ohne die anderen abzuschalten.
Diese Schalter filtern nur das Bedienfeld der Sandbox. Die Warnungen, die die Engine selbst festhält – Kästen, die ihre Spalte überlaufen, in doc.warnings; unbekannte Ressourcen-IDs, Direktiven, Einbettungen und Formatkennungen sowie unregelmäßige Tabellenraster in doc.contentWarnings –, sind unabhängig von den Schaltern vorhanden, und die Renderer melden Bilder, die sie als Platzhalter malen; siehe Warnungen im Dokument.
interface WarningsToggleConfig {
missingFont?: boolean;
looseLines?: boolean;
headingHierarchy?: boolean;
consecutiveHeadings?: boolean;
listAfterHeading?: boolean;
designIssues?: boolean;
}| Eigenschaft | Typ | Standard | Beschreibung |
|---|---|---|---|
missingFont | boolean | true | Meldet, wenn eine von der Konfiguration angeforderte Schrift im Browser nicht geladen werden konnte. Fängt Tippfehler in fontFamily und fehlende Pakete @fontsource/... früh ab, bevor sie in der gesetzten Ausgabe als stille Ersetzung durch eine Ersatzschrift auftauchen. |
looseLines | boolean | true | Meldet Zeilen im Blocksatz, deren Wortabstand debug.looseLineHighlight.threshold übersteigt. Ergänzt die Überlagerung: Die Warnung zählt sie im Bedienfeld auf, die Überlagerung zeigt sie an Ort und Stelle. |
headingHierarchy | boolean | true | Meldet Überschriftenebenen, die eine Stufe überspringen – z. B. eine H1, auf die direkt eine H3 folgt. Solche Lücken in der Gliederung deuten meist auf einen Tippfehler in der Überschriftentiefe oder auf ein Missverständnis der Gliederung des Dokuments hin. |
consecutiveHeadings | boolean | false | Meldet, wenn auf eine Überschrift unmittelbar eine weitere folgt, ohne Absatz oder Liste dazwischen. Standardmäßig aus, weil gestapelte Überschriften in vielen Vorlagen berechtigt sind (Titel + Untertitel, Kapitel + Motto); schalten Sie sie für Manuskripte ein, in denen jede Überschrift Fließtext einleiten soll. |
listAfterHeading | boolean | false | Meldet, wenn eine Liste unmittelbar nach einer Überschrift beginnt, ohne einleitenden Absatz. Standardmäßig aus, weil Nachschlagewerke das ständig tun; schalten Sie sie für erzählende Texte ein, in denen jede Liste von Fließtext eingerahmt sein soll. |
designIssues | boolean | true | Meldet Integritätsprobleme in Gestaltungsplätzen – Kopfzeilen, Fußzeilen, der Teilauftakt und die leere linke Seite danach, die Zeilen der Teile im Inhaltsverzeichnis, die Plätze für erweiterte Überschriftengestaltung sowie Gestaltung und Abschnitts-Kolumnentitel jedes Überschriftenformats. Erfasst zyklische Ankerketten und ins Leere zeigende Ankerverweise (ein Element, das an einer #id verankert ist, die es nicht mehr gibt), eine Überschrift über die ganze Seitenbreite, deren breakBefore abgeschaltet ist, und eine eingeschaltete erweiterte Gestaltung, deren Elemente nie ausgeben. |
debug: {
warnings: {
missingFont: true,
looseLines: true,
headingHierarchy: true,
consecutiveHeadings: true,
listAfterHeading: false,
designIssues: true,
},
}Daneben listet das Bedienfeld immer die Warnungen auf, die das Layout selbst auslöst (VDTDocument.warnings), etwa einen Kasten, der seine Spalte überläuft (calloutOverflow), und die Konfigurationswerte, die die Engine ersetzt hat (VDTDocument.configWarnings oder collectConfigWarnings(config); siehe Konfigurationswarnungen unten).
#Konfigurationswarnungen
Acht Fehler in der Konfiguration selbst bleiben nie stumm, und kein Schalter blendet sie aus. Die Engine scheitert an keinem davon; sie setzt einen Wert ein oder lässt die Einstellung weg und sagt es:
- Unbekanntes Zahlenformat – ein
numberFormateiner geordneten Liste, einpage.pageNumbering.formatoder eincounterFormateines Ressourcentyps, das keiner der Schreibweisen der Nummernformate entspricht. Es wird dezimal nummeriert. - Schriftliste in einer Schriftfamilie – ein
fontFamily(oder ein beliebiges…FontFamily), das eine CSS-Schriftliste enthält. Der Text wird in der ersten Familie der Liste gesetzt (siehe Eine Familie profontFamily). - Seitenspalte ohne Platz – ein
sideColumnPercenteines Layouts'oneAndHalf'(des Dokuments oder im eigenenlayouteines Überschriftenformats), das einer der Spalten weniger als 1 % der Inhaltsbreite ließe oder keine Zahl ist. Die Spalten werden beim nächstgelegenen Wert geteilt, den beide annehmen können, undusednennt ihn (sideColumnPercentClamped; siehe das Layout'oneAndHalf'). - Spaltenzahl außerhalb des Bereichs – ein
columnCounteines Layouts'multiple'(des Dokuments oder im eigenenlayouteines Überschriftenformats), das keine ganze Zahl von 3 bis 8 ist. Die Seite wird in die nächstgelegene gültige Anzahl geteilt (3 für einen Wert, der keine Zahl ist), undusednennt sie (columnCountClamped; siehe das Layout'multiple'). - Zeichenraster zu groß – ein
cjk.gridmit mehr Zeichen pro Zeile oder Zeilen pro Seite, als die Ränder Platz lassen. Das Raster wird mit dem Höchstwert gesetzt, der passt, undusednennt die Zahl (cjkGridClamped; siehe Zeichenraster). - Unbekannte Überschrifteneinstellung – ein Schlüssel, den
headings,headings.balancing, eine Überschriftenebene, ein Überschriftenformat oder ein Absatzformat nicht kennt: ein falsch geschriebenesletterSpacng, ein aus einem anderen Werkzeug entlehntestracking, einlevelin einem Überschriftenformat, einfontStyle: 'italic'in einem Absatzformat (dasitalic: trueerwartet). Ein Tabulator wird genauso geprüft (einleadersstattleader). Die Engine ignoriert ihn (bis postext 1.4 tat sie das wortlos).valueist der Schlüssel,usedist leer, undsuggestionnennt die Einstellung, der er am nächsten kommt, wenn eine nur ein oder zwei Buchstaben entfernt ist oder sich nur in Groß- und Kleinschreibung unterscheidet (unknownConfigKey). - Unbekannter Einstellungswert – eine Einstellung, die eines von wenigen Wörtern annimmt, aber ein anderes enthält, etwa
direction: 'right'(sie nimmtauto,ltroderrtl). Die Engine liest stattdessen den Standardwert, undusednennt, was daraus wurde: beidirectiondie Schreibrichtung der Dokumentsprache (unknownConfigValue). Einaligneines Tabulators, das keines seiner vier Wörter ist, wird als'start'gelesen, und eineposition, die weder Länge noch'end'noch Prozentwert ist, lässt den Tabulator weg (usedist'none'). Auch die Wörter der Comic-Einstellungen werden geprüft (Comics › Comic-Warnungen):usedist der Wert, zu dem die Einstellung aufgelöst wurde (bei einem eingebauten Format der eigene Standardwert des Sprechblasenformats), undsuggestionnennt das Wort, dem der Wert am nächsten kommt, wenn eines nahe liegt.levelundmodeder Kontrastprüfung werden genauso geprüft:usedist'AA'oder'auto'. - Zeilennummern im vertikalen Text –
lineNumbers.enabled: truein einem vertikal gesetzten Dokument (layout.writingMode: 'vertical-rl'). Vertikale Seiten erhalten keine Zeilennummern, undusedistfalse(lineNumbersUnsupported; siehe Zeilennummern). - Umfließen in vertikalem Text – ein
defaultPlacement.wrapeines Ressourcentyps in einem vertikal gesetzten Dokument. Vertikale Seiten setzen keinen Text neben eine Abbildung, undusedistnone(wrapUnsupported; siehe Dokumentformat › Textumfluss). Einwrap, das keine Seite nennt, ist ein unbekannter Einstellungswert.
Die Sandbox listet sie im Bedienfeld Prüfungen mit dem Pfad der Einstellung auf. Im Code legt buildDocument sie als configWarnings am Dokument ab (das fehlt, wenn die Konfiguration fehlerfrei ist), und collectConfigWarnings(config) gibt sie zurück, ohne etwas zu setzen:
import { buildDocument, collectConfigWarnings } from 'postext';
// Plain JavaScript: in TypeScript, 'roman' does not type-check to begin with.
const config = { bodyText: { fontFamily: 'EB Garamond, serif' }, orderedLists: { numberFormat: 'roman' } };
const doc = buildDocument({ markdown }, config);
doc.configWarnings;
// [{ kind: 'fontFamilyStack', path: 'bodyText.fontFamily', value: 'EB Garamond, serif', used: 'EB Garamond' },
// { kind: 'unknownNumberFormat', path: 'orderedLists.numberFormat', value: 'roman', used: 'arabic' }]
collectConfigWarnings(config); // the same listAuch jede verschachtelte Teilkonfiguration wird geprüft: Überschriftenformate, die Listen innerhalb von Teilen, htmlViewer.overrides, Gestaltungselemente.
formatWarning (siehe Warnungen im Dokument) beschreibt sie ebenfalls, mit dem Pfad der Einstellung voran – bodyText.fontFamily: font stack "EB Garamond, serif" — set in "EB Garamond", headingStyles[0].letterSpacng: unknown setting "letterSpacng" — ignored (did you mean "letterSpacing"?) –, sodass ein Host alle drei Listen, die ein Build zurückgibt, in einer einzigen Schleife protokollieren kann.