Is your PDF accessible?
A screen reader can't infer your document. It needs tags that say what's a heading and what order to read things, alt text on the images, a declared language, a title to announce. Most PDFs carry none of that. access checks in seconds, and is honest about where its judgment ends.
How to do it
pip install pdfblah
pdfblah access report.pdf
tagged: NO | language: NO | title: yes | text layer: yes | bookmarks: yes
problem: not tagged: no structure tree, so a screen reader gets a bag of text with no headings or order
problem: no document language declared (/Lang); screen readers can't pick a voice
mechanical checks only: failing means not accessible; passing does not certify.
What gets checked
- Tags. A marked structure tree is the skeleton of accessibility; without it there is nothing to fix, only everything.
- Language and title. The two one-line fixes with outsized effect: the voice a reader picks, and what it announces instead of "download (3).pdf". (Title also needs viewers told to display it; the report checks that too.)
- Alt text. Tagged figures are counted against how many actually carry a description.
- A text layer at all. A scan reads as silence; OCR is the first fix, and the report says so.
- Bookmarks on long documents, as an advisory, plus whether the file claims PDF/UA in its metadata.
The honest boundary
These are the checks a machine can make deterministically, and that cuts both ways. Failing them means the document is not accessible. Passing them does not certify it: tags can exist and be wrong, reading order can be nonsense, alt text can say "image". Judging that takes eyes. Formal validation is veraPDF and PAC territory, and repairing structure is authorship work in a remediation tool, not a conversion. This command tells you, honestly and in exit codes (1 when problems exist, so it gates a publish), whether a document is even trying.
Tips
- The cheap wins first: OCR the scans, set a title (
pdfblah meta in.pdf out.pdf --set title="Annual Report"), add bookmarks. A one-flag language setter is on the engine backlog; until then the language fix lives in your authoring tool. - Check before you publish, like links: both exit 1 on problems and slot into CI.
- Under the European Accessibility Act and ADA, "we didn't know" ages badly; a 60-second check is cheap knowledge.