プログラミング
レイアウト、テーブル、数式、バウンディングボックスを備えた軽量PDFパーサー
Lightweight PDF parser with layout, tables, formulas and bounding boxes (github.com)
要約
Papero-PDF-Text-Extractorは、軽量なスタックでPDFの構造を抽出するツールです。テキストだけでなく、読み取り順序、テーブル、数式、各ブロックの位置情報まで、Markdown、JSON、Word、Excel形式で出力できます。CPUのみで動作し、MLモデルは使用しません。ブラウザ、Python、APIとして利用可能です。
全文翻訳
軽量なスタックでドキュメント構造を抽出します。PDF → Markdown · JSON · Word · Excel — 読み取り順序、テーブル、数式、図、および各ブロックの位置情報付き。CPUのみ。MLモデルなし。ブラウザ、Python、またはAPIとして実行できます。
▶ ブラウザで試す · クイックスタート · ベンチマーク
ブラウザアプリで30秒:PDFをロードし、任意のブロックを検査し、テーブルと数式を確認し、Wordにエクスポートします。あなたのPDFはあなたのマシンから離れることはありません。
なぜPaperoか
PDFからテキストを取得するのは簡単です。その構造(どの列が先か、どの行がテーブルか、数式はどこにあるか)を取り戻すことが、RAG、検索、LLMでの利用を可能にするのです。Paperoはプレーンなジオメトリでこれを実現するため、ラップトップCPUでも高速に動作します。
📖 読み取り順序
2列または3列の論文は、列ごとに読み取られます。ヘッダー、フッター、ページ番号、繰り返しのロゴは除外されます。
▦ 実際のテーブル
罫線あり、罫線なし、LaTeXのbooktabsテーブルは、複数行のセルを含めて、行と列として復元されます。CSVまたはExcelにエクスポートできます。
∑ 数式
指数、添え字、積み重ねられた分数、根号は、数学として読み取られ(例: 5/12、10√2、CO₂(g))、LaTeX(例: \frac{5}{12}, \sqrt{2})と数式のクロップ画像として書き出されます。
📍 すべての位置
各ブロックにはバウンディングボックスがあり、RAGの回答で正確な場所を参照したり、ページ上に描画したり、クロップしたりできます。
🖼 図とグラフ
画像とベクトルグラフはPNGにクロップされ、キャプション、軸ラベル、凡例が一緒に保持されます。
📝 Wordへの復元
列、配置、インデント、行間、太字の実行、フォントが保持されるため、.docxまたはHTMLエクスポートは元のページのように見えます — 2列は2列のままです。また、LaTeX PDFで別々のグリフとして描画されるアクセント(例: Computa¸ca˜o → Computação)、フォームジェネレーターによって使用される非表示の白いテキストは削除され、スキャンされたページはOCRを通過し、DOCX/PPTX/XLSX/EPUB/HTMLはApache Tika経由で読み取られます。
クイックスタート
pip install papero-extract
from papero_extract import extract
doc = extract("paper.pdf")
print(doc.to_markdown())
またはインストールをスキップ:ブラウザアプリを開き、PDFをドロップし、必要な形式にエクスポートします。
さらにPythonで — テーブル、数式、位置、画像、オプション
from papero_extract import extract, extract_text
doc = extract("paper.pdf", images=True)
doc.tables[0].rows # [["Model", "Accuracy"], ["Base", "0.81"], ...]
doc.formulas[0].latex # "E = mc^{2}"
doc.figures[0].image.data # PNGバイト
for block in doc.pages[0].blocks:
# 読み取り順序、位置情報付き
print(block.type, block.bbox, block.text[:60])
doc.to_html() # 配置とインデントを保持
doc.to_dict() # 完全なJSON
# MarkdownまたはプレーンテキストでLaTeX形式の段落内の数式 — オペレーター、関数、指数、根号など、テキストフォントで設定されていても、その構成要素によって検出されます。
doc.to_markdown(math="latex") # "Se $\operatorname{tg} x - \operatorname{cotg} x = 1$, então…"
doc.to_text(math="latex") # "a) $1{,35}\cdot 10^{9}$ e $5{,}5\cdot 10^{7}$"
extract("slides.pptx").to_markdown() # Apache Tikaが読み取る任意の形式
extract_text("contract.pdf").text # 最速:テキストのみ
オプション
デフォルト
ページ
すべて
"1-3,5,10-"
画像
False
図、テーブル、数式をPNGにクロップ
テーブル/数式
True
検出オン/オフ
OCR
"auto"
"auto"(スキャンされたページのみ)、「force」、「off」
OCR言語
"por+eng"
Tika
True
False
レイアウトエンジンのみを実行(Javaなし)
ワーカー
1
長文書用のプロセス
CLI
papero-extract extract paper.pdf -o paper.md --images # Markdown + images/フォルダ
papero-extract extract paper.pdf -o paper.json # 拡張子からの形式
papero-extract extract paper.pdf -f csv -o tables.csv # テーブルのみ
papero-extract extract paper.pdf -p 1-5 -f html
papero-extract extract paper.pdf --math latex -o p.md # テキスト内の数式を$...$として
papero-extract extract paper.pdf --fast # テキストのみ
papero-extract batch ./documents -o ./dataset # フォルダ全体、RAG用
papero-extract serve --port 8000 # API + ブラウザアプリ
バッチ&忠実度レポート — PDFのフォルダをRAGデータセットに、レビューするものを選択
papero-extract batch ./documents -o ./dataset
dataset/
├── documents/
│ ├── one .md and one .json per PDF (same sub-folders)
├── chunks.jsonl
│ every chunk, cut at headings, tables kept whole
├── manifest.json
│ per document: pages, tables, chunks, fidelity scores
└── fidelity/
├── report.json
│ totals, signals and every document's issues
├── summary.html
│ the same, to open in a browser
└── problematic/
├── one .json per document with warnings or errors
各チャンクはどこから来たかを知っているため、検索ヒットをページ上に表示できます。
{"id": "paper.pdf#12", "type": "table", "headings": ["4 Results"], "pages": [6, 6], "blocks": ["p6-b3"], "text": "Table 2: Accuracy per model.\n\n| Model | Top-1 | …"}
レポートは、各ドキュメントをそのドキュメント自身のPDFと比較してチェックします — 正解データはないため、精度ではなく、どこを見るべきかの指標として読んでください。
シグナル
チェックされる内容
テキスト
各ページでPDFiumが読み取る単語がすべて出力に含まれているか
読み取り順序
同じ列の下にあるブロックより前に読み取られるブロックはないか
テーブル
各 "Table N" キャプションに対応するテーブルがあるか。各テーブルはクリーンなグリッドか
図
各 "Figure N" キャプションに対応する図があるか
数式
各数式にLaTeXがあり、マッピングされていないグリフがないか
ブラウザアプリは、ドロップしたPDFに対して同じチェックを実行します。忠実度スコアはページ数とともに表示され、「比較」タブでは各ページとその抽出結果を並べて表示し、出力に含まれていないPDFテキストとチェックに失敗したブロックをマークします。
from papero_extract import extract
from papero_extract.batch import run_batch
from papero_extract.chunks import chunk_document
from papero_extract.fidelity import assess, reference_text
run_batch("./documents", "./dataset", workers=8)["totals"] # {"documents": …, "ok": …, "warning": …, "error": …}
doc = extract("paper.pdf")
chunk_document(doc, document="paper.pdf", max_chars=1500)
assess(doc, reference_text("paper.pdf")).issues # [Issue(code="table_not_detected", pages=[5], …)]
REST API & Docker
docker compose up # API + Apache Tika + Tesseract + ブラウザアプリを :8000 で実行
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?format=markdown"
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?format=zip&images=true" -o paper.zip
curl -F "file=@paper.pdf" "localhost:8000/v1/extract?per_page=true" # ブロック + 位置情報
1つのエンドポイント、POST /v1/extract; インタラクティブなドキュメントは /docs で確認できます。
パラメータ
デフォルト
モード
structured
structured (レイアウト + Tika) または fast (テキストのみ)
フォーマット
json
json, markdown, text, html, csv, zip
ページ
すべて
1-3,5,10-
per_page
false
JSONにページ、ブロック、位置情報を含める
画像
false
図、テーブル、数式をクロップ
OCR
auto
auto, force, off
環境変数による設定 — .env.example を参照してください。
出力
各ブロックは、それが何であり、どこにあるかを知っています。
{ "type": "table", "bbox": [56.7, 294.8, 481.9, 374.2], "rows": [["Model", "Accuracy"], ["Base", "0.81"]], "caption": "Table 1: Comparison between models." }
出力
Python · CLI · API
ブラウザアプリ
Markdown, プレーンテキスト, JSON
✓ ✓
HTML (配置とインデントを保持)
✓ ✓
テーブルのCSV, 画像付きZIP
✓ ✓
Word .docx (ページの見た目を保持)
✓
Excel .xlsx, テーブルごとに1シート
— ✓
完全なJSONスキーマとブロックタイプ
{ "schema": "pdf-text-api/document@1", "engine": "tika+pdfium", "page_count": 12, "metadata": { "title": "...", "author": "...", "language": "en" }, "pages": [{ "number": 1, "width": 595.3, "height": 841.9, "blocks": [{ "id": "p1-b4", "type": "paragraph", "bbox": [74.0, 217.0, 522.0, 275.0], "text": "Atestamos que a estudante ...", "style": { "pt": 11.0, "font": "Arial", "bold": false }, "format": { "align": "justify", "first_line": 42.7, "line_spacing": 1.8 }, "runs": [{ "text": "FULANA DE TAL", "bold": true, "italic": false, "script": null }] }] }] }
ブロックタイプ:heading (レベル付き), paragraph, list_item (マーカー付き), table (行付き), figure, formula (LaTeX付き), caption, code、そしてテキストとは別に保持される header, footer, page_number。
バウンディングボックスは、ページの左上を原点とするポイント単位の [x0, y0, x1, y1] です。
ベンチマーク
密なarXiv論文(マルチカラム、数式、テーブル、図)を対象に