claude-code-ultimate-guide/guide/workflows/pdf-generation.md
Florian BRUNIAUX 624b2e0425 docs(guide): add YAML frontmatter to 15 workflow guide files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 19:20:35 +01:00

10 KiB

title description tags
PDF Generation with Claude Code Generate professional PDFs using Claude Code with Quarto and Typst stack
workflow
guide
integration

PDF Generation with Claude Code

Confidence: Tier 2 — Based on production-tested workflow with Quarto/Typst stack.

Generate professional PDFs (documentation, whitepapers, reports) using Claude Code with modern typography and design.


Table of Contents

  1. TL;DR
  2. When to Use
  3. Stack Overview
  4. Setup
  5. Workflow
  6. Integration with Claude Code
  7. Customization
  8. Troubleshooting
  9. See Also

TL;DR

# Install
brew install quarto  # macOS

# Generate
quarto render document.qmd  # → document.pdf

# Preview
quarto preview document.qmd  # Hot-reload

Stack: Quarto (orchestration) + Typst (typography) + Pandoc (markdown)


When to Use

Use Case Good Fit Alternative
Technical documentation
Whitepapers / Reports
API documentation ⚠️ OpenAPI + Redoc
Slides / Presentations ⚠️ Quarto Revealjs
Quick notes Plain Markdown
Collaborative editing Google Docs, Notion

Best for: Long-form technical content requiring professional layout, version control, and reproducibility.


Stack Overview

┌─────────────────────────────────────────────────┐
│                  Your .qmd File                 │
│         (Markdown + YAML frontmatter)           │
└─────────────────────────────────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────┐
│                    Quarto                       │
│           (Document rendering engine)           │
│         • Processes YAML metadata               │
│         • Handles extensions                    │
│         • Manages output formats                │
└─────────────────────────────────────────────────┘
                        │
          ┌─────────────┴─────────────┐
          ▼                           ▼
┌─────────────────────┐    ┌─────────────────────┐
│       Pandoc        │    │       Typst         │
│   (MD → AST → ?)    │    │  (Typography/PDF)   │
│  • Markdown parser  │    │  • Modern engine    │
│  • AST transforms   │    │  • Fast compilation │
│  • Format bridges   │    │  • No LaTeX needed  │
└─────────────────────┘    └─────────────────────┘
                        │
                        ▼
┌─────────────────────────────────────────────────┐
│                  document.pdf                   │
│        (Professional typography output)         │
└─────────────────────────────────────────────────┘
Component Version Role
Quarto ≥1.4.0 Orchestration, extensions, multi-format
Typst 0.13.0 Modern typography (replaces LaTeX)
Pandoc 3.x Markdown parsing (bundled with Quarto)

Setup

Installation

macOS:

brew install quarto

Linux (Debian/Ubuntu):

wget https://github.com/quarto-dev/quarto-cli/releases/download/v1.4.555/quarto-1.4.555-linux-amd64.deb
sudo dpkg -i quarto-1.4.555-linux-amd64.deb

Windows:

winget install Posit.Quarto

Verify:

quarto --version  # Should be ≥1.4.0

Project Structure

project/
├── _extensions/           # Quarto extensions (templates)
│   └── custom-template/
│       ├── _extension.yml
│       ├── typst-template.typ
│       └── typst-show.typ
├── documents/
│   ├── guide.qmd          # Source file
│   └── guide.pdf          # Generated output
└── assets/
    └── logo.png           # Shared assets

Minimal Document

Create document.qmd:

---
title: "My Document"
author: "Author Name"
date: 2026-01-17
format:
  typst:
    toc: true
lang: en
---

# Introduction

Your content here...

## Section 1

More content with **bold** and `code`.

```bash
echo "Code blocks work!"

Section 2

Column A Column B
Data 1 Data 2

Generate:
```bash
quarto render document.qmd  # Creates document.pdf

Workflow

1. Content-First Approach

1. Write content in Markdown (.qmd)
2. Add YAML frontmatter for metadata
3. Preview with hot-reload
4. Generate final PDF
5. Version control both source and PDF

2. Available YAML Parameters

