Bỏ qua để đến nội dung

Xuất cây cấu trúc PDF/UA-2 có gắn thẻ từ nội dung ngữ nghĩa

Công thức này tạo ra một tệp Portable Document Format/Universal Accessibility 2 (PDF/UA-2) có gắn thẻ, hướng tới International Organization for Standardization (ISO) 14289-2. NextPDF phát ra một cây cấu trúc logic, các chuỗi nội dung được đánh dấu, ngôn ngữ của catalog và siêu dữ liệu nhận dạng ở cấp tài liệu. Cấu trúc đó hỗ trợ việc soạn nội dung có thể truy cập, nhưng chỉ một trình kiểm tra độc lập mới quyết định mức tuân thủ. Công thức này dựa trên examples/31-pdfua2-tagged.php.

Terminal window
composer require nextpdf/core:^3

Hãy đặt một trình kiểm tra PDF/UA-2 trên PATH để xác minh. Công thức này dùng veraPDF với biến thể ua2. Bạn không cần gói Pro hay Enterprise để phát ra cấu trúc có gắn thẻ.

Một PDF có gắn thẻ mang theo một cây cấu trúc logic song song với luồng nội dung hiển thị. Công nghệ hỗ trợ đọc cây này thay vì bố cục theo pixel, nên cấu trúc quyết định thứ tự đọc được bộc lộ. ISO 14289-2 đặt ra bốn yêu cầu liên quan ở đây. Nội dung thực (không phải artifact) phải truy cập được qua cây đó (§8.2.2). Các phần tử cấu trúc phải lồng nhau theo một thứ tự đã định nghĩa (§8.2.3). Mọi phần tử phải phân giải về một namespace cấu trúc đã biết, trực tiếp hoặc qua ánh xạ vai trò (§8.2.4). Ngôn ngữ tự nhiên của nội dung được khai báo ở cấp tài liệu và tinh chỉnh theo từng phần tử cấu trúc ở những nơi nó khác đi (§8.4.4).

NextPDF mô hình hóa điều này bằng một ConformanceMode có kiểu. enableTaggedPdf() đặt ConformanceMode::PdfUa2; việc này (a) khiến pipeline Hypertext Markup Language (HTML) kết nối một TaggedContentEmitter ngay khi bộ phân tích được dựng, (b) đặt cờ catalog MarkInfoMarked báo hiệu một PDF có gắn thẻ (ISO 32000-2 §14.7), và (c) ghi lại ngôn ngữ Best Current Practice 47 (BCP-47) cho mục catalog Lang. Bộ ghi cũng phát ra mục Tabs theo từng trang, nên thứ tự tab tuân theo thứ tự cấu trúc (ISO 32000-2 §14.8).

Các bất biến UA-2 nghiêm ngặt chỉ áp dụng cho ConformanceMode::PdfUa2. Theo thiết kế, việc dựng một ConformancePolicy nghiêm ngặt cho bất kỳ chế độ nào khác đều sẽ ném InvalidConfigException.

Bề mặt application programming interface (API) được lấy từ PHPDoc. Dùng các điểm vào chính sau:

  • \NextPDF\Core\Document::createStandalone(): Document
  • Document::enableTaggedPdf(string $lang = 'en', ?ConformancePolicy $policy = null): static
  • Document::setLanguage(string $lang): static
  • \NextPDF\Conformance\ConformancePolicy::strictUa2(): self
  • \NextPDF\Conformance\ConformanceMode::PdfUa2 (chế độ do enableTaggedPdf() đặt)
  • Document::beginTag(string $type): static / Document::endTag(): static (gắn thẻ thủ công cho nội dung không phải HTML)
examples/31-pdfua2-tagged.php
<?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 expose
a 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";

Chương trình khép kín này có thể chạy trong harness. Trong môi trường thật, hãy báo lỗi sớm khi thẻ ngôn ngữ sai định dạng, thay vì chờ đến lúc trình kiểm tra bên ngoài chạy mới phát hiện. Hãy truyền ConformancePolicy::strictUa2() để từ chối một thẻ BCP-47 không hợp lệ ngay tại ranh giới API, rồi chặn bản build theo kết luận của trình kiểm tra.

<?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";

Trên máy chủ nơi verapdf --flavour ua2 báo cáo một tệp tuân thủ, standard output (STDOUT) dự kiến là:

veraPDF PASS — accessible.pdf carries a conforming UA-2 structure

