Figure Extractor Skill
Use this skill when the user needs complete figures or images extracted from PDFs, arXiv papers, or HTML article pages.
What this skill actually is (read first)
figure-extractor is a command-line tool (Python + PyMuPDF). "Using it" means
running its CLI in a shell — e.g. figure-extractor extract paper.pdf. It is
not an in-agent callable, a hosted service, or a "page" you activate, and it
cannot run inside a runtime that has no shell or cannot install Python packages
(e.g. Notion Agent, browser-only agents).
Invocation contract
- Mechanism: shell command
figure-extractor <subcommand> ...(installed viapip install -e .). - Input: a local PDF/HTML path or a PDF/arXiv/HTML URL.
- Output: PNG files +
manifest.json+contact_sheet.jpg(+ optionalfigures.zip) written to--out.
Step 0 — precondition check (always do this first)
Before you promise figure extraction, verify the tool is actually runnable in this environment:
figure-extractor --help # if this errors, or there is no shell, the tool is UNAVAILABLE
- Available (command runs) → follow Preferred algorithm.
- Unavailable (no shell / not installed / sandboxed) → go to Degraded mode. Not having the tool is not a failure and not a rule violation — degrade gracefully and tell the user what you did.
Core rule (when the extractor is available)
Do not rely on embedded PDF image extraction alone. Many figures are composed of vector drawings, text labels, legends, and raster fragments. Embedded-image extraction often returns incomplete fragments — prefer the caption-bbox render-crop pipeline below.
Preferred algorithm (requires a shell + the CLI)
- Resolve the input source:
- local PDF
- PDF URL
- arXiv abs URL (
/abs/is auto-normalized to/pdf/) - HTML URL
- local HTML
- If HTML is available, first try to extract original figure images from
<figure>,<img>,<picture>,srcset, and lazy-load attributes. - If HTML does not provide enough high-quality figures, locate or download the PDF.
- For PDFs:
- locate every caption:
Figure 2.1,Figure B.1,Extended Data Fig. 1,Supplementary Table S3,Scheme/Algorithm/Listing/Box,图 1; - recover the page's column grid and confine each crop to its caption's band;
- grow the bbox from graphic primitives, stopping at other captions and prose;
- render the page at 300 dpi and crop;
- generate PNGs,
manifest.json, andcontact_sheet.jpg.
- locate every caption:
- Read the
statusfield of every entry inmanifest.json. Anything markedsuspectorfailedcarriesquality_reasonsexplaining what went wrong. Do not present afailedcrop to the user as if it were the figure. - If a crop is wrong, correct it with
crop --bbox, starting from the bbox the manifest already recorded.
Degraded mode (no shell / CLI unavailable / bitmaps unreachable)
Use this when you cannot run figure-extractor (no shell, no Python/pip,
sandboxed runtime), or when you can run nothing that retrieves the actual
bitmap (e.g. the HTML strips <img> src, arXiv image URLs 404, page behind
auth). This path is explicitly allowed and does not count as failing the
"core rule":
- Link the original. Provide the direct figure URL, the source page, or the arXiv PDF page number + figure number so the user can open the real image.
- Describe faithfully. Give a structured read of each figure from its caption + surrounding text: what it shows, axes/panels/legend, key trend. Never invent figure content you could not actually see.
- Label the gap. State plainly, e.g.:
Bitmap not embedded — reason: no shell available(orimage 404,src stripped by sanitizer,auth-gated).
Degraded output = original link + faithful structured description + an explicit "why the bitmap is missing" note. That is an acceptable result, not a violation.
Setup
A missing package is not a reason to degrade — install it. The dependency set is small (PyMuPDF, Pillow, beautifulsoup4); no GPU, no model, no service.
pip install git+https://github.com/Sunrich-HT/figure-extractor
From a checkout: pip install -e .
Have a PDF? Run it on the PDF.
If the user attached a PDF, or you can download one, that is the simplest and most reliable path. Do not start with HTML or a browser.
figure-extractor extract <pdf-path> --out ./figures --dpi 300 --zip
Only when no PDF is obtainable should you try the HTML route. Note that some
environments' HTML fetchers strip <img src>, leaving text only — when that
happens, stop working the HTML and go back to fetching the PDF.
Commands
# Auto-extract (local PDF, PDF URL, arXiv abs URL, or HTML article)
figure-extractor extract paper.pdf --out ./figures --dpi 300 --zip
figure-extractor extract https://arxiv.org/abs/2606.23443 --out ./figures --zip
figure-extractor extract https://openreview.net/forum?id=XXXX --out ./figures
figure-extractor extract https://example.com/article --prefer html --fallback pdf
# Figures only, or only the crops most likely to be load-bearing
figure-extractor extract paper.pdf --kinds figure --tiers A,B
# Manual bbox correction for a single figure
figure-extractor crop paper.pdf --page 5 --bbox 295,245,556,475 --out fig04.png --dpi 300
Default settings
dpi: 300margin: 8 PDF pointsprefer:autofallback:pdfkinds:all— extraction is exhaustive by defaulttiers:A,B,C— nothing filtered by default; the tier is a triage signal, not a judgement about which exhibits carry the argumentcontact_sheet: true
Quality-control guidance
When the extractor ran, always inspect contact_sheet.jpg and the status
of each manifest entry. suspect and failed crops are flagged in orange and
red on the sheet. If a figure includes surrounding body text or misses part of
the figure, rerun crop with a manual bbox.
The manifest accounts for every candidate the tool saw. If containers_found
exceeds what was rendered, the dropped list says why each one was not — treat
an unexplained gap as a bug, not as a clean run.