skills/pdf-generator/SKILL.md
Create and manipulate professional PDF documents with formatting, images, and metadata
npx skillsauth add jmsktm/claude-settings PDF GeneratorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The PDF Generator skill enables creation of professional PDF documents from various sources including Markdown, HTML, plain text, and structured data. It handles formatting, images, metadata, watermarks, and multi-page layouts. This skill leverages Node.js libraries like puppeteer, pdfkit, or jsPDF for comprehensive PDF generation capabilities.
Whether you need to convert documentation to PDF, generate reports with charts, create printable forms, or produce client deliverables, this skill provides the tools and workflows to create publication-quality PDFs programmatically.
Purpose: Transform Markdown files into formatted PDF documents with styling
Steps:
markedImplementation:
const puppeteer = require('puppeteer');
const marked = require('marked');
const fs = require('fs');
async function markdownToPdf(mdPath, outputPath, options = {}) {
const markdown = fs.readFileSync(mdPath, 'utf8');
const html = marked.parse(markdown);
const styledHtml = `
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: 'Helvetica', sans-serif; margin: 40px; line-height: 1.6; }
h1 { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
h2 { color: #34495e; margin-top: 30px; }
code { background: #f4f4f4; padding: 2px 6px; border-radius: 3px; }
pre { background: #f4f4f4; padding: 15px; border-radius: 5px; overflow-x: auto; }
blockquote { border-left: 4px solid #3498db; padding-left: 20px; color: #7f8c8d; }
</style>
</head>
<body>${html}</body>
</html>
`;
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setContent(styledHtml);
await page.pdf({
path: outputPath,
format: 'A4',
margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' },
printBackground: true,
...options
});
await browser.close();
}
Purpose: Create structured reports with headers, footers, page numbers, and sections
Steps:
Implementation:
const PDFDocument = require('pdfkit');
const fs = require('fs');
function generateReport(data, outputPath) {
const doc = new PDFDocument({
size: 'A4',
margins: { top: 50, bottom: 50, left: 50, right: 50 }
});
const stream = fs.createWriteStream(outputPath);
doc.pipe(stream);
// Cover page
doc.fontSize(28)
.text(data.title, { align: 'center' })
.moveDown(2)
.fontSize(14)
.text(`Generated: ${new Date().toLocaleDateString()}`, { align: 'center' });
doc.addPage();
// Table of contents
doc.fontSize(20).text('Table of Contents', { underline: true });
doc.moveDown();
data.sections.forEach((section, idx) => {
doc.fontSize(12)
.fillColor('blue')
.text(`${idx + 1}. ${section.title}`, { link: `#section${idx}` })
.fillColor('black');
});
// Sections
data.sections.forEach((section, idx) => {
doc.addPage();
doc.fontSize(18)
.fillColor('black')
.text(section.title, { destination: `section${idx}` });
doc.moveDown();
doc.fontSize(11).text(section.content, { align: 'justify' });
});
// Add page numbers
const pages = doc.bufferedPageRange();
for (let i = 0; i < pages.count; i++) {
doc.switchToPage(i);
doc.fontSize(10)
.text(`Page ${i + 1} of ${pages.count}`,
50, doc.page.height - 50,
{ align: 'center' });
}
doc.end();
}
Purpose: Convert multiple HTML files to PDFs in a single operation
Steps:
Purpose: Apply text or image watermarks to PDF documents
Steps:
Implementation:
const { PDFDocument, rgb, degrees } = require('pdf-lib');
const fs = require('fs');
async function addWatermark(inputPath, outputPath, watermarkText) {
const existingPdfBytes = fs.readFileSync(inputPath);
const pdfDoc = await PDFDocument.load(existingPdfBytes);
const pages = pdfDoc.getPages();
pages.forEach(page => {
const { width, height } = page.getSize();
page.drawText(watermarkText, {
x: width / 2 - 100,
y: height / 2,
size: 48,
color: rgb(0.75, 0.75, 0.75),
opacity: 0.3,
rotate: degrees(-45)
});
});
const pdfBytes = await pdfDoc.save();
fs.writeFileSync(outputPath, pdfBytes);
}
Purpose: Combine multiple PDF documents into a single file
Steps:
| Action | Command/Trigger | |--------|-----------------| | Convert Markdown to PDF | "convert [file.md] to pdf" | | Generate report from data | "create pdf report from [data]" | | Batch convert HTML | "convert all html files to pdf" | | Add watermark | "add watermark [text] to [file.pdf]" | | Merge PDFs | "merge [file1.pdf] and [file2.pdf]" | | Extract pages | "extract pages 1-5 from [file.pdf]" | | Compress PDF | "compress [file.pdf]" | | Add metadata | "set pdf metadata for [file.pdf]" |
page-break-before or page-break-after for controlled paginationDocumentation Export:
// Convert project README to PDF with styling
await markdownToPdf('./README.md', './docs/README.pdf', {
headerTemplate: '<div style="font-size:10px; text-align:center;">Project Documentation</div>',
footerTemplate: '<div style="font-size:10px; text-align:center;">Page <span class="pageNumber"></span></div>',
displayHeaderFooter: true
});
Invoice Generation:
// Create PDF invoice from template
const doc = new PDFDocument();
doc.pipe(fs.createWriteStream('invoice.pdf'));
doc.fontSize(20).text('INVOICE', { align: 'center' });
doc.fontSize(12).text(`Invoice #: ${invoiceNumber}`);
doc.text(`Date: ${date}`);
// ... add line items, totals, etc.
doc.end();
Install required packages:
npm install puppeteer pdfkit pdf-lib marked
data-ai
Optimize YouTube videos for SEO, thumbnails, descriptions, and audience retention
testing
Design and facilitate effective workshops with agendas, activities, and outcomes
data-ai
Design and optimize AI-powered workflows for complex tasks
data-ai
Design and implement automated workflows to eliminate repetitive tasks and streamline processes