AgentSkillsCN

pdf-conversion

利用 WeasyPrint 将 Markdown 文件转换为专业的 PDF 文档。 当用户希望将 Markdown 转换为 PDF、导出为 PDF,或从文档中生成 PDF 时,可使用此技能。 支持自定义 CSS 样式、页眉/页脚,以及 Autodesk 品牌主题。

SKILL.md
--- frontmatter
name: pdf-conversion
description: |
  Converts Markdown files to professional PDF documents using WeasyPrint.
  Use when user wants to convert markdown to PDF, export as PDF, or generate PDF from documents.
  Supports custom CSS styling, page headers/footers, and Autodesk brand themes.

Markdown to PDF Converter Skill

Purpose

Convert Markdown files to professional PDF documents using WeasyPrint (HTML→PDF engine) with customizable CSS styling. Runs entirely in sandbox with no external dependencies beyond Python packages.


Architecture

Technology Stack

ComponentLibraryPurpose
MD ParsermarkdownConvert Markdown → HTML with extensions
PDF EngineweasyprintRender HTML+CSS → PDF
StylingCustom CSSProfessional typography and layout

Why This Stack?

  • Pure Python: No subprocess calls, no external tools (Pandoc, LaTeX) required
  • Sandbox-Safe: Works within Cursor sandbox restrictions
  • CSS Control: Full styling customization via CSS
  • Quality Output: Professional typography with proper page handling

Features

Markdown Support

FeatureStatusNotes
Headers (h1-h6)Proper hierarchy styling
Bold/ItalicStandard inline formatting
Lists (ordered/unordered)Nested list support
Code blocksSyntax-highlighted with fenced_code
TablesGFM-style tables
LinksClickable in PDF
ImagesEmbedded (local paths)
BlockquotesStyled callouts
Horizontal rulesSection dividers
Task listsCheckbox rendering
FootnotesEnd-of-document notes
Table of ContentsAuto-generated with [TOC]

PDF Features

  • Page sizes: A4, Letter, Legal, custom dimensions
  • Margins: Configurable (default: 2.5cm)
  • Headers/Footers: Page numbers, document title, date
  • Page breaks: Before major sections (configurable)
  • Typography: Professional fonts, proper line-height

Workflow

Step 1: Understand Request

  • What Markdown file(s) need conversion?
  • Any specific styling requirements?
  • Output filename/location preference?
  • Page size requirements (A4 default)?

Step 2: Check/Setup Environment

bash
# One-time setup (if not done)
cd /Users/samarvir/code/autodesk/Product\ management
source .venv/bin/activate
pip install markdown weasyprint

Step 3: Execute Conversion

bash
# Basic conversion
python .claude/skills/md-to-pdf/convert_md_to_pdf.py input.md output.pdf

# With options
python .claude/skills/md-to-pdf/convert_md_to_pdf.py input.md output.pdf \
  --css custom.css \
  --page-size letter \
  --title "Document Title"

Step 4: Report Results

code
**PDF Generated Successfully**

**Input**: input.md
**Output**: Output/document.pdf
**Pages**: [N] pages
**Size**: [X] KB

Styling: [default/custom CSS path]

Usage Options

Command Line Arguments

ArgumentTypeDefaultDescription
inputpositionalrequiredInput Markdown file path
outputpositionalrequiredOutput PDF file path
--cssstringdefault.cssCustom CSS file path
--page-sizestringa4Page size: a4, letter, legal
--marginstring2.5cmPage margins
--titlestring(from md)Document title for header
--no-tocflagfalseDisable table of contents
--no-headerflagfalseDisable page header
--no-footerflagfalseDisable page footer

Examples

Basic Conversion

bash
python .claude/skills/md-to-pdf/convert_md_to_pdf.py \
  Initiatives/docs-integration/prd.md \
  Output/prd.pdf

With Custom Styling

bash
python .claude/skills/md-to-pdf/convert_md_to_pdf.py \
  Initiatives/ai-renderings/case-for-a-new-squad.md \
  Operations/adhoc/ai-renderings/proposal.pdf \
  --css .claude/skills/md-to-pdf/styles/autodesk.css \
  --title "AI Renderings Squad Proposal"

Letter Size for US Audience

bash
python .claude/skills/md-to-pdf/convert_md_to_pdf.py \
  document.md \
  document.pdf \
  --page-size letter \
  --margin 1in

CSS Themes

Available Themes

ThemeFileUse Case
Defaultdefault.cssClean, professional documents
Autodeskautodesk.cssAutodesk brand colors
Minimalminimal.cssSimple, no-frills output

Custom CSS

