SPB Git

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%

# name: processing-pdf description: 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).

# Processing PDF

# When to use / when NOT to use

  • Use for: any operation where a .pdf file is the input or the output — extraction, creation, page manipulation, forms, encryption.
  • Do NOT use for: Word documents (.docx), images, or converting Office files to PDF — use the corresponding Office skill and export instead.

# Quick reference — one default per operation

Extract text/tables — pdfplumber:

python
import pdfplumber
with pdfplumber.open("in.pdf") as pdf:
    text = "\n".join(p.extract_text() or "" for p in pdf.pages)
    tables = pdf.pages[0].extract_tables()

Escape 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).

Page operations (merge/split/rotate/encrypt) and form filling — pypdf:

python
from pypdf import PdfReader, PdfWriter
writer = PdfWriter()
for path in ["a.pdf", "b.pdf"]:
    writer.append(path)                      # merge
writer.write("merged.pdf")

Create new PDFs — reportlab (Platypus):

python
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.styles import getSampleStyleSheet
styles = getSampleStyleSheet()
SimpleDocTemplate("out.pdf", pagesize=letter).build(
    [Paragraph("Title", styles["Title"]), Paragraph("Body text.", styles["Normal"])])

# Workflow

  1. Identify the operation (extract / create / modify / form-fill) and pick the default tool above.
  2. Run the operation with the minimal code needed; write output next to the input unless the user names a path.
  3. 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.
  4. If validation fails, fix and repeat step 2 — never deliver an unverified file.
  5. Report the output path and a one-line summary (page count, or rows/chars extracted).

# Edge cases & failure modes

  • Missing dependency → install exactly: pip install pdfplumber pypdf reportlab.
  • Corrupt/malformed PDF → report the parser's error message verbatim (it names the object/offset); do not guess at contents.
  • Encrypted PDFPdfReader(path) raises or reader.is_encrypted is True; call reader.decrypt(password) — ask the user for the password, never brute-force.
  • Scanned PDF (no text layer)extract_text() returns None/empty; switch to OCR (recipes) and tell the user accuracy depends on scan quality.
  • Huge PDF → process page-by-page (pdfplumber pages are lazy); never load all text into one string above ~1,000 pages.
  • Empty file (0 bytes) → report "file is empty, not a valid PDF" and stop.

# References

Deeper copy-paste recipes (watermark, split, encrypt, forms, OCR, conversion): see references/recipes.md.