Skip to content

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 papersize and geometry (see Book metadata).
  • EPUB → e-book stores and readers. EPUB is what e-book retailers and reading apps expect. Set a cover with cover-image so it appears in the store listing and the reader's library.

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 / geometry to 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-image covers 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.