Pular para o conteúdo

Produza conteúdo textual que ferramentas posteriores consigam extrair

O NextPDF Core é um produtor de PDF. Ele não fornece nenhum leitor público de PDF voltado à extração de texto. No contexto do Core, “extrair conteúdo de texto” significa criar o documento de modo que seu texto seja extraível. Os glifos carregam um CMap /ToUnicode, e o documento tem uma estrutura lógica marcada (tagged). Um leitor em conformidade ou uma ferramenta de extração posterior pode então recuperar o texto Unicode na ordem de leitura.

Ler texto de um PDF arbitrário de terceiros é trabalho do consumidor. Use o sidecar do módulo Inspect ou uma ferramenta externa para essa tarefa, não a superfície de produtor do Core.

Terminal window
composer require nextpdf/core:^3

Operadores de exibição de texto no stream de conteúdo posicionam o texto em uma página (ISO 32000-2 §9.4.3). Códigos de glifo não são Unicode. Um CMap /ToUnicode permite que um leitor mapeie esses códigos de volta para Unicode durante a extração (ISO 32000-2 §9.10.2). Uma árvore de estrutura marcada registra a ordem lógica de leitura, de modo que a extração possa recuperar o texto na ordem do documento, e não na ordem de pintura (ISO 32000-2 §14.8).

enableTaggedPdf() constrói essa árvore de estrutura e mantém o CMap /ToUnicode para fontes com subconjunto incorporado. Juntos, esses recursos tornam a saída extraível de forma confiável.

Document::enableTaggedPdf(string $lang = 'en') constrói a árvore de estrutura e define o modo de conformidade que preserva o CMap /ToUnicode. Document::setLanguage(string $lang) registra a tag de idioma BCP-47. Chame os dois métodos antes de escrever o conteúdo. Em seguida, escreva o texto usando a superfície habitual setFont() / cell() / multiCell().

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setLanguage('en');
$doc->enableTaggedPdf('en'); // structure tree + ToUnicode retention
$doc->addPage();
$doc->setFont('helvetica', '', 12);
$doc->multiCell(0, 7, 'This text is extractable by a downstream reader.');
file_put_contents(__DIR__ . '/extractable.pdf', $doc->getPdfData());

Este programa autocontido é executado no harness. Ele espelha examples/38-extract-text-content.php. Ele cria um documento marcado cujo texto carrega um CMap /ToUnicode e uma ordem lógica de leitura. Um extrator posterior pode então recuperar o texto Unicode na ordem correta.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$paragraphs = [
'NextPDF produces documents whose text content is extractable.',
'A tagged structure tree records the logical reading order.',
'The ToUnicode CMap lets a reader recover Unicode from glyph codes.',
];
$doc = Document::createStandalone();
$doc->setTitle('Extractable text content');
$doc->setAuthor('NextPDF Cookbook');
$doc->setLanguage('en'); // BCP-47; validated on enableTaggedPdf()
// Configure tagged mode BEFORE content so the structure tree captures the
// text in reading order and the /ToUnicode CMap is retained.
$doc->enableTaggedPdf('en');
$doc->addPage();
$doc->setFont('helvetica', '', 12);
foreach ($paragraphs as $p) {
$doc->multiCell(0, 7, $p); // captured in reading order
$doc->ln(2);
}
$pdf = $doc->getPdfData();
// $pdf contains a /StructTreeRoot and per-font /ToUnicode CMaps; an external
// extractor (or the Inspect sidecar) recovers the Unicode text in order.
echo "Wrote a tagged PDF with extractable text content\n";
echo 'Paragraphs authored: ' . count($paragraphs) . "\n";
echo "Text is recoverable via the /ToUnicode CMap + tagged reading order.\n";
// The harness sets NEXTPDF_COOKBOOK_OUTPUT and runs this script under the
// semantic profile; emit the document to the side-channel.
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');
file_put_contents($out !== false && $out !== '' ? $out : __DIR__ . '/extractable.pdf', $pdf);

STDOUT esperado:

Wrote a tagged PDF with extractable text content
Paragraphs authored: 3
Text is recoverable via the /ToUnicode CMap + tagged reading order.
  • Produtor, não leitor. O Core não tem nenhum extractText() público. Ler texto de um PDF de terceiros existente é uma tarefa do consumidor. Use o módulo Inspect com o sidecar Spectrum, ou use uma ferramenta de extração externa. Esta receita torna a sua própria saída extraível.
  • Configure a marcação (tagging) primeiro. Chame enableTaggedPdf() antes de escrever o conteúdo, para que a árvore de estrutura capture o texto na ordem de leitura. Uma chamada feita depois que o conteúdo é adicionado não marca o conteúdo anterior.
  • Tag de idioma inválida. enableTaggedPdf() valida a tag BCP-47 e lança InvalidConfigException quando ela é inválida. Use uma tag registrada, por exemplo en, zh-Hant-TW ou ja.
  • Saída simples (não marcada). Sem enableTaggedPdf(), a saída simples pode suprimir o CMap /ToUnicode para fontes de CMap predefinido a fim de reduzir o tamanho. A extração então deixa de ser confiável para essas fontes. Marque o documento quando você precisar de texto extraível.

A marcação acrescenta a árvore de estrutura e retém os CMaps /ToUnicode, de modo que o tamanho da saída aumenta de forma modesta. O custo escala com o volume de conteúdo e não altera o modelo de renderização de passagem única.

Conteúdo de texto marcado é legível por máquina por design. Não coloque segredos no texto do documento esperando que eles permaneçam ocultos. Qualquer pessoa com o arquivo pode extrair texto extraível. Esta é uma receita de correção do produtor, não um controle de confidencialidade. Para confidencialidade, consulte a receita de criptografia.

AfirmaçãoEspecificaçãoCláusulareference_id
Um CMap ToUnicode mapeia códigos de caractere para Unicode na extração de texto.ISO 32000-2§9.10.2
Operadores de exibição de texto posicionam strings na página no stream de conteúdo.ISO 32000-2§9.4.3
Uma árvore de estrutura marcada registra a ordem lógica de leitura para extração.ISO 32000-2§14.8

Esta receita produz conteúdo de texto extraível. Ela não declara conformidade com PDF/UA-2; isso é determinado por um verificador. Consulte a receita de acessibilidade.