Eigene Layout-Engines und Text-Interception zur Layout-Zeit
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“NextPDF stellt keine austauschbare Layout-Engine-Schnittstelle bereit. Der öffentliche Layout-Extension-Vertrag ist TextPreprocessorInterface; diese Schnittstelle fängt Text zur Layout-Zeit ab. Außerdem erhalten Sie die Content-Lifecycle-Events, mit denen Sie beobachten können, was das Layout erzeugt.
Installation
Abschnitt betitelt „Installation“composer require nextpdf/core:^3Konzeptioneller Überblick
Abschnitt betitelt „Konzeptioneller Überblick“Die Layout-Pipeline ist intern. Sie umfasst Glyphen-Layout, Font-Subsetting, die Ausgabe der ToUnicode-CMap und den Strukturbaum; NextPDF erlaubt nicht, sie zu ersetzen. Stabile Byte-Ausgabe und die Konformität für getaggtes PDF beruhen auf einem einzigen kontrollierten Build.
NextPDF legt jedoch sehr wohl den Punkt vor dem Layout offen: TextPreprocessorInterface. Eine Implementierung erhält Rohtext und gibt ein segmentiertes Ergebnis zurück, bevor dieser Text in Glyphen-Layout, Font-Subsetting, die ToUnicode-CMap oder den Strukturbaum eingeht. Das ist der unterstützte Weg, um Textinhalt zu ändern, ohne die Layout-Engine anzufassen.
Der Vertrag enthält in seinem PHPDoc des Quellcodes eine harte Regel: Eine Implementierung darf nicht verändern, wie das Layout arbeitet. Sie darf keine layoutbeeinflussenden Zeichen wie Line Feed, Carriage Return oder Tab hinzufügen, und sie muss die logische Lesereihenfolge erhalten. Der Präprozessor beschreibt einen Inhaltsaustausch; Layout-Entscheidungen trifft er nicht. Halten Sie diese Regel ein, sonst zerstören Sie die stabile Ausgabe und die Barrierefreiheit.
Um das Ergebnis des Layouts zu beobachten — nicht, um es zu ändern — nutzen Sie die Content-Lifecycle-Events in Action-Trigger und Event-Listener. ContentRenderedEvent wird ausgelöst, nachdem Inhalt auf eine Seite gezeichnet wurde. FontLoadedEvent wird einmal pro Schriftfamilie und Stil ausgelöst.
API-Oberfläche
Abschnitt betitelt „API-Oberfläche“NextPDF\Contracts\TextPreprocessorInterface (stabil, seit 1.9.0):
| Methode | Rückgabe | Zweck |
|---|---|---|
process(string $text) | TextPreprocessResult | Wandelt Rohtext um, bevor er in die Render-Pipeline gelangt; gibt ein segmentiertes Ergebnis mit Redaction-Metadaten zurück. |
Das zurückgegebene NextPDF\Contracts\TextPreprocessResult ist ein eingefrorenes Value Object. Seine Konstruktorsignatur und seine öffentlichen Eigenschaften sind stabil und ändern sich nicht in einem Minor- oder Patch-Release. Neue Methoden können hinzukommen.
Codebeispiel — Schnellstart
Abschnitt betitelt „Codebeispiel — Schnellstart“Dieser kleine Präprozessor maskiert ein festes Token. Er fügt keine layoutbeeinflussenden Zeichen hinzu und bewahrt die Lesereihenfolge.
<?php
declare(strict_types=1);
use NextPDF\Contracts\TextPreprocessorInterface;use NextPDF\Contracts\TextPreprocessResult;use NextPDF\Contracts\TextSegment;
final class TokenMaskingPreprocessor implements TextPreprocessorInterface{ public function process(string $text): TextPreprocessResult { $masked = \str_replace('SECRET-TOKEN', '••••••••••••', $text);
return new TextPreprocessResult([ new TextSegment($masked, redacted: $masked !== $text), ]); }}Codebeispiel — Produktion
Abschnitt betitelt „Codebeispiel — Produktion“Ein produktionsreifer Präprozessor hält die Matching-Regeln an einer Stelle. Bei einem fehlerhaften Pattern verhält er sich fail-closed und protokolliert niemals den Originaltext.
<?php
declare(strict_types=1);
use NextPDF\Contracts\TextPreprocessorInterface;use NextPDF\Contracts\TextPreprocessResult;use NextPDF\Contracts\TextSegment;use Psr\Log\LoggerInterface;
final class PatternRedactionPreprocessor implements TextPreprocessorInterface{ /** * @param non-empty-string $pattern A valid PCRE pattern for sensitive spans */ public function __construct( private readonly string $pattern, private readonly LoggerInterface $logger, ) {}
public function process(string $text): TextPreprocessResult { $result = \preg_replace($this->pattern, '[REDACTED]', $text);
if ($result === null) { // Fail closed: never emit unredacted text on a pattern error. $this->logger->error('Redaction pattern failed; substituting empty text');
return new TextPreprocessResult([new TextSegment('', redacted: true)]); }
return new TextPreprocessResult([ new TextSegment($result, redacted: $result !== $text), ]); }}Sonderfälle & Fallstricke
Abschnitt betitelt „Sonderfälle & Fallstricke“- Kein Ersatz des Layouts. Es gibt keinen Vertrag, um Box-Layout, Zeilenumbruch oder Pagination zu ersetzen. Eine Anfrage, eine Layout-Engine eines Drittanbieters einzuklinken, ist per Design nicht abgedeckt.
- Durchsetzung der Regel. Das Hinzufügen von
\n,\roder\tinprocess()beschädigt das Layout und zerstört die stabile Ausgabe. Die Engine vertraut auf diese Regel; sie prüft Ihre Ausgabe nicht erneut auf layoutbeeinflussende Zeichen. - Lesereihenfolge. Das Umordnen von Segmenten zerstört die Lesereihenfolge von getaggtem PDF und die PDF/UA-Konformität.
- Eine Verantwortung. Der Präprozessor beschreibt einen Inhaltsaustausch. Nutzen Sie Lifecycle-Events zum Beobachten und schleusen Sie keine Seiteneffekte über
process()ein.
Performance
Abschnitt betitelt „Performance“process() läuft einmal pro Text-Run auf dem kritischen Layout-Pfad. Halten Sie es speicherschonend. Kompilieren Sie Patterns einmal im Konstruktor, nicht bei jedem Aufruf. Die Content-Lifecycle-Events verursachen keinen Aufwand, wenn kein Listener gebunden ist.
Sicherheitshinweise
Abschnitt betitelt „Sicherheitshinweise“TextPreprocessorInterface ist die unterstützte Stelle, um sensiblen Inhalt zu entfernen, bevor er den Content-Stream, die Font-Subsets oder die Metadaten erreicht. Weil die Vorverarbeitung vor dem Subsetting und der ToUnicode-CMap läuft, gelangen redigierte Glyphen niemals in die Datei. Behandeln Sie ein Scheitern des Präprozessors als fail-closed und nutzen Sie leeren oder maskierten Text, statt das Original auszugeben.
Konformität
Abschnitt betitelt „Konformität“Auf diese Seite treffen keine normativen Signatur- oder Archivierungs-Aussagen zu. Die Regel zur Lesereihenfolge bringt den Vertrag mit den Anforderungen von getaggtem PDF in Einklang. Die Konformität auf Tag-Ebene wird in der Barrierefreiheits-Referenz behandelt.
Kommerzieller Kontext
Abschnitt betitelt „Kommerzieller Kontext“NextPDF Pro liefert produktionsreife Text-Preprocessing-Strategien, darunter PII-Redaction, abgestimmt auf gängige Dokumenttypen. In Core schreiben Sie TextPreprocessorInterface selbst, oder Sie nutzen einen verifizierten Build der kostenpflichtigen Edition über denselben öffentlichen Vertrag.
Siehe auch
Abschnitt betitelt „Siehe auch“- Übersicht zur Extension-Erstellung
- Action-Trigger und Event-Listener
- Eigene Schriften
- SPI-Stabilitätsregeln
Verwandte Verträge und Module
Abschnitt betitelt „Verwandte Verträge und Module“- Referenz der Typography-Verträge — in der
TextPreprocessorInterfaceundTextPreprocessResultkatalogisiert sind. - Referenz der Streaming-Verträge — die Verträge
experimentalCursorInterfaceundStreamingWriterInterface, für die eine ausgelieferte Engine-Implementierung vorliegt. - Action-Trigger und Event-Listener — die Lifecycle-Events, mit denen die Layout-Ausgabe beobachtet wird.
- SPI-Stabilitätsregeln — das Versprechen des eingefrorenen Value Objects hinter
TextPreprocessResult. - Übersicht zur Extension-Erstellung — die vollständige öffentliche SPI-Oberfläche.
Das Glossar definiert Text-Präprozessor und Erweiterungspunkt; die jeweilige kanonische Definition finden Sie im veröffentlichten Glossar.