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

Trợ năng: các nguyên thủy gắn thẻ và mô hình cấu trúc PDF/UA-2

NextPDF Core cung cấp các nguyên thủy để tạo tài liệu trợ năng: cây cấu trúc logic, ánh xạ vai trò chuẩn, thẻ cho nội dung được đánh dấu và các thuộc tính ngôn ngữ Best Current Practice (BCP) 47 phù hợp với mô hình cây cấu trúc trong ISO 14289-2 (PDF/UA-2) và ISO 32000-2 §14.7. Tệp được tạo ra chỉ tuân thủ khi tài liệu cuối cùng, lựa chọn nội dung của tác giả và một trình kiểm tra bên ngoài cùng chứng thực kết quả đó. Thư viện không thay bạn khẳng định sự bảo đảm này.

Terminal window
composer require nextpdf/core

Một tệp Portable Document Format (PDF) đã gắn thẻ gồm một cây cấu trúc logic, trong đó gốc cây chứa đúng một phần tử cấu trúc Document. Công nghệ hỗ trợ đọc cây này để xác định thứ tự đọc có ý nghĩa, độc lập với bố cục trực quan (ISO 32000-2 §14.7.2; ISO 14289-2 §8.2.5.2). NextPDF mô hình hóa cơ chế này bằng ba kiểu phối hợp với nhau trong namespace NextPDF\Accessibility.

StructureTree sở hữu hệ thống phân cấp. Nó cấp phát định danh nội dung được đánh dấu cho từng trang, theo dõi quan hệ lồng nhau giữa phần tử cha và phần tử con, đồng thời tuần tự hóa gốc cây cấu trúc, các phần tử cấu trúc, cây cha, ánh xạ vai trò và namespace cấu trúc chuẩn PDF 2.0 theo ISO 32000-2 §14.7. createRoot() khởi tạo phần tử Document duy nhất bắt buộc cùng với một thuộc tính ngôn ngữ. addElement() gắn các phần tử con có kiểu. hasRoot()rootHasChildren() cho biết cây có tồn tại hay không và cây có phần tử con cháu hay không.

StructureElement là value object cho một từ điển phần tử cấu trúc. Nó lưu kiểu cấu trúc chuẩn (các tên trong Bảng 368 như H1 đến H6, P, L, LI, Table, Figure, Link), các mục định danh nội dung được đánh dấu và các thuộc tính trợ năng tùy chọn cho văn bản thay thế, văn bản thay thế nội dung, tiêu đề và ngôn ngữ. Một phần tử đơn lẻ có thể trải dài trên nhiều trang. Nó tích lũy một mục định danh cho mỗi trang để mảng kids tham chiếu được đến nội dung được đánh dấu xuyên qua ranh giới trang.

TaggedContentEmitter kết nối quy trình Hypertext Markup Language (HTML) với cây cấu trúc. Khi Document::enableTaggedPdf() đang hoạt động, bộ kết xuất HTML sẽ kết nối bộ phát để các phần tử cấp khối tạo ra các cặp toán tử nội dung được đánh dấu cùng với các nút phần tử cấu trúc tương ứng. HtmlToStructureMap cung cấp ánh xạ dạng bảng từ thẻ HTML sang kiểu cấu trúc PDF (ISO 14289-2 §8). Bộ phát chuyển nội dung trang trí lặp lại, chẳng hạn như vùng đầu trang và chân trang HTML, thành artifact và giữ chúng ngoài thứ tự đọc.

Bcp47Validator xác thực thẻ ngôn ngữ (Request for Comments (RFC) 5646). Nó cung cấp một bước kiểm tra cú pháp đúng định dạng và một bước kiểm tra tính hợp lệ dựa trên sổ đăng ký. Chế độ nghiêm ngặt (ConformancePolicy::strictUa2()) từ chối các thẻ sai định dạng ngay tại ranh giới application programming interface (API), thay vì âm thầm loại bỏ chúng khi ghi. Điều này phù hợp với yêu cầu ISO 14289-2 §8.4.4 rằng mục ngôn ngữ trong catalog phải phân giải về một ngôn ngữ cụ thể.

