本文へ移動
cccskills
無料GitHub で公開

pdf

Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text/tables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting/decrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.

インストール方法を見る

含まれるファイル(11)

  • SKILL.md10.5 KB
  • forms.md11.6 KB
  • reference.md16.3 KB
  • scripts/check_bounding_boxes.py2.7 KB
  • scripts/check_fillable_fields.py268 B
  • scripts/convert_pdf_to_images.py1008 B
  • scripts/create_validation_image.py1.2 KB
  • scripts/extract_form_field_info.py4.2 KB
  • scripts/extract_form_structure.py3.9 KB
  • scripts/fill_fillable_fields.py3.7 KB
  • scripts/fill_pdf_form_with_annotations.py3.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

PDF Processing Guide

Overview

This guide covers PDF transformations — merging, splitting, rotating, watermarking, encrypting, filling forms, extracting images, and OCRing scanned PDFs. Reading text/tables is handled by read_file directly; do NOT use this skill for plain reading. See REFERENCE.md for advanced library usage and FORMS.md for form filling.

Dependencies are pre-installed in the sandbox image — do NOT pip install or npm install anything. Just import or invoke directly.

  • Python libraries (always present): pypdf, pdfplumber, pypdfium2, reportlab, pytesseract, pdf2image, Pillow, pandas, numpy.
  • JavaScript libraries (always present): pdf-lib, pdfjs-dist.
  • CLI tools (present on current sandbox images): pdftotext / pdftoppm / pdfimages (poppler-utils), qpdf, pdftk, pandoc, tesseract. Older sandbox images may be missing some of these — if a CLI tool returns not found, fall back to the equivalent Python library on this page rather than trying to install it.

Reading PDF text — use read_file

For any request to read, summarise, analyse, extract data from, or aggregate the contents of a PDF, call read_file directly:

read_file(path="path/to/document.pdf")

The harness parses PDFs natively via markitdown and returns markdown. Pagination via offset/limit is free (cached). Do NOT pip install pypdf/pdfplumber/pymupdf or write subprocess extraction scripts for reading — that bootstrap is exactly what read_file eliminates.

If read_file fails or times out on a specific PDF (large papers, encrypted, corrupt, or a scanned image-only PDF with no text layer), fall back in this order:

  1. pypdf first. It's a pure-Python library that's always importable in the sandbox and doesn't depend on apt packages. Use it to read pages directly — see the snippet below.
  2. pdftotext / pandoc (poppler-utils) when pypdf can't handle the specific PDF (e.g. tricky encoding). These are CLI tools and may be missing on older sandbox images; if which pdftotext errors, stay on pypdf.
  3. ocr-and-documents skill for scanned image-only PDFs.
# Reliable fallback when read_file times out — chunk by page range
# so a single call doesn't run past the tool timeout on long papers.
from pypdf import PdfReader
reader = PdfReader("path/to/document.pdf")
print(f"Total pages: {len(reader.pages)}")
for i in range(0, len(reader.pages)):
    print(f"--- Page {i + 1} ---")
    print(reader.pages[i].extract_text())

The other Python libraries on this page are for transformations (the next sections), not for plain reading.

Python Libraries

pypdf - Basic Operations

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

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)

Extract Metadata

reader = PdfReader("document.pdf")
meta = reader.metadata
print(f"Title: {meta.title}")
print(f"Author: {meta.author}")
print(f"Subject: {meta.subject}")
print(f"Creator: {meta.creator}")

Rotate Pages

reader = PdfReader("input.pdf")
writer = PdfWriter()

page = reader.pages[0]
page.rotate(90)  # Rotate 90 degrees clockwise
writer.add_page(page)

with open("rotated.pdf", "wb") as output:
    writer.write(output)

pdfplumber - Layout-aware text + tables (fallback only)

