Tagged PDF (Accessibility)
The Accessibility module (StructureTreeManager, RoleMap, TaggedContentManager) enables tagged PDF output for screen readers and assistive technologies. When enabled, every piece of content is wrapped in structure elements that describe its semantic role. All tagging methods return static for chaining.
Quick Reference
| Method | Description |
|---|---|
setTaggedPdf() | Enable or disable tagged PDF mode |
setLanguage() | Set the document's primary language (BCP 47) |
openTag() | Begin a tagged structure element |
closeTag() | End a tagged structure element |
image(..., alt:) | Add an image with alt text for accessibility |
Enabling Tagged PDF
use Yeeefang\TcpdfNext\Core\Document;
$pdf = Document::create()
->setTaggedPdf(true)
->setLanguage('en-US')
->addPage()
->setFont('Helvetica', '', 12);When setTaggedPdf(true) is called, the StructureTreeManager is lazily initialized and a MarkInfo dictionary with Marked = true is written to the PDF catalog.
Structure Elements
TCPDF-Next supports the full PDF 2.0 standard tag set:
| Category | Tags |
|---|---|
| Grouping | Document, Part, Sect, Div, BlockQuote, Caption, NonStruct |
| Headings | H1, H2, H3, H4, H5, H6 |
| Paragraphs | P, Span |
| Lists | L, LI, Lbl, LBody |
| Tables | Table, TR, TH, TD, THead, TBody, TFoot |
| Inline | Link, Em, Strong, Code |
| Illustrations | Figure, Formula, Form |
Basic Tagging
use Yeeefang\TcpdfNext\Core\Document;
$pdf = Document::create()
->setTaggedPdf(true)
->setLanguage('en-US')
->addPage()
->setFont('Helvetica', '', 12)
->openTag('H1')
->cell(0, 10, 'Annual Report 2026', newLine: true)
->closeTag('H1')
->openTag('P')
->multiCell(0, 6, 'This document demonstrates tagged PDF output for accessibility compliance.')
->closeTag('P')
->save('tagged-basic.pdf');Tags must be properly nested. The StructureTreeManager validates nesting and throws an exception on mismatch.
Tagged Tables
$pdf->openTag('Table')
->openTag('TR')
->openTag('TH')->cell(50, 8, 'Quarter')->closeTag('TH')
->openTag('TH')->cell(50, 8, 'Revenue')->closeTag('TH')
->closeTag('TR')
->openTag('TR')
->openTag('TD')->cell(50, 8, 'Q1')->closeTag('TD')
->openTag('TD')->cell(50, 8, '$1,200,000')->closeTag('TD')
->closeTag('TR')
->closeTag('Table');Tag Attributes
Pass additional attributes when opening a tag:
$pdf->openTag('Figure', ['Alt' => 'Company logo', 'ActualText' => 'Acme Corp Logo'])
->image('/path/to/logo.png', 10, 50, 40, 40)
->closeTag('Figure');Common attributes:
| Attribute | Description |
|---|---|
Alt | Alternative text for non-text elements |
ActualText | Exact text replacement for the element |
Lang | Language override for this element (BCP 47) |
Title | Human-readable title |
The image() method also accepts an alt parameter as a shorthand — $pdf->image('chart.png', 10, 80, 120, 60, alt: 'Revenue chart') automatically wraps the image in a Figure tag.
Role Mapping
The RoleMap maps custom tag names to standard PDF structure types. This lets you use domain-specific names while maintaining PDF/UA compatibility:
$pdf->openTag('Invoice', ['roleMap' => 'Sect'])
->openTag('LineItem', ['roleMap' => 'P'])
->cell(0, 8, 'Widget x 10 — $500.00', newLine: true)
->closeTag('LineItem')
->closeTag('Invoice');The role map is written to the structure tree root so validators resolve custom tags to standard equivalents. For multilingual content, override the language per-element: ->openTag('P', ['Lang' => 'de-DE']).
PDF/UA Compliance
To produce a fully PDF/UA-compliant document, ensure:
- Tagged PDF is enabled —
setTaggedPdf(true) - Document language is set —
setLanguage('en-US') - All content is tagged — no untagged content outside structure elements
- All images have alt text — via
alt:parameter orFiguretag withAltattribute - Tables use
THfor headers — header cells must be distinguished from data cells - Fonts are embedded — TCPDF-Next embeds all fonts by default
Integration with PDF/A-4
Tagged PDF is fully compatible with PDF/A-4. Enable both for archival + accessible documents:
$pdf = Document::create()
->setTaggedPdf(true)
->setPdfA(true)
->setLanguage('en-US')
->setTitle('Accessible Archival Document')
->addPage()
->setFont('Helvetica', '', 12)
->openTag('H1')
->cell(0, 10, 'PDF/A-4 + PDF/UA Document', newLine: true)
->closeTag('H1')
->save('accessible-archival.pdf');