Ký hiệuLoạiTóm tắt
Document::enableTaggedPdf(string $lang = 'en', ?ConformancePolicy $policy = null): staticphương thứcKích hoạt cây cấu trúc và cầu nối HTML; đặt các mục mark-info và mục ngôn ngữ trong catalog.
Document::setLanguage(string $lang): staticphương thứcĐặt ngôn ngữ tự nhiên ở cấp tài liệu (BCP-47).
Document::isTaggedPdfEnabled(): boolphương thứcCho biết liệu chế độ tuân thủ đang hoạt động có yêu cầu bắt buộc gắn thẻ cấu trúc hay không.
StructureTree::createRoot(string $lang = 'en'): intphương thứcTạo phần tử gốc Document duy nhất bắt buộc.
StructureTree::addElement(int $parentIndex, string $type, int $pageIndex, ...): intphương thứcGắn một phần tử cấu trúc con có kiểu.
StructureTree::hasRoot(): boolrootHasChildren(): boolphương thứcCho biết cây có tồn tại hay không và cây có phần tử con cháu hay không.
StructureElementfinal classValue object cho một phần tử cấu trúc (văn bản thay thế, văn bản thay thế nội dung, tiêu đề, ngôn ngữ, định danh).
RoleMap::standard(): array<string,string>staticTrả về bộ từ vựng kiểu cấu trúc chuẩn (ISO 32000-2 Bảng 368 cùng các kiểu PDF 2.0).
Bcp47Validator::isWellFormed/isValid/validate/normalisephương thứcXác thực các thẻ ngôn ngữ RFC 5646 bằng các bước kiểm tra cú pháp và kiểm tra dựa trên sổ đăng ký.
AccessibilityAutoFixerRegistryfinal classSổ đăng ký theo phong cách PHP Standards Recommendation (PSR)-11 dạng tùy chọn bật cho các bộ sửa cấu trúc theo phương pháp suy luận.
<?php
declare(strict_types=1);
use NextPDF\Core\Document;
$doc = Document::createStandalone();
// The BCP 47 tag drives the catalog language entry and the
// structure-tree root language attribute.
$doc->enableTaggedPdf(lang: 'en');
$doc->setTitle('Tagged accessibility demo');
$doc->addPage();
// Semantic HTML maps to structure elements: h1 to /H1, p to /P,
// ul and li to /L plus /LI. Text runs are wrapped in
// marked-content operators with stable identifiers.
$doc->writeHtml('<h1>Document title</h1><p>Body paragraph.</p>');
$doc->save(__DIR__ . '/output/tagged.pdf');
<?php
declare(strict_types=1);
use NextPDF\Conformance\ConformancePolicy;
use NextPDF\Core\Document;
use NextPDF\Exception\InvalidConfigException;
use Psr\Log\LoggerInterface;
final class AccessibleReportWriter
{
public function __construct(private readonly LoggerInterface $logger)
{
}
public function render(string $html, string $bcp47Lang, string $outPath): void
{
$doc = Document::createStandalone();
try {
// strictUa2() rejects malformed BCP 47 tags at the API
// boundary (ISO 14289-2 §8.4.4) instead of dropping silently.
$doc->enableTaggedPdf($bcp47Lang, ConformancePolicy::strictUa2());
} catch (InvalidConfigException $e) {
$this->logger->error('Rejected language tag for tagged PDF', [
'lang' => $bcp47Lang,
'reason' => $e->getMessage(),
]);
throw $e;
}
$doc->setTitle('Quarterly accessibility report')
->setLanguage($bcp47Lang)
->addPage();
$doc->writeHtml($html);
// The engine emits a Degraded / ComplianceRisk advisory directing
// the caller to validate externally; surface it to operators
// rather than treating tagged output as certified.
foreach ($doc->getWarnings() as $warning) {
$this->logger->warning('Tagged-PDF advisory', [
'code' => $warning->code->value,
'message' => $warning->message,
]);
}
$doc->save($outPath);
}
}
  • Thứ tự gọi. Gọi enableTaggedPdf() trước writeHtml(). Quy trình HTML kiểm tra chế độ tuân thủ khi trình phân tích được khởi tạo và không kết nối hồi tố bộ phát cho nội dung đã kết xuất.
  • Cây cấu trúc rỗng. Một tài liệu có enableTaggedPdf() nhưng không gắn phần tử cấu trúc con cháu nào thì không công bố PDF/UA-2 trong metadata. Cổng kiểm soát khi xuất bản là rootHasChildren(), không phải hasRoot(), vì các trình kiểm tra từ chối tệp tuyên bố PDF/UA-2 nhưng có cây cấu trúc rỗng (ISO 14289-2 §5; được kiểm chứng bởi EmptyTaggedPdfDoesNotAdvertisePdfUa2Test).
  • Sự suy giảm chế độ tuân thủ. Khi bạn gọi enablePdfA()enableTaggedPdf() trên cùng một tài liệu, bộ phân biệt tuân thủ đơn giá trị thu gọn về giá trị được gọi sau cùng. Các tác dụng phụ (cây cấu trúc, mark-info) vẫn cộng dồn, và NextPDF phát ra cảnh báo CONFORMANCE_MODE_CLOBBERED để có thể quan sát được sự suy giảm này.
  • Các bộ tự động sửa không hề tự động. Các bộ sửa tích hợp sẵn (EmptyTagStripper, LegacyLangNormaliser, RootLangFallback) được phân phối trong NextPDF\Accessibility\AutoFixer\* nhưng không bao giờ được đăng ký tự động. Bạn phải đăng ký chúng một cách tường minh trên AccessibilityAutoFixerRegistry.

