Papero is een CPU-gebaseerde, open-source tool voor het extraheren van tekst en documentstructuren uit PDF-bestanden. Het is specifiek ontworpen om bruikbare output te genereren voor RAG-systemen en LLM's door structuren zoals kolommen, tabellen en formules nauwkeurig te herkennen.
De belangrijkste kenmerken zijn:
- Structuurbehoud: Het herkent de leesvolgorde van multi-kolom documenten en zet tabellen en formules (via LaTeX) correct om.
- Visuele extractie: Figuren, grafieken en formules kunnen worden uitgesneden als PNG-bestanden.
- Precisie: Elk geëxtraheerd blok is voorzien van een bounding box voor exacte positionering.
- Veelzijdige export: Ondersteuning voor Markdown, JSON, HTML, CSV, Word (.docx) en Excel (.xlsx).
- Implementatie: De tool is beschikbaar als Python-library, CLI-tool, REST API (via Docker) en als browser-app.
Technisch gezien combineert Papero een eigen Layout Engine (gebaseerd op PDFium) met Apache Tika voor metadata en OCR-ondersteuning via Tesseract.
Papero PDF Text Extractor: Een snelle, open-source API voor PDF-tekstextractie
De tool werkt uitsluitend op de CPU en maakt geen gebruik van ML-modellen. Het kan worden uitgevoerd in de browser, in Python of als een API.
Waarom Papero?
Het extraheren van tekst uit een PDF is eenvoudig, maar het herstellen van de structuur — zoals bepalen welke kolom eerst komt, welke regels een tabel vormen en waar een formule staat — is essentieel om de output bruikbaar te maken voor RAG (Retrieval-Augmented Generation), zoekfuncties en LLM's. Papero bereikt dit via eenvoudige geometrie, waardoor het snel blijft draaien op een laptop-CPU.
Belangrijkste kenmerken
- Leesvolgorde: Documenten met twee of drie kolommen worden kolom voor kolom gelezen. Headers, footers, paginanummers en herhaalde logo's worden apart gezet.
- Echte tabellen: Tabellen met lijnen, zonder randen en LaTeX booktabs-tabellen worden omgezet naar rijen en kolommen, inclusief cellen met meerdere regels. Export naar CSV of Excel is mogelijk.
- Formules: Bovenschriften, onderschriften en wiskundige symbolen worden omgezet naar LaTeX (bijv. $E = mc^{2}$), aangevuld met een uitgesneden afbeelding van de formule.
- Positie van alle elementen: Elk blok heeft een bounding box. Hierdoor kun je in een RAG-antwoord naar de exacte plek verwijzen, over de pagina tekenen of delen uitknippen.
- Figuren & grafieken: Afbeeldingen en vectorgrafieken worden uitgesneden als PNG, waarbij het bijschrift, de aslabels en de legenda behouden blijven.
- Terug naar Word: Uitlijning, inspringingen, regelafstand, vetgedrukte teksten en lettertypen worden behouden, zodat een
.docx-export lijkt op de originele pagina.
Aanvullende functionaliteiten:
- Accenttekens die in LaTeX-PDF's als aparte tekens zijn getekend (bijv. Computa¸ca˜o → Computação) worden gecorrigeerd.
- Onzichtbare witte tekst (vaak gebruikt door formuliergeneratoren) wordt verwijderd.
- Gescannde pagina's worden verwerkt via OCR.
- DOCX, PPTX, XLSX, EPUB en HTML worden gelezen via Apache Tika.
Snel aan de slag
Installatie
pip install papero-extract
Basisgebruik in Python
from pdf_text_api import extract
doc = extract("paper.pdf")
print(doc.to_markdown())
Alternatief: Gebruik de browser-app om een PDF te uploaden en te exporteren naar het gewenste formaat zonder installatie.
Geavanceerd Python-gebruik (tabellen, formules, posities, afbeeldingen)
from pdf_text_api import extract, extract_text
doc = extract("paper.pdf", images=True)
# Toegang tot tabelgegevens
doc.tables[0].rows # [["Model", "Accuracy"], ["Base", "0.81"], ...]
# Toegang tot LaTeX-formules
doc.formulas[0].latex # "E = mc^{2}"
# Toegang tot afbeeldingen (PNG bytes)
doc.figures[0].image.data
# Doorloop blokken per pagina (leesvolgorde inclusief posities)
for block in doc.pages[0].blocks:
print(block.type, block.bbox, block.text[:60])
# Exporteer naar verschillende formaten
doc.to_html() # behoudt uitlijning en inspringingen
doc.to_dict() # volledige JSON-output
extract("slides.pptx").to_markdown() # ondersteunt elk formaat dat Apache Tika leest
extract_text("contract.pdf").text # snelste methode: alleen schone tekst
Opties
| Optie | Standaardwaarde | Beschrijving |
pages | all | Bijv. "1-3,5,10-" |
images | False | Snij figuren, tabellen en formules uit naar PNG |
tables / formulas | True | Detectie aan/uit |
ocr | "auto" | "auto" (alleen gescannde pagina's), "force", "off" |
ocr_language | "por+eng" | Tesseract talen |
tika | True | False voert alleen de layout-engine uit (geen Java nodig) |
workers | 1 | Processen voor lange documenten |
Command Line Interface (CLI)
# Markdown + afbeeldingen map
pdf-text-api extract paper.pdf -o paper.md --images
# Export in het formaat van de extensie
pdf-text-api extract paper.pdf -o paper.json
# Alleen tabellen naar CSV
pdf-text-api extract paper.pdf -f csv -o tables.csv
# Specifieke pagina's naar HTML
pdf-text-api extract paper.pdf -p 1-5 -f html
# Alleen schone tekst (snel)
pdf-text-api extract paper.pdf --fast
# Start de API + browser-app op poort 8000
pdf-text-api serve --port 8000
REST API & Docker
Starten met Docker
docker compose up
Dit start de API, Apache Tika, Tesseract en de browser-app op poort 8000.
Voorbeelden van API-aanvragen
# Extractie naar Markdown
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?format=markdown"
# Extractie naar ZIP inclusief afbeeldingen
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?format=zip&images=true" -o paper.zip
# Extractie met blokken en posities per pagina
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?per_page=true"
Endpoint: POST /v1/extract. Interactieve documentatie is beschikbaar op /docs.
API Parameters
| Parameter | Standaard | Beschrijving |
mode | structured | structured (layout + Tika) of fast (alleen tekst) |
format | json | json, markdown, text, html, csv, zip |
pages | all | Bijv. 1-3,5,10- |
per_page | false | Voeg pagina's, blokken en posities toe aan de JSON |
images | false | Snij figuren, tabellen en formules uit |
ocr | auto | auto, force, off |
Configuratie is mogelijk via omgevingsvariabelen (zie .env.example).
Output-specificaties
Elk blok bevat informatie over het type en de positie:
{
"type": "table",
"bbox": [56.7, 294.8, 481.9, 374.2],
"rows": [["Model", "Accuracy"], ["Base", "0.81"]],
"caption": "Table 1: Comparison between models."
}
Ondersteunde Output-formaten
| Formaat | Python · CLI · API | Browser App |
| Markdown, platte tekst, JSON | ✓ | ✓ |
| HTML (behoudt uitlijning/inspringing) | ✓ | ✓ |
| CSV van tabellen, ZIP met afbeeldingen | ✓ | ✓ |
Word .docx (behoudt uiterlijk pagina) | — | ✓ |
Excel .xlsx (één blad per tabel) | — | ✓ |
JSON Schema en Bloktypes
Het volledige JSON-schema bevat metadata en een lijst van pagina's. Binnen elke pagina bevinden zich blokken.
Bloktypes:
heading (met niveau)
paragraph
list_item (met marker)
table (met rijen)
figure
formula (met LaTeX)
caption
code
- Apart gehouden van de hoofdtekst:
header, footer, page_number.
De bounding boxes worden weergegeven als [x0, y0, x1, y1] in punten, met de oorsprong linksboven op de pagina.
Benchmarks
Getest op dichte arXiv-papers (multi-kolom, formules, tabellen, figuren) op een laptop-CPU zonder GPU.
- Snelheid: Gemiddeld 39 ms per pagina.
- Betrouwbaarheid: 0 fouten op 54 papers.
Vergelijking met andere tools
| Kenmerk | papero | PyMuPDF | pdfplumber | pypdf | Docling | Marker |
| Licentie | MIT | AGPL | MIT | BSD | MIT | GPL |
| ML modellen nodig | Nee | Nee | Nee | Nee | Ja | Ja |
| Multi-kolom leesvolgorde | ✓ | Gedeeltelijk | — | — | ✓ | ✓ |
| Gestructureerde tabellen | ✓ | ✓ | ✓ | — | ✓ | ✓ |
| Formules | LaTeX + beeld | — | — | — | ✓ | ✓ |
| Bounding boxes | ✓ | ✓ | ✓ | — | ✓ | ✓ |
| DOCX/PPTX/XLSX/EPUB | ✓ | Gedeeltelijk | — | — | ✓ | Gedeeltelijk |
| Volledig in browser | ✓ | — | — | — | — | — |
Opmerking: ML-gebaseerde tools presteren nog steeds beter bij zeer onregelmatige layouts en complexe wiskunde (zoals matrices). Papero biedt in dat geval de formule als benaderde LaTeX en als afbeelding, zodat er geen informatie verloren gaat.
Hoe het werkt
Twee engines werken gelijktijdig op hetzelfde bestand:
- Layout Engine: Gebaseerd op PDFium. Deze leest elk glief met positie, lettertype en grootte, inclusief lijnen en afbeeldingen. Met een kolom-bewuste XY-cut worden kolommen, tabellen, formules, lijsten en figuren gereconstrueerd.
- Apache Tika: Voegt metadata, tagged-PDF koppen, OCR (via Tesseract) en ondersteuning voor niet-PDF formaten toe.
De browser-app gebruikt hetzelfde algoritme, geporteerd naar JavaScript via pdf.js. De CI-tests controleren blok voor blok of beide engines overeenstemmen.
Beperkingen
- Wiskunde: LaTeX wordt gereconstrueerd uit gliefen. Gestapelde breuken, matrices en grote wortels worden lineair weergegeven (de uitgesneden afbeelding is echter altijd aanwezig).
- Tabellen: Randloze tabellen met zeer smalle tussenruimtes tussen kolommen kunnen per ongeluk als tekst worden gelezen.
- OCR: Gescannde PDF's hebben OCR nodig, wat alleen via de server-route werkt (Tesseract zit in de Docker-image).
- Export: Word/Excel-export is momenteel alleen beschikbaar in de browser-app.
Ontwikkeling
Installatie voor ontwikkelaars
git clone https://github.com/beatrizalmeidaf/papero-pdf-text-extractor.git && cd pdf-text-extractor
pip install -e ".[dev]"
Testen en Controleren
pytest -q # inclusief real-world regressies
ruff check src tests && ruff format --check src tests
npm install --prefix tests/js && python tests/js/expected.py tests/js/out && node tests/js/parity.mjs tests/js/out
python -m http.server -d web # browser app op http://localhost:8000
src/pdftextapi/: De Python engine, API en CLI.
web/: De browser-app (GitHub Pages).
tests/js/: Controleert of beide engines overeenstemmen.
benchmarks/: Downloadt de dataset en tekent de grafieken.
Bijdragen
Heb je een PDF gevonden die Papero niet correct verwerkt? Dit is de meest nuttige manier om bij te dragen: open een issue en voeg het bestand (of een pagina ervan) toe met een beschrijving van de verwachte output. Onderwerpen als leesvolgorde, tabellen, formules, encoding, OCR en verschillen tussen browser/server zijn welkom.
Licentie: MIT © Beatriz Almeida. Gepubliceerd als papero-extract op PyPI.
Papero PDF Text Extractor: Een snelle, open-source API voor PDF-tekstextractie
De tool werkt uitsluitend op de CPU en maakt geen gebruik van ML-modellen. Het kan worden uitgevoerd in de browser, in Python of als een API.
Waarom Papero?
Het extraheren van tekst uit een PDF is eenvoudig, maar het herstellen van de structuur — zoals bepalen welke kolom eerst komt, welke regels een tabel vormen en waar een formule staat — is essentieel om de output bruikbaar te maken voor RAG (Retrieval-Augmented Generation), zoekfuncties en LLM's. Papero bereikt dit via eenvoudige geometrie, waardoor het snel blijft draaien op een laptop-CPU.
Belangrijkste kenmerken
- Leesvolgorde: Documenten met twee of drie kolommen worden kolom voor kolom gelezen. Headers, footers, paginanummers en herhaalde logo's worden apart gezet.
- Echte tabellen: Tabellen met lijnen, zonder randen en LaTeX booktabs-tabellen worden omgezet naar rijen en kolommen, inclusief cellen met meerdere regels. Export naar CSV of Excel is mogelijk.
- Formules: Bovenschriften, onderschriften en wiskundige symbolen worden omgezet naar LaTeX (bijv. $E = mc^{2}$), aangevuld met een uitgesneden afbeelding van de formule.
- Positie van alle elementen: Elk blok heeft een bounding box. Hierdoor kun je in een RAG-antwoord naar de exacte plek verwijzen, over de pagina tekenen of delen uitknippen.
- Figuren & grafieken: Afbeeldingen en vectorgrafieken worden uitgesneden als PNG, waarbij het bijschrift, de aslabels en de legenda behouden blijven.
- Terug naar Word: Uitlijning, inspringingen, regelafstand, vetgedrukte teksten en lettertypen worden behouden, zodat een
.docx-export lijkt op de originele pagina.
Aanvullende functionaliteiten:
- Accenttekens die in LaTeX-PDF's als aparte tekens zijn getekend (bijv. Computa¸ca˜o → Computação) worden gecorrigeerd.
- Onzichtbare witte tekst (vaak gebruikt door formuliergeneratoren) wordt verwijderd.
- Gescannde pagina's worden verwerkt via OCR.
- DOCX, PPTX, XLSX, EPUB en HTML worden gelezen via Apache Tika.
Snel aan de slag
Installatie
pip install papero-extract
Basisgebruik in Python
from pdf_text_api import extract
doc = extract("paper.pdf")
print(doc.to_markdown())
Alternatief: Gebruik de browser-app om een PDF te uploaden en te exporteren naar het gewenste formaat zonder installatie.
Geavanceerd Python-gebruik (tabellen, formules, posities, afbeeldingen)
from pdf_text_api import extract, extract_text
doc = extract("paper.pdf", images=True)
# Toegang tot tabelgegevens
doc.tables[0].rows # [["Model", "Accuracy"], ["Base", "0.81"], ...]
# Toegang tot LaTeX-formules
doc.formulas[0].latex # "E = mc^{2}"
# Toegang tot afbeeldingen (PNG bytes)
doc.figures[0].image.data
# Doorloop blokken per pagina (leesvolgorde inclusief posities)
for block in doc.pages[0].blocks:
print(block.type, block.bbox, block.text[:60])
# Exporteer naar verschillende formaten
doc.to_html() # behoudt uitlijning en inspringingen
doc.to_dict() # volledige JSON-output
extract("slides.pptx").to_markdown() # ondersteunt elk formaat dat Apache Tika leest
extract_text("contract.pdf").text # snelste methode: alleen schone tekst
Opties
| Optie | Standaardwaarde | Beschrijving |
pages | all | Bijv. "1-3,5,10-" |
images | False | Snij figuren, tabellen en formules uit naar PNG |
tables / formulas | True | Detectie aan/uit |
ocr | "auto" | "auto" (alleen gescannde pagina's), "force", "off" |
ocr_language | "por+eng" | Tesseract talen |
tika | True | False voert alleen de layout-engine uit (geen Java nodig) |
workers | 1 | Processen voor lange documenten |
Command Line Interface (CLI)
# Markdown + afbeeldingen map
pdf-text-api extract paper.pdf -o paper.md --images
# Export in het formaat van de extensie
pdf-text-api extract paper.pdf -o paper.json
# Alleen tabellen naar CSV
pdf-text-api extract paper.pdf -f csv -o tables.csv
# Specifieke pagina's naar HTML
pdf-text-api extract paper.pdf -p 1-5 -f html
# Alleen schone tekst (snel)
pdf-text-api extract paper.pdf --fast
# Start de API + browser-app op poort 8000
pdf-text-api serve --port 8000
REST API & Docker
Starten met Docker
docker compose up
Dit start de API, Apache Tika, Tesseract en de browser-app op poort 8000.
Voorbeelden van API-aanvragen
# Extractie naar Markdown
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?format=markdown"
# Extractie naar ZIP inclusief afbeeldingen
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?format=zip&images=true" -o paper.zip
# Extractie met blokken en posities per pagina
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?per_page=true"
Endpoint: POST /v1/extract. Interactieve documentatie is beschikbaar op /docs.
API Parameters
| Parameter | Standaard | Beschrijving |
mode | structured | structured (layout + Tika) of fast (alleen tekst) |
format | json | json, markdown, text, html, csv, zip |
pages | all | Bijv. 1-3,5,10- |
per_page | false | Voeg pagina's, blokken en posities toe aan de JSON |
images | false | Snij figuren, tabellen en formules uit |
ocr | auto | auto, force, off |
Configuratie is mogelijk via omgevingsvariabelen (zie .env.example).
Output-specificaties
Elk blok bevat informatie over het type en de positie:
{
"type": "table",
"bbox": [56.7, 294.8, 481.9, 374.2],
"rows": [["Model", "Accuracy"], ["Base", "0.81"]],
"caption": "Table 1: Comparison between models."
}
Ondersteunde Output-formaten
| Formaat | Python · CLI · API | Browser App |
| Markdown, platte tekst, JSON | ✓ | ✓ |
| HTML (behoudt uitlijning/inspringing) | ✓ | ✓ |
| CSV van tabellen, ZIP met afbeeldingen | ✓ | ✓ |
Word .docx (behoudt uiterlijk pagina) | — | ✓ |
Excel .xlsx (één blad per tabel) | — | ✓ |
JSON Schema en Bloktypes
Het volledige JSON-schema bevat metadata en een lijst van pagina's. Binnen elke pagina bevinden zich blokken.
Bloktypes:
heading (met niveau)
paragraph
list_item (met marker)
table (met rijen)
figure
formula (met LaTeX)
caption
code
- Apart gehouden van de hoofdtekst:
header, footer, page_number.
De bounding boxes worden weergegeven als [x0, y0, x1, y1] in punten, met de oorsprong linksboven op de pagina.
Benchmarks
Getest op dichte arXiv-papers (multi-kolom, formules, tabellen, figuren) op een laptop-CPU zonder GPU.
- Snelheid: Gemiddeld 39 ms per pagina.
- Betrouwbaarheid: 0 fouten op 54 papers.
Vergelijking met andere tools
| Kenmerk | papero | PyMuPDF | pdfplumber | pypdf | Docling | Marker |
| Licentie | MIT | AGPL | MIT | BSD | MIT | GPL |
| ML modellen nodig | Nee | Nee | Nee | Nee | Ja | Ja |
| Multi-kolom leesvolgorde | ✓ | Gedeeltelijk | — | — | ✓ | ✓ |
| Gestructureerde tabellen | ✓ | ✓ | ✓ | — | ✓ | ✓ |
| Formules | LaTeX + beeld | — | — | — | ✓ | ✓ |
| Bounding boxes | ✓ | ✓ | ✓ | — | ✓ | ✓ |
| DOCX/PPTX/XLSX/EPUB | ✓ | Gedeeltelijk | — | — | ✓ | Gedeeltelijk |
| Volledig in browser | ✓ | — | — | — | — | — |
Opmerking: ML-gebaseerde tools presteren nog steeds beter bij zeer onregelmatige layouts en complexe wiskunde (zoals matrices). Papero biedt in dat geval de formule als benaderde LaTeX en als afbeelding, zodat er geen informatie verloren gaat.
Hoe het werkt
Twee engines werken gelijktijdig op hetzelfde bestand:
- Layout Engine: Gebaseerd op PDFium. Deze leest elk glief met positie, lettertype en grootte, inclusief lijnen en afbeeldingen. Met een kolom-bewuste XY-cut worden kolommen, tabellen, formules, lijsten en figuren gereconstrueerd.
- Apache Tika: Voegt metadata, tagged-PDF koppen, OCR (via Tesseract) en ondersteuning voor niet-PDF formaten toe.
De browser-app gebruikt hetzelfde algoritme, geporteerd naar JavaScript via pdf.js. De CI-tests controleren blok voor blok of beide engines overeenstemmen.
Beperkingen
- Wiskunde: LaTeX wordt gereconstrueerd uit gliefen. Gestapelde breuken, matrices en grote wortels worden lineair weergegeven (de uitgesneden afbeelding is echter altijd aanwezig).
- Tabellen: Randloze tabellen met zeer smalle tussenruimtes tussen kolommen kunnen per ongeluk als tekst worden gelezen.
- OCR: Gescannde PDF's hebben OCR nodig, wat alleen via de server-route werkt (Tesseract zit in de Docker-image).
- Export: Word/Excel-export is momenteel alleen beschikbaar in de browser-app.
Ontwikkeling
Installatie voor ontwikkelaars
git clone https://github.com/beatrizalmeidaf/papero-pdf-text-extractor.git && cd pdf-text-extractor
pip install -e ".[dev]"
Testen en Controleren
pytest -q # inclusief real-world regressies
ruff check src tests && ruff format --check src tests
npm install --prefix tests/js && python tests/js/expected.py tests/js/out && node tests/js/parity.mjs tests/js/out
python -m http.server -d web # browser app op http://localhost:8000
src/pdftextapi/: De Python engine, API en CLI.
web/: De browser-app (GitHub Pages).
tests/js/: Controleert of beide engines overeenstemmen.
benchmarks/: Downloadt de dataset en tekent de grafieken.
Bijdragen
Heb je een PDF gevonden die Papero niet correct verwerkt? Dit is de meest nuttige manier om bij te dragen: open een issue en voeg het bestand (of een pagina ervan) toe met een beschrijving van de verwachte output. Onderwerpen als leesvolgorde, tabellen, formules, encoding, OCR en verschillen tussen browser/server zijn welkom.
Licentie: MIT © Beatriz Almeida. Gepubliceerd als papero-extract op PyPI.