---
name: md-to-pdf
description: Convert Markdown to PDF via Typst, with full math (LaTeX-style), tables, code blocks, and professional typesetting. Runs via a self-contained WASM binary — no admin rights, no installation needed beyond wasmtime. Use when an agent needs to produce a polished PDF from a Markdown document.
metadata:
  { "openclaw": { "emoji": "📄", "os": ["darwin", "linux"], "requires": { "bins": ["wasmtime"] } } }
---

# md-to-pdf Skill (OpenClaw)

Convert Markdown to polished PDF using a self-contained WASM binary backed by
the [Typst](https://typst.app/) typesetting engine. No admin rights needed —
just `wasmtime` and the `.wasm` file in this folder.

**Source:** https://github.com/minkymorgan/md-to-pdf-wasm

---

## Why This Exists

On locked-down machines (government, enterprise) where you can't `apt install`,
`brew install`, or touch system directories, you still need to produce
professional PDFs. This skill ships everything needed — fonts included — in a
single `md-to-pdf.wasm` file. Wasmtime is a single static binary that can live
in `~/bin` without admin access.

---

## Quick Start

```bash
# The WASM binary lives alongside this SKILL.md
SKILL_DIR="$(dirname "$0")"

# Convert a file
wasmtime run --dir=. "$SKILL_DIR/md-to-pdf.wasm" report.md -o report.pdf

# Auto-name: report.md → report.pdf
wasmtime run --dir=. "$SKILL_DIR/md-to-pdf.wasm" report.md

# From stdin
cat report.md | wasmtime run --dir=. "$SKILL_DIR/md-to-pdf.wasm" --stdin -o report.pdf
```

---

## Supported Markdown

| Feature | Syntax |
|---------|--------|
| Headings | `# H1` through `###### H6` |
| Bold / Italic | `**bold**` / `*italic*` |
| Inline code | `` `code` `` |
| Code blocks | ```` ```lang ... ``` ```` |
| Inline math | `$E = mc^2$` |
| Display math | `$$\int_0^\infty f(x)\,dx$$` |
| Tables | Standard GFM table syntax |
| Lists | Bullet (`-`) and ordered (`1.`) |
| Blockquotes | `> quote` |
| Links | `[text](url)` |
| Horizontal rule | `---` |

Math uses Typst's native syntax — nearly identical to LaTeX for common cases.

---

## Agent Workflow

When asked to produce a PDF report:

1. Write the content as Markdown (use `$...$` for inline math, `$$...$$` for display)
2. Save to a `.md` file in the working directory
3. Run the converter
4. Return the path to the `.pdf`

```bash
# Full example
cat > /tmp/report.md << 'EOF'
# Experiment Results

## Summary

The model achieves **94.2% accuracy** on the test set.

## Loss Function

The cross-entropy loss is:

$$L = -\sum_{i} y_i \log(\hat{y}_i)$$

## Results Table

| Model | Accuracy | F1 |
|-------|----------|----|
| Baseline | 87.3% | 0.871 |
| Ours | 94.2% | 0.940 |
EOF

SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
wasmtime run --dir=/tmp "$SKILL_DIR/md-to-pdf.wasm" /tmp/report.md -o /tmp/report.pdf
echo "PDF written to /tmp/report.pdf"
```

---

## Installing Wasmtime (no admin needed)

If `wasmtime` isn't available, install it to `~/bin`:

```bash
mkdir -p ~/bin
curl -sSL https://github.com/bytecodealliance/wasmtime/releases/latest/download/wasmtime-$(uname -m)-macos.tar.gz | tar xz -C ~/bin --strip-components=1
# or for Linux:
curl -sSL https://github.com/bytecodealliance/wasmtime/releases/latest/download/wasmtime-$(uname -m)-linux.tar.gz | tar xz -C ~/bin --strip-components=1
export PATH="$HOME/bin:$PATH"
```

No sudo. No package manager. Just a file in your home directory.

---

## How It Works

```
Markdown input
    ↓  comrak (AST parser)
Typst markup
    ↓  typst compiler
Typst document
    ↓  typst-pdf
PDF bytes → output file
```

Fonts are embedded from `typst-assets` — the binary is fully self-contained.
No font directories need to be mounted or installed.

**Binary size:** ~28 MB  
**Output quality:** Typst-grade (comparable to LaTeX, much faster)  
**Build source:** `cargo build --release --target wasm32-wasip1`

---

## Updating the Binary

To rebuild from source:

```bash
git clone https://github.com/minkymorgan/md-to-pdf-wasm.git
cd md-to-pdf-wasm
rustup target add wasm32-wasip1
cargo build --release --target wasm32-wasip1
cp target/wasm32-wasip1/release/md-to-pdf.wasm /path/to/openclaw-skills/md-to-pdf/
```

---

## Troubleshooting

**`wasmtime: command not found`**  
Install wasmtime to `~/bin` — see the section above. No admin needed.

**`Error: failed to open file`**  
Make sure `--dir=.` (or `--dir=/path/to/files`) is passed so wasmtime grants
filesystem access to the working directory.

**Math not rendering**  
Check your `$` syntax — Typst uses `$E = mc^2$` (inline) and `$ ... $` with
spaces for display math. Double `$$...$$` is also supported as a convenience.

**Large documents are slow**  
Typst is fast natively but the WASM layer adds overhead. Documents up to ~50
pages should be fine; very large documents may take 10–30s.
