Motores de layout personalizados e interceptação de texto durante o layout
Visão geral
Seção intitulada “Visão geral”O NextPDF não expõe uma interface para motor de layout plugável. Use o contrato público de extensão de layout, TextPreprocessorInterface, para interceptar texto durante o layout. Os eventos de ciclo de vida do conteúdo permitem observar o que o layout produz.
Instalação
Seção intitulada “Instalação”composer require nextpdf/core:^3Visão geral conceitual
Seção intitulada “Visão geral conceitual”O pipeline de layout é interno. Ele abrange o layout de glifos, o subconjunto de fontes, a saída do CMap ToUnicode e a árvore de estrutura. O NextPDF não permite que você substitua esse pipeline. A saída de bytes estável e a conformidade com PDF marcado dependem de um único build controlado.
O NextPDF, porém, expõe o ponto antes do layout: TextPreprocessorInterface. Uma implementação recebe o texto bruto e retorna um resultado segmentado antes que esse texto entre no layout de glifos, no subconjunto de fontes, no CMap ToUnicode ou na árvore de estrutura. Use esse caminho suportado para alterar o conteúdo do texto sem mexer no motor de layout.
O PHPDoc original define uma regra rígida: uma implementação não deve alterar o funcionamento do layout. Ela não deve adicionar caracteres que afetem o layout, como avanço de linha, retorno de carro ou tabulação, e deve preservar a ordem lógica de leitura. O pré-processador declara uma substituição de conteúdo; ele não toma decisões de layout. Respeite essa regra; caso contrário, a saída estável e a acessibilidade serão comprometidas.
Para observar o resultado do layout sem alterá-lo, use os eventos de ciclo de vida do conteúdo em Gatilhos de ação e ouvintes de eventos. O ContentRenderedEvent é disparado depois que o conteúdo é desenhado em uma página. O FontLoadedEvent é disparado uma vez por família e estilo de fonte.
Superfície da API
Seção intitulada “Superfície da API”NextPDF\Contracts\TextPreprocessorInterface (estável, desde a 1.9.0):
| Método | Retorna | Finalidade |
|---|---|---|
process(string $text) | TextPreprocessResult | Transformar o texto bruto antes do pipeline de renderização e retornar um resultado segmentado com metadados de censura. |
O NextPDF\Contracts\TextPreprocessResult retornado é um objeto de valor congelado. A assinatura do construtor e as propriedades públicas são estáveis e não mudam em uma versão menor ou de correção. Novos métodos podem ser adicionados.
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”O pequeno pré-processador abaixo mascara um token fixo. Ele não adiciona caracteres que afetem o layout e mantém a ordem de leitura.
<?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), ]); }}Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”Um pré-processador de produção mantém as regras de correspondência em um só lugar. Diante de um padrão inválido, ele falha de modo fechado e nunca registra o texto original.
<?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), ]); }}Casos extremos & armadilhas
Seção intitulada “Casos extremos & armadilhas”- Sem substituição de layout. Você não pode substituir o layout de caixas, a quebra de linha ou a paginação por meio deste contrato. Conectar um motor de layout de terceiros está fora de escopo por decisão de design.
- Aplicação da regra. Se você adicionar
\n,\rou\temprocess(), isso corrompe o layout e quebra a saída estável. O motor confia nessa regra; ele não revalida a saída em busca de caracteres que afetem o layout. - Ordem de leitura. Se você reordenar os segmentos, você quebra a ordem de leitura do PDF marcado e a conformidade com PDF/UA.
- Uma única responsabilidade. O pré-processador declara uma substituição de conteúdo. Use os eventos de ciclo de vida para observar e não introduza efeitos colaterais por meio de
process().
Desempenho
Seção intitulada “Desempenho”process() é executado uma vez para cada trecho de texto no caminho crítico do layout. Mantenha baixo o uso de memória. Compile os padrões uma única vez no construtor, não a cada chamada. Os eventos de ciclo de vida do conteúdo não têm custo quando nenhum ouvinte está vinculado.
Notas de segurança
Seção intitulada “Notas de segurança”Use TextPreprocessorInterface para remover conteúdo sensível antes que ele chegue ao fluxo de conteúdo, aos subconjuntos de fontes ou aos metadados. Como a execução ocorre antes do subconjunto de fontes e do CMap ToUnicode, os glifos censurados nunca entram no arquivo. Trate uma falha do pré-processador como falha fechada e emita texto vazio ou mascarado em vez do original.
Conformidade
Seção intitulada “Conformidade”Esta página não faz nenhuma afirmação normativa sobre assinatura ou arquivamento. A regra de ordem de leitura alinha o contrato às necessidades de PDF marcado. A referência de acessibilidade abrange a conformidade no nível de marcação.
Contexto comercial
Seção intitulada “Contexto comercial”O NextPDF Pro oferece estratégias de pré-processamento de texto prontas para produção, incluindo censura de informações de identificação pessoal (PII) ajustada para tipos comuns de documento. No Core, você mesmo implementa TextPreprocessorInterface, ou usa um build verificado da edição paga por meio do mesmo contrato público.
Veja também
Seção intitulada “Veja também”- Visão geral da criação de extensões
- Gatilhos de ação e ouvintes de eventos
- Fontes personalizadas
- Regras de estabilidade da SPI
Contratos e módulos relacionados
Seção intitulada “Contratos e módulos relacionados”- Referência de contratos de tipografia — onde
TextPreprocessorInterfaceeTextPreprocessResultestão catalogados. - Referência de contratos de streaming — os contratos
experimentalCursorInterfaceeStreamingWriterInterface, que contam com uma implementação de motor fornecida. - Gatilhos de ação e ouvintes de eventos — os eventos de ciclo de vida usados para observar a saída do layout.
- Regras de estabilidade da SPI — a promessa de objeto de valor congelado que sustenta
TextPreprocessResult. - Visão geral da criação de extensões — toda a superfície pública da interface de provedor de serviço (SPI).
O glossário define pré-processador de texto e ponto de extensão; consulte o glossário publicado para cada definição canônica.