Extract text/tables from PDFs, create formatted PDFs, merge/split/rotate, handle forms and metadata. Supports pdf-lib/pdfkit (Node.js) and pypdf/pdfplumber/ReportLab (Python).
This skill enables PDF creation, extraction, manipulation, and analysis. Apply these patterns when users need to generate invoices, reports, extract data from PDFs, merge documents, or work with PDF forms.
Modern Best Practices (Jul 2026):
references/pdf-extraction-patterns.md.scripts/ helpers over re-implementing ad hoc.pdfplumber first and spot-check output against the source page; escalate to Camelot only when columns/rows are visibly wrong, and always inspect Camelot's per-table accuracy score rather than trusting output blindly.PyMuPDF/fitz (used by scrub_metadata.py and most redaction/OCR-prep code below) is dual-licensed AGPL-3.0 / commercial. Flag this before shipping it inside a closed-source product or SaaS backend β AGPL's network-use clause can trigger a source-disclosure obligation; get a commercial license from Artifex or substitute pypdf/pdfplumber where the required functionality overlaps.pdf-lib (Node) has had no active upstream releases for an extended period as of mid-2026; for new Node projects needing ongoing fixes, evaluate a maintained fork (e.g. @cantoo/pdf-lib) before committing, and pin the dependency either way.| Task | Tool/Library | Language | When to Use |
|---|---|---|---|
| Create PDF | pdfkit | Node.js | Reports, invoices, certificates |
| Create PDF | ReportLab | Python | Complex layouts, tables |
| Create PDF | FPDF2 | Python | Simple PDFs with Unicode support |
| Edit PDF | pdf-lib | Node.js | Modify existing PDFs, add pages (upstream low-activity β consider a maintained fork) |
| Parse/merge/split/rotate | pypdf | Python | Deterministic PDF manipulation |
| Extract text | pdfplumber | Python | OCR-free text extraction |
| OCR scanned PDF | OCRmyPDF | Python/CLI | Searchable text layer for scanned PDFs |
| Custom OCR pipeline | PyMuPDF (fitz) + Tesseract | Python | Page-level OCR or image-heavy extraction β PyMuPDF is AGPL-3.0/commercial dual-licensed |
| Extract tables | pdfplumber | Python | Default table extraction; verify visually before trusting |
| Extract hard tables | Camelot (camelot-py) | Python | Lattice/stream edge cases; 2026 releases add an optional neural backend β check table.accuracy either way |
| Fill forms | pdf-lib | Node.js | Form automation |
| Sign PDFs | pyHanko | Python/CLI | Digital signatures and validation |
| HTML to PDF | Playwright | Node.js | Browser-faithful web page rendering |
| HTML to tagged PDF | WeasyPrint | Python | Semantic HTML, PDF/A or PDF/UA-oriented export |
| Validate PDF/A | veraPDF | CLI/GUI | Archival conformance checks |
| Validate PDF accessibility | PAC / Acrobat Checker | GUI | PDF/UA and accessibility checks |
| Inspect/edit file metadata | exiftool | CLI | Audit or rewrite internal dates, XMP, EXIF, ICC across PDF/image files |
| Set filesystem dates | touch / SetFile | CLI (macOS) | Correct creation/modification timestamps at OS level |
Use this skill when a user requests:
Playwright for browser-faithful HTML/CSS, WeasyPrint for semantic/tagged HTML exports, ReportLab for Python-heavy layouts, or pdfkit for Node-first custom layout.OCRmyPDF before downstream extraction on scanned PDFs, then use references/pdf-extraction-patterns.md.assets/pdf-release-checklist.md; add PAC / Acrobat checks for accessibility-sensitive PDFs and veraPDF when archival conformance matters.PDF request
|
v
Classify task
|-- create new PDF
|-- extract text / tables / images
|-- modify existing PDF
|-- fill / sign forms
|-- merge / split / rotate / scrub
|
v
Classify source and risk
|-- born-digital ----> extract directly
|-- scanned ---------> OCR first
|-- sensitive -------> real redaction + metadata scrub
|-- compliance ------> tagged / structured source workflow
|
v
Select tool or script
|-- HTML/CSS --------> Playwright or WeasyPrint
|-- Python layout ---> ReportLab / FPDF2
|-- deterministic ---> scripts/ + pypdf
|-- extraction ------> pdfplumber / OCRmyPDF / Camelot
|
v
Verify fidelity, accessibility, metadata, and redaction
Scripts are optional helpers; they assume Python 3 plus the listed dependencies in each file.
python3 scripts/merge_pdfs.py merged.pdf a.pdf b.pdfpython3 scripts/split_pdf.py in.pdf out_dir --each-pagepython3 scripts/rotate_pdf.py in.pdf out.pdf --degrees 90python3 scripts/scrub_metadata.py in.pdf out.pdfpython3 scripts/scrub_metadata.py in.pdf out.pdf --filesystem-date 2025-09-20 --strip-xattrsINVOICE STRUCTURE
βββ Header (logo, company info, invoice #)
βββ Bill To / Ship To blocks
βββ Line items table
β βββ Description | Qty | Unit Price | Total
β βββ Subtotal, Tax, Total
βββ Payment terms
βββ Footer (contact, thank you)
REPORT PDF STRUCTURE
βββ Cover page (title, author, date)
βββ Table of contents
βββ Body sections with page numbers
βββ Charts/images with captions
βββ Appendices
βββ Running header/footer
PDF Task: [What do you need?]
ββ Create new PDF?
β ββ Browser-faithful HTML/CSS β Playwright
β ββ Semantic HTML / tagged export β WeasyPrint
β ββ Node-first custom layout β pdfkit
β ββ Python complex layout β ReportLab / FPDF2
β
ββ Extract from PDF?
β ββ Born-digital text β pdfplumber (Python)
β ββ Scanned pages β OCRmyPDF, then pdfplumber
β ββ Tables β pdfplumber first, Camelot for hard cases
β ββ Images / raster work β PyMuPDF/fitz
β
ββ Modify existing PDF?
β ββ Add text/images β pdf-lib (Node)
β ββ Merge/split/rotate/scrub β pypdf + scripts
β ββ Fill forms β pdf-lib
β ββ Sign β pyHanko
β
ββ Batch processing?
ββ OCRmyPDF / pypdf / pdfplumber pipeline
OCRmyPDF for scanned PDFs before text extraction.exiftool -all -G1 after scrubbing β check for tool fingerprints (XMP Toolkit) and residual dates.wkhtmltopdf in new 2026 workflows.XMP Toolkit fingerprint.Camelot/pdfplumber table output on financial or legal documents without a visual spot-check or accuracy-score review β misaligned columns fail silently.assets/pdf-release-checklist.md.Use only when explicitly requested and policy-compliant.
Resources
Scripts
scripts/merge_pdfs.py β Merge PDFs in orderscripts/split_pdf.py β Split one-per-page or by rangescripts/rotate_pdf.py β Rotate all pages by 90/180/270 degreesscripts/scrub_metadata.py β Scrub Info/XMP metadata, attachments, JavaScript, and thumbnailsTemplates
Related Skills
Before applying this skill on a non-trivial task, read learnings.consolidated.md in this directory (and learnings.md if present).
After applying it, if you encountered a pattern worth remembering, a mistake worth preventing, or a domain fact that surprised you, append one dated bullet to learnings.md via agents-skills-feedback-loop/scripts/append_learning.py. Do not modify SKILL.md itself.