7. PDF/A & accessibility
Producing archival PDF/A output and accessible, tagged documents.
A PDF you file for the long term, or hand to someone using a screen reader, has to carry more than pixels. It needs embedded fonts so it renders the same in 2050, a declared language, machine-readable structure so a reader can follow the logical order, and metadata that says exactly which standard it conforms to. This chapter covers the three switches that produce such documents (PDF/A mode, tagged structure, and XMP metadata) and how they fit together.
All of these go through PdfDocumentRenderer and PdfSaveOptions, the same path
you used for security.
PDF/A conformance
Section titled “PDF/A conformance”PDF/A (ISO 19005) is the archival profile: it constrains PDF so a document
reproduces reliably for decades. Embed all fonts, use device-independent colour,
carry XMP metadata with a PDF/A identifier, and (crucially), no encryption,
no JavaScript, no external references. You opt in with
PdfSaveOptions.PdfAMode:
using Rivoli.Pdf;
var renderer = new PdfDocumentRenderer("1.4");renderer.RenderToFile(doc, "archive.pdf", new PdfSaveOptions{ PdfAMode = PdfAMode.PdfA1b, Language = "en-US",});The PdfAMode enum (namespace Rivoli.Pdf) offers:
| Value | Conformance | Notes |
|---|---|---|
None | n/a | Standard PDF (the default) |
PdfA1b | PDF/A-1b, Level B (Basic) | Reliable visual reproduction; fonts embedded, device-independent colour, PDF/A XMP. Based on PDF 1.4 |
PdfA1a | PDF/A-1a, Level A (Accessible) | Everything in 1b plus tagged structure, declared language, and Unicode mapping for a logical reading order |
Later parts of the family (PDF/A-2, PDF/A-3) are noted as future work in the enum and are not yet selectable.
Tagged PDF (logical structure)
Section titled “Tagged PDF (logical structure)”A tagged PDF carries a structure tree: a logical outline of headings,
paragraphs, lists, tables, and the reading order through them. This is what makes
a document navigable by assistive technology rather than a flat wall of glyphs.
Turn it on with EnableTaggedPDF:
renderer.RenderToFile(doc, "accessible.pdf", new PdfSaveOptions{ EnableTaggedPDF = true, Language = "en-US",});Tagging is coupled to the accessible profile: selecting PdfAMode.PdfA1a
implies tagged output even if you do not set the flag explicitly, because Level A
requires a structure tree. The renderer writes a StructTreeRoot, a
MarkInfo dictionary, and marks every painting operator: content that is not
semantic (decorative rules, backgrounds) is wrapped as an /Artifact so it is
accounted for rather than left untagged.
Language
Section titled “Language”A declared natural language lets a screen reader pick the right pronunciation
rules and is mandatory for Level A and PDF/UA. Set it with Language (BCP-47
tag), which the renderer writes as the catalog /Lang:
Language = "en-US", // or "fr-FR", "de-DE", …If you do not set it, the value falls back to PdfGlobalOptions.DefaultLanguage.
XMP metadata
Section titled “XMP metadata”XMP is the standardized, embedded metadata stream that carries the document’s
title, authorship, and (for conformance), the identifiers that declare which
standard the file meets. It is controlled by IncludeXmpMetadata:
renderer.RenderToFile(doc, "archive.pdf", new PdfSaveOptions{ PdfAMode = PdfAMode.PdfA1b, IncludeXmpMetadata = true, Language = "en-US",});When you request PDF/A, the XMP stream carries the PDF/A identification schema
(pdfaid:part and pdfaid:conformance, e.g. part 1 / level B). When the output
is fully tagged, the renderer additionally declares PDF/UA-1 conformance through
the pdfuaid identifier, and registers the pdfuaid extension schema as
ISO 19005-1 §6.7.9 requires for unrecognized namespaces. Title and author come
from the document’s Metadata, so populate that when you create the document:
var doc = Document.Create("Annual Report 2025", "Finance Team");doc.Metadata.Subject = "Year-end financial summary";doc.Metadata.Keywords = "finance, annual, 2025";Accessibility / PDF/UA
Section titled “Accessibility / PDF/UA”PDF/UA (ISO 14289, “Universal Accessibility”) is the accessibility profile built on top of tagged PDF: a structure tree, a declared language, artifacted non-content, and the metadata that asserts conformance. There is no separate “PDF/UA mode” switch: you produce a PDF/UA-shaped document by enabling tagging, declaring a language, and including XMP:
renderer.RenderToFile(doc, "ua.pdf", new PdfSaveOptions{ EnableTaggedPDF = true, IncludeXmpMetadata = true, Language = "en-US",});Putting it together
Section titled “Putting it together”A fully archival, accessible document is just the three switches together: minus encryption, which the profile forbids:
var doc = Document.Create("Compliance Report", "Records Office");
var renderer = new PdfDocumentRenderer("1.4");renderer.RenderToFile(doc, "report-archival.pdf", new PdfSaveOptions{ PdfAMode = PdfAMode.PdfA1a, // Level A implies tagging IncludeXmpMetadata = true, Language = "en-US", // SecuritySettings here would make Validate() throw.});- How-to guides: task-focused recipes that build on these options.
- The document model: why a clean structure tree starts with clean authoring.
- 6. Security: encryption & signatures: the access-control side, and why it is mutually exclusive with PDF/A.