For plain text/markdown, read_file(path) is the right call (see top of this skill). Use pdfplumber only when you need precise layout preservation or per-table structured extraction that read_file does not give you — e.g., multi-line cells, merged headers, or extracting a specific table on a specific page.

Extract Text with Layout

import pdfplumber

with pdfplumber.open("document.pdf") as pdf:
    for page in pdf.pages:
        text = page.extract_text()
        print(text)

Extract Tables

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)

Advanced Table Extraction

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:  # Check if table is not empty
                df = pd.DataFrame(table[1:], columns=table[0])
                all_tables.append(df)

# Combine all tables
if all_tables:
    combined_df = pd.concat(all_tables, ignore_index=True)
    combined_df.to_excel("extracted_tables.xlsx", index=False)

reportlab - Create PDFs

Basic PDF Creation

from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

c = canvas.Canvas("hello.pdf", pagesize=letter)
width, height = letter

# Add text
c.drawString(100, height - 100, "Hello World!")
c.drawString(100, height - 120, "This is a PDF created with reportlab")

# Add a line
c.line(100, height - 140, 400, height - 140)

# Save
c.save()

Create PDF with Multiple Pages

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 = []

# Add content
title = Paragraph("Report Title", styles['Title'])
story.append(title)
story.append(Spacer(1, 12))

body = Paragraph("This is the body of the report. " * 20, styles['Normal'])
story.append(body)
story.append(PageBreak())

# Page 2
story.append(Paragraph("Page 2", styles['Heading1']))
story.append(Paragraph("Content for page 2", styles['Normal']))

# Build PDF
doc.build(story)

Subscripts and Superscripts

IMPORTANT: Never use Unicode subscript/superscript characters (₀₁₂₃₄₅₆₇₈₉, ⁰¹²³⁴⁵⁶⁷⁸⁹) in ReportLab PDFs. The built-in fonts do not include these glyphs, causing them to render as solid black boxes.

Instead, use ReportLab's XML markup tags in Paragraph objects:

from reportlab.platypus import Paragraph
from reportlab.lib.styles import getSampleStyleSheet

styles = getSampleStyleSheet()

# Subscripts: use <sub> tag
chemical = Paragraph("H<sub>2</sub>O", styles['Normal'])

# Superscripts: use <super> tag
squared = Paragraph("x<super>2</super> + y<super>2</super>", styles['Normal'])

For canvas-drawn text (not Paragraph objects), manually adjust font the size and position rather than using Unicode subscripts/superscripts.

Command-Line Tools

pdftotext (poppler-utils)

# Extract text
pdftotext input.pdf output.txt

# Extract text preserving layout
pdftotext -layout input.pdf output.txt

# Extract specific pages
pdftotext -f 1 -l 5 input.pdf output.txt  # Pages 1-5

qpdf

# Merge PDFs
qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf

# Split pages
qpdf input.pdf --pages . 1-5 -- pages1-5.pdf
qpdf input.pdf --pages . 6-10 -- pages6-10.pdf

# Rotate pages
qpdf input.pdf output.pdf --rotate=+90:1  # Rotate page 1 by 90 degrees

# Remove password
qpdf --password=mypassword --decrypt encrypted.pdf decrypted.pdf

pdftk (if available)

# Merge
pdftk file1.pdf file2.pdf cat output merged.pdf

# Split
pdftk input.pdf burst

# Rotate
pdftk input.pdf rotate 1east output rotated.pdf

Common Tasks

Extract Text from Scanned PDFs

# pytesseract + pdf2image are pre-installed; tesseract-ocr is in the
# sandbox image's apt layer.  Just import and run.
import pytesseract
from pdf2image import convert_from_path

# Convert PDF to images
images = convert_from_path('scanned.pdf')

# OCR each page
text = ""
for i, image in enumerate(images):
    text += f"Page {i+1}:\n"
    text += pytesseract.image_to_string(image)
    text += "\n\n"

print(text)

Add Watermark

from pypdf import PdfReader, PdfWriter