Parameter Type Description Example
title string Main title "Technical Guide"
subtitle string Secondary title "v2.0 Edition"
author string/array Author(s) "John Doe"
date date Document date 2026-01-17
date-format string Display format "MMMM YYYY"
toc boolean Table of contents true
toc-depth number TOC levels (1-3) 2
lang string Language fr or en
section-numbering string Number format "1.1"

3. Markdown Features

Page Breaks:

{{< pagebreak >}}

Code Blocks (with syntax highlighting):

```typescript
function hello(): string {
  return "world";
}
```

Tables:

| Feature | Supported |
|---------|-----------|
| Tables  | ✅        |
| Images  | ✅        |
| Links   | ✅        |

Images:

![Alt text](path/to/image.png){width=50%}

Integration with Claude Code

Using the pdf-generator Skill

Invoke the skill for guided PDF generation:

/pdf-generator

The skill provides:

  • Template with YAML frontmatter
  • Design system configuration
  • Common troubleshooting fixes
  • Generation commands

Prompt Examples

Generate documentation:

Create a technical guide for our API as a Quarto document.
Use the Typst format with a table of contents.
Include sections for: Authentication, Endpoints, Error Codes.

Convert existing Markdown:

Convert README.md to a professional PDF.
Add a cover page with title and date.
Use Quarto/Typst format.

Create template:

Create a Quarto extension for our company's document style:
- Logo in header
- Custom colors: primary #0f172a, accent #6366f1
- Inter font for body, JetBrains Mono for code

With Plan Mode

For complex documents:

/plan

I need to create a series of 5 technical whitepapers.
Plan the structure:
1. Common template/extension
2. Shared assets
3. Build automation
4. Version management

With Hooks

Auto-generate PDF on save:

# .claude/hooks.yaml
post_edit:
  - pattern: "**/*.qmd"
    command: "quarto render $FILE"

Customization

Custom Template Extension

Create _extensions/mytemplate/_extension.yml:

title: My Template
author: Your Name
version: 1.0.0
contributes:
  formats:
    typst:
      template: typst-template.typ
      template-partials:
        - typst-show.typ

Typst Template Variables

In typst-template.typ:

// Colors
#let primary = rgb("#0f172a")      // Dark text
#let secondary = rgb("#334155")    // Lighter text
#let accent = rgb("#6366f1")       // Highlights

// Typography
#set text(
  font: ("Inter", "Helvetica Neue", "Arial"),
  size: 11pt,
)

#set par(
  leading: 0.75em,  // Line height
  justify: true,
)

// Code blocks
#show raw.where(block: true): it => {
  block(
    fill: rgb("#f8fafc"),
    stroke: (left: 3pt + accent),
    inset: 10pt,
    radius: 4pt,
    it,
  )
}

Callout Boxes

Define in template:

#let info(title: "Note", body) = {
  block(
    fill: rgb("#E0F2FE"),
    stroke: (left: 3pt + rgb("#0284C7")),
    inset: 12pt,
    radius: 4pt,
    [*#title*: #body]
  )
}

#let warning(title: "Warning", body) = { ... }
#let success(title: "Success", body) = { ... }
#let danger(title: "Danger", body) = { ... }

Use in document:

#info[This is an informational note.]
#warning(title: "Attention")[Check your configuration.]

Troubleshooting

Quick Checks

# Verify Quarto
quarto --version

# Check extension exists
ls _extensions/*/

# Validate code block pairs (must be even)
grep -c '^```' document.qmd

# Check encoding
file -i document.qmd  # Should show utf-8

Common Issues

Issue Symptom Fix
Nested code blocks Content escapes block Use 4+ backticks for outer block
Tables as code Grey background Check unmatched ``` above
Missing extension "Extension not found" Verify _extensions/ path
Font warnings "unknown font family" Normal; uses fallbacks
Special chars broken ? or garbled Convert to UTF-8

Nested Code Blocks

Problem: Inner code block closes outer block prematurely.

Solution: Use more backticks for outer block:

````markdown
# Outer block with 4 backticks

```bash
echo "Inner block with 3 backticks"
```

Outer block continues...
````

Validation Script

#!/bin/bash
# validate-qmd.sh

for f in *.qmd; do
  count=$(grep -c '^```' "$f")
  if [ $((count % 2)) -ne 0 ]; then
    echo "ERROR: $f has odd code block count ($count)"
  fi
done

See Also