# Scrivener Compile

> When the user wants to compile or export the Draft as a finished manuscript — assemble the chapters into one Markdown or plain-text file with titles turned into headings, or produce a docx/epub/pdf/Fountain document. Use when the user says "compile," "compile to Markdown," "export as Markdown/docx/epub/pdf," "produce the manuscript," "build the book," "assemble the draft," or "compile to Fountain." For section types that drive compile layouts, see scrivener-metadata. For raw per-document text without binder structure, see scrivener-extract. For the named styles that markup compile, see scrivener-styles.

- Skill: `donnfelker/scrivener-compile` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add donnfelker/scrivener-compile`
- Raw SKILL.md: https://api.skillmd.com/api/skills/donnfelker/scrivener-compile/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: donnfelker (https://skillmd.com/u/donnfelker)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/donnfelker/scrivener-compile

---


# Scrivener Compile

You help the writer turn a `.scriv` project into a single finished document —
the **Compile** step, where the Draft's documents are assembled in binder order
into a manuscript. Compile is **read-only** for the project: it reads the binder
and writes a new output file; it never mutates the `.scriv`.

This is the place to get a *structured* manuscript: titles become headings, the
documents flow in order, and items flagged out of the compile are skipped. For
the raw words of one document (no structure), route to **scrivener-extract**.

## When to use this skill

- "Compile the draft to Markdown."
- "Produce the manuscript as one file."
- "Export the book as docx / epub / pdf." (planned — engine-gated)
- "Compile just the first act / this folder."
- "Compile to Fountain." (planned)
- "Build a table of contents / front matter into the compile." (planned)

## Compiling to Markdown or plain text (available now)

`compile` assembles the Draft (the `DraftFolder`, whatever it is renamed to) in
binder order. It turns each item's **title into a heading by its depth** (a
top-level item → `#`, its child → `##`, and so on) and **honors
`IncludeInCompile`** — items flagged out are skipped.

```bash
# Compile the whole Draft to Markdown (default)
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py compile \
  --to md --project "<path.scriv>"

# Compile to plain text
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py compile \
  --to txt --project "<path.scriv>"

# Compile only one container (e.g. a single Part/folder) by UUID
python3 ${CLAUDE_PLUGIN_ROOT}/tools/scrivener/cli.py compile \
  --to md --group <uuid> --project "<path.scriv>"
```

Output is JSON by default (the assembled document plus a manifest of which items
were included or skipped). Add `--format text` for the assembled document alone.
Items with no body text (folders, empty documents, Image items) contribute their
**title heading** but no paragraph text; that is normal, not an error.

**Titles are not unique.** When the user names the group to compile, run `find`
(see scrivener-inspect) first and pass the **UUID** to `--group` if more than one
item matches.

## The compile model is bounded — say so

Scrivener's real Compile binds each document's **section type** to a **section
layout** (from a chosen compile **Format**), and the layout is what controls
title prefixes/suffixes, numbering (`Chapter <$n>`), separators, page breaks, and
heading levels. **Those layout definitions do not live inside the `.scriv`** —
`Settings/compile.xml` stores only the section-type → layout-ID *mapping*; the
actual definitions live in app-level stock Formats / `.scrformat` files outside
the project.

Be honest with the writer: because the definitions are external, a faithful
compile is **bounded and approximate**. The v0.1.0 `compile`:

- assembles in binder order, honors Include-in-Compile, and maps **title → ATX
  heading by binder depth** — a sensible, predictable approximation;
- does **not** yet read `compile.xml`, apply section-type → layout, add title
  prefixes/numbering, insert separators, or run compile-time replacements.

If the user expects the exact output of a specific Scrivener compile Format, tell
them this toolkit approximates it rather than reproducing the external layout
definitions. See `references/compile-model.md` for the full inputs and the
bounded-approximation note.

## Rich formats are engine-gated (planned)

Markdown, plain text (and, planned, HTML) are produced with the Python standard
library — always available. Richer outputs require an **external engine** and are
**planned**, gated, and degrade gracefully when the engine is absent:

| Output | Engine | Status |
|---|---|---|
| `--to md` / `--to txt` | stdlib | ✅ available now |
| `--to html` | stdlib | 🔜 planned |
| `--to docx` / `--to odt` / `--to epub` | pandoc | 🔜 planned (needs pandoc) |
| `--to pdf` | LaTeX (pdflatex) or native print | 🔜 planned (engine-gated) |
| `--to fountain` | stdlib (scripts) | 🔜 planned |

When asked for a planned format, say it isn't in the CLI yet and offer the
closest path: **compile to Markdown now**, then convert with pandoc/LaTeX
yourself, or wait for the gated engine support. Never claim a docx/epub/pdf
compile succeeded when the engine isn't wired up.

## Section-type → layout is on the roadmap

Mapping section types to layouts (`compile-format list|show|assign-layout`),
choosing a Format, and per-type title/numbering/separator behavior are
**planned**, not in the CLI yet. The primary end-to-end workflow — *set section
types, then compile* — is two skills today: assign section types with
**scrivener-metadata**, then run `compile --to md` here. The section types are
read and reported, but the v0.1.0 compile does not yet vary layout by type.

## Safety

Compile is read-only — it writes a *new* output file and never modifies the
`.scriv`, so no backup or snapshot is taken. Even so, remind the writer to
**close the project in Scrivener** and let **cloud sync (Dropbox/iCloud) finish**
before compiling a live project, so you read a consistent on-disk state.
`docs.checksum` mismatches are advisory and never block a compile.

## Toolkit support

| Capability | Status |
|---|---|
| `compile [--to md\|txt] [--group <uuid>]` (binder order; titles → headings by depth; honors IncludeInCompile) | ✅ available now |
| `compile --to html` (stdlib) | 🔜 planned |
| `compile --to docx\|odt\|epub` (pandoc) | 🔜 planned |
| `compile --to pdf` (LaTeX / native print) | 🔜 planned |
| `compile --to fountain` (scripts) | 🔜 planned |
| Read `compile.xml`; section-type → **layout** mapping | 🔜 planned |
| `compile-format list\|show\|assign-layout` (read/select/assign Formats) | 🔜 planned |
| Separators (before/between/after) | 🔜 planned |
| Title prefix/suffix + numbering (`Chapter <$n>`) | 🔜 planned |
| Front / back matter | 🔜 planned |
| Compile-time replacements (incl. regex) | 🔜 planned |
| Placeholder substitution (`<$projecttitle>`, `<$author>`, `<$n>`…) | 🔜 planned |
| Table-of-contents generation (`<$toc>`) | 🔜 planned |
| Filtering by label / status / collection | 🔜 planned |

Authoring new Formats/Layouts in a WYSIWYG designer is **out of scope** — the
toolkit reads/selects/assigns existing Formats; it does not reproduce the visual
Format Designer.

## Related skills

- **scrivener-metadata** — assign **section types** (the input the planned
  section-type → layout mapping will key on); do this before compiling.
- **scrivener-extract** — raw per-document text (one doc, subtree, all) with no
  binder structure; use it when you want words, not a manuscript.
- **scrivener-styles** — named **Styles** that compile as markup (prefix/suffix);
  what gets emitted around styled ranges on compile.
- **scrivener-inspect** — `outline`, `read`, `find`; use `find` to resolve an
  ambiguous group title to the UUID you pass to `--group`.
- **scrivener-scriptwriting** — script mode + Fountain I/O, the home of the
  planned `compile --to fountain`.
- **scrivener-format** — the `.scriv` package + `compile.xml` reference these
  notes cite.