Create your own CSS file with:

  • @page rules for margins, headers, footers
  • Typography settings (fonts, sizes, line-height)
  • Table styling
  • Code block formatting
  • Color schemes

Example custom CSS sections:

css
/* Page setup */
@page {
  size: A4;
  margin: 2.5cm;
  @top-center { content: "Document Title"; }
  @bottom-right { content: "Page " counter(page); }
}

/* Typography */
body {
  font-family: 'Helvetica Neue', Arial, sans-serif;
  font-size: 11pt;
  line-height: 1.6;
}

/* Headers */
h1 { color: #1D91D0; page-break-before: always; }
h1:first-of-type { page-break-before: avoid; }

Output Location Guidelines

Follow the project's Output Location Protocol:

Document TypeSave ToExample
Initiative PRDsInitiatives/[name]/Initiatives/ai-renderings/prd.pdf
Leadership DocsOperations/recurring/leadership-reviews/q1-2026.pdf
Ad-hoc AnalysisOperations/adhoc/[topic]/adhoc/market-analysis/report.pdf
Test/TemporaryOutput/Output/test.pdf

Security Compliance

RuleImplementation
No user input in file pathsValidated input/output paths
No eval/execPure library API calls
No subprocessWeasyPrint is pure Python
Input validationFile existence checks
Sandboxed executionRuns in Cursor sandbox
Resource limitsHandles large files gracefully

Input Sanitization

  • HTML content is escaped by default
  • Raw HTML in Markdown disabled unless explicitly enabled
  • Image paths validated (local only, no URLs without flag)
  • File size warnings for documents > 1MB source

Troubleshooting

Common Issues

IssueCauseFix
Missing fontsSystem fonts not availableUse web-safe fonts in CSS
Images not showingRelative paths brokenUse absolute paths or --base-path
Tables overflowWide tablesAdd table { width: 100%; } to CSS
No page breaksCSS missing rulesAdd h1 { page-break-before: always; }
WeasyPrint warningsFont/CSS issuesUsually safe to ignore

Debug Mode

bash
python .claude/skills/md-to-pdf/convert_md_to_pdf.py input.md output.pdf --debug

Outputs:

  • Intermediate HTML (for inspection)
  • CSS applied
  • Any warnings/errors

File Locations

FilePurpose
.claude/skills/md-to-pdf/SKILL.mdThis documentation
.claude/skills/md-to-pdf/convert_md_to_pdf.pyMain converter script
.claude/skills/md-to-pdf/default.cssDefault styling
.claude/skills/md-to-pdf/styles/Additional CSS themes

Setup (One-Time)

bash
cd /Users/samarvir/code/autodesk/Product\ management
source .venv/bin/activate
pip install markdown weasyprint

Dependencies

PackageVersionPurpose
markdown>=3.4Markdown parsing with extensions
weasyprint>=60.0HTML to PDF rendering

System Requirements

WeasyPrint requires some system libraries. On macOS:

bash
brew install pango

If you encounter font issues:

bash
brew install fontconfig

API Usage (Programmatic)

For integration with other scripts:

python
from convert_md_to_pdf import MarkdownToPDF

converter = MarkdownToPDF(
    css_path="default.css",
    page_size="a4",
    margin="2.5cm"
)

# Convert file
converter.convert_file("input.md", "output.pdf")

# Convert string
converter.convert_string(
    markdown_text="# Hello World\n\nThis is a test.",
    output_path="output.pdf",
    title="Test Document"
)

Best Practices

DO

  • ✅ Use semantic Markdown (proper header hierarchy)
  • ✅ Keep images local or use absolute URLs
  • ✅ Test with --debug first for complex documents
  • ✅ Use CSS for all styling (not inline HTML)
  • ✅ Add [TOC] for documents > 5 pages

DON'T

  • ❌ Embed raw HTML unless necessary
  • ❌ Use complex nested tables
  • ❌ Expect pixel-perfect browser rendering
  • ❌ Use remote images without --allow-remote flag

Response Templates

Conversion Acknowledgment

code
I'll convert the Markdown file to PDF.

**Input**: [filename.md]
**Output**: [path/output.pdf]
**Styling**: [default/custom]
**Page Size**: [A4/Letter]

Converting...

Conversion Complete

code
**PDF Generated Successfully**

**File**: `Output/[filename].pdf`
**Pages**: [N] pages
**Size**: [X] KB

The PDF includes:
- [TOC if present]
- [N] sections
- [N] tables
- [N] images

Open the PDF to review formatting.

Conversion Failed

code
**PDF Generation Failed**

**Error**: [error message]

Troubleshooting:
1. [specific fix based on error]
2. Run with `--debug` for more info
3. Check CSS syntax if using custom styles