本文へ移動
cccskills
無料GitHub で公開

ocr-and-documents

Extract text from a PDF or a scanned document, with or without OCR.

インストール方法を見る

含まれるファイル(3)

  • SKILL.md7.3 KB
  • scripts/extract_marker.py3.0 KB
  • scripts/extract_pymupdf.py3.1 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Getting text out of documents

A PDF is not a text file. It is a set of drawing instructions that usually, but not always, include the characters. When they do, extraction is instant and free. When they do not, because the page is a photograph of paper, no amount of retrying helps and you need optical recognition, which costs gigabytes.

So the first question is never "which tool", it is does this file contain text at all.

The ladder, cheapest rung first

RungToolCostHandles
0read_extractnothinga local PDF, .txt or .md with a text layer
1web_fetchnothinga document behind a URL, PDF included
2pymupdf25 MBfull text, page ranges, basic tables, images, metadata
3marker-pdf3 to 5 GBscans, equations, columns, real tables

Never start at rung 3. Most documents are answered at rung 0.

Rung 0: the file is on disk

read_extract with path. One call, no install, always available.

read_extract(path="C:/dev/docs/report.pdf")

Its limits are exactly what send you up the ladder:

  • path only. Given a URL it answers File not found; it has no network at all.
  • Use an ABSOLUTE path. A relative one resolves against the server's working directory.
  • No OCR. On a scan it returns almost nothing.
  • A long document comes back as a head and a tail, with the middle dropped. For a passage in the middle, go to pymupdf with --pages.

Rung 1: the document is behind a URL

web_fetch with url extracts a PDF served over HTTP by itself, with nothing installed. It takes ONE url, as a string.

web_fetch(url="https://example.com/annual-report.pdf")

If the server refuses it, download it and drop back to rung 0:

curl -sL "https://example.com/annual-report.pdf" -o "C:\tmp\report.pdf"

Is it a scan? Decide before installing anything

This is the whole diagnosis, and it takes one command:

python skills/ocr-and-documents/scripts/extract_pymupdf.py document.pdf --metadata

Compare the page count against the characters you got at rung 0. Forty pages and two hundred characters means the pages are images. It does not mean the document is empty, and it does not mean the extraction failed. Nothing below rung 3 will ever read it.

A document with a PARTIAL text layer, common in scanned paperwork carrying a searchable overlay, is worse: it gives you text that is present and wrong. Plausible words in an implausible order is the signature. Check one page against the original before trusting any of it.

Rung 2: pymupdf

pip install pymupdf pymupdf4llm
python skills/ocr-and-documents/scripts/extract_pymupdf.py doc.pdf              # plain text
python skills/ocr-and-documents/scripts/extract_pymupdf.py doc.pdf --markdown   # structure kept
python skills/ocr-and-documents/scripts/extract_pymupdf.py doc.pdf --pages 0-4  # first five pages
python skills/ocr-and-documents/scripts/extract_pymupdf.py doc.pdf --tables
python skills/ocr-and-documents/scripts/extract_pymupdf.py doc.pdf --images out/
python skills/ocr-and-documents/scripts/extract_pymupdf.py doc.pdf --metadata

--pages is 0-based: 0-4 is the first five pages, not pages one to four.

Reading order is the PDF's internal order, which for a two-column paper is not the order a human reads it in. Text arriving interleaved between columns is that limitation, and it is a reason to climb to rung 3 rather than a bug to work around.

For anything programmatic, execute_code with pymupdf directly beats the script: splitting, merging, searching across pages.

import pymupdf
doc = pymupdf.open("C:/dev/docs/report.pdf")
for number, page in enumerate(doc, 1):
    hits = page.search_for("revenue")
    if hits:
        print(number, len(hits))

Rung 3: marker-pdf

Real OCR, layout analysis, reading order, equations, and tables that survive.

Check the cost before proposing it, and give the user the number:

python skills/ocr-and-documents/scripts/extract_marker.py --check

