<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PDF Generation</title>
<meta name="description" content="A programming language that compiles to HTML, CSS, and JavaScript. Build SPAs and static sites with built-in components, reactivity, routing, i18n, and animations.">
<link rel="stylesheet" href="../styles.css">
</head>
<body>
<div id="app">
<div class="wf-row">
<div class="wf-container wf-animate-fadeIn">
<div class="wf-spacer"></div>
<h1 class="wf-heading wf-heading--h1">PDF Generation</h1>
<p class="wf-text wf-text--muted">Generate PDF documents directly from .wf source files. No external dependencies — raw PDF 1.7 output.</p>
<div class="wf-spacer"></div>
<h2 class="wf-heading wf-heading--h2">Enable PDF Output</h2>
<p class="wf-text">Set the output type to pdf in your project config.</p>
<div class="wf-spacer"></div>
<div class="wf-card wf-card--outlined">
<div class="wf-card__body">
<code class="wf-code">{
"build": {
"output_type": "pdf",
"pdf": {
"page_size": "A4",
"margins": { "top": 72, "bottom": 72, "left": 72, "right": 72 },
"default_font": "Helvetica",
"default_font_size": 12,
"output_filename": "report.pdf"
}
}
}</code>
</div>
</div>
<div class="wf-spacer"></div>
<hr class="wf-divider">
<div class="wf-spacer"></div>
<h2 class="wf-heading wf-heading--h2">Quick Start</h2>
<div class="wf-card wf-card--outlined">
<div class="wf-card__body">
<code class="wf-code">wf init my-report --template pdf
cd my-report
wf build</code>
</div>
</div>
<div class="wf-spacer"></div>
<p class="wf-text wf-text--muted">This creates a sample PDF project and builds it to build/my-report.pdf.</p>
<div class="wf-spacer"></div>
<hr class="wf-divider">
<div class="wf-spacer"></div>
<h2 class="wf-heading wf-heading--h2">Document Structure</h2>
<p class="wf-text">PDF documents use the same .wf syntax. Wrap content in a Document element with optional Header and Footer.</p>
<div class="wf-spacer"></div>
<div class="wf-card wf-card--outlined">
<div class="wf-card__body">
<code class="wf-code">Page Report (path: "/", title: "Q1 Report") {
Document(page_size: "A4") {
Header {
Text("Company Inc.", muted, small, right)
}
Footer {
Text("Confidential", muted, small, center)
}
Section {
Heading("Quarterly Report", h1)
Text("Revenue grew 15% this quarter.")
Table {
Thead {
Trow {
Tcell("Region")
Tcell("Revenue")
}
}
Tbody {
Trow {
Tcell("North America")
Tcell("$2.4M")
}
}
}
PageBreak()
Heading("Key Highlights", h2)
List {
Text("Launched 3 new products")
Text("Expanded to 5 new markets")
}
}
}
}</code>
</div>
</div>
<div class="wf-spacer"></div>
<hr class="wf-divider">
<div class="wf-spacer"></div>
<h2 class="wf-heading wf-heading--h2">Supported Components</h2>
<p class="wf-text">These components render in PDF output:</p>
<div class="wf-spacer"></div>
<table class="wf-table">
<thead>
<td>Component</td>
<td>PDF Behavior</td>
</thead>
<tr>
<td>Document</td>
<td>Root element. Sets page size via page_size arg.</td>
</tr>
<tr>
<td>Header / Footer</td>
<td>Repeated on every page. Positioned in margins.</td>
</tr>
<tr>
<td>Section</td>
<td>Groups content with spacing.</td>
</tr>
<tr>
<td>Paragraph</td>
<td>Block of text with paragraph spacing.</td>
</tr>
<tr>
<td>PageBreak</td>
<td>Forces a new page.</td>
</tr>
<tr>
<td>Heading(text, h1..h6)</td>
<td>Bold heading. h1=28pt, h2=22pt, h3=18pt...</td>
</tr>
<tr>
<td>Text(text)</td>
<td>Body text with word wrapping.</td>
</tr>
<tr>
<td>Table / Thead / Tbody / Trow / Tcell</td>
<td>Gridded table with borders and header styling.</td>
</tr>
<tr>
<td>List</td>
<td>Bulleted list. Add ordered modifier for numbered.</td>
</tr>
<tr>
<td>Code(text, block)</td>
<td>Monospace code with gray background.</td>
</tr>
<tr>
<td>Blockquote</td>
<td>Indented text with left bar.</td>
</tr>
<tr>
<td>Divider</td>
<td>Horizontal line.</td>
</tr>
<tr>
<td>Alert(text, variant)</td>
<td>Colored box with left accent bar.</td>
</tr>
<tr>
<td>Badge / Tag</td>
<td>Colored pill with white text.</td>
</tr>
<tr>
<td>Progress(value, max)</td>
<td>Horizontal bar.</td>
</tr>
<tr>
<td>Card</td>
<td>Bordered box around children.</td>
</tr>
<tr>
<td>Image(src)</td>
<td>Placeholder rectangle (JPEG planned).</td>
</tr>
<tr>
<td>Spacer</td>
<td>Vertical space. Modifiers: sm, md, lg, xl.</td>
</tr>
</table>
<div class="wf-spacer"></div>
<hr class="wf-divider">
<div class="wf-spacer"></div>
<h2 class="wf-heading wf-heading--h2">Rejected Components</h2>
<p class="wf-text">Interactive and web-only components cause compile-time errors in PDF mode:</p>
<div class="wf-spacer"></div>
<div class="wf-card wf-card--outlined">
<div class="wf-card__body">
<code class="wf-code">error[pdf]: 'Button' cannot be used in PDF output (Page Report)
— interactive elements are not supported in PDF
error[pdf]: 'Input' cannot be used in PDF output (Page Report)
— interactive elements are not supported in PDF</code>
</div>
</div>
<div class="wf-spacer"></div>
<p class="wf-text wf-text--muted">Rejected: Button, Input, Select, Checkbox, Switch, Slider, Form, Modal, Dialog, Toast, Router, Navbar, Sidebar, Tabs, Video, Carousel, and all event handlers.</p>
<div class="wf-spacer"></div>
<hr class="wf-divider">
<div class="wf-spacer"></div>
<h2 class="wf-heading wf-heading--h2">Page Sizes</h2>
<table class="wf-table">
<thead>
<td>Value</td>
<td>Dimensions (points)</td>
<td>Dimensions (mm)</td>
</thead>
<tr>
<td>A4</td>
<td>595 x 842</td>
<td>210 x 297</td>
</tr>
<tr>
<td>A3</td>
<td>842 x 1191</td>
<td>297 x 420</td>
</tr>
<tr>
<td>A5</td>
<td>420 x 595</td>
<td>148 x 210</td>
</tr>
<tr>
<td>Letter</td>
<td>612 x 792</td>
<td>216 x 279</td>
</tr>
<tr>
<td>Legal</td>
<td>612 x 1008</td>
<td>216 x 356</td>
</tr>
</table>
<div class="wf-spacer"></div>
<hr class="wf-divider">
<div class="wf-spacer"></div>
<h2 class="wf-heading wf-heading--h2">Fonts</h2>
<p class="wf-text">PDF output uses the 14 standard PDF base fonts. No embedding needed.</p>
<div class="wf-spacer"></div>
<table class="wf-table">
<thead>
<td>Font Family</td>
<td>Variants</td>
</thead>
<tr>
<td>Helvetica</td>
<td>Regular, Bold, Oblique, BoldOblique</td>
</tr>
<tr>
<td>Times</td>
<td>Roman, Bold, Italic, BoldItalic</td>
</tr>
<tr>
<td>Courier</td>
<td>Regular, Bold, Oblique, BoldOblique</td>
</tr>
</table>
<div class="wf-spacer"></div>
<p class="wf-text wf-text--muted">Set the default font in config or override per-element with style blocks:</p>
<div class="wf-spacer"></div>
<div class="wf-card wf-card--outlined">
<div class="wf-card__body">
<code class="wf-code">Heading("Title", h1) {
style {
font-family: "Helvetica-Bold"
color: "#1a1a2e"
}
}</code>
</div>
</div>
<div class="wf-spacer"></div>
<hr class="wf-divider">
<div class="wf-spacer"></div>
<h2 class="wf-heading wf-heading--h2">Styling in PDF</h2>
<p class="wf-text">Style blocks support these properties in PDF output:</p>
<div class="wf-spacer"></div>
<table class="wf-table">
<thead>
<td>Property</td>
<td>Values</td>
<td>Example</td>
</thead>
<tr>
<td>font-size</td>
<td>Number (points)</td>
<td>font-size: 14</td>
</tr>
<tr>
<td>font-family</td>
<td>Base14 font name</td>
<td>font-family: "Courier"</td>
</tr>
<tr>
<td>color</td>
<td>Hex color</td>
<td>color: "#333333"</td>
</tr>
<tr>
<td>text-align</td>
<td>left, center, right</td>
<td>text-align: "center"</td>
</tr>
</table>
<div class="wf-spacer"></div>
<p class="wf-text wf-text--muted">Modifiers also work: bold, muted, primary, danger, success, warning, info, small, large, center, right.</p>
<div class="wf-spacer"></div>
<hr class="wf-divider">
<div class="wf-spacer"></div>
<h2 class="wf-heading wf-heading--h2">Auto Page Breaks</h2>
<p class="wf-text wf-text--muted">Content automatically flows to a new page when it reaches the bottom margin. Headers and footers are rendered on every page, including auto-generated ones.</p>
<div class="wf-spacer"></div>
</div>
</div>
</div>
<script src="../app.js"></script>
</body>
</html>