NextPDF phát ra cấu trúc nhất quán với mô hình cây cấu trúc PDF/UA-2, nhưng không tạo ra ngữ nghĩa mà nó không thể suy luận. Bạn phải cung cấp markup hoặc thuộc tính cho những mục sau; NextPDF không tạo chúng thay cho bạn:

  • văn bản thay thế cho hình ảnh và các nội dung phi văn bản khác;
  • phạm vi tiêu đề bảng và liên kết giữa tiêu đề với ô vượt ngoài những gì markup HTML thể hiện;
  • văn bản mô tả mục đích liên kết khi văn bản liên kết hiển thị không tự mô tả được;
  • ngữ nghĩa danh sách cho nội dung được trình bày trực quan như một danh sách nhưng thiếu markup danh sách;
  • thứ tự đọc đã hiệu chỉnh khi thứ tự nguồn khác với thứ tự đọc mong muốn;
  • việc phân loại trang trí so với có ý nghĩa cho nội dung mơ hồ.

NextPDF không kiểm chứng PDF/UA-2 đầu cuối. Trong lúc chạy, nó phát ra thông báo Degraded / ComplianceRisk (PDFUA2_FOUNDATIONAL) hướng dẫn bên gọi xác thực đầu ra bằng một trình kiểm tra bên ngoài trước khi phê duyệt cho sản xuất. Hãy xác thực bằng một trình kiểm tra PDF/UA (ví dụ, veraPDF). NextPDF không khẳng định tính tuân thủ thay cho bạn. Tính tuân thủ của tài liệu cuối cùng phụ thuộc vào các lựa chọn khi tạo tài liệu và một trình kiểm tra, chứ không phụ thuộc vào việc gọi API.

Việc dựng cây cấu trúc tuyến tính theo số lượng phần tử cấu trúc. Việc cấp phát định danh có thời gian hằng số khấu hao cho mỗi chuỗi nội dung được đánh dấu. Việc tuần tự hóa là một lượt duyệt tuyến tính duy nhất qua tập phần tử. Với quy trình gắn thẻ do HTML điều khiển, chi phí chủ đạo nằm ở chính quy trình HTML, không phải ở việc phát thẻ. Giới hạn theo từng recipe được khai báo trong performance_budget (1500 ms thời gian thực, 64 MB đỉnh) áp dụng cho một tài liệu ngữ nghĩa nhiều trang điển hình. Các tài liệu lớn tăng tuyến tính theo số lượng phần tử chứ không theo số lượng trang.

Các thẻ ngôn ngữ và thuộc tính trợ năng đi vào các đối tượng name và string của PDF. NextPDF thoát chúng qua PdfStringEscaper, nên các giá trị ngôn ngữ, văn bản thay thế, văn bản thay thế nội dung và tiêu đề sai định dạng hoặc độc hại không thể thoát khỏi ngữ cảnh đối tượng PDF của chúng. Chế độ nghiêm ngặt cũng từ chối các thẻ BCP-47 chưa được đăng ký ngay tại ranh giới API, thu hẹp bề mặt đầu vào trước khi chúng đến writer. Các thuộc tính trợ năng có thể chứa văn bản tự do do tác giả cung cấp. Hãy coi chúng là đầu ra không đáng tin cậy và rà soát như mọi nội dung tài liệu khác. Xem mô-đun Conformance để biết hành vi của trình kiểm tra hồ sơ.

Trang này ánh xạ hành vi của thư viện tới các định danh điều khoản. Nó không khẳng định rằng đầu ra của bạn tuân thủ. Các điều khoản được trích dẫn đều được diễn giải lại, không bao giờ trích nguyên văn. Xem ánh xạ đặc tả PDF/UA-2 để biết bảng ở cấp điều khoản và phần phạm vi không bao phủ được nêu rõ. Các hash khối trích dẫn được ghi lại trong docs/public/modules/core/_normative-evidence-a11y.md.