Перейти к содержимому
getnextpdf.com

Создание доступного тегированного PDF из HTML

Используйте этот рецепт для создания тегированного PDF из семантического HTML. NextPDF записывает дерево логической структуры, запись языка в каталоге и маркеры PDF/UA-2. Соответствие определяет валидатор. Рецепт основан на examples/31-pdfua2-tagged.php.

  • Установите Core: composer require nextpdf/core:^3.
  • Для проверки используйте валидатор PDF/UA; в примере это veraPDF.
  1. Создайте документ.
  2. Вызовите enableTaggedPdf() с языковым тегом Best Current Practice (BCP) 47 до writeHtml(). HTML-конвейер определяет тегированный режим при построении парсера, а затем подключает эмиттер тегированного содержимого.
  3. Задайте метаданные документа: заголовок и язык. setLanguage() можно безопасно вызывать вместе с enableTaggedPdf(), поскольку метод идемпотентен.
  4. Запишите семантический HTML. Парсер сопоставляет каждый блочный элемент с соответствующим элементом структуры: h1 с H1, p с P, ul/li с L/LI, а table — с Table/TR/TD.
  5. Сохраните файл и проверьте его валидатором PDF/UA.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
// Step 2 — enable tagged mode BEFORE writeHtml(). The lang argument
// drives the catalog /Lang entry and the structure tree root language.
$doc->enableTaggedPdf(lang: 'en');
// Step 3 — metadata. setLanguage() restates intent; it is idempotent here.
$doc->setTitle('Accessible Report');
$doc->setLanguage('en');
$doc->addPage();
// Step 4 — semantic HTML. Each block element becomes a StructElem; text
// runs are wrapped in BDC/EMC operators with stable MCIDs.
$html = <<<'HTML'
<h1>Quarterly Accessibility Report</h1>
<p>This document opts into tagged PDF so assistive technology can expose
a meaningful reading order.</p>
<h2>Findings</h2>
<ul>
<li>Headings carry semantic roles.</li>
<li>Lists keep their item structure.</li>
</ul>
HTML;
$doc->writeHtml($html);
$doc->save(__DIR__ . '/accessible.pdf');
echo "Wrote accessible.pdf — validate with: verapdf --flavour ua2 accessible.pdf\n";
Wrote accessible.pdf — validate with: verapdf --flavour ua2 accessible.pdf

Полученный файл содержит дерево структуры, /MarkInfo << /Marked true >>, запись каталога /Lang и XMP-маркер pdfuaid:part. Запустите валидатор, чтобы подтвердить наличие этих элементов и их внутреннюю согласованность.

  • Порядок вызовов. Вызов enableTaggedPdf() после writeHtml() не добавляет теги задним числом к содержимому, которое уже было записано. Сначала включите тегированный режим.
  • Языковой тег. Передайте ConformancePolicy::strictUa2() вторым аргументом, чтобы отклонять некорректный тег BCP-47 на границе API, а не молча отбрасывать его во время записи.
  • Идемпотентное повторное включение. При повторном вызове enableTaggedPdf() NextPDF обновляет язык, не перестраивая уже заполненное дерево структуры.
  • Ручное тегирование. Для содержимого вне HTML оборачивайте элементы в beginTag() / endTag(). Контейнерные типы (Table, THead, TBody, TFoot, TR, L, LI, а также группирующие элементы Sect/Div/Art/Aside/BlockQuote) становятся группирующими элементами без маркированного содержимого; свободное строчное содержимое, помещённое непосредственно внутри группирующего элемента, оборачивается в синтезированный P. Конечные типы (P, H1H6, TD, TH) получают MCID.
  • Поддержка — это не соответствие. NextPDF формирует структурные метаданные, необходимые для PDF/UA-2. Он также выдаёт предупреждение о пониженном паритете: перед допуском в эксплуатацию проверка внешним оракулом остаётся ответственностью вызывающей стороны. Запустите валидатор, прежде чем утверждать, что файл соответствует требованиям.
  • Тегированные HTML-таблицы и группирующие элементы проходят veraPDF ua2. Тегированная <table> — плоская, с colspan/rowspan, разбитая на страницы или вложенная в ячейку — выдаёт структуру Table/TR/TH/TD (ISO 32000-2 §14.8; объединённые ячейки несут атрибуты /ColSpan и /RowSpan из Table 384), а группирующие элементы <section>/<div>/<article>/<aside>/<blockquote> выдают группирующую структуру, при этом свободное строчное содержимое оборачивается в синтезированный P. veraPDF --flavour ua2 не сообщает ни об одной ошибке во всех этих случаях. По-прежнему не проходит один случай: блочный элемент, вложенный внутрь строчного, — заголовок внутри ссылки, <a><h2>…</h2></a> — нарушает правило Link shall not contain Hn, поэтому держите блочное содержимое вне строчных обёрток. Запустите валидатор, прежде чем утверждать, что файл соответствует требованиям.
УтверждениеСпецификацияПункт
Для реального содержимого требуется логическая структура.ISO 14289-2§8.2.2
Элементы структуры должны соблюдать заданные порядок вложенности и порядок чтения.ISO 14289-2§8.2.3

Рецепт показывает, как создать тегированную структуру, поддерживающую доступное авторство. Он не заявляет о соответствии PDF/UA-2; это определяет валидатор.