PDF/UA-Barrierefreiheit
PDF/UA (ISO 14289) definiert die Anforderungen an universell zugängliche PDF-Dokumente. PDF Oxide validiert Strukturbäume, Überschriftenabfolgen, Alternativtexte, Tabellenüberschriften, Sprachdeklarationen und mehr.
Abdeckung in den Bindings. Die PDF/UA-Validierung ist in Python (
doc.validate_pdf_ua()), Rust (validate_pdf_ua+ BuilderPdfUaValidator) und Go (doc.ValidatePdfUa()) verfügbar. WASM stellt, sofern vorhanden, übervalidatePdfUaeine einfache Bestanden/Nicht-bestanden-Prüfung bereit. Ein öffentlicher C#-Wrapper ist noch nicht verfügbar — nutzen Sie die Rust-CLI (pdf-oxide validate --pdfua doc.pdf) oder rufen Sie die Prüfung über eines der unterstützten Bindings auf.
Unterstützte Stufen
| Stufe | Standard | Beschreibung |
|---|---|---|
| PDF/UA-1 | ISO 14289-1:2014 | Grundlegende Anforderungen an die Barrierefreiheit |
| PDF/UA-2 | ISO 14289-2:2024 | Erweiterte Anforderungen, abgestimmt auf WCAG 2.1 |
Schnelle Validierung
from pdf_oxide import PdfDocument
doc = PdfDocument("document.pdf")
result = doc.validate_pdf_ua()
print(f"Valid: {result.valid}")
for error in result.errors:
print(f" {error}")
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{validate_pdf_ua, PdfUaLevel};
let mut doc = PdfDocument::open("accessible.pdf")?;
let result = validate_pdf_ua(&mut doc, PdfUaLevel::UA1)?;
if result.has_errors() {
println!("Not PDF/UA-1 compliant:");
for error in &result.errors {
println!(" [{}] {} (clause {})",
error.code, error.message,
error.clause.as_deref().unwrap_or("n/a"));
}
} else {
println!("Document is PDF/UA-1 compliant");
}
doc, err := pdfoxide.Open("accessible.pdf")
if err != nil { log.Fatal(err) }
defer doc.Close()
valid, errs, err := doc.ValidatePdfUa()
if err != nil { log.Fatal(err) }
if valid {
fmt.Println("Document is PDF/UA-1 compliant")
} else {
fmt.Println("Not PDF/UA-1 compliant:")
for _, e := range errs {
fmt.Printf(" %s\n", e)
}
}
Validator-API
Der Builder PdfUaValidator erlaubt das Konfigurieren bestimmter Prüfungen:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{PdfUaValidator, PdfUaLevel};
let mut doc = PdfDocument::open("report.pdf")?;
let result = PdfUaValidator::new()
.check_heading_sequence(true)
.check_color_contrast(true)
.allow_custom_types(vec!["Caption".into(), "Aside".into()])
.validate(&mut doc, PdfUaLevel::UA1)?;
println!("Errors: {}", result.errors.len());
println!("Warnings: {}", result.warnings.len());
println!("Structure elements checked: {}",
result.stats.structure_elements_checked);
Konfigurationsoptionen
| Methode | Standard | Beschreibung |
|---|---|---|
check_heading_sequence(bool) |
true |
Prüft, ob H1-H6 keine Ebenen überspringen |
check_color_contrast(bool) |
true |
Markiert mögliche Kontrastprobleme |
allow_custom_types(Vec<String>) |
[] |
Lässt nicht standardisierte Strukturtypen ohne Warnung zu |
Untersuchung des Strukturbaums
Vor der Validierung können Sie den Strukturbaum und die Markierungsinformationen des Dokuments untersuchen:
use pdf_oxide::PdfDocument;
let mut doc = PdfDocument::open("tagged.pdf")?;
// Check if the document claims to be tagged
let mark_info = doc.mark_info()?;
println!("Marked: {}", mark_info.marked);
println!("Suspects: {}", mark_info.suspects);
// Access the structure tree
if let Some(tree) = doc.structure_tree()? {
println!("Root tag: {}", tree.root_type);
println!("Children: {}", tree.children.len());
}
Die Methode mark_info() gibt zurück:
| Feld | Typ | Beschreibung |
|---|---|---|
marked |
bool |
Ob sich das Dokument als getaggt deklariert |
suspects |
bool |
Ob Tag-Zuordnungen möglicherweise fehlerhaft sind |
user_properties |
bool |
Ob Benutzereigenschaften vorhanden sind |
Wenn suspects true ist, greift PDF Oxide bei der Textextraktion automatisch auf die geometrische Anordnung zurück, anstatt sich auf den möglicherweise unzuverlässigen Strukturbaum zu verlassen.
Was geprüft wird
Der Validator deckt die folgenden PDF/UA-Anforderungen ab:
Dokumentebene
| Prüfung | Abschnitt | Beschreibung |
|---|---|---|
| Sprache | 7.2 | Eintrag /Lang im Katalog vorhanden |
| Titel | 7.1 | Dokumenttitel gesetzt und in der Titelleiste angezeigt |
| Getaggt | 7.1 | Das MarkInfo-Dictionary deklariert Marked = true |
| XMP-Metadaten | 7.1 | pdfuaid:part im XMP-Stream deklariert |
Struktur
| Prüfung | Abschnitt | Beschreibung |
|---|---|---|
| Strukturbaum | 7.1 | Vollständiger Strukturbaum mit StructTreeRoot als Wurzel |
| Rollenzuordnung | 7.5 | Nicht standardisierte Typen auf Standard-Strukturelemente abgebildet |
| Überschriftenhierarchie | 7.4.2 | Überschriften (H1-H6) überspringen keine Ebenen |
| Artefaktmarkierung | 7.3 | Dekorative Inhalte als Artefakt markiert |
| Lesereihenfolge | 7.2 | Der Strukturbaum definiert eine logische Lesereihenfolge |
Inhalt
| Prüfung | Abschnitt | Beschreibung |
|---|---|---|
| Alternativtext für Bilder | 7.3 | /Alt oder /ActualText an Figure-Elementen |
| Tabellenüberschriften | 7.5 | TH-Elemente in Tabellenstrukturen vorhanden |
| Formularbeschriftungen | 7.6.2 | Formularfelder haben zugeordnete Beschriftungen oder Tooltips |
| Linktext | 7.18 | Link-Annotationen haben beschreibenden Inhalt |
| Listenstruktur | 7.4.3 | Listen verwenden die Struktur L, LI, Lbl, LBody |
Schrift und Text
| Prüfung | Abschnitt | Beschreibung |
|---|---|---|
| Unicode-Zuordnung | 7.21.3 | Sämtlicher Text hat eine Unicode-Repräsentation |
| Schrifteinbettung | 7.21.4 | Schriften eingebettet oder Standard-Base14-Schriften |
| ActualText | 7.21.5 | Ligaturen und Sonderglyphen haben /ActualText |
UaValidationResult
pub struct UaValidationResult {
pub level: PdfUaLevel,
pub errors: Vec<UaComplianceError>,
pub warnings: Vec<ComplianceWarning>,
pub stats: UaValidationStats,
}
UaComplianceError
Jeder Fehler enthält einen optionalen WCAG-Abgleich:
pub struct UaComplianceError {
pub code: UaErrorCode,
pub message: String,
pub location: Option<String>,
pub wcag_ref: Option<String>,
pub clause: Option<String>,
}
Das Feld wcag_ref ordnet den PDF/UA-Verstoß dem entsprechenden WCAG-Erfolgskriterium zu (z. B. "1.1.1" für Nicht-Text-Inhalte, "1.3.1" für Info und Beziehungen).
Kategorien von UaErrorCode
Das Enum UaErrorCode umfasst Fehlerkategorien wie:
MissingLanguage– kein/Lang-Eintrag im DokumentkatalogMissingStructureTree– Dokument ist nicht getaggtMissingAltText– Figure-Element ohne AlternativtextHeadingSkipped– Überschriftenebenen werden übersprungen (z. B. von H1 zu H3)MissingTableHeaders– Tabelle ohneTH-ElementeFormFieldNoLabel– Formularfeld ohne zugeordnete BeschriftungInvalidRoleMapping– nicht standardisierter Typ nicht auf ein Standardelement abgebildetArtifactNotMarked– dekorativer Inhalt nicht als Artefakt markiertMissingUnicode– Text ohne Unicode-Zuordnung
Praktisches Beispiel: Barrierefreiheitsbericht
Erzeugen Sie aus den Validierungsergebnissen einen menschenlesbaren Barrierefreiheitsbericht:
use pdf_oxide::PdfDocument;
use pdf_oxide::compliance::{validate_pdf_ua, PdfUaLevel};
let mut doc = PdfDocument::open("document.pdf")?;
let result = validate_pdf_ua(&mut doc, PdfUaLevel::UA1)?;
println!("=== PDF/UA Accessibility Report ===");
println!("Level: PDF/UA-{}", result.level.xmp_part());
println!("Status: {}", if result.has_errors() { "FAIL" } else { "PASS" });
println!();
if result.has_errors() {
println!("Errors ({}):", result.errors.len());
for (i, error) in result.errors.iter().enumerate() {
print!(" {}. [{}] {}", i + 1, error.code, error.message);
if let Some(ref wcag) = error.wcag_ref {
print!(" (WCAG {})", wcag);
}
println!();
}
}
if result.has_warnings() {
println!("\nWarnings ({}):", result.warnings.len());
for warning in &result.warnings {
println!(" - [{}] {}", warning.code, warning.message);
}
}
println!("\nStats:");
println!(" Structure elements checked: {}",
result.stats.structure_elements_checked);
Nächste Schritte
- PDF/A-Validierung – Konformität für die Langzeitarchivierung
- PDF/X-Druckproduktion – Konformität für die Druckproduktion
- API-Referenz – vollständige Rust-API