Gerar uma árvore de estrutura de PDF/UA-2 marcado a partir de conteúdo semântico
Visão geral
Seção intitulada “Visão geral”Esta receita cria um arquivo Portable Document Format/Universal Accessibility 2 (PDF/UA-2) marcado. Ela tem como alvo a norma International Organization for Standardization (ISO) 14289-2. O NextPDF emite uma árvore de estrutura lógica, sequências de conteúdo marcado, o idioma do catálogo e metadados de identificação em nível de documento. Essa estrutura dá suporte a uma autoria acessível, mas um verificador independente decide a conformidade. A receita segue examples/31-pdfua2-tagged.php.
Instalação
Seção intitulada “Instalação”composer require nextpdf/core:^3Coloque um verificador de PDF/UA-2 no PATH para a etapa de verificação. Esta receita usa o veraPDF com o flavour ua2. Você não precisa de um pacote Pro ou Enterprise para emitir a estrutura marcada.
Visão geral conceitual
Seção intitulada “Visão geral conceitual”Um PDF marcado carrega uma árvore de estrutura lógica paralela junto com o fluxo de conteúdo visual. A tecnologia assistiva lê a árvore em vez do layout de pixels; por isso, a estrutura determina a ordem de leitura exposta. A ISO 14289-2 define quatro requisitos aqui. O conteúdo real (não artefato) precisa ser alcançável por meio dessa árvore (§8.2.2). Os elementos de estrutura precisam se aninhar em uma ordem definida (§8.2.3). Todo elemento precisa resolver para um namespace de estrutura conhecido, diretamente ou por mapeamento de papel (§8.2.4). O idioma natural do conteúdo é declarado no nível do documento e refinado por elemento de estrutura quando difere (§8.4.4).
O NextPDF modela isso com um ConformanceMode tipado. O enableTaggedPdf() define ConformanceMode::PdfUa2, o que (a) faz o pipeline de Hypertext Markup Language (HTML) conectar um TaggedContentEmitter no momento da construção do parser, (b) define o sinalizador MarkInfoMarked do catálogo que indica um PDF marcado (ISO 32000-2 §14.7) e (c) registra o idioma Best Current Practice 47 (BCP-47) para a entrada Lang do catálogo. O escritor também emite a entrada Tabs por página, de modo que a ordem de tabulação segue a ordem da estrutura (ISO 32000-2 §14.8).
As invariantes estritas de UA-2 se aplicam apenas a ConformanceMode::PdfUa2. Por design, construir uma ConformancePolicy estrita contra qualquer outro modo lança InvalidConfigException.
Superfície da API
Seção intitulada “Superfície da API”A superfície da application programming interface (API) é documentada no PHPDoc. Use estes principais pontos de entrada:
\NextPDF\Core\Document::createStandalone(): DocumentDocument::enableTaggedPdf(string $lang = 'en', ?ConformancePolicy $policy = null): staticDocument::setLanguage(string $lang): static\NextPDF\Conformance\ConformancePolicy::strictUa2(): self\NextPDF\Conformance\ConformanceMode::PdfUa2(o modo definido porenableTaggedPdf())Document::beginTag(string $type): static/Document::endTag(): static(marcação manual para conteúdo não HTML)
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
// Enable tagged mode BEFORE writeHtml(). The HTML pipeline detects the// mode at parser construction time and wires the tagged-content emitter.$doc->enableTaggedPdf(lang: 'en');
$doc->setTitle('Quarterly Accessibility Report');$doc->setLanguage('en');$doc->addPage();
$doc->writeHtml(<<<'HTML'<h1>Quarterly Accessibility Report</h1><p>This document opts into tagged PDF so assistive technology can exposea meaningful reading order.</p><ul> <li>Headings carry semantic roles.</li> <li>Lists keep their item structure.</li></ul>HTML);
$doc->save(__DIR__ . '/output/31-pdfua2-tagged.pdf');
echo "Created: output/31-pdfua2-tagged.pdf\n";Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”Este programa autossuficiente pode ser executado no harness. Em produção, falhe rapidamente diante de uma tag de idioma malformada em vez de descobri-la somente quando o verificador externo for executado. Passe ConformancePolicy::strictUa2() para rejeitar uma tag BCP-47 inválida na fronteira da API e, em seguida, condicione a build ao veredito do verificador.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Conformance\ConformancePolicy;use NextPDF\Core\Document;use NextPDF\Exception\InvalidConfigException;
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: (__DIR__ . '/accessible.pdf');
try { $doc = Document::createStandalone();
// Strict UA-2: a malformed BCP 47 tag throws here, not silently at // write time. strictUa2() also forces the §8.4.4 Lang validation. $doc->enableTaggedPdf(lang: 'en-GB', policy: ConformancePolicy::strictUa2());
$doc->setTitle('Accessible Annual Report 2026'); $doc->setLanguage('en-GB'); $doc->addPage();
$doc->writeHtml(<<<'HTML'<h1>Annual Report 2026</h1><p>Audited results for the financial year ending March 2026.</p><h2>Segment performance</h2><table> <tr><th>Segment</th><th>Revenue</th></tr> <tr><td>Cloud</td><td>42.1</td></tr> <tr><td>Services</td><td>18.7</td></tr></table>HTML);
$doc->save($out);} catch (InvalidConfigException $e) { fwrite(STDERR, "Tagged PDF/UA-2 setup rejected: {$e->getMessage()}\n"); exit(1);}
// The gate is the checker, not the library.$exitCode = 0;$report = [];exec('verapdf --flavour ua2 ' . escapeshellarg($out), $report, $exitCode);
if ($exitCode !== 0) { fwrite(STDERR, "veraPDF FAILED — output is not PDF/UA-2 conforming\n"); fwrite(STDERR, implode("\n", $report) . "\n"); exit(1);}
echo "veraPDF PASS — accessible.pdf carries a conforming UA-2 structure\n";Em um host onde verapdf --flavour ua2 relata um arquivo em conformidade, a saída padrão (STDOUT) esperada é:
veraPDF PASS — accessible.pdf carries a conforming UA-2 structureSe enableTaggedPdf() rejeitar a tag de idioma, o programa sai com código diferente de zero após Tagged PDF/UA-2 setup rejected: … na saída de erro padrão (STDERR). Se o verificador relatar um problema, ele sai com código diferente de zero após veraPDF FAILED — output is not PDF/UA-2 conforming. O verificador dá o veredito: o NextPDF emite a estrutura, mas não afirma conformidade.
Casos extremos & pegadinhas
Seção intitulada “Casos extremos & pegadinhas”- Ordem de chamada. Chamar
enableTaggedPdf()depois dewriteHtml()não marca retroativamente o conteúdo já escrito. Ative o modo marcado primeiro. - Verificação estrita de idioma. Sem uma política, uma tag BCP-47 não analisável é descartada silenciosamente e aparece somente no momento da verificação. Com
ConformancePolicy::strictUa2(), a mesma tag lançaInvalidConfigExceptionna fronteira deenableTaggedPdf()(ISO 14289-2 §8.4.4, caminho estrito). - Reativação idempotente. Se você chamar
enableTaggedPdf()duas vezes, o NextPDF atualiza o idioma sem reconstruir uma árvore de estrutura já preenchida. - Marcação manual. Para conteúdo não HTML, envolva os itens com
beginTag()/endTag(). Os papéis de container (Table,TR,L,LI) tornam-se elementos de agrupamento sem conteúdo marcado. Os papéis de folha (P,H1–H6,TD) recebem identificadores de conteúdo marcado (MCIDs). - Exclusividade de modo. Uma
ConformancePolicyestrita é válida apenas comConformanceMode::PdfUa2. Combinar sinalizadores estritos de UA-2 com um modo PDF/A lançaInvalidConfigException. Componha um entregável PDF/A marcado ativando o modo marcado e o perfil PDF/A separadamente.
Desempenho
Seção intitulada “Desempenho”A árvore de estrutura adiciona uma árvore paralela de dicionários leves e operadores BDC/EMC por sequência de texto. Para um relatório típico, a sobrecarga é de alguns por cento do tamanho da saída e permanece bem dentro do orçamento de 2000 ms / 128 MB. O perfil de reprodutibilidade semântica se aplica porque um entregável orientado ao verificador é comparado por abstract syntax tree (AST) estrutural mais metadados, e não por bytes brutos. Veja a seção Conformidade.
Notas de segurança
Seção intitulada “Notas de segurança”Residência de dados & mitigações de PII
Seção intitulada “Residência de dados & mitigações de PII”A árvore de estrutura carrega o mesmo texto que o conteúdo visível. Se o HTML de origem contiver dados pessoais, incluindo informações de identificação pessoal (PII), esses dados também ficam alcançáveis por meio da árvore e dos atributos ActualText/Alt. Aplique a mesma redação e minimização antes da autoria, assim como você faria para o conteúdo visível. A marcação não adiciona nenhum novo caminho de exfiltração, mas torna o texto extraível programaticamente por design.
Telemetria segura & limpeza de logs
Seção intitulada “Telemetria segura & limpeza de logs”A receita escreve apenas uma linha de progresso fixa na STDOUT. Ela direciona o PDF para o canal lateral do harness (NEXTPDF_COOKBOOK_OUTPUT) ou para um caminho do chamador. O texto do documento nunca é registrado em log. Mantenha a saída do verificador, que pode reproduzir fragmentos de conteúdo, fora de logs compartilhados.
Modelo de ameaças
Seção intitulada “Modelo de ameaças”Um PDF marcado não é uma fronteira de confiança. Se o consumidor confiar na árvore de estrutura para processamento automatizado, ele ainda precisa validar o arquivo, porque um produtor hostil pode emitir uma árvore estruturalmente bem formada, mas enganosa. Trate a estrutura como um recurso de acessibilidade, e não como um sinal de integridade ou autenticidade.
Comportamento em modo FIPS
Seção intitulada “Comportamento em modo FIPS”Esta receita não realiza nenhuma operação criptográfica. O modo Federal Information Processing Standards (FIPS) não altera o seu comportamento. Nenhuma assinatura ou criptografia está envolvida.
Mapeamento de PDF/UA-2
Seção intitulada “Mapeamento de PDF/UA-2”| Requisito de PDF/UA-2 | O que o NextPDF emite | Cláusula |
|---|---|---|
| O conteúdo real está na árvore de estrutura | StructTreeRoot com StructElem por bloco e conteúdo marcado vinculado a MCID | ISO 14289-2 §8.2.2 |
| Aninhamento e ordem de leitura definidos | Elementos de bloco mapeados para papéis de grouping/leaf na ordem do documento | ISO 14289-2 §8.2.3 |
| Namespace de estrutura conhecido | Papéis no namespace do PDF 2.0; tags HTML mapeadas por papel quando necessário | ISO 14289-2 §8.2.4 |
| Idioma do documento e do elemento | O Lang do catálogo a partir da tag BCP-47; Lang por elemento quando difere | ISO 14289-2 §8.4.4 |
| O conteúdo não textual possui uma alternativa textual | Alt/ActualText presentes em elementos de estrutura de figure/non-text | ISO 14289-2 §8.5.1 |
| Relacionamentos de tabela | Table/TR/TH/TD com associação de cabeçalho | ISO 14289-2 §8.2.5.26 |
| Metadados de identificação da parte | Identificação em nível de documento agendada no salvamento | ISO 14289-2 §Intro (pdfua2#p17) |
Referência cruzada Tag → ISO 32000-2 §14
Seção intitulada “Referência cruzada Tag → ISO 32000-2 §14”O PDF/UA-2 sobrepõe requisitos de acessibilidade sobre a maquinaria de PDF marcado da ISO 32000-2. O NextPDF depende deste mapeamento:
| Emissão do NextPDF | Recurso da ISO 32000-2 §14 | Cláusula |
|---|---|---|
Árvore de estrutura lógica (StructTreeRoot) | Estrutura lógica de PDF marcado | §14.7 (iso32000_2_sec14#x1.x38.p13) |
Catálogo MarkInfo << /Marked true >> | Marcador de PDF marcado | §14.7 (iso32000_2_sec14#x1.x40.p3) |
Entrada Tabs por página seguindo a ordem da estrutura | Navegação estrutural / ordem de tabulação | §14.8 (iso32000_2_sec14#x1.x50) |
Mapeamento de WCAG 2.2
Seção intitulada “Mapeamento de WCAG 2.2”O PDF/UA-2 é a expressão em formato PDF de requisitos de estrutura que as Web Content Accessibility Guidelines (WCAG) 2.2 declaram de forma independente de formato. O alinhamento relevante:
| Critério de sucesso da WCAG 2.2 | Mecanismo de PDF/UA-2 que esta receita produz |
|---|---|
| 1.3.1 Informações e relacionamentos (Nível A) | A árvore de estrutura torna cabeçalhos, listas e relacionamentos de tabela determináveis programaticamente (wcag_2_2#x2.x3.x3.x1.p3). |
| 1.3.2 Sequência com significado (Nível A) | A ordem da estrutura define a ordem de leitura independentemente do layout visual. |
| 3.1.1 Idioma da página (Nível A) | A entrada Lang do catálogo a partir da tag BCP-47. |
| 1.1.1 Conteúdo não textual (Nível A) | Alt/ActualText em elementos de estrutura não textuais (ISO 14289-2 §8.5.1). |
Este mapeamento mostra onde a estrutura emitida dá suporte a um critério da WCAG 2.2. Ele não é uma declaração de conformidade com a WCAG. A conformidade com a WCAG abrange toda a experiência do usuário, e quem a determina é uma avaliação de acessibilidade, não o produtor.
Conformidade
Seção intitulada “Conformidade”| Afirmação | Norma | Cláusula | reference_id |
|---|---|---|---|
| O conteúdo real exige uma estrutura lógica. | ISO 14289-2 | §8.2.2 | |
| Os elementos de estrutura seguem um aninhamento e uma ordem de leitura definidos. | ISO 14289-2 | §8.2.3 | |
| Todo elemento de estrutura resolve para um namespace conhecido, diretamente ou por mapeamento de papel. | ISO 14289-2 | §8.2.4 | |
| O idioma natural é declarado no nível do documento e do elemento de estrutura. | ISO 14289-2 | §8.4.4 | |
| O conteúdo não textual carrega uma alternativa textual. | ISO 14289-2 | §8.5.1 | |
| As células de tabela carregam relacionamentos de row/header/data. | ISO 14289-2 | §8.2.5.26 | |
O marcador de PDF marcado é o sinalizador MarkInfoMarked do catálogo. | ISO 32000-2 | §14.7 | |
| A conformidade é decidida em relação à parte, e não afirmada pelo produtor. | ISO 14289-2 | §8.14.2 |
O NextPDF emite a estrutura marcada que dá suporte a uma autoria acessível. Suporte não é conformidade. Esta receita não afirma conformidade com PDF/UA-2. Um verificador independente, como o veraPDF, faz essa determinação. Execute o verificador antes de afirmar que um arquivo está em conformidade.