Ga naar inhoud

Aangepaste layout-engines en tekst onderscheppen tijdens de lay-out

NextPDF stelt geen pluggable interface voor een layout-engine beschikbaar. Gebruik het publieke contract voor lay-out-uitbreiding, TextPreprocessorInterface, om tekst tijdens de lay-out te onderscheppen. Met levenscyclusgebeurtenissen voor inhoud kun je observeren wat de lay-out oplevert.

Terminal window
composer require nextpdf/core:^3

De lay-outpijplijn is intern. Deze omvat glyph-lay-out, font-subsetting, ToUnicode CMap-uitvoer en de structuurboom. NextPDF staat niet toe dat je deze vervangt. Byte-stabiele uitvoer en conformiteit met tagged PDF zijn afhankelijk van één gecontroleerde build.

NextPDF stelt het punt vóór de lay-out wel beschikbaar: TextPreprocessorInterface. Een implementatie ontvangt onbewerkte tekst en retourneert een gesegmenteerd resultaat voordat die tekst de glyph-lay-out, font-subsetting, de ToUnicode CMap of de structuurboom bereikt. Gebruik dit ondersteunde pad om tekstinhoud te wijzigen zonder de layout-engine aan te raken.

De PHPDoc in de broncode legt een harde regel vast: een implementatie mag niet wijzigen hoe de lay-out werkt. Ze mag geen tekens toevoegen die de lay-out beïnvloeden, zoals een regelinvoer, een regelterugloop of een tab, en ze moet de logische leesvolgorde behouden. De preprocessor geeft een inhoudswijziging aan; ze maakt geen lay-outkeuzes. Houd je aan deze regel, anders raken stabiele uitvoer en toegankelijkheid beschadigd.

Als je het resultaat van de lay-out wilt observeren in plaats van wijzigen, gebruik je de levenscyclusgebeurtenissen voor inhoud in Actietriggers en gebeurtenislisteners. ContentRenderedEvent wordt geactiveerd nadat inhoud op een pagina is getekend. FontLoadedEvent wordt eenmaal per lettertypefamilie en -stijl geactiveerd.

NextPDF\Contracts\TextPreprocessorInterface (stabiel, sinds 1.9.0):

MethodeRetourneertDoel
process(string $text)TextPreprocessResultTransformeert onbewerkte tekst vóór de renderpijplijn en retourneert een gesegmenteerd resultaat met redactie-metadata.

Het geretourneerde NextPDF\Contracts\TextPreprocessResult is een bevroren value-object. De constructor-signatuur en de publieke eigenschappen zijn stabiel en wijzigen niet in een minor- of patchrelease. Er kunnen wel nieuwe methoden worden toegevoegd.

De kleine preprocessor hieronder maskeert een vast token. Hij voegt geen tekens toe die de lay-out beïnvloeden en behoudt de leesvolgorde.

<?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),
]);
}
}

Een productie-preprocessor houdt de matchingregels op één plaats. Hij faalt fail-closed bij een ongeldig patroon en logt nooit de oorspronkelijke tekst.

<?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),
]);
}
}
  • Geen vervanging van de lay-out. Je kunt box-lay-out, regelafbreking of paginering niet via dit contract vervangen. Het aansluiten van een layout-engine van derden valt bewust buiten het bereik.
  • Handhaving van de regel. Als je \n, \r of \t toevoegt in process(), beschadig je de lay-out en gaat de stabiele uitvoer kapot. De engine vertrouwt op deze regel; ze controleert je uitvoer niet opnieuw op tekens die de lay-out beïnvloeden.
  • Leesvolgorde. Als je segmenten herordent, doorbreek je de leesvolgorde van tagged PDF en de PDF/UA-conformiteit.
  • Eén verantwoordelijkheid. De preprocessor geeft een inhoudswijziging aan. Gebruik levenscyclusgebeurtenissen om te observeren en laat neveneffecten niet via process() lopen.

process() draait eenmaal per text run op het hot path van de lay-out. Houd het geheugengebruik laag. Compileer patronen één keer in de constructor, niet bij elke aanroep. Levenscyclusgebeurtenissen voor inhoud brengen geen kosten met zich mee wanneer er geen listener is gekoppeld.

Gebruik TextPreprocessorInterface om gevoelige inhoud te verwijderen voordat deze de content stream, font-subsets of metadata bereikt. Omdat deze vóór de subsetting en de ToUnicode CMap draait, komen geredigeerde glyphs nooit in het bestand terecht. Behandel een fout in de preprocessor als fail-closed en geef lege of gemaskeerde tekst terug in plaats van het origineel.

Deze pagina doet geen normatieve uitspraken over ondertekening of archivering. De regel voor de leesvolgorde stemt het contract af op de behoeften van tagged PDF. De toegankelijkheidsreferentie behandelt conformiteit op tagniveau.

NextPDF Pro biedt productierijpe strategieën voor tekstvoorbewerking, waaronder redactie van persoonlijk identificeerbare informatie (PII) afgestemd op veelvoorkomende documenttypen. In Core schrijf je TextPreprocessorInterface zelf, of gebruik je een geverifieerde build van een betaalde editie via hetzelfde publieke contract.

De woordenlijst definieert text preprocessor en extension point; raadpleeg de gepubliceerde woordenlijst voor de canonieke definities.