spb/ultra-sharp-agent-skills Public
Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.
Python 100%
1---2name: processing-pdf3description: Reads, creates, and modifies PDF files — extracts text and tables, builds new PDFs, merges, splits, rotates, watermarks, encrypts/decrypts, and fills PDF forms. Use when the user asks to read, extract, parse, create, generate, merge, combine, split, rotate, watermark, password-protect, decrypt, or fill a PDF, mentions a .pdf file, or asks to pull text or tables out of a PDF. Do not use for Word documents, images, or converting Office files to PDF (use the corresponding Office skill and export).4---56<!--7Author: Simon-Pierre Boucher8Contact: contact@spboucher.ai9-->1011# Processing PDF1213## When to use / when NOT to use14- **Use for:** any operation where a `.pdf` file is the input or the output — extraction, creation, page manipulation, forms, encryption.15- **Do NOT use for:** Word documents (`.docx`), images, or converting Office files to PDF — use the corresponding Office skill and export instead.1617## Quick reference — one default per operation1819**Extract text/tables — pdfplumber:**20```python21import pdfplumber22with pdfplumber.open("in.pdf") as pdf:23 text = "\n".join(p.extract_text() or "" for p in pdf.pages)24 tables = pdf.pages[0].extract_tables()25```26Escape hatch: if output is garbled or misordered, use `pdftotext -layout in.pdf out.txt` (poppler-utils). If pages yield no text at all, the PDF is scanned — OCR it with pytesseract + pdf2image (see recipes).2728**Page operations (merge/split/rotate/encrypt) and form filling — pypdf:**29```python30from pypdf import PdfReader, PdfWriter31writer = PdfWriter()32for path in ["a.pdf", "b.pdf"]:33 writer.append(path) # merge34writer.write("merged.pdf")35```3637**Create new PDFs — reportlab (Platypus):**38```python39from reportlab.lib.pagesizes import letter40from reportlab.platypus import SimpleDocTemplate, Paragraph41from reportlab.lib.styles import getSampleStyleSheet42styles = getSampleStyleSheet()43SimpleDocTemplate("out.pdf", pagesize=letter).build(44 [Paragraph("Title", styles["Title"]), Paragraph("Body text.", styles["Normal"])])45```4647## Workflow481. Identify the operation (extract / create / modify / form-fill) and pick the default tool above.492. Run the operation with the minimal code needed; write output next to the input unless the user names a path.503. **Validate:** re-open the output with `PdfReader("out.pdf")` and check `len(reader.pages)` matches expectations; for extraction, confirm the text/tables are non-empty before reporting success.514. If validation fails, fix and repeat step 2 — never deliver an unverified file.525. Report the output path and a one-line summary (page count, or rows/chars extracted).5354## Edge cases & failure modes55- **Missing dependency** → install exactly: `pip install pdfplumber pypdf reportlab`.56- **Corrupt/malformed PDF** → report the parser's error message verbatim (it names the object/offset); do not guess at contents.57- **Encrypted PDF** → `PdfReader(path)` raises or `reader.is_encrypted` is True; call `reader.decrypt(password)` — ask the user for the password, never brute-force.58- **Scanned PDF (no text layer)** → `extract_text()` returns None/empty; switch to OCR (recipes) and tell the user accuracy depends on scan quality.59- **Huge PDF** → process page-by-page (pdfplumber pages are lazy); never load all text into one string above ~1,000 pages.60- **Empty file (0 bytes)** → report "file is empty, not a valid PDF" and stop.6162## References63Deeper copy-paste recipes (watermark, split, encrypt, forms, OCR, conversion): see [references/recipes.md](references/recipes.md).64