Build an EPUB file from the current fiction project.
Build Context
- •Chapter count: !
ls chapters/*.md 2>/dev/null | wc -l | tr -d ' ' - •Has cover: !
ls covers/cover.* 2>/dev/null | head -1 || echo "no cover found"
What This Does
- •Reads project metadata from README.md
- •Compiles all chapters from
chapters/in order - •Applies styling from
epub.css(if present) - •Includes cover image from
covers/(if specified) - •Sets a stable EPUB identifier (preserves highlights across builds)
- •Outputs to
builds/directory
Usage
/fiction:build # Build dated epub (archive mode) /fiction:build --sync # Build for Apple Books sync (preserves highlights) /fiction:build --cover cover.png # Include specific cover image /fiction:build /path/to/project # Build specific project
If arguments provided: $ARGUMENTS
Build Modes
Archive Mode (default)
Outputs: builds/YYYY-MM-DD/project-name-YYYY-MM-DD.epub
- •Each build is date-stamped
- •Preserves history of versions
- •Good for milestones and backups
Sync Mode (--sync)
Outputs: builds/project-name.epub
- •Same filename every time
- •Uses stable EPUB identifier
- •Preserves highlights and reading position in Apple Books
- •Ideal for reading on devices while writing
What to Do
1. Find Project Root
Look for README.md, chapters/ directory. Support both flat and part-based structures:
Flat structure:
chapters/01-chapter.md chapters/02-chapter.md
Part-based structure:
part-1-name/chapters/01-chapter.md part-2-name/chapters/10-chapter.md
2. Gather Metadata
Extract from README.md:
- •Title — Project name (H1 heading)
- •Author — From frontmatter or infer from git config
- •Description — From "The Story" section or premise
3. Generate Identifier
Create a stable identifier for the EPUB:
com.author-name.project-name
This identifier is what Apple Books uses to recognize "same book, updated" — preserving highlights and reading position between builds.
4. Collect Chapters
Read all markdown files from chapters/ in order:
- •Sort by filename (01-chapter.md, 02-chapter.md, etc.)
- •For part-based projects, read parts in order (part-1, part-2, etc.)
- •Convert markdown to HTML
- •Preserve chapter breaks
5. Check for Cover
Look in covers/ for:
- •
cover.pngorcover.jpg(default) - •Or use
--coverargument to specify
6. Check for Styles
Look for epub.css in project root. If present, include in epub.
7. Build EPUB
Create a metadata file with the stable identifier:
--- title: "Book Title" author: "Author Name" identifier: "com.author-name.book-title" lang: en-GB ---
Use pandoc to compile:
pandoc chapters/*.md \ --metadata-file=/tmp/metadata.yaml \ -o "builds/project-name.epub" \ --epub-cover-image=covers/cover.png \ --css=epub.css \ --split-level=1 \ --toc \ --toc-depth=1
Key options:
- •
--split-level=1— Only break chapters on H1 headings (avoids empty pages) - •
--toc— Include table of contents - •
--toc-depth=1— Only show chapter titles in TOC
8. Create Metadata File (Archive Mode)
Write builds/YYYY-MM-DD/metadata.yaml:
title: "Book Title" author: "Author Name" identifier: "com.author-name.book-title" built: "2026-01-18T21:30:00Z" chapters: 18 word_count: 75000 cover: "cover.png"
9. Report Build
Output build summary:
## Build Complete **File:** builds/project-name.epub **Size:** 8.4 MB **Chapters:** 18 **Word count:** ~75,000 Cover: covers/cover.png included Styles: epub.css applied To open in Apple Books: open -a 'Books' builds/project-name.epub
Build Directory Structure
Archive Mode
builds/
├── 2026-01-15/
│ ├── project-name-2026-01-15.epub
│ └── metadata.yaml
└── 2026-01-18/
├── project-name-2026-01-18.epub
└── metadata.yaml
Sync Mode
builds/ └── project-name.epub # Always same file, updated in place
Apple Books Sync
For highlights to persist between builds:
- •Same identifier — The
identifierfield in metadata must stay constant - •Same filename — Use
--syncmode for consistent naming - •iCloud sync enabled — Both Mac and iPhone need Books enabled in iCloud settings
How it works: Apple Books uses the EPUB's dc:identifier (stored in the OPF file) to recognize books. When you import a new build with the same identifier, it updates the existing book rather than adding a duplicate.
Caveat: Highlights are tied to text position. Major edits (adding/removing paragraphs) may shift or orphan highlights in that area. Minor edits (typos, word changes) are fine.
Covers Directory
covers/ ├── cover-01-concept.png # Early iterations ├── cover-02-revised.png # Refinements ├── cover-final.png # Selected cover └── cover.png # Symlink or copy of final (used by build)
Store all cover iterations. The build uses cover.png by default.
Dependencies
Requires pandoc for epub generation:
brew install pandoc
Tips
- •Use
--syncfor daily reading while writing - •Use archive mode (default) for milestone builds
- •Test epub in Apple Books, Kindle Previewer, or Calibre
- •The
covers/directory is for iterations;cover.pngis what gets built
After Building
- •Open in Apple Books to test formatting
- •Check chapter breaks and styling
- •Verify cover displays correctly
- •For sync mode, delete old version in Books first if highlights don't update
Troubleshooting
Highlights Not Persisting
- •Ensure you're using
--syncmode - •Check that the identifier hasn't changed
- •Try deleting the old book from Apple Books, then importing fresh
- •Verify iCloud sync is enabled for Books on both devices
Empty Pages
If you see blank pages between chapters:
- •Check for
page-break-after: alwaysin epub.css — remove or change toauto - •Look for double line breaks or
\newpagein markdown files - •Ensure
--split-level=1is set (breaks only on H1) - •Check chapter files don't end with multiple blank lines
Recommended epub.css
Minimal CSS that avoids empty page issues:
body {
font-family: Georgia, serif;
line-height: 1.6;
}
h1 {
page-break-before: auto;
margin-top: 2em;
}
p {
text-indent: 1.5em;
margin: 0;
}
p:first-of-type {
text-indent: 0;
}