- name
- pdf-report
- description
- |
- 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:
- Title — ask if not obvious. Keep short (≤ 60 chars).
- Subtitle / author — optional; leave blank or omit if unknown.
- Content scope — exactly which findings/tables/sections from the
conversation belong in the document. Do not invent data the user did not provide.
- Output path — default
./report-YYYY-MM-DD.pdfin 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()withtable.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
typst compile <output>.typ <output>.pdftypst 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:
- Read the error — Typst errors include file, line, and a usually-clear hint.
- Fix the
.typsource and retry once. - 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 1or justtypst query— or simply state
"compiled successfully" if neither is convenient),
- that the
.typsource is kept alongside for future tweaks.
Offer to open it (xdg-open <path>) but do not open without confirmation.
Quick reference: minimal Typst patterns
// 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.])