Batch release¶
bubble-batch¶
Orchestrates a release build: full book variants per language, optional per-chapter PDFs, and collection into books/ (override with --output-dir or batch_output_dir in config).
bubble-batch
bubble-batch --chapters
bubble-batch --chapters-only
bubble-batch --chapters-only --chapter 1
bubble-batch --chapter 1-3
bubble-batch --chapter 1,9
bubble-batch en --cover 7x10 --cover-provider kdp/paperback
bubble-batch en,cn,tc --style none
bubble-batch en,cn,tc --style square --chapter-opener-size 2
bubble-batch all --cover 7x10 --cover-provider ingram/hardcover --cover-version v2
bubble-batch --lang all --optimize-pdf
Many book repos expose a thin wrapper:
./run.sh # exec bubble-batch "$@"
Language selection¶
| Argument | Behavior |
|---|---|
| (none) | Uses batch_default_langs from config, or single lang, or all scanned langs |
--lang en, --lang cn, … |
Build only that locale |
--lang en,cn,tc or --lang en cn tc |
Build multiple locales |
--lang all |
Every language with source files |
Typical outputs per language¶
Without --style, each language gets the release set:
- Full book with cover (style from
batch_cover_style/ peanut.config) - Interior PDF, square (
--no-cover) - Interior PDF, none (
--no-cover)
With --style none (or square / circle), only that style is built:
- Full book with cover
- Matching interior (
*_interior.pdf)
Optional: per-chapter PDFs when --chapters is set (also uses --style when given).
Use --chapters-only to skip full-book builds, optionally filtered with --chapter SPEC:
--chapter 1→ chapter 1--chapter 1-3→ chapters 1, 2, 3--chapter 1,9→ chapters 1 and 9--chapteralone (without--chapters) also skips the full book
Files are copied or linked into books/ (or batch_output_dir).
Cross-chapter references in per-chapter PDFs¶
By default, each chapter PDF is compiled standalone — its own pandoc + multi-pass LaTeX
run, isolated from every other chapter. Any \ref/\eqref pointing at a label defined in a
different chapter has no .aux entry to resolve against, so it renders as ??, every time.
This is not a transient "rerun to fix" issue; it's inherent to compiling each chapter in
isolation.
Pass --chapters-from-book to avoid it:
bubble-batch --chapters-only --chapters-from-book
bubble-batch --chapters --chapters-from-book --chapter 1-3
This builds one full-book interior PDF (at the chapter style) and slices each chapter's page
range out of it with qpdf, instead of recompiling per chapter. Because the source PDF already
went through the full-book multi-pass compile, cross-chapter references resolve correctly.
Page ranges come from the PDF's own bookmarks (one per \chapter, written by hyperref), not
from the .toc file's page numbers — those record LaTeX's \thepage counter, which resets to
Arabic 1 at \mainmatter and does not match the chapter's actual physical page position
(front matter — cover, copyright, preface, TOC, part dividers — precedes it). Bookmark
destinations give the real physical page regardless of front-matter length. If the build has no
bookmarks (or PyPDF2 isn't installed), --chapters-from-book refuses to run rather than slice
from the wrong offset.
Trade-offs vs. the standalone compile:
- Page numbers reflect the book's continuous numbering (not restarted at 1 per chapter).
--book-adsfooter text is not applied — it's baked into the LaTeX header at compile time, and these pages are cut from an already-compiled PDF.--protect(rasterize) still applies, same as the standalone path.- Requires
qpdfonPATH.
See Cross-references troubleshooting for the full-book (non-per-chapter) case.
Cover options¶
--cover 7x10
--cover-provider kdp/paperback | ingram/hardcover | lulu/paperback | lulu/hardcover
--cover-version v1 | v2
Cover scripts in the active folder run before PDF assembly (see Covers & templates).
Part divider pages¶
Full-book PDF builds call bubble-convert-parts before merging chapters. Manual refresh:
bubble-convert-parts
bubble-convert-parts 1
See Build & convert — bubble-convert-parts.
Optimization¶
PDF optimization follows locale rules (Ghostscript vs qpdf). Controlled by:
batch_optimize_pdf/batch_optimize_pdf_qualityinpeanut.config- CLI:
--optimize-pdf,--no-optimize-pdf,--optimize-pdf-quality
Protected chapter PDFs¶
When building per-chapter PDFs, pages are rasterized (anti-copy/OCR) by default.
--no-optimize-pdf also skips that protect/rasterize step (keeps the vector LaTeX PDF),
unless you pass --protect. Use --no-protect to skip protect while still allowing
--optimize-pdf. Ads footer text (--book-ads / batch_book_ads) is independent of protect.
Config reference¶
See Configuration — Batch release keys.
Per-chapter builds (--chapters / --chapters-only) use the highest chapter number found under chapter*/chapter*.md, unless --chapter SPEC selects a subset.