Skip to main content

Pdf

Activate for any direct PDF action a user wants executed right now: generate a PDF from a document file (markdown, HTML, RST, Word), print a file to a printer, preview a document's formatted appearance, email a file as a PDF attachment, merge multiple PDFs, split a PDF into pages, extract specific pages, rotate pages, add watermarks, OCR a scanned PDF, extract text or tables, fill a form, or password-protect a file. Has the pandoc commands, Typst template, and Resend API integration needed — load before starting, not after. Skip for: reading or summarizing an existing PDF, writing PDF-generation code, setting up CI pipelines, or comparing PDF libraries.

PDF Skill

Two capabilities: generate PDFs from documents, and manipulate existing PDFs.


Part 1: PDF Generation & Distribution

Convert documents to PDFs and distribute them — save, preview, print, or email.

Prerequisites

  • pandoc and typst installed (brew install pandoc typst)
  • For email mode: RESEND_API_KEY environment variable set

Modes

Mode Flag What happens
save (default) PDF saved to ~/Desktop/<filename>.pdf
preview --preview PDF opens in Preview.app (temp file)
print --print PDF sent to default printer, temp file cleaned up
email --email <address> PDF emailed via Resend, temp file cleaned up

Examples

/pdf docs/plans/phase-3/M10-pdf-email.md
/pdf README.md --preview
/pdf report.html --print
/pdf changelog.md --email ameet@rajababa.io

How to Generate the PDF

Step 1: Determine the input format.

Pandoc auto-detects from file extension. Common formats:

  • .mdgfm (GitHub-Flavored Markdown)
  • .htmlhtml
  • .docxdocx
  • .rstrst

Step 2: Run pandoc with the template.

SKILL_DIR="<framework-root>/.claude/skills/pdf"
TEMPLATE_PATH="$SKILL_DIR/templates/clean.typ"
FILTER_PATH="$SKILL_DIR/filters/github-alerts.lua"

# For save mode (to Desktop):
pandoc <input-file> -f gfm -o ~/Desktop/<output-name>.pdf \
  --pdf-engine=typst \
  --template="$TEMPLATE_PATH" \
  --lua-filter="$FILTER_PATH" \
  -V timestamp="$(date '+%b %d, %Y %I:%M %p')"

# For preview/print/email (use temp file):
pandoc <input-file> -f gfm -o /tmp/<output-name>.pdf \
  --pdf-engine=typst \
  --template="$TEMPLATE_PATH" \
  --lua-filter="$FILTER_PATH" \
  -V timestamp="$(date '+%b %d, %Y %I:%M %p')"

Adjust -f gfm to match the input format if not markdown.

Step 3: Distribute based on mode.

Save (default)

Output is already at ~/Desktop/<name>.pdf. Tell the user.

Preview

open /tmp/<name>.pdf

Print

lpr /tmp/<name>.pdf && rm /tmp/<name>.pdf

Email

Resend requires attachments as Base64-encoded content in JSON:

B64=$(base64 -i /tmp/<name>.pdf)

curl -s -X POST 'https://api.resend.com/emails' \
  -H "Authorization: Bearer $RESEND_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"from\": \"Rajababa <noreply@rajababa.io>\",
    \"to\": [\"<recipient>\"],
    \"subject\": \"<document title>\",
    \"text\": \"PDF attached.\",
    \"attachments\": [{
      \"filename\": \"<name>.pdf\",
      \"content\": \"$B64\"
    }]
  }"

rm /tmp/<name>.pdf

Important: The to field must be an array: ["email@example.com"], not a string.

Template

The Typst template lives at templates/clean.typ in this skill directory. It uses:

  • Font: Helvetica Neue (body), Menlo (code) — macOS system fonts, zero install
  • Colors: Neutral palette — charcoal text, gray headings, light rules
  • Layout: US Letter, justified body text, 0.9em leading, rules under H1/H2
  • Admonitions: #admonition("NOTE")[...] with colored left borders (NOTE=blue, TIP=green, IMPORTANT=purple, WARNING=amber, CAUTION=red)
  • Tables: Light gray header row fill for clear data separation
  • Footer: Page numbers (left), timestamp (right)

The Lua filter at filters/github-alerts.lua converts GitHub alert syntax (> [!NOTE], etc.) into Typst admonition blocks automatically during PDF generation.

Pandoc Metadata

Pass metadata to customize the title page:

pandoc input.md -o output.pdf \
  --pdf-engine=typst \
  --template="$TEMPLATE_PATH" \
  --lua-filter="$FILTER_PATH" \
  -V title="Document Title" \
  -V author="Ameet" \
  -V date="March 2026" \
  -V timestamp="$(date '+%b %d, %Y %I:%M %p')"

If the markdown has YAML frontmatter with title, author, or date, Pandoc picks those up automatically.


Part 2: PDF Manipulation

For working with existing PDF files — merging, splitting, extracting, transforming. Uses Python libraries.

For detailed code examples, patterns, and advanced usage, read these reference files:

  • references/reference.md — Full manipulation guide (pypdf, pdfplumber, reportlab, CLI tools)
  • references/forms.md — PDF form filling guide

Quick Reference

Task Best Tool Example
Merge PDFs pypdf writer.add_page(page) in a loop
Split PDFs pypdf One page per output file
Extract text pdfplumber page.extract_text()
Extract tables pdfplumber page.extract_tables()
Create PDFs programmatically reportlab Canvas or Platypus
Rotate pages pypdf page.rotate(90)
Add watermark pypdf page.merge_page(watermark)
Password protect pypdf writer.encrypt("password")
OCR scanned PDFs pytesseract + pdf2image Convert to image, then OCR
CLI merge qpdf qpdf --empty --pages f1.pdf f2.pdf -- out.pdf

Prerequisites

Install Python libraries as needed:

pip install pypdf pdfplumber reportlab
# For OCR:
pip install pytesseract pdf2image
brew install tesseract poppler
# For CLI tools:
brew install qpdf poppler

Important Notes

  • Never use Unicode subscript/superscript characters in reportlab — they render as black boxes. Use <sub> and <super> tags in Paragraph objects instead.
  • For detailed examples of each operation, read reference.md.
  • For PDF form filling, read forms.md first — it has specific instructions.

Troubleshooting

Problem Fix
Font rendering issues Template uses macOS system fonts (Helvetica Neue, Menlo) — should work on any Mac
"unknown variable: horizontalrule" Make sure you're using the template from this skill
Resend email fails Check $RESEND_API_KEY is set: echo $RESEND_API_KEY
No default printer lpstat -p to list printers, or set one in System Settings → Printers
pypdf/pdfplumber not found pip install pypdf pdfplumber

Search Framework Explorer

Search agents, skills, and standards