Generowanie otagowanego drzewa struktury PDF/UA-2 z treści semantycznej
W skrócie
Dział zatytułowany „W skrócie”Ten przepis pokazuje, jak utworzyć otagowany plik Portable Document Format/Universal Accessibility 2 (PDF/UA-2). Jest przeznaczony dla International Organization for Standardization (ISO) 14289-2. NextPDF generuje drzewo struktury logicznej, sekwencje oznaczonej treści, język w katalogu oraz metadane identyfikacyjne na poziomie dokumentu. Taka struktura wspiera tworzenie dostępnych treści, ale o zgodności rozstrzyga niezależny walidator. Przepis odpowiada plikowi examples/31-pdfua2-tagged.php.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Umieść walidator PDF/UA-2 w PATH na potrzeby weryfikacji. Ten przepis używa narzędzia veraPDF w odmianie ua2. Do generowania otagowanej struktury nie jest potrzebny pakiet Pro ani Enterprise.
Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”Otagowany plik PDF zawiera równoległe drzewo struktury logicznej obok wizualnego strumienia treści. Technologie wspomagające odczytują to drzewo zamiast układu pikseli, więc to struktura wyznacza udostępnianą kolejność odczytu. ISO 14289-2 określa w tym zakresie cztery wymagania. Rzeczywista treść (niebędąca artefaktem) musi być osiągalna z poziomu tego drzewa (§8.2.2). Elementy struktury muszą zagnieżdżać się w zdefiniowanej kolejności (§8.2.3). Każdy element musi odwzorowywać się na znaną przestrzeń nazw struktury, bezpośrednio albo przez mapowanie ról (§8.2.4). Język naturalny treści jest deklarowany na poziomie dokumentu i doprecyzowywany dla poszczególnych elementów struktury tam, gdzie jest inny (§8.4.4).
NextPDF modeluje to za pomocą typowanego ConformanceMode. enableTaggedPdf() ustawia ConformanceMode::PdfUa2, co (a) powoduje, że potok Hypertext Markup Language (HTML) podłącza TaggedContentEmitter podczas konstruowania parsera, (b) ustawia w katalogu flagę MarkInfoMarked, która sygnalizuje otagowany plik PDF (ISO 32000-2 §14.7), oraz (c) zapisuje znacznik języka Best Current Practice 47 (BCP 47) we wpisie Lang katalogu. Moduł zapisujący generuje również wpis Tabs dla każdej strony, dzięki czemu kolejność kart jest zgodna z kolejnością struktury (ISO 32000-2 §14.8).
Rygorystyczne niezmienniki UA-2 dotyczą wyłącznie ConformanceMode::PdfUa2. Zgodnie z założeniem próba skonstruowania rygorystycznej ConformancePolicy dla dowolnego innego trybu zgłasza InvalidConfigException.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”Powierzchnia API (application programming interface) pochodzi z PHPDoc. Korzystaj z następujących głównych punktów wejścia:
\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(tryb ustawiany przezenableTaggedPdf())Document::beginTag(string $type): static/Document::endTag(): static(ręczne tagowanie treści innej niż HTML)
Przykład kodu — Szybki start
Dział zatytułowany „Przykład kodu — Szybki start”<?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";Przykład kodu — Środowisko produkcyjne
Dział zatytułowany „Przykład kodu — Środowisko produkcyjne”Ten samodzielny program można uruchomić w środowisku testowym. W środowisku produkcyjnym przerywaj działanie natychmiast po wykryciu nieprawidłowego znacznika języka, zamiast wykrywać go dopiero podczas uruchomienia zewnętrznego walidatora. Przekaż ConformancePolicy::strictUa2(), aby odrzucić nieprawidłowy znacznik BCP 47 na granicy API, a następnie uzależnij proces budowania od werdyktu walidatora.
<?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";Na hoście, na którym verapdf --flavour ua2 uznaje plik za zgodny, oczekiwane standardowe wyjście (STDOUT) to:
veraPDF PASS — accessible.pdf carries a conforming UA-2 structureJeśli enableTaggedPdf() odrzuci znacznik języka, program kończy działanie z kodem niezerowym po wypisaniu komunikatu Tagged PDF/UA-2 setup rejected: … na standardowym wyjściu błędów (STDERR). Jeśli walidator zgłosi problem, program kończy działanie z kodem niezerowym po komunikacie veraPDF FAILED — output is not PDF/UA-2 conforming. Werdykt wydaje walidator: NextPDF generuje strukturę, ale nie potwierdza zgodności.
Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Kolejność wywołań.
enableTaggedPdf()wywołane powriteHtml()nie taguje wstecznie treści już zapisanej. Najpierw włącz tryb otagowany. - Rygorystyczna bramka języka. Bez polityki niemożliwy do przetworzenia znacznik BCP 47 jest po cichu odrzucany, a problem ujawnia się dopiero podczas działania walidatora. Z
ConformancePolicy::strictUa2()ten sam znacznik zgłaszaInvalidConfigExceptionna granicyenableTaggedPdf()(ISO 14289-2 §8.4.4 ścieżka rygorystyczna). - Idempotentne ponowne włączenie. Jeśli wywołasz
enableTaggedPdf()dwukrotnie, NextPDF aktualizuje język bez przebudowywania już zapełnionego drzewa struktury. - Ręczne tagowanie. W przypadku treści innej niż HTML otaczaj elementy znacznikami
beginTag()/endTag(). Role kontenerowe (Table,TR,L,LI) stają się elementami grupującymi bez oznaczonej treści. Role liściowe (P,H1–H6,TD) otrzymują identyfikatory oznaczonej treści (MCID). - Wyłączność trybów. Rygorystyczna
ConformancePolicyjest prawidłowa wyłącznie zConformanceMode::PdfUa2. Łączenie rygorystycznych flag UA-2 z trybem PDF/A zgłaszaInvalidConfigException. Otagowany wynik PDF/A przygotuj, włączając tryb otagowany i profil PDF/A osobno.
Wydajność
Dział zatytułowany „Wydajność”Drzewo struktury dodaje jedno równoległe drzewo lekkich słowników oraz operatory BDC/EMC dla każdego przebiegu tekstu. W typowym raporcie narzut to kilka procent rozmiaru pliku wynikowego i z dużym zapasem mieści się w budżecie 2000 ms / 128 MB. Stosowany jest profil powtarzalności semantycznej, ponieważ wynik przeznaczony dla walidatora porównuje się na podstawie strukturalnego drzewa składni abstrakcyjnej (AST) wraz z metadanymi, a nie surowych bajtów. Zobacz sekcję Zgodność.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”Rezydencja danych i środki ograniczania ryzyka PII
Dział zatytułowany „Rezydencja danych i środki ograniczania ryzyka PII”Drzewo struktury zawiera ten sam tekst, co treść widoczna. Jeśli źródłowy HTML zawiera dane osobowe, w tym dane umożliwiające identyfikację osoby (PII), są one także dostępne przez drzewo oraz przez atrybuty ActualText/Alt. Przed utworzeniem treści zastosuj tę samą redakcję i minimalizację, jaką zastosowałbyś do treści widocznej. Tagowanie nie dodaje nowej ścieżki eksfiltracji, ale z założenia sprawia, że tekst można wydobyć programowo.
Bezpieczna telemetria i czyszczenie dzienników
Dział zatytułowany „Bezpieczna telemetria i czyszczenie dzienników”Przepis zapisuje na STDOUT tylko stały wiersz postępu. Plik PDF trafia do kanału bocznego środowiska testowego (NEXTPDF_COOKBOOK_OUTPUT) lub do ścieżki podanej przez wywołującego. Tekst dokumentu nigdy nie jest zapisywany w dziennikach. Trzymaj wynik walidatora, który może powtarzać fragmenty treści, poza współdzielonymi dziennikami.
Model zagrożeń
Dział zatytułowany „Model zagrożeń”Otagowany plik PDF nie jest granicą zaufania. Jeśli odbiorca polega na drzewie struktury podczas automatycznego przetwarzania, nadal musi walidować plik, ponieważ złośliwy producent może wygenerować strukturalnie poprawne, lecz mylące drzewo. Traktuj strukturę jako mechanizm wspierający dostępność, a nie jako sygnał integralności czy autentyczności.
Działanie w trybie FIPS
Dział zatytułowany „Działanie w trybie FIPS”Ten przepis nie wykonuje żadnej operacji kryptograficznej. Tryb Federal Information Processing Standards (FIPS) nie zmienia jego działania. Nie zachodzi żadne podpisywanie ani szyfrowanie.
Mapowanie PDF/UA-2
Dział zatytułowany „Mapowanie PDF/UA-2”| Wymaganie PDF/UA-2 | Co generuje NextPDF | Klauzula |
|---|---|---|
| Rzeczywista treść znajduje się w drzewie struktury | StructTreeRoot z elementem StructElem dla każdego bloku oraz oznaczoną treścią powiązaną przez MCID | ISO 14289-2 §8.2.2 |
| Zdefiniowane zagnieżdżanie i kolejność odczytu | Elementy blokowe odwzorowane na role grouping/leaf w kolejności dokumentu | ISO 14289-2 §8.2.3 |
| Znana przestrzeń nazw struktury | Role w przestrzeni nazw PDF 2.0; znaczniki HTML odwzorowane przez role tam, gdzie to konieczne | ISO 14289-2 §8.2.4 |
| Język dokumentu i elementu | Lang w katalogu na podstawie znacznika BCP 47; Lang dla danego elementu, gdy się różni | ISO 14289-2 §8.4.4 |
| Treść inna niż tekstowa ma alternatywę tekstową | Alt/ActualText przenoszone na elementach struktury figure/non-text | ISO 14289-2 §8.5.1 |
| Relacje w tabeli | Role Table/TR/TH/TD z powiązaniem nagłówków | ISO 14289-2 §8.2.5.26 |
| Metadane identyfikacji części | Identyfikacja na poziomie dokumentu zaplanowana przy zapisie | ISO 14289-2 §Intro (pdfua2#p17) |
Odniesienie krzyżowe znaczników do ISO 32000-2 §14
Dział zatytułowany „Odniesienie krzyżowe znaczników do ISO 32000-2 §14”PDF/UA-2 nakłada wymagania dostępności na mechanizmy otagowanego PDF z ISO 32000-2. NextPDF opiera się na tym mapowaniu:
| Emisja NextPDF | Mechanizm ISO 32000-2 §14 | Klauzula |
|---|---|---|
Drzewo struktury logicznej (StructTreeRoot) | Struktura logiczna otagowanego PDF | §14.7 (iso32000_2_sec14#x1.x38.p13) |
Katalog MarkInfo << /Marked true >> | Znacznik otagowanego PDF | §14.7 (iso32000_2_sec14#x1.x40.p3) |
Wpis Tabs dla każdej strony podążający za kolejnością struktury | Nawigacja strukturalna / kolejność kart | §14.8 (iso32000_2_sec14#x1.x50) |
Mapowanie WCAG 2.2
Dział zatytułowany „Mapowanie WCAG 2.2”PDF/UA-2 ujmuje w formacie PDF wymagania dotyczące struktury, które Web Content Accessibility Guidelines (WCAG) 2.2 określa niezależnie od formatu. Istotne powiązanie:
| Kryterium sukcesu WCAG 2.2 | Mechanizm PDF/UA-2 generowany przez ten przepis |
|---|---|
| 1.3.1 Informacje i relacje (poziom A) | Drzewo struktury sprawia, że nagłówki, listy oraz relacje w tabelach można określić programowo (wcag_2_2#x2.x3.x3.x1.p3). |
| 1.3.2 Sensowna kolejność (poziom A) | Kolejność struktury wyznacza kolejność odczytu niezależnie od układu wizualnego. |
| 3.1.1 Język strony (poziom A) | Wpis Lang w katalogu na podstawie znacznika BCP 47. |
| 1.1.1 Treść inna niż tekstowa (poziom A) | Alt/ActualText na elementach struktury innej niż tekstowa (ISO 14289-2 §8.5.1). |
To mapowanie pokazuje, gdzie wygenerowana struktura wspiera kryterium WCAG 2.2. Nie jest to deklaracja zgodności z WCAG. Zgodność z WCAG obejmuje pełne doświadczenie użytkownika i rozstrzyga o niej ocena dostępności, a nie producent.
Zgodność
Dział zatytułowany „Zgodność”| Stwierdzenie | Norma | Klauzula | reference_id |
|---|---|---|---|
| Rzeczywista treść wymaga struktury logicznej. | ISO 14289-2 | §8.2.2 | |
| Elementy struktury są zgodne ze zdefiniowanym zagnieżdżaniem i kolejnością odczytu. | ISO 14289-2 | §8.2.3 | |
| Każdy element struktury odwzorowuje się na znaną przestrzeń nazw, bezpośrednio albo przez mapowanie ról. | ISO 14289-2 | §8.2.4 | |
| Język naturalny jest deklarowany na poziomie dokumentu i elementu struktury. | ISO 14289-2 | §8.4.4 | |
| Treść inna niż tekstowa zawiera alternatywę tekstową. | ISO 14289-2 | §8.5.1 | |
| Komórki tabeli zawierają relacje row/header/data. | ISO 14289-2 | §8.2.5.26 | |
Znacznikiem otagowanego PDF jest flaga MarkInfoMarked w katalogu. | ISO 32000-2 | §14.7 | |
| O zgodności rozstrzyga się względem części, a nie potwierdza jej producent. | ISO 14289-2 | §8.14.2 |
NextPDF generuje otagowaną strukturę, która wspiera tworzenie dostępnych treści. Takie wsparcie nie oznacza zgodności. Ten przepis nie deklaruje zgodności z PDF/UA-2. Rozstrzyga ją niezależny walidator, taki jak veraPDF. Uruchom walidator, zanim stwierdzisz, że plik jest zgodny.