It reports free disk. marker-pdf pulls PyTorch, then downloads roughly 2.5 GB of models into ~/.cache/huggingface/ on first use. That is a real cost on someone's laptop, and spending it is their decision.

pip install marker-pdf

python skills/ocr-and-documents/scripts/extract_marker.py scanned.pdf
python skills/ocr-and-documents/scripts/extract_marker.py doc.pdf --json
python skills/ocr-and-documents/scripts/extract_marker.py doc.pdf --output_dir out/
python skills/ocr-and-documents/scripts/extract_marker.py doc.pdf --use_llm

It also reads DOCX, PPTX, XLSX, HTML, EPUB and plain images.

--use_llm sends page content to a model provider. Do not reach for it on a document the user has treated as confidential without asking first.

When the disk is not there, say so and give the alternatives plainly: free some space, provide a URL for rung 1, or accept pymupdf's output knowing it cannot read a scan.

Formats that are not PDFs

OCR is the wrong tool for a format that already carries its structure. Use the parser:

  • DOCX: python-docx through execute_code. Paragraphs, styles and tables as authored.
  • PPTX: python-pptx. Slides and speaker notes.
  • XLSX: openpyxl, or pandas.read_excel.

Running OCR over a DOCX throws the structure away and then guesses it back.

Traps

  • An almost-empty result is a diagnosis, not a failure. See the scan check above.
  • --pages counts from zero.
  • A table extracted as prose is not a table. pymupdf's --tables is basic. If the answer lives in a table, climb to marker-pdf instead of reconstructing rows by eye.
  • Ligatures and hyphens. Extracted text contains real ligature characters, and a word broken across two lines keeps its hyphen. Normalise before matching on a string, or the search silently finds nothing and you conclude the term is absent.
  • Headers, footers and page numbers land in the text, mid-sentence, at every page break. Strip them before summarising or they get quoted as content.
  • Never install marker-pdf silently. Several gigabytes without being asked is not a detail.

Failure modes

Almost no text from a PDF with visible words. It is a scan, or the text layer is an image. Confirm with --metadata, then rung 3.

pip install marker-pdf fails or fills the disk. It pulls PyTorch. Run --check first. Without the space, say so and fall back to pymupdf for any document that does have a text layer.

Columns interleaved, sentences from two places mixed together. pymupdf reading order. marker-pdf does reading-order detection; use it for papers and magazines.

The text is there but full of question marks or boxes. An encoding or embedded-font problem. Try --markdown, then marker-pdf, which re-recognises the glyphs rather than trusting the font's character map.

The document is encrypted. pymupdf raises on open. If the user has the password, pymupdf.open(path) then doc.authenticate(password) through execute_code. If they do not, stop: that is not something to work around.

It worked on page one and produced nothing after. Either a --pages range is still set, or the document changes format partway, which is normal in a text-layer report carrying scanned appendices. Extract the sections separately.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Drive an installed LaRuche App through its declared actions, never its files.

日本語の概要は準備中です。原文の説明を表示しています。

infinition/LaRuche332026年9月22日 更新

arxiv

無料

Find academic papers on arXiv, with citation counts and BibTeX.

日本語の概要は準備中です。原文の説明を表示しています。

infinition/LaRuche332026年9月22日 更新

ascii-art

無料

Render text or an image as ASCII art for terminal-friendly output.

日本語の概要は準備中です。原文の説明を表示しています。

infinition/LaRuche332026年9月22日 更新

Track RSS/Atom feeds and blogs via blogwatcher-cli.

日本語の概要は準備中です。原文の説明を表示しています。

infinition/LaRuche332026年9月22日 更新

Drive a real web browser: navigate, read, find, click, fill, screenshot

日本語の概要は準備中です。原文の説明を表示しています。

infinition/LaRuche332026年9月22日 更新

Measure a codebase: lines of code, language mix, and symbol lookups.

日本語の概要は準備中です。原文の説明を表示しています。

infinition/LaRuche332026年9月22日 更新

infinition のスキルをすべて見る

このスキルの問題を報告する