Nếu enableTaggedPdf() từ chối thẻ ngôn ngữ, chương trình thoát với mã khác không sau khi ghi Tagged PDF/UA-2 setup rejected: … vào standard error (STDERR). Nếu trình kiểm tra báo cáo một vấn đề, chương trình thoát với mã khác không sau veraPDF FAILED — output is not PDF/UA-2 conforming. Bên đưa ra kết luận là trình kiểm tra: NextPDF phát ra cấu trúc nhưng không khẳng định mức tuân thủ.

  • Thứ tự gọi. enableTaggedPdf() sau writeHtml() không gắn thẻ hồi tố cho nội dung đã ghi. Hãy bật chế độ gắn thẻ trước.
  • Kiểm soát ngôn ngữ nghiêm ngặt. Nếu không có chính sách, một thẻ BCP-47 không phân tích được sẽ bị âm thầm bỏ qua và chỉ lộ ra khi trình kiểm tra chạy. Với ConformancePolicy::strictUa2(), chính thẻ đó ném InvalidConfigException tại ranh giới enableTaggedPdf() (ISO 14289-2 §8.4.4 nhánh nghiêm ngặt).
  • Bật lại bất biến (idempotent). Nếu bạn gọi enableTaggedPdf() hai lần, NextPDF cập nhật ngôn ngữ mà không dựng lại cây cấu trúc đã có nội dung.
  • Gắn thẻ thủ công. Với nội dung không phải HTML, hãy bọc các mục bằng beginTag() / endTag(). Các vai trò vùng chứa (Table, TR, L, LI) trở thành các phần tử nhóm không có nội dung được đánh dấu. Các vai trò lá (P, H1H6, TD) nhận mã định danh nội dung được đánh dấu (MCID).
  • Tính loại trừ theo chế độ. Một ConformancePolicy nghiêm ngặt chỉ hợp lệ với ConformanceMode::PdfUa2. Kết hợp các cờ UA-2 nghiêm ngặt với một chế độ PDF/A sẽ ném InvalidConfigException. Hãy tạo một sản phẩm PDF/A có gắn thẻ bằng cách bật chế độ gắn thẻ và hồ sơ PDF/A riêng biệt.

Cây cấu trúc bổ sung một cây song song gồm các từ điển nhẹ và các toán tử BDC/EMC theo từng đoạn văn bản. Với một báo cáo thông thường, chi phí phụ trội chỉ vài phần trăm kích thước đầu ra và nằm gọn trong ngân sách 2000 ms / 128 MB. Hồ sơ tái lập ở mức ngữ nghĩa được áp dụng vì đầu ra hướng đến trình kiểm tra được so sánh bằng abstract syntax tree (AST) cấu trúc cùng siêu dữ liệu, chứ không bằng byte thô. Xem phần Tuân thủ.

Cây cấu trúc mang cùng nội dung văn bản với nội dung hiển thị. Nếu HTML nguồn chứa dữ liệu cá nhân, bao gồm thông tin nhận dạng cá nhân (PII), dữ liệu đó cũng có thể được truy cập qua cây và qua các thuộc tính ActualText/Alt. Hãy áp dụng cùng biện pháp che thông tin và tối giản dữ liệu trước khi soạn nội dung, như bạn vẫn làm với nội dung hiển thị. Việc gắn thẻ không thêm con đường rò rỉ dữ liệu mới nào, nhưng theo thiết kế nó khiến văn bản có thể trích xuất được bằng chương trình.

Công thức chỉ ghi một dòng trạng thái cố định ra STDOUT. Nó định tuyến PDF tới kênh phụ của harness (NEXTPDF_COOKBOOK_OUTPUT) hoặc một đường dẫn do bên gọi chỉ định. Văn bản của tài liệu không bao giờ được ghi nhật ký. Hãy để đầu ra của trình kiểm tra, vốn có thể lặp lại các mảnh nội dung, nằm ngoài nhật ký dùng chung.

Một PDF có gắn thẻ không phải là ranh giới tin cậy. Nếu bên sử dụng của bạn tin tưởng cây cấu trúc để xử lý tự động, họ vẫn phải kiểm định tệp vì một bên tạo lập có ý đồ xấu có thể phát ra một cây đúng cấu trúc nhưng gây hiểu lầm. Hãy xem cấu trúc như một phương tiện hỗ trợ khả năng truy cập, không phải như một tín hiệu về tính toàn vẹn hay tính xác thực.

Công thức này không thực hiện thao tác mật mã nào. Chế độ Federal Information Processing Standards (FIPS) không làm thay đổi hành vi của nó. Không có thao tác ký hay mã hóa nào liên quan.

