pdf-generator — Claude Code skill: build and edit PDFs
A skill that fills PDF forms, stamps watermarks, merges documents and builds new files from a JSON spec, all from the terminal.
npx skills add jwynia/agent-skills --skill pdf-generator -a claude-codeWhat pdf-generator does
Two jobs in one skill. The first is editing existing PDFs: reading form fields, writing values into them, laying text, images and shapes on top, and merging files with page selection. The second is building a document from nothing out of JSON — headings, lines, tables with column widths and row heights, A4 or Letter pages.
Two Deno scripts do the work. analyze-template.ts pulls text, metadata and form fields out of a PDF, which is how you learn the exact field names before filling anything in. generate-from-template.ts handles the actual edits: form filling, overlays, merging. Both run through deno run with --allow-read and --allow-write.
Deno has to be installed first, or the scripts won't start at all. Template work needs a source PDF; scratch generation needs a JSON specification. Scanned files without a text layer and password-protected PDFs are out of scope here — the first needs OCR, the second a different tool. Heavy flowing-text layouts across many pages are usually easier with an HTML-to-PDF route.
What it helps with
- fill a PDF form from JSON and save the result
- list form field names in an existing PDF before writing values
- stamp a watermark or an APPROVED mark onto a page
- merge a cover page, appendices and a report body into one file
- generate a report with a data table from a spec
Example prompts for the agent
- Analyze the form fields in
application.pdfand list them - Fill
form-template.pdfwith the data inform-data.jsonand save it asfilled-form.pdf - Build a PDF from
report-spec.jsonwith the sales table
How to install pdf-generator
1Skills CLI (Vercel)
npx skills add jwynia/agent-skills --skill pdf-generator -a claude-code2Manually: put the files in place
~/.claude/skills/pdf-generator/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/pdf-generator/
1Skills CLI (Vercel)
npx skills add jwynia/agent-skills --skill pdf-generator -a codex2Manually: put the files in place
.agents/skills/pdf-generator/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add jwynia/agent-skills --skill pdf-generator -a cursor2Manually: put the files in place
.cursor/skills/pdf-generator/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install jwynia/agent-skills pdf-generator2Manually: put the files in place
.github/skills/pdf-generator/SKILL.md1Skills CLI (Vercel)
npx skills add jwynia/agent-skills --skill pdf-generator -a gemini-cli2Platform CLI
gemini skills install https://github.com/jwynia/agent-skills --path skills/general/document-processing/pdf/pdf-generatorManually: put the files in place
.devin/skills/pdf-generator/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add jwynia/agent-skills --skill pdf-generator -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about pdf-generator
How do I install pdf-generator in Claude?
Run npx skills add jwynia/agent-skills --skill pdf-generator -a claude-code. The skill lands in ~/.claude/skills/pdf-generator/SKILL.md.
What does pdf-generator do?
It fills PDF forms, adds watermarks and overlays, merges documents, and creates PDFs from scratch using a JSON specification.
What do I need to run pdf-generator?
Deno installed, since the scripts run with --allow-read and --allow-write. Template operations also need a source PDF; scratch generation needs a JSON spec.
Source text
SKILL.md · MIT
---
name: pdf-generator
description: "Create and manipulate PDF files programmatically. Use when the user needs to generate PDFs, fill PDF forms, extract PDF content, add watermarks/overlays, or merge documents. Supports both template-based generation (form filling, overlays) and from-scratch creation. Keywords: PDF, document, form, fillable, merge, watermark, extract, text, report."
license: MIT
compatibility: Requires Deno with --allow-read, --allow-write permissions
metadata:
author: agent-skills
version: "1.0"
type: generator
mode: generative
domain: documents
---
# PDF Generator
## When to Use This Skill
Use this skill when:
- Creating PDF documents programmatically from data or specifications
- Filling PDF forms with dynamic data
- Adding watermarks, stamps, or overlays to existing PDFs
- Extracting text and metadata from PDF files
- Merging multiple PDFs into one document
- Analyzing PDF structure and form fields
Do NOT use this skill when:
- User wants to open/view PDFs (use native PDF viewer)
- Complex page layout with flowing text is needed (consider HTML-to-PDF tools)
- Working with password-protected PDFs (limited support)
- OCR is needed for scanned documents
## Prerequisites
- Deno installed (https://deno.land/)
- Input PDF files for template-based operations
- JSON specification for scratch generation
## Quick Start
### Two Modes of Operation
1. **Template Mode**: Modify existing PDF templates
- Fill form fields (text, checkbox, dropdown)
- Add overlays (text, images, shapes)
- Merge and combine PDFs
2. **Scratch Mode**: Create PDFs from nothing using JSON specifications
## Instructions
### Mode 1: Template-Based Generation
#### Step 1a: Analyze the Template
Extract form fields and structure from an existing PDF:
```bash
deno run --allow-read scripts/analyze-template.ts form-template.pdf > inventory.json
```
**Output** (inventory.json):
```json
{
"filename": "form-template.pdf",
"pageCount": 2,
"title": "Application Form",
"author": "Company Inc",
"pages": [
{ "pageNumber": 1, "width": 612, "height": 792, "text": "..." }
],
"formFields": [
{ "name": "FullName", "type": "text", "value": "" },
{ "name": "Email", "type": "text", "value": "" },
{ "name": "AgreeToTerms", "type": "checkbox", "value": false }
],
"placeholders": [
{ "tag": "{{DATE}}", "location": "page 1", "pageNumber": 1 }
],
"hasFormFields": true
}
```
#### Step 1b: Create Fill Specification
Create `form-data.json`:
```json
{
"formFields": [
{ "name": "FullName", "value": "John Smith" },
{ "name": "Email", "value": "[email protected]" },
{ "name": "AgreeToTerms", "value": true }
],
"flattenForm": true
}
```
#### Step 1c: Generate Filled PDF
```bash
deno run --allow-read --allow-write scripts/generate-from-template.ts \
form-template.pdf form-data.json filled-form.pdf
```
### Adding Overlays (Watermarks, Stamps)
Create `watermark-spec.json`:
```json
{
"overlays": [
{
"type": "text",
"page": 1,
"x": 200,
"y": 400,
"text": "CONFIDENTIAL",
"fontSize": 48,
"color": { "r": 1, "g": 0, "b": 0 },
"rotate": 45
},
{
"type": "image",
"page": 1,
"x": 450,
"y": 700,
"path": "logo.png",
"width": 100,
"height": 50
}
]
}
```
### Merging PDFs
Create `merge-spec.json`:
```json
{
"prependPdfs": [
{ "path": "cover-page.pdf" }
],
"appendPdfs": [
{ "path": "appendix-a.pdf", "pages": [1, 2, 3] },
{ "path": "appendix-b.pdf" }
],
"excludePages": [5, 6]
}
```
### Mode 2: From-Scratch Generation
#### Step 2a: Create Specification
Create `spec.json`:
```json
{
"title": "Quarterly Report",
"author": "Finance Team",
"pages": [
{
"size": "A4",
"elements": [
{
"type": "text",
"x": 50,
"y": 750,
"text": "Q4 2024 Financial Report",
"fontSize": 28,
"font": "HelveticaBold",
"color": { "r": 0, "g": 0, "b": 0.5 }
},
{
"type": "line",
"startX": 50,
"startY": 740,
"endX": 550,
"endY": 740,
"thickness": 2
},
{
"type": "text",
"x": 50,
"y": 700,
"text": "Executive Summary",
"fontSize": 18,
"font": "HelveticaBold"
},
{
"type": "text",
"x": 50,
"y": 670,
"text": "This quarter showed strong growth across all divisions...",
"fontSize": 12,
"maxWidth": 500,
"lineHeight": 16
}
]
}
]
}
```
#### Step 2b: Generate PDF
```bash
deno run --allow-read --allow-write scripts/generate-scratch.ts spec.json output.pdf
```
## Examples
### Example 1: Fill Application Form
**Scenario**: Automatically fill a job application form.
```bash
# 1. Analyze form to find field names
deno run --allow-read scripts/analyze-template.ts application.pdf --pretty
# 2. Create form-data.json with applicant info
# 3. Generate filled form
deno run --allow-read --allow-write scripts/generate-from-template.ts \
application.pdf form-data.json john-smith-application.pdf
```
### Example 2: Add Approval Stamp
**Scenario**: Add an "APPROVED" stamp to a document.
**stamp-spec.json**:
```json
{
"overlays": [
{
"type": "rectangle",
"page": 1,
"x": 400,
"y": 700,
"width": 150,
"height": 50,
"color": { "r": 0.9, "g": 1, "b": 0.9 }
},
{
"type": "text",
"page": 1,
"x": 410,
"y": 720,
"text": "APPROVED",
"fontSize": 20,
"font": "HelveticaBold",
"color": { "r": 0, "g": 0.5, "b": 0 }
},
{
"type": "text",
"page": 1,
"x": 410,
"y": 705,
"text": "2024-12-15",
"fontSize": 10
}
]
}
```
### Example 3: Create Report with Table
**Scenario**: Generate a simple report with a data table.
**report-spec.json**:
```json
{
"title": "Sales Report",
"pages": [{
"size": "Letter",
"elements": [
{
"type": "text",
"x": 72,
"y": 720,
"text": "Monthly Sales Report",
"fontSize": 24,
"font": "HelveticaBold"
},
{
"type": "table",
"x": 72,
"y": 680,
"rows": [
["Product", "Units", "Revenue"],
["Widget A", "150", "$15,000"],
["Widget B", "75", "$11,250"],
["Widget C", "200", "$8,000"]
],
"columnWidths": [150, 80, 100],
"rowHeight": 25,
"headerBackground": { "r": 0.9, "g": 0.9, "b": 0.9 }
}
]
}]
}
```
## Script Reference
| Script | Purpose | Permissions |
|--------|---------|-------------|
| `analyze-template.ts` | Extract text, metadata, form fields from PDF | `--allow-read` |
| `generate-from-template.ts` | Fill forms, add overlays, merge PDFs | `--allow-read --allow-write` |
| `generate-scratch.ts` | Create PDF from JSON specification | `--allow-read --allow-write` |
## Element Types (Scratch Mode)
| Type | Description | Key Options |
|------|-------------|-------------|
| `text` | Text content | `x`, `y`, `text`, `fontSize`, `font`, `color`, `rotate` |
| `image` | PNG/JPEG images | `x`, `y`, `path`, `width`, `height`, `opacity` |
| `rectangle` | Filled/outlined rectangles | `x`, `y`, `width`, `height`, `color`, `borderColor` |
| `line` | Straight lines | `startX`, `startY`, `endX`, `endY`, `thickness` |
| `circle` | Filled/outlined circles | `x`, `y`, `radius`, `color`, `borderColor` |
| `table` | Basic table layout | `x`, `y`, `rows`, `columnWidths`, `rowHeight` |
## Available Fonts
- `Helvetica` (default)
- `HelveticaBold`
- `HelveticaOblique`
- `TimesRoman`
- `TimesBold`
- `Courier`
- `CourierBold`
## Page Sizes
- `A4` (595.28 x 841.89 points)
- `Letter` (612 x 792 points)
- `Legal` (612 x 1008 points)
- Custom: `[width, height]` in points
## Common Issues and Solutions
### Issue: Form fields not found
**Symptoms**: Error saying field name doesn't exist.
**Solution**:
1. Run `analyze-template.ts` to get exact field names
2. Field names are case-sensitive
3. Some PDFs have non-fillable text that looks like form fields
### Issue: Text positioning is off
**Symptoms**: Text appears in wrong location.
**Solution**:
- PDF coordinates start from bottom-left (0,0)
- Y increases upward, X increases rightward
- Use `analyze-template.ts` to see page dimensions
### Issue: Images not appearing
**Symptoms**: Image overlay not visible.
**Solution**:
1. Check file path is relative to spec.json location
2. Verify image is PNG or JPEG format
3. Ensure coordinates are within page bounds
### Issue: Merged PDF has wrong page order
**Symptoms**: Pages appear in unexpected order.
**Solution**:
- `prependPdfs` add pages before template
- `appendPdfs` add pages after template
- Use `pages` array to select specific pages: `[1, 3, 5]`
## Limitations
- **No built-in table layout**: Tables require manual column width specification
- **Standard fonts only**: Custom font embedding not supported in scratch mode
- **No flowing text**: Text doesn't automatically wrap to next page
- **Limited form field creation**: Can fill existing forms, not create new fields
- **No encryption**: Cannot create password-protected PDFs
- **Basic graphics**: No gradients, patterns, or complex paths
- **Text extraction**: May not work perfectly on all PDFs (depends on PDF structure)
## Related Skills
- **pptx-generator**: For creating PowerPoint presentations
- **docx-generator**: For creating Word documents
- **xlsx-generator**: For creating Excel spreadsheets
© agent-skills · MIT · jwynia/agent-skills