Extract, manipulate, and generate PDF documents using secure Python-based workflows.
Install
mkdir -p .claude/skills/pdf-sam-cogan && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/10540" && unzip -o skill.zip -d .claude/skills/pdf-sam-cogan && rm skill.zipInstalls to .claude/skills/pdf-sam-cogan
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Read, extract, create, merge, split, rotate, watermark, encrypt, OCR, or fill forms in PDF files. Triggers: any mention of \".pdf\", \"PDF\", or requests to extract text/tables from PDFs, combine/merge PDFs, split pages, create new PDFs, fill PDF forms, add watermarks, encrypt/decrypt, extract images, or OCR scanned documents. Do NOT use for Word documents (use docx skill), spreadsheets (use xlsx skill), or PowerPoint files.Key capabilities
- →Extract text and tables from PDF files
- →Merge multiple PDF documents into one
- →Split a PDF into individual page files
- →Add watermarks to PDF pages
- →Encrypt or decrypt PDF files
- →Perform OCR on scanned PDF documents
How it works
The skill uses Python libraries like pypdf and pdfplumber to perform various PDF operations, and it manages a virtual environment for dependency isolation.
Inputs & outputs
When to use pdf
- →Merging PDF files
- →Extracting data from documents
- →Encrypting sensitive PDFs
About this skill
PDF Processing Guide
Python Environment — MANDATORY
All Python scripts in this skill MUST run inside a virtual environment. No exceptions.
# Create venv (once per session, skip if .venv already exists)
python -m venv .venv
# Activate (Windows PowerShell)
.venv\Scripts\Activate.ps1
# Activate (bash/macOS)
source .venv/bin/activate
# Install dependencies INSIDE venv only
pip install pypdf pdfplumber reportlab
# For OCR (only if needed)
pip install pytesseract pdf2image
# For advanced rendering (only if needed)
pip install pypdfium2
Rules:
- NEVER run
pip installglobally — always activate.venvfirst - Check if
.venvexists before creating:Test-Path .venv - All
python scripts/...commands assume the venv is active - Clean up
.venvwhen the session is done if it was created for this task
Temp file cleanup — MANDATORY:
- All temp scripts MUST use
.tmp_prefix (e.g.,.tmp_merge_pdfs.py) - After the task completes, delete ALL
.tmp_*files autonomously — never leave them behind, never ask the user Remove-Itemis deny-listed in auto-approval mode. Use Python instead:.venv\Scripts\python.exe -c "import os,glob; [os.remove(f) for f in glob.glob('.tmp_*')]"- If no
.venvexists, use systempython -c "..."
Overview
This guide covers PDF processing using Python libraries and command-line tools. For advanced features and JavaScript libraries, see reference.md. For PDF form filling, see forms.md.
Output directory: Save generated/merged/split .pdf files to the Obsidian vault (see shared-patterns.instructions.md § Artifact Output Directory). Create directories before writing. Never save into a git repo.
Note:
scripts/paths are relative to this skill folder (.github/skills/pdf/).
Quick Reference
| Task | Best Tool | Key Code |
|---|---|---|
| Read/extract text | pdfplumber | page.extract_text() |
| Extract tables | pdfplumber | page.extract_tables() |
| Merge PDFs | pypdf | writer.add_page(page) |
| Split PDFs | pypdf | One page per file |
| Create PDFs | reportlab | Canvas or Platypus |
| Rotate pages | pypdf | page.rotate(90) |
| Add watermark | pypdf | page.merge_page(watermark) |
| Encrypt/decrypt | pypdf | writer.encrypt() |
| OCR scanned PDFs | pytesseract | Convert to image first |
| Fill PDF forms | See forms.md | Fillable or annotation-based |
| Command-line merge | qpdf | qpdf --empty --pages ... |
Reading & Extracting
Quick Start
from pypdf import PdfReader
reader = PdfReader("document.pdf")
print(f"Pages: {len(reader.pages)}")
text = ""
for page in reader.pages:
text += page.extract_text()
Text with Layout (pdfplumber)
import pdfplumber
with pdfplumber.open("document.pdf") as pdf:
for page in pdf.pages:
text = page.extract_text()
print(text)
Extract Tables
import pdfplumber
with pdfplumber.open("document.pdf") as pdf:
for i, page in enumerate(pdf.pages):
tables = page.extract_tables()
for j, table in enumerate(tables):
print(f"Table {j+1} on page {i+1}:")
for row in table:
print(row)
Tables to Excel
import pdfplumber
import pandas as pd
with pdfplumber.open("document.pdf") as pdf:
all_tables = []
for page in pdf.pages:
tables = page.extract_tables()
for table in tables:
if table:
df = pd.DataFrame(table[1:], columns=table[0])
all_tables.append(df)
if all_tables:
combined_df = pd.concat(all_tables, ignore_index=True)
combined_df.to_excel("extracted_tables.xlsx", index=False)
Extract Metadata
reader = PdfReader("document.pdf")
meta = reader.metadata
print(f"Title: {meta.title}, Author: {meta.author}, Pages: {len(reader.pages)}")
Merging & Splitting
Merge PDFs
from pypdf import PdfWriter, PdfReader
writer = PdfWriter()
for pdf_file in ["doc1.pdf", "doc2.pdf", "doc3.pdf"]:
reader = PdfReader(pdf_file)
for page in reader.pages:
writer.add_page(page)
with open("merged.pdf", "wb") as output:
writer.write(output)
Split PDF
from pypdf import PdfReader, PdfWriter
reader = PdfReader("input.pdf")
for i, page in enumerate(reader.pages):
writer = PdfWriter()
writer.add_page(page)
with open(f"page_{i+1}.pdf", "wb") as output:
writer.write(output)
Page Manipulation
Rotate Pages
from pypdf import PdfReader, PdfWriter
reader = PdfReader("input.pdf")
writer = PdfWriter()
page = reader.pages[0]
page.rotate(90) # 90 degrees clockwise
writer.add_page(page)
with open("rotated.pdf", "wb") as output:
writer.write(output)
Add Watermark
from pypdf import PdfReader, PdfWriter
watermark = PdfReader("watermark.pdf").pages[0]
reader = PdfReader("document.pdf")
writer = PdfWriter()
for page in reader.pages:
page.merge_page(watermark)
writer.add_page(page)
with open("watermarked.pdf", "wb") as output:
writer.write(output)
Creating PDFs (reportlab)
Basic PDF
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
c = canvas.Canvas("hello.pdf", pagesize=letter)
width, height = letter
c.drawString(100, height - 100, "Hello World!")
c.line(100, height - 140, 400, height - 140)
c.save()
Multi-Page Report
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet
doc = SimpleDocTemplate("report.pdf", pagesize=letter)
styles = getSampleStyleSheet()
story = []
story.append(Paragraph("Report Title", styles['Title']))
story.append(Spacer(1, 12))
story.append(Paragraph("Body content here. " * 20, styles['Normal']))
story.append(PageBreak())
story.append(Paragraph("Page 2", styles['Heading1']))
doc.build(story)
Subscripts and Superscripts
IMPORTANT: Never use Unicode subscript/superscript characters in ReportLab. They render as black boxes. Use XML markup instead:
from reportlab.platypus import Paragraph
from reportlab.lib.styles import getSampleStyleSheet
styles = getSampleStyleSheet()
chemical = Paragraph("H<sub>2</sub>O", styles['Normal'])
squared = Paragraph("x<super>2</super>", styles['Normal'])
Security
Encrypt PDF
from pypdf import PdfReader, PdfWriter
reader = PdfReader("input.pdf")
writer = PdfWriter()
for page in reader.pages:
writer.add_page(page)
writer.encrypt("userpassword", "ownerpassword")
with open("encrypted.pdf", "wb") as output:
writer.write(output)
OCR (Scanned PDFs)
# Requires: pip install pytesseract pdf2image
# Also requires Tesseract OCR engine installed on system
import pytesseract
from pdf2image import convert_from_path
images = convert_from_path('scanned.pdf')
text = ""
for i, image in enumerate(images):
text += f"Page {i+1}:\n"
text += pytesseract.image_to_string(image)
text += "\n\n"
Extract Images
# Using pdfimages (poppler-utils)
pdfimages -j input.pdf output_prefix
# Extracts as output_prefix-000.jpg, output_prefix-001.jpg, etc.
Command-Line Tools
qpdf
qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf # Merge
qpdf input.pdf --pages . 1-5 -- pages1-5.pdf # Extract pages
qpdf input.pdf output.pdf --rotate=+90:1 # Rotate page 1
qpdf --password=mypassword --decrypt encrypted.pdf out.pdf # Decrypt
pdftotext (poppler-utils)
pdftotext input.pdf output.txt # Extract text
pdftotext -layout input.pdf output.txt # Preserve layout
pdftotext -f 1 -l 5 input.pdf output.txt # Pages 1-5 only
PDF Form Filling
For form filling workflows, read forms.md — it covers both fillable (AcroForm) and non-fillable (annotation-based) approaches with helper scripts.
Next Steps
- reference.md — Advanced pypdfium2, pdf-lib (JS), pdfjs-dist
- forms.md — Complete form filling workflow with validation
When not to use it
- →Working with Word documents
- →Working with spreadsheet files
- →Working with PowerPoint files
Limitations
- →Requires a Python virtual environment for all script execution
- →Temporary files must use a specific prefix and be deleted after use
- →Does not support Word, Excel, or PowerPoint documents
How it compares
This skill automates PDF processing tasks using Python scripts within a managed virtual environment, unlike manual operations or separate tools for each function.
Compared to similar skills
pdf side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| pdf (this skill) | 0 | 4mo | Review | Intermediate |
| pdf-processing-pro | 17 | 10mo | Review | Intermediate |
| data-engineering | 13 | 7mo | Review | Advanced |
| crawl4ai | 21 | 8mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
pdf-processing-pro
davila7
Production-ready PDF processing with forms, tables, OCR, validation, and batch operations. Use when working with complex PDF workflows in production environments, processing large volumes of PDFs, or requiring robust error handling and validation.
data-engineering
pluginagentmarketplace
ETL pipelines, Apache Spark, data warehousing, and big data processing. Use for building data pipelines, processing large datasets, or data infrastructure.
crawl4ai
basher83
This skill should be used when users need to scrape websites, extract structured data, handle JavaScript-heavy pages, crawl multiple URLs, or build automated web data pipelines. Includes optimized extraction patterns with schema generation for efficient, LLM-free extraction.
data-cleaning-pipeline
aj-geddes
Build robust processes for data cleaning, missing value imputation, outlier handling, and data transformation for data preprocessing, data quality, and data pipeline automation
paddle-ocr-validation
jgtolentino
PaddleOCR-based receipt and BIR form extraction with validation
ocr
trpc-group
Extract text from images using Tesseract OCR