Procurement portals parse the text out of your submission. Search engines index it. Compliance tools scan it for terms. Applicant systems read CVs. None of them look at the page; they all extract.
So I tested what actually comes back out. Five Arabic strings, written into PDFs by four generators, read back by three extractors.
Nothing is reliable, and the ends invert
| Generator | pypdf | pdfminer.six | poppler |
|---|---|---|---|
| Chrome (HTML → PDF) | 3/5 | 0/5 | 1/5 |
| ReportLab (naive) | 0/5 | 5/5 | 0/5 |
| ReportLab (+ reshaper) | 3/5 | 0/5 | 3/5 |
| LibreOffice (.docx → PDF) | 5/5 | 0/5 | 2/5 |
ReportLab-naive extracts perfectly through pdfminer and fails every other reader. Chrome — the route most web tooling uses — is zero for five through pdfminer, which is what a great many document pipelines run.
You cannot pick a “good” PDF library or a “good” extractor.
Correctness belongs to the pair, and when you submit a PDF you do not control
the reader on the other side.
Why pdfminer inverts
pdfminer is zero for five against three generators and five for five against exactly one — the only one that performs no text layout. That is not coincidence, and it explains the whole table.
ReportLab-naive writes characters into the PDF in logical order, because it does no shaping and no bidi. Chrome, LibreOffice and reshaped ReportLab all lay the line out visually first, so the file stores glyphs in visual order. pdfminer returns what is stored without re-applying bidi, so it is correct precisely when the generator was naive. pypdf and poppler apply their own reordering heuristics, which is why they land in between.
The question a PDF actually answers is not “is the Arabic correct”.
It is which order the text is stored in, and whether this reader re-applies
bidi. No tool tells you either.
Three failure modes, not one
My first read of this was “Arabic comes back reversed”. That was too crude — only one failure in eleven was an actual reversal. Separating them matters, because they need different fixes and one of them is far more dangerous than the others.
| Mode | Source | Extracted |
|---|---|---|
| Reversed — visual order, reads backwards | مرحبا بكم في دولة الإمارات | تاراملإا ةلود يف مكب ابحرم |
| Ligature — lam-alef returns as two letters, wrong order | الإمارات | اإلمارات |
| Spacing — letters intact, boundaries lost | النسبة 2026 في | النسبة2026في |
The ligature mode is the one to fear. A reader skims straight past it — the difference is a single swapped pair inside a common word — so it survives human proofreading while still breaking exact-match search, keyword compliance checks and any automated comparison. It was the most common failure in the whole matrix: seventeen occurrences against nine reversals.
The same recipe, opposite verdicts
The ReportLab rows confirm part two from the
other direction. ReportLab performs no complex-text layout, so there the
arabic_reshaper recipe is genuinely required — it takes
that generator from 0/5 to 3/5 through poppler. In Chrome, the same recipe corrupts
the output. One rule, opposite results, decided entirely by whether the renderer
already shapes.
What this does not cover
Microsoft Word itself, InDesign and LaTeX are untested. LibreOffice covers the .docx route — it is the dominant headless converter and the realistic path a Word file takes on its way to a portal — but it is a different engine from Word and may lay text out differently. InDesign and LaTeX are not installed on the machine I ran this on, and WeasyPrint could not run because it needs Pango. I would rather say that than imply coverage I do not have; the harness takes a new generator in about ten lines.
What to do about it
- If a PDF containing Arabic will be read by software, test the round trip yourself. Do not assume it survived because the page looks right.
- Where the recipient allows it, submit a format that carries text losslessly alongside the PDF.
- If you generate PDFs programmatically, check which of the two rendering worlds your library lives in before adding or removing reshaping.
- Search for a common word from your own document in the extracted text. If الإمارات does not match, nothing downstream will find it either.
The data
Every generator × extractor combination, with the text each one returned, is published as ArPDF on Hugging Face, alongside ArNum-TTS and ArShape.
The series: part one, speech · part two, the screen · part three, the page.