Publishing your book
Keystone's output is publication-ready: the PDF is a print-quality file and the EPUB is a standards-compliant e-book. When the writing is done, the last step is getting those files to readers — Keystone produces the artifacts, and a publishing platform handles printing and distribution.
Which file goes where
- PDF → print. Print-on-demand (POD) services and offset printers take a PDF.
Match your page setup to the printer's spec first — trim size and binding
margins both come from
papersizeandgeometry(see Book metadata). - EPUB → e-book stores and readers. EPUB is what e-book retailers and reading
apps expect. Set a cover with
cover-imageso it appears in the store listing and the reader's library.
Print-on-demand and self-publishing
These platforms turn your files into a printed book, an e-book listing, or both. Common starting points:
- Lulu — print-on-demand and distribution.
- Amazon KDP — print and Kindle on Amazon.
- IngramSpark — print distribution to retailers and libraries.
- Draft2Digital — e-book distribution across multiple stores.
Keystone doesn't endorse any of these. Each sets its own specs for
trim size, bleed (art that extends
past the trim edge), margins, and metadata — read theirs and match yours in
pandoc.yaml.
Before you upload
A short checklist for a first book:
- Pick a trim size and set
papersize/geometryto match the platform's template — see Page sizes. Common print-on-demand trims are 6×9in, 5×8in, 5.5×8.5in, and 8.5×8.5in square. - Set the gutter if the book will be bound — the spine takes part of the inner margin, and the default reserves nothing for it. See The gutter.
- Add a cover.
cover-imagecovers the EPUB; print covers are usually a separate wraparound file the platform builds to your page count. - Get an ISBN if you want retail distribution — some platforms provide one free.
- Proof the PDF at full size, and open the EPUB in a couple of readers to check how it reflows.
- Fill in your metadata — title, author, description, and keywords all carry into the files (see Book metadata).
Watching a build run
A PDF spends most of its time typesetting, which prints nothing while it runs. Keystone names each stage as it starts, keeps a clock on the one in progress, and reports the total when the file lands:
Publishing target: 'book' | format: pdf
✓ Preparing your artifact 1.5s
✓ Typesetting (pass 1) 22.1s
✓ Typesetting (pass 2) 19.8s
✓ Typesetting (pass 3) 16.5s
OK: artifacts/my-project-book-20260101.pdf (1m 01s)
Typesetting runs more than once because a table of contents can't be laid out
until the pages it points at exist; two to four passes is normal. A stage that
took under a second folds into Preparing your artifact, so what stays on
screen is what took time. A build that stops shows ✗ against the stage it
stopped in, and that line always appears — a stage that fails is never folded
away.
A build that reports every stage ✓ and then stops failed after the last of
them — either the strict gate refused to promote the artifact, or the finished
file could not be placed in artifacts/. See
Strict builds and
An artifact that can't be written.
Where a stage performs a check, its name is the row to look up in the error map — Expanding shortcuts, Running handlers, Converting math and the rest appear in both. A warning from a fast stage arrives after that stage has folded, so match it by its message rather than by a stage line.
Some stages run no checks of their own and so have no row. Scanning your
manuscript and Collecting your fonts are EPUB-only passes that find the
fonts your book uses and gather what travels with them. Typesetting is the
one worth knowing: it is LaTeX, not Keystone, so a ✗ there is followed by
LaTeX's own message —
usually naming a line of generated source rather than yours. Suspect raw LaTeX
in your manuscript, or a font that can't render a character you used.
KEYSTONE_PROGRESS in
project.conf sets how much of this you
get:
| Mode | What it does |
|---|---|
auto |
Stages, folded and updating in place on a terminal; plain anywhere else, so CI needs no setting. The default |
plain |
Every stage on its own line, nothing folded and nothing redrawn |
off |
No stage reporting |
verbose |
Pandoc's raw output, unfiltered, for diagnosing a failure |
make publish progress=<mode> overrides it for one build.
The first three change only how much progress you see; a warning reads the same
in all of them. verbose is the exception: it shows Pandoc's own [WARNING]
prefix and the full logs Keystone otherwise hides. That is what makes it worth
reaching for when the ordinary output doesn't explain a failure.
Strict builds for CI and release
While you're drafting, Keystone prints warnings — a mistyped attribute, an unrecognized placeholder, a missing font — and keeps going, so you always get something to look at. For the build you actually publish, you usually want the opposite: a warning should stop the line, not ship.
Set KEYSTONE_WARNINGS_AS_ERRORS=true to make any warning fail the build
and write no new file — including structural slips Pandoc catches, like a fenced
div you forgot to close. Turn it on in
project.conf for release builds, or run
make publish strict=true in CI to override that value without editing it — so
automated builds stay strict while local drafts stay lenient.
The file you built is the file you publish — there's no separate export step.