# Create watermark (or load existing)
watermark = PdfReader("watermark.pdf").pages[0]

# Apply to all pages
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)

Extract Images

# Using pdfimages (poppler-utils)
pdfimages -j input.pdf output_prefix

# This extracts all images as output_prefix-000.jpg, output_prefix-001.jpg, etc.

Password Protection

from pypdf import PdfReader, PdfWriter

reader = PdfReader("input.pdf")
writer = PdfWriter()

for page in reader.pages:
    writer.add_page(page)

# Add password
writer.encrypt("userpassword", "ownerpassword")

with open("encrypted.pdf", "wb") as output:
    writer.write(output)

Quick Reference

TaskBest ToolCommand/Code
Read text / tables / aggregate dataread_fileread_file(path="document.pdf")
Merge PDFspypdfwriter.add_page(page)
Split PDFspypdfOne page per file
Layout-precise text / structured tables (fallback)pdfplumberpage.extract_text() / page.extract_tables()
Create PDFsreportlabCanvas or Platypus
Command line mergeqpdfqpdf --empty --pages ...
OCR scanned PDFsocr-and-documents skill or pytesseractConvert to image first
Fill PDF formspdf-lib or pypdf (see FORMS.md)See FORMS.md

Next Steps

  • For advanced pypdfium2 usage, see REFERENCE.md
  • For JavaScript libraries (pdf-lib), see REFERENCE.md
  • If you need to fill out a PDF form, follow the instructions in FORMS.md
  • For troubleshooting guides, see REFERENCE.md

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

The Arbor research-coordinator protocol: the OBSERVE -> IDEATE -> SELECT -> DISPATCH -> DECIDE cycle over a durable Idea Tree. Preloaded automatically on /auto-research sessions. The coordinator never edits code or runs commands — executors do that in isolated worktrees; the coordinator steers the tree with idea_tree / dispatch_experiments / merge_experiment.

日本語の概要は準備中です。原文の説明を表示しています。

invergent-ai/surogates282026年10月12日 更新

The Arbor executor workflow: clone the repo from the git bundle your brief hands you, implement and evaluate exactly ONE hypothesis with the file tools, then report structured results via worker_complete. Preloaded automatically on arbor-executor task workers. Never touch the held-out test split.

日本語の概要は準備中です。原文の説明を表示しています。

invergent-ai/surogates282026年10月12日 更新

Hard-gated ideation for an Arbor research run. Load at the START of every IDEATE round, before drafting any hypothesis. Enforces the PI mindset (mechanism over knob), the four-question first-principles probe, the kill-filter, and the four-line hypothesis format. Ported from Arbor's idea_drafting + first_principles_probe.

日本語の概要は準備中です。原文の説明を表示しています。

invergent-ai/surogates282026年10月12日 更新

DECIDE-phase doctrine for an Arbor research run: when to merge, prune, combine, or finalize; how the held-out merge gate works; and the rule that the final report uses TEST scores. Load before deciding what to do with completed experiments.

日本語の概要は準備中です。原文の説明を表示しています。

invergent-ai/surogates282026年10月12日 更新

Intake for an autonomous research run (Arbor). Use when the user wants to optimize a metric in a repo over many isolated experiments — 'optimize this benchmark', 'improve the model F1 overnight', 'beat the leaderboard'. Discovers the repo/eval/splits, measures the baseline, confirms a Research Contract, then emits a ready-to-send /auto-research command. Does NOT start the run itself.

日本語の概要は準備中です。原文の説明を表示しています。

invergent-ai/surogates282026年10月12日 更新

You MUST use this before any creative work — creating features, building components, drafting documents, designing workflows, or modifying behavior. Explores your human partner's intent, requirements, and design before any implementation begins.

日本語の概要は準備中です。原文の説明を表示しています。

invergent-ai/surogates282026年10月12日 更新

invergent-ai のスキルをすべて見る

このスキルの問題を報告する