Yêu cầu PDF/UA-2NextPDF phát ra gìĐiều khoản
Nội dung thực nằm trong cây cấu trúcStructTreeRoot kèm StructElem theo từng khối và nội dung được đánh dấu liên kết qua MCIDISO 14289-2 §8.2.2
Thứ tự lồng nhau và thứ tự đọc được định nghĩaCác phần tử khối được ánh xạ tới các vai trò grouping/leaf theo thứ tự tài liệuISO 14289-2 §8.2.3
Namespace cấu trúc đã biếtCác vai trò trong namespace PDF 2.0; các thẻ HTML được ánh xạ vai trò khi cầnISO 14289-2 §8.2.4
Ngôn ngữ của tài liệu và từng phần tửMục Lang của catalog lấy từ thẻ BCP-47; Lang theo từng phần tử khi nó khác điISO 14289-2 §8.4.4
Nội dung phi văn bản có phương án thay thế dạng văn bảnAlt/ActualText được mang trên các phần tử cấu trúc figure/non-textISO 14289-2 §8.5.1
Quan hệ trong bảngTable/TR/TH/TD với vai trò cùng liên kết tiêu đềISO 14289-2 §8.2.5.26
Siêu dữ liệu nhận dạng phần (part)Nhận dạng ở cấp tài liệu được lên lịch ghi khi lưuISO 14289-2 §Phần giới thiệu (pdfua2#p17)

PDF/UA-2 đặt thêm các yêu cầu về khả năng truy cập lên bộ máy PDF có gắn thẻ của ISO 32000-2. NextPDF dựa vào ánh xạ này:

Đầu ra NextPDF phát raCơ chế ISO 32000-2 §14Điều khoản
Cây cấu trúc logic (StructTreeRoot)Cấu trúc logic của PDF có gắn thẻ§14.7 (iso32000_2_sec14#x1.x38.p13)
Catalog MarkInfo << /Marked true >>Dấu hiệu PDF có gắn thẻ§14.7 (iso32000_2_sec14#x1.x40.p3)
Mục Tabs theo từng trang tuân theo thứ tự cấu trúcĐiều hướng theo cấu trúc / thứ tự tab§14.8 (iso32000_2_sec14#x1.x50)

PDF/UA-2 là cách thể hiện trong định dạng PDF của những yêu cầu về cấu trúc mà Web Content Accessibility Guidelines (WCAG) 2.2 nêu ra theo cách độc lập với định dạng. Những tương ứng liên quan:

Tiêu chí thành công WCAG 2.2Cơ chế PDF/UA-2 mà công thức này tạo ra
1.3.1 Thông tin và quan hệ (Mức A)Cây cấu trúc làm cho các tiêu đề, danh sách và quan hệ trong bảng xác định được bằng chương trình (wcag_2_2#x2.x3.x3.x1.p3).
1.3.2 Trình tự có ý nghĩa (Mức A)Thứ tự cấu trúc xác định thứ tự đọc độc lập với bố cục hiển thị.
3.1.1 Ngôn ngữ của trang (Mức A)Mục Lang của catalog lấy từ thẻ BCP-47.
1.1.1 Nội dung phi văn bản (Mức A)Alt/ActualText trên các phần tử cấu trúc phi văn bản (ISO 14289-2 §8.5.1).

Ánh xạ này cho thấy cấu trúc được phát ra hỗ trợ từng tiêu chí WCAG 2.2 ở điểm nào. Đây không phải là một khẳng định tuân thủ WCAG. Mức tuân thủ WCAG bao trùm toàn bộ trải nghiệm người dùng, và một đợt đánh giá khả năng truy cập mới quyết định điều đó, chứ không phải bên tạo lập.

Phát biểuĐặc tảĐiều khoảnreference_id
Nội dung thực đòi hỏi cấu trúc logic.ISO 14289-2§8.2.2
Các phần tử cấu trúc tuân theo một thứ tự lồng nhau và thứ tự đọc đã định nghĩa.ISO 14289-2§8.2.3
Mọi phần tử cấu trúc phân giải về một namespace đã biết, trực tiếp hoặc qua ánh xạ vai trò.ISO 14289-2§8.2.4
Ngôn ngữ tự nhiên được khai báo ở cấp tài liệu và cấp phần tử cấu trúc.ISO 14289-2§8.4.4
Nội dung phi văn bản mang theo phương án thay thế dạng văn bản.ISO 14289-2§8.5.1
Các ô bảng mang theo quan hệ row/header/data.ISO 14289-2§8.2.5.26
Dấu hiệu PDF có gắn thẻ chính là cờ catalog MarkInfoMarked.ISO 32000-2§14.7
Mức tuân thủ được quyết định dựa trên phần (part), không phải do bên tạo lập khẳng định.ISO 14289-2§8.14.2

NextPDF phát ra cấu trúc có gắn thẻ để hỗ trợ việc soạn nội dung có thể truy cập. Hỗ trợ không đồng nghĩa với tuân thủ. Công thức này không khẳng định mức tuân thủ PDF/UA-2. Một trình kiểm tra độc lập, chẳng hạn veraPDF, mới đưa ra quyết định đó. Hãy chạy trình kiểm tra trước khi bạn tuyên bố rằng một tệp tuân thủ.