Agent skill
pdf-generation
This skill should be used when the user asks to "generate a PDF from markdown", "create a printable book", "convert documentation to PDF", or "export chapters as a PDF". Automatically activates when producing a PDF from a directory of ordered markdown chapters using pandoc and weasyprint. Not for single-file markdown-to-PDF conversion or non-documentation use cases.
Install this agent skill to your Project
npx add-skill https://github.com/sjungling/sjungling-claude-plugins/tree/main/plugins/technical-writer/skills/pdf-generation
SKILL.md
PDF Book Generation
Overview
Converts a directory of ordered markdown chapters into a single, styled PDF book with table of contents, page numbers, and resolved inter-chapter links.
Core principle: The markdown files are the source of truth. The PDF is a derived artifact -- never edit the PDF directly.
When to Use
Automatically activates when:
- A request to generate a PDF from markdown chapters is made
- A
technical-overviewor similar multi-chapter doc set is ready for export - A printable or shareable version of documentation is needed
Prerequisites
Three tools must be installed before generation can proceed:
| Tool | Install command | Purpose |
|---|---|---|
pandoc |
brew install pandoc |
Markdown to HTML conversion |
weasyprint |
uv tool install weasyprint |
HTML to PDF rendering |
pango |
brew install pango |
Text layout (weasyprint dependency) |
Before running the script, verify availability:
command -v pandoc >/dev/null 2>&1 || echo "Missing: pandoc (brew install pandoc)"
command -v weasyprint >/dev/null 2>&1 || echo "Missing: weasyprint (uv tool install weasyprint)"
If either tool is missing, install it and retry. The script itself checks for dependencies and exits with a clear error message.
How It Works
The generation pipeline has four stages:
- Collect -- Gather markdown files in order:
README.mdfirst, then00-*.mdthrough99-*.md, thenappendix-*.md - Convert -- Pandoc stitches all files into a single HTML document with a generated table of contents
- Fix links -- Inter-chapter
.mdlinks (e.g.,[architecture](01-architecture.md)) are rewritten to internal#anchorlinks so they work within the single document - Render -- Weasyprint converts the styled HTML to PDF with print-optimized CSS
Usage
Run the generation script using $CLAUDE_PLUGIN_ROOT:
${CLAUDE_PLUGIN_ROOT}/skills/pdf-generation/scripts/generate-pdf.sh <input-dir> [output.pdf]
input-dir-- Directory containing the ordered markdown chaptersoutput.pdf-- Optional output path (defaults to<input-dir>/technical-overview.pdf)
Handling Missing CLAUDE_PLUGIN_ROOT
If $CLAUDE_PLUGIN_ROOT is not set (e.g., running outside a plugin context), locate the script manually:
# Fallback: find the script in the plugin installation directory
SCRIPT_PATH=$(find ~/.claude/plugins -path "*/pdf-generation/scripts/generate-pdf.sh" 2>/dev/null | head -1)
if [ -z "$SCRIPT_PATH" ]; then
echo "Error: generate-pdf.sh not found. Ensure the technical-writer plugin is installed."
exit 1
fi
"$SCRIPT_PATH" <input-dir> [output.pdf]
Expected Directory Structure
The input directory must contain ordered markdown files following this naming convention:
docs/technical-overview/
├── README.md # Title page and introduction (always first)
├── 00-getting-started.md # Numbered chapters in sequence
├── 01-architecture.md
├── 02-data-model.md
├── 03-api-reference.md
├── 04-deployment.md
├── appendix-a-glossary.md # Appendices after numbered chapters
└── appendix-b-faq.md
Expected output:
docs/technical-overview/
├── ... (source files unchanged)
└── technical-overview.pdf # Generated PDF (default output location)
The PDF includes:
- A title derived from the first
#heading inREADME.md(or the directory name as fallback) - A generated table of contents with depth 2 (h1 and h2 headings)
- Page numbers centered at the bottom of each page
- Chapter breaks (each h1 starts on a new page)
- Resolved inter-chapter links as internal anchors
Inter-Document Linking Requirements
For the PDF to have working internal links, the source markdown must follow these rules:
- Use relative links between chapters:
[architecture overview](01-architecture.md) - Section links with anchors work too:
[the store layer](03-data-layer.md#store) - Every chapter should have exactly one
#heading -- this is used to resolve link targets - The script warns about any
.mdlinks it cannot resolve
Common linking mistakes:
| Mistake | Fix |
|---|---|
Absolute paths (/docs/01-arch.md) |
Use relative paths (01-arch.md) |
Missing # heading in chapter |
Add exactly one h1 heading per chapter |
| Link to file not in input directory | Ensure all linked files are in the same directory |
Styling and Customization
The script embeds a print-optimized CSS stylesheet with sensible defaults:
- Page size: US Letter with 1-inch top/bottom margins
- Fonts: System font stack (Apple system fonts, Segoe UI, Helvetica, Arial)
- Code blocks: Light gray background with monospace font at 9pt
- Tables: Bordered with alternating row colors
- Chapter breaks: Each h1 heading starts on a new page
For detailed CSS customization options (fonts, colors, page sizes, themes), see ./references/css-customization.md.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| "Error: 'pandoc' is not installed" | Missing dependency | brew install pandoc |
| "Error: 'weasyprint' is not installed" | Missing dependency | uv tool install weasyprint && brew install pango |
Warning about unresolved .md links |
Chapter heading does not match filename pattern | Ensure each chapter has a # heading and the link target filename is correct |
| PDF renders but fonts look wrong | Missing system fonts | weasyprint uses system fonts; install desired fonts via Font Book |
| Empty PDF or no chapters found | Files not matching naming convention | Verify files follow README.md, 00-*.md through 99-*.md, appendix-*.md pattern |
CLAUDE_PLUGIN_ROOT is empty |
Running outside plugin context | Use the fallback script discovery method described above |
| Long code blocks overflow margins | Default CSS handles this | Verify overflow-wrap: break-word and white-space: pre-wrap in CSS |
Additional Resources
./references/css-customization.md-- Detailed CSS customization options for fonts, page sizes, colors, and themes./scripts/generate-pdf.sh-- The generation script (inspect for advanced modification)
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
git-bisect-debugging
This skill should be used when the user asks to "find which commit broke this", "debug a regression", "bisect to find the bug", or says "this used to work". Automatically activates for performance regressions, test failures that appeared recently, or any issue known to have worked at a previous commit. Can be invoked from systematic-debugging or used standalone. Not for general debugging without a known-good commit or regression history.
structured-logging
This skill should be used when the user asks to "analyze data with SQLite", "query logs", "find patterns in test results", or "correlate errors across files". Automatically activates when parsing large output (>100 lines), correlating data from multiple sources, tracking state across operations, aggregating results (counts, averages, grouping), or querying the same dataset multiple times. Not for tiny datasets (<50 records) with a single simple query.
tmux-aware
This skill should be used when the user asks to "start a service in tmux", "check tmux pane output", "manage background processes", or "run a server in a pane". Automatically activates when running in a TMUX session (detected by SessionStart hook). Not for one-off commands that do not need a persistent pane.
cli-ux-designer
This skill should be used when the user asks to "design a CLI", "improve command structure", "format terminal output", "review CLI usability", "design help text", or "add flags and arguments". Automatically activates when designing new CLI tools, improving command interfaces, formatting terminal output, or reviewing CLI usability. Not for GUI/web design, backend APIs, or shell scripting.
ios-swift-expert
This skill should be used when the user asks to "build an iOS app", "create a SwiftUI view", "fix Xcode build errors", "implement Core Data", "design app architecture", or "optimize Swift performance". Automatically activates when working with .swift files, Xcode projects (.xcodeproj, .xcworkspace), SwiftUI interfaces, or Apple platform frameworks (UIKit, Core Data, Combine, WidgetKit, App Intents). Not for cross-platform frameworks (React Native, Flutter), non-Apple platforms, or backend server development.
obsidian-vault-manager
This skill should be used when the user asks to "manage Obsidian vault", "create a daily note", "move notes without breaking links", "search vault content", or "organize Obsidian notes". Automatically activates when working with Obsidian vaults, markdown notes with [[wiki-links]], daily notes, templates, or tags. Not for general markdown editing outside Obsidian vaults.
Didn't find tool you were looking for?