Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Professional PDF documentation generation. Convert Markdown to PDF with custom templates, styling, table of contents, cross-references, and optimized output for print and archival.
.claude/skills/a5c-ai-pdf-generation/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 191% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -13% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 47% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 92% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 88% | 0% |
Professional PDF documentation generation.
Invoke this skill when you need to:
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | inputPath | string | Yes | Path to Markdown source(s) | | outputPath | string | Yes | Output PDF file path | | template | string | No | Path to PDF template | | config | object | No | PDF generation options | | metadata | object | No | Document metadata | | toc | boolean | No | Generate table of contents |
json{ "inputPath": "./docs", "outputPath": "./output/documentation.pdf", "template": "./templates/manual.html", "toc": true, "metadata": { "title": "Product Documentation", "author": "Documentation Team", "version": "1.0.0" } }
output/
└── documentation.pdf
├── Cover page
├── Table of Contents
├── Chapter 1: Getting Started
│ ├── Installation
│ └── Quick Start
├── Chapter 2: User Guide
│ ├── Configuration
│ └── Features
├── Chapter 3: API Reference
└── Appendixoutput/
├── getting-started.pdf
├── user-guide.pdf
├── api-reference.pdf
└── complete-manual.pdfyamlfrom: markdown+smart+yaml_metadata_block+implicit_figures+table_captions to: pdf pdf-engine: xelatex variables: documentclass: report papersize: letter fontsize: 11pt geometry: - margin=1in - top=1.25in - bottom=1.25in mainfont: "Source Serif Pro" sansfont: "Source Sans Pro" monofont: "Source Code Pro" linkcolor: blue urlcolor: blue toccolor: black toc-depth: 3 include-before-body: - cover.tex include-in-header: - preamble.tex metadata: title: "Documentation" author: "Documentation Team" date: "2026-01-24" lang: en-US toc: true toc-title: "Table of Contents" number-sections: true colorlinks: true highlight-style: pygments
latex% Custom styling \usepackage{fancyhdr} \usepackage{titlesec} \usepackage{xcolor} \usepackage{listings} \usepackage{graphicx} % Header/Footer \pagestyle{fancy} \fancyhf{} \fancyhead[L]{\leftmark} \fancyhead[R]{\thepage} \fancyfoot[C]{\small Documentation v1.0} % Code block styling \lstset{ basicstyle=\ttfamily\small, breaklines=true, frame=single, backgroundcolor=\color{gray!10} } % Heading styles \titleformat{\chapter}[display] {\normalfont\huge\bfseries} {\chaptertitlename\ \thechapter}{20pt}{\Huge} % Link colors \definecolor{linkblue}{RGB}{0,102,204}
css@page { size: letter; margin: 1in; margin-top: 1.25in; margin-bottom: 1.25in; @top-center { content: string(chapter-title); font-size: 10pt; color: #666; } @bottom-center { content: "Page " counter(page) " of " counter(pages); font-size: 9pt; } } @page :first { @top-center { content: none; } @bottom-center { content: none; } } /* Cover page */ .cover { page: cover; text-align: center; padding-top: 3in; } .cover h1 { font-size: 36pt; color: #333; } .cover .version { font-size: 14pt; color: #666; margin-top: 1in; } /* Table of contents */ #toc { page-break-after: always; } #toc h2 { font-size: 24pt; margin-bottom: 0.5in; } #toc a { text-decoration: none; color: inherit; } #toc a::after { content: leader('.') target-counter(attr(href), page); } /* Chapters */ h1 { string-set: chapter-title content(); page-break-before: always; font-size: 28pt; border-bottom: 2px solid #333; padding-bottom: 0.25in; } h2 { font-size: 20pt; margin-top: 0.5in; } h3 { font-size: 16pt; margin-top: 0.3in; } /* Code blocks */ pre { background-color: #f5f5f5; padding: 0.5em; border-radius: 4px; font-size: 9pt; overflow-x: auto; page-break-inside: avoid; } code { font-family: "Source Code Pro", monospace; background-color: #f0f0f0; padding: 0.1em 0.3em; border-radius: 3px; } /* Tables */ table { width: 100%; border-collapse: collapse; margin: 1em 0; page-break-inside: avoid; } th, td { border: 1px solid #ddd; padding: 0.5em; text-align: left; } th { background-color: #f5f5f5; font-weight: bold; } /* Images */ img { max-width: 100%; height: auto; } figure { text-align: center; page-break-inside: avoid; } figcaption { font-style: italic; color: #666; margin-top: 0.5em; } /* Links */ a { color: #0066cc; text-decoration: none; } /* Print optimizations */ @media print { a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; color: #666; } }
html<!DOCTYPE html> <html> <head> <style> body { font-family: "Source Sans Pro", sans-serif; text-align: center; padding-top: 200px; } .logo { max-width: 200px; margin-bottom: 50px; } h1 { font-size: 48px; color: #333; margin-bottom: 20px; } .subtitle { font-size: 24px; color: #666; margin-bottom: 100px; } .version { font-size: 18px; color: #999; } .date { font-size: 14px; color: #999; margin-top: 10px; } .footer { position: absolute; bottom: 50px; width: 100%; text-align: center; color: #666; } </style> </head> <body> <img src="logo.png" alt="Company Logo" class="logo"> <h1>{{title}}</h1> <p class="subtitle">{{subtitle}}</p> <p class="version">Version {{version}}</p> <p class="date">{{date}}</p> <div class="footer"> <p>{{company}}</p> <p>Confidential</p> </div> </body> </html>
javascriptconst pandoc = require('pandoc'); const fs = require('fs'); const path = require('path'); async function buildManual(config) { const chapters = [ { title: 'Getting Started', files: ['intro.md', 'installation.md', 'quickstart.md'] }, { title: 'User Guide', files: ['configuration.md', 'features.md', 'advanced.md'] }, { title: 'API Reference', files: ['api/*.md'] }, { title: 'Appendix', files: ['glossary.md', 'changelog.md'] } ]; // Combine all Markdown files let combined = ''; for (const chapter of chapters) { combined += `# ${chapter.title}\n\n`; for (const filePattern of chapter.files) { const files = glob.sync(filePattern, { cwd: config.docsDir }); for (const file of files) { const content = fs.readFileSync(path.join(config.docsDir, file), 'utf8'); // Adjust heading levels const adjusted = adjustHeadings(content, 1); combined += adjusted + '\n\n'; } } } // Write combined file const tempFile = '/tmp/combined.md'; fs.writeFileSync(tempFile, combined); // Run Pandoc await pandoc({ input: tempFile, output: config.outputPath, args: [ '--defaults', config.pandocDefaults, '--metadata-file', config.metadataFile ] }); return { output: config.outputPath }; }
bash# Using Pandoc with PDF/A output pandoc input.md \ -o output.pdf \ --pdf-engine=xelatex \ -V 'pdfa=1b' \ --include-in-header=pdfa-header.tex # pdfa-header.tex \usepackage{hyperref} \hypersetup{ pdfstartview=, colorlinks=false, pdfpagelayout=SinglePage } \usepackage[a-1b]{pdfx}
json{ "devDependencies": { "pandoc": "^0.2.0", "weasyprint": "via pip", "puppeteer": "^21.0.0", "pdf-lib": "^1.17.0" } }
bash# macOS brew install pandoc brew install --cask basictex pip install weasyprint # Ubuntu sudo apt install pandoc texlive-xetex texlive-fonts-recommended pip install weasyprint # Windows (via Chocolatey) choco install pandoc miktex pip install weasyprint
bash# Single file with Pandoc pandoc input.md -o output.pdf --defaults pandoc-defaults.yaml # Multiple files combined pandoc docs/*.md -o manual.pdf --toc --number-sections # Using WeasyPrint weasyprint input.html output.pdf -s style.css # Using Puppeteer (for HTML-based PDFs) node generate-pdf.js --input docs/ --output manual.pdf
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 12,053 | 15,574 | +29% | 1 | 1 | 0% | 1,896 | 5,514 | +191% | 0 | 0 | — |
case-02 | fail→pass | 39,521 | 18,874 | -52% | 1 | 1 | 0% | 7,145 | 6,213 | -13% | 0 | 0 | — |
case-03 | fail→pass | 34,935 | 45,761 | +31% | 1 | 1 | 0% | 4,648 | 6,841 | +47% | 0 | 0 | — |
case-04 | pass→pass | 20,134 | 19,019 | -6% | 1 | 1 | 0% | 2,801 | 5,926 | +112% | 0 | 0 | — |
case-05 | pass→pass | 15,163 | 16,101 | +6% | 1 | 1 | 0% | 2,045 | 5,560 | +172% | 0 | 0 | — |
case-06 | pass→pass | 18,719 | 18,392 | -2% | 1 | 1 | 0% | 2,630 | 5,606 | +113% | 0 | 0 | — |
case-07 | fail→pass | 20,340 | 17,475 | -14% | 1 | 1 | 0% | 2,776 | 5,317 | +92% | 0 | 0 | — |
case-08 | fail→pass | 16,844 | 8,687 | -48% | 1 | 1 | 0% | 2,088 | 3,935 | +88% | 0 | 0 | — |
case-09 | pass→pass | 12,480 | 11,025 | -12% | 1 | 1 | 0% | 1,237 | 4,387 | +255% | 0 | 0 | — |
case-10 | pass→pass | 16,499 | 14,976 | -9% | 1 | 1 | 0% | 2,118 | 5,275 | +149% | 0 | 0 | — |
case-11 | pass→fail | 15,046 | 20,282 | +35% | 1 | 1 | 0% | 1,769 | 5,850 | +231% | 0 | 0 | — |
case-12 | fail→pass | 12,932 | 9,980 | -23% | 1 | 1 | 0% | 1,469 | 4,200 | +186% | 0 | 0 | — |
case-13 | fail→pass | 17,427 | 10,868 | -38% | 1 | 1 | 0% | 2,139 | 4,464 | +109% | 0 | 0 | — |
case-14 | fail→pass | 20,156 | 20,615 | +2% | 1 | 1 | 0% | 3,145 | 6,804 | +116% | 0 | 0 | — |
case-15 | fail→pass | 24,579 | 21,590 | -12% | 1 | 1 | 0% | 3,287 | 6,288 | +91% | 0 | 0 | — |
case-16 | pass→pass | 9,537 | 10,356 | +9% | 1 | 1 | 0% | 936 | 4,290 | +358% | 0 | 0 | — |
case-17 | pass→pass | 19,337 | 13,055 | -32% | 1 | 1 | 0% | 2,297 | 4,750 | +107% | 0 | 0 | — |
case-18 | pass→pass | 25,067 | 8,410 | -66% | 1 | 1 | 0% | 1,217 | 3,833 | +215% | 0 | 0 | — |
case-19 | fail→pass | 20,492 | 23,311 | +14% | 1 | 1 | 0% | 2,328 | 6,184 | +166% | 0 | 0 | — |
case-20 | fail→fail | 22,147 | 39,501 | +78% | 1 | 1 | 0% | 2,849 | 6,679 | +134% | 0 | 0 | — |
case-21 | pass→pass | 18,997 | 6,902 | -64% | 1 | 1 | 0% | 511 | 3,514 | +588% | 0 | 0 | — |
case-22 | pass→pass | 9,809 | 8,002 | -18% | 1 | 1 | 0% | 839 | 3,722 | +344% | 0 | 0 | — |
case-23 | pass→pass | 14,244 | 14,309 | +0% | 1 | 1 | 0% | 1,712 | 5,022 | +193% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +39 percentage points is the difference between those two pass rates over the 23 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.