Generate a polished PDF report or summary from findings, data, or tables gathered earlier in the conversation. Use when the user asks to "make a PDF", "gener...
---
name: pdf-report
description: |
Generate a polished PDF report or summary from findings, data, or tables
gathered earlier in the conversation. Use when the user asks to "make a PDF",
"generate a report", "export findings", "summarize as a PDF", or similar.
Produces Typst source, compiles it with `typst`, and reports the output path.
metadata: {"openclaw":{"emoji":"📄","requires":{"bins":["typst"]}}}
---
# pdf-report
Turn gathered conversation content (findings, data, tables) into a clean PDF
via Typst. Two templates ship with this skill — pick one, fill it in, compile.
## When to invoke
Trigger on any of:
- "make a PDF" / "create a PDF" / "export to PDF"
- "generate a report" / "write up a report"
- "summarize this as a PDF" / "PDF summary"
- "export these findings/results"
If the user says "export" or "deliverable" without specifying format and the
context has tabular data or distinct findings, ask once whether they want PDF
before invoking.
## Inputs to gather
Before writing any Typst, confirm or infer:
1. **Title** — ask if not obvious. Keep short (≤ 60 chars).
2. **Subtitle / author** — optional; leave blank or omit if unknown.
3. **Content scope** — exactly which findings/tables/sections from the
conversation belong in the document. Do not invent data the user did not
provide.
4. **Output path** — default `./report-YYYY-MM-DD.pdf` in cwd. If a file with
that name exists, append `-2`, `-3`, etc.
## Pick a template
| Template | Use when |
|----------|----------|
| `templates/summary.typ` | 1–3 sections, executive summary, ≤ ~3 pages. **Default.** |
| `templates/report.typ` | 3+ distinct sections, title page + TOC desired, or user said "report". |
Both live next to this `SKILL.md`. Read the chosen one, then write a new
`.typ` file at `<output>.typ` (next to the target PDF) with placeholders
replaced and example tables swapped for real data.
## Authoring rules
- **Tables**: always use `#table()` with `table.header(...)`. Right-align
numeric columns. Preserve the precision the user gave you — do not round.
- **Long tables**: `table.header(repeat: true, ...)` repeats headers on page
breaks automatically (Typst 0.12+).
- **Special characters in cell text**: wrap in `[...]` content blocks; escape
`#`, `$`, `@`, `\` if they appear literally.
- **Adapt freely**: add or drop sections to match the content. Keep the page
setup, font sizing, and heading shows from the template — those define the
look.
- **No watermarks**. Do not add "Generated by AI", "Claude", "Qwen", or
similar. The user does not want it.
## Compile
```bash
typst compile <output>.typ <output>.pdf
```
`typst` is at `/home/linuxbrew/.linuxbrew/bin/typst` (linuxbrew). If it's not
on PATH in the current shell, use the full path.
## Error handling
If compile fails:
1. Read the error — Typst errors include file, line, and a usually-clear hint.
2. Fix the `.typ` source and retry **once**.
3. If it still fails, stop. Show the user:
- the error output,
- the path to the `.typ` source so they can edit directly.
Do not loop indefinitely on errors.
## Reporting back
On success, tell the user:
- output PDF path (absolute),
- page count (from `pdftotext -l 1` or just `typst query` — or simply state
"compiled successfully" if neither is convenient),
- that the `.typ` source is kept alongside for future tweaks.
Offer to open it (`xdg-open <path>`) but do not open without confirmation.
## Quick reference: minimal Typst patterns
```typst
// Two-column table with numeric right-align
#table(
columns: (auto, auto),
align: (left, right),
stroke: 0.5pt + gray,
inset: 7pt,
table.header([*Name*], [*Count*]),
[alpha], [42],
[beta], [108],
)
// Bullet list
- one
- two
- three
// Inline emphasis
This is *bold* and this is _italic_ and this is `mono`.
// Math (inline and block)
The energy is $E = m c^2$.
$ integral_0^infinity e^(-x^2) dif x = sqrt(pi) / 2 $
// Image
#figure(image("plot.png", width: 80%), caption: [A plot.])
```
don't have the plugin yet? install it then click "run inline in claude" again.