Generare un albero della struttura PDF/UA-2 con tag da contenuto semantico
In sintesi
Sezione intitolata “In sintesi”Questa ricetta crea un PDF con tag conforme a ISO 14289-2 (PDF/UA-2). NextPDF genera un albero della struttura logica, le sequenze di contenuto marcato, la lingua del catalogo e i metadati di identificazione a livello di documento. Questa struttura supporta la creazione accessibile, ma la conformità viene stabilita da un checker indipendente. La ricetta si basa su examples/31-pdfua2-tagged.php.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/core:^3La verifica richiede un checker PDF/UA-2 in PATH. Gli esempi di questa ricetta usano veraPDF con il profilo ua2. Non serve un pacchetto Pro o Enterprise per generare la struttura con tag.
Panoramica concettuale
Sezione intitolata “Panoramica concettuale”Un PDF con tag include un albero della struttura logica parallelo al flusso del contenuto visivo. Le tecnologie assistive leggono l’albero, non l’impaginazione dei pixel; è quindi la struttura a determinare l’ordine di lettura esposto. ISO 14289-2 definisce qui quattro requisiti. Il contenuto reale (non artifact) deve essere raggiungibile attraverso questo albero (§8.2.2). Gli elementi di struttura devono annidarsi secondo un ordine definito (§8.2.3). Ogni elemento deve risolversi in un namespace di struttura noto, direttamente o tramite role mapping (§8.2.4). Inoltre, la lingua naturale del contenuto è dichiarata a livello di documento e raffinata per singolo elemento di struttura quando differisce (§8.4.4).
NextPDF modella questo comportamento con un ConformanceMode tipizzato. enableTaggedPdf() imposta ConformanceMode::PdfUa2, che (a) fa sì che la pipeline HTML colleghi un TaggedContentEmitter al momento della costruzione del parser, (b) attiva il flag MarkInfoMarked del catalogo che segnala un PDF con tag (ISO 32000-2 §14.7) e (c) registra la lingua BCP-47 per la voce Lang del catalogo. Il writer genera inoltre la voce Tabs per ogni pagina, affinché l’ordine di tabulazione segua l’ordine della struttura (ISO 32000-2 §14.8).
Gli invarianti stretti UA-2 si applicano solo a ConformanceMode::PdfUa2. Costruire una ConformancePolicy stretta per qualsiasi altra modalità genera InvalidConfigException per impostazione progettuale.
Superficie API
Sezione intitolata “Superficie API”La superficie API è generata dal PHPDoc. I principali punti di ingresso sono:
\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(la modalità impostata daenableTaggedPdf())Document::beginTag(string $type): static/Document::endTag(): static(assegnazione manuale dei tag per contenuto non HTML)
Esempio di codice — Avvio rapido
Sezione intitolata “Esempio di codice — Avvio rapido”<?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";Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”Questo è il programma autonomo, eseguibile dall’harness. In produzione, il chiamante fallisce subito su un tag di lingua malformato, invece di scoprirlo solo quando viene eseguito il checker esterno. Passare ConformancePolicy::strictUa2() per rifiutare un tag BCP-47 non valido al confine dell’API, quindi subordinare la build al verdetto del checker.
<?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";STDOUT atteso, su un host in cui verapdf --flavour ua2 riporta il file come conforme:
veraPDF PASS — accessible.pdf carries a conforming UA-2 structureSe enableTaggedPdf() rifiuta il tag di lingua, il programma termina con codice diverso da zero dopo Tagged PDF/UA-2 setup rejected: … su STDERR. Se il checker segnala un problema, termina con codice diverso da zero dopo veraPDF FAILED — output is not PDF/UA-2 conforming. Il verdetto spetta al checker: NextPDF genera la struttura ma non asserisce la conformità.
Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- Ordine delle chiamate.
enableTaggedPdf()dopowriteHtml()non applica retroattivamente i tag al contenuto già scritto. Attivare prima la modalità con tag. - Gate stretto sulla lingua. In assenza di un criterio, un tag BCP-47 non analizzabile viene scartato in modo silenzioso ed emerge solo al momento del checker. Con
ConformancePolicy::strictUa2()lo stesso tag generaInvalidConfigExceptional confine dienableTaggedPdf()(ISO 14289-2 §8.4.4 percorso stretto). - Riattivazione idempotente. Chiamare
enableTaggedPdf()due volte aggiorna la lingua senza ricostruire un albero della struttura già popolato. - Assegnazione manuale dei tag. Per contenuto non HTML, racchiudere gli elementi con
beginTag()/endTag(). I ruoli contenitore (Table,TR,L,LI) diventano elementi di raggruppamento senza contenuto marcato. I ruoli foglia (P,H1–H6,TD) ottengono gli MCID. - Esclusività delle modalità. Una
ConformancePolicystretta è valida solo conConformanceMode::PdfUa2. La combinazione di flag UA-2 stretti con una modalità PDF/A generaInvalidConfigException. Per comporre un deliverable PDF/A con tag, attivare la modalità con tag e il profilo PDF/A separatamente.
Prestazioni
Sezione intitolata “Prestazioni”L’albero della struttura aggiunge un albero parallelo di dizionari leggeri più gli operatori BDC/EMC per ciascuna sequenza di testo. In un report tipico, l’overhead è di qualche punto percentuale della dimensione di output e resta ampiamente entro il budget di 2000 ms / 128 MB. Qui si applica il profilo di riproducibilità semantica, perché un deliverable orientato al checker viene confrontato in base a un albero di sintassi astratta (AST) strutturale e ai metadati, non ai byte grezzi. Vedere la sezione Conformità.
Note di sicurezza
Sezione intitolata “Note di sicurezza”Residenza dei dati e mitigazioni PII
Sezione intitolata “Residenza dei dati e mitigazioni PII”L’albero della struttura contiene lo stesso testo del contenuto visibile. Se l’HTML di origine contiene dati personali, tali dati sono raggiungibili anche attraverso l’albero e tramite gli attributi ActualText/Alt. Applicare lo stesso oscuramento e la stessa minimizzazione prima della creazione, come si farebbe per il contenuto visibile. L’assegnazione dei tag non aggiunge alcun nuovo percorso di esfiltrazione, ma rende il testo estraibile in modo programmatico per impostazione progettuale.
Telemetria sicura e scrubbing dei log
Sezione intitolata “Telemetria sicura e scrubbing dei log”La ricetta scrive su STDOUT solo una riga fissa di avanzamento. Instradare il PDF al canale laterale dell’harness (NEXTPDF_COOKBOOK_OUTPUT) o a un percorso del chiamante. Il testo del documento non viene mai registrato nei log. Tenere l’output del checker, che può riportare frammenti di contenuto, fuori dai log condivisi.
Modello delle minacce
Sezione intitolata “Modello delle minacce”Un PDF con tag non è un confine di fiducia. Un consumatore che si fida dell’albero della struttura per l’elaborazione automatica deve comunque convalidare il file, perché un produttore ostile può generare un albero strutturalmente ben formato ma fuorviante. Considerare la struttura un’affordance di accessibilità, non un segnale di integrità o autenticità.
Comportamento in modalità FIPS
Sezione intitolata “Comportamento in modalità FIPS”Questa ricetta non esegue alcuna operazione crittografica. La modalità FIPS non ne modifica il comportamento. Non è coinvolta alcuna firma o cifratura.
Mappatura PDF/UA-2
Sezione intitolata “Mappatura PDF/UA-2”| Requisito PDF/UA-2 | Ciò che genera NextPDF | Clausola |
|---|---|---|
| Il contenuto reale è nell’albero della struttura | StructTreeRoot con StructElem per blocco e contenuto marcato collegato tramite MCID | ISO 14289-2 §8.2.2 |
| Annidamento e ordine di lettura definiti | Elementi di blocco mappati a ruoli grouping/leaf nell’ordine del documento | ISO 14289-2 §8.2.3 |
| Namespace di struttura noto | Ruoli nel namespace PDF 2.0; tag HTML mappati ai ruoli dove necessario | ISO 14289-2 §8.2.4 |
| Lingua del documento e dell’elemento | Dal catalogo, Lang ricavato dal tag BCP-47; Lang per elemento quando differisce | ISO 14289-2 §8.4.4 |
| Il contenuto non testuale ha un’alternativa testuale | Alt/ActualText applicati agli elementi di struttura figure/non-text | ISO 14289-2 §8.5.1 |
| Relazioni di tabella | Table/TR/TH/TD ruoli con associazione delle intestazioni | ISO 14289-2 §8.2.5.26 |
| Metadati di identificazione della parte | Identificazione a livello di documento pianificata al salvataggio | ISO 14289-2 §Intro (pdfua2#p17) |
Riferimento incrociato tag → ISO 32000-2 §14
Sezione intitolata “Riferimento incrociato tag → ISO 32000-2 §14”PDF/UA-2 sovrappone requisiti di accessibilità al meccanismo dei PDF con tag di ISO 32000-2. La mappatura su cui si basa NextPDF:
| Generazione NextPDF | Funzionalità ISO 32000-2 §14 | Clausola |
|---|---|---|
Albero della struttura logica (StructTreeRoot) | Struttura logica del PDF con tag | §14.7 (iso32000_2_sec14#x1.x38.p13) |
Catalogo MarkInfo << /Marked true >> | Marcatore per PDF con tag | §14.7 (iso32000_2_sec14#x1.x40.p3) |
Voce Tabs per pagina che segue l’ordine della struttura | Navigazione strutturale / ordine di tabulazione | §14.8 (iso32000_2_sec14#x1.x50) |
Mappatura WCAG 2.2
Sezione intitolata “Mappatura WCAG 2.2”PDF/UA-2 è l’espressione, in formato PDF, dei requisiti di struttura che WCAG 2.2 esprime in modo indipendente dal formato. L’allineamento pertinente:
| Criterio di successo WCAG 2.2 | Meccanismo PDF/UA-2 prodotto da questa ricetta |
|---|---|
| 1.3.1 Informazioni e relazioni (Livello A) | L’albero della struttura rende le intestazioni, gli elenchi e le relazioni di tabella determinabili in modo programmatico (wcag_2_2#x2.x3.x3.x1.p3). |
| 1.3.2 Sequenza significativa (Livello A) | L’ordine della struttura definisce l’ordine di lettura indipendentemente dall’impaginazione visiva. |
| 3.1.1 Lingua della pagina (Livello A) | La voce Lang del catalogo dal tag BCP-47. |
| 1.1.1 Contenuto non testuale (Livello A) | Alt/ActualText sugli elementi di struttura non testuali (ISO 14289-2 §8.5.1). |
Questa mappatura mostra dove la struttura generata supporta un criterio WCAG 2.2. Non è un’asserzione di conformità WCAG. La conformità WCAG riguarda l’intera esperienza utente ed è determinata da una valutazione di accessibilità, non dal produttore.
Conformità
Sezione intitolata “Conformità”| Affermazione | Specifica | Clausola | reference_id |
|---|---|---|---|
| Il contenuto reale richiede una struttura logica. | ISO 14289-2 | §8.2.2 | |
| Gli elementi di struttura seguono un annidamento e un ordine di lettura definiti. | ISO 14289-2 | §8.2.3 | |
| Ogni elemento di struttura si risolve in un namespace noto, direttamente o tramite role mapping. | ISO 14289-2 | §8.2.4 | |
| La lingua naturale è dichiarata a livello di documento e di elemento di struttura. | ISO 14289-2 | §8.4.4 | |
| Il contenuto non testuale porta un’alternativa testuale. | ISO 14289-2 | §8.5.1 | |
| Le celle di tabella portano relazioni row/header/data. | ISO 14289-2 | §8.2.5.26 | |
Il marcatore di PDF con tag è il flag MarkInfoMarked del catalogo. | ISO 32000-2 | §14.7 | |
| La conformità è decisa rispetto alla parte, non asserita dal produttore. | ISO 14289-2 | §8.14.2 |
NextPDF genera la struttura con tag che supporta la creazione accessibile. Il supporto non è conformità. Questa ricetta non asserisce la conformità PDF/UA-2. A determinarla è un checker indipendente (per esempio veraPDF). Eseguire il checker prima di dichiarare che un file è conforme.