DEV Community

Cover image for From outline.json to Published EPUB: The Exact Command Sequence (Copy-Paste Ready)
German Yamil
German Yamil

Posted on

From outline.json to Published EPUB: The Exact Command Sequence (Copy-Paste Ready)

From outline.json to Published EPUB: The Exact Command Sequence (Copy-Paste Ready)

Most pipeline documentation shows architecture diagrams. Here's what you actually type.

This is the exact command sequence — every command, every flag, expected output — to go from an empty directory to a published bilingual EPUB.

Copy, adapt, run.


The full pipeline with all scripts: germy5.gumroad.com/l/xhxkzz — $12.99, all 10 Python scripts included.


Prerequisites

# Install required tools
pip install anthropic requests
brew install pandoc        # macOS
# apt install pandoc       # Ubuntu/Debian

# Install epubcheck (Java required)
brew install epubcheck     # macOS
# or download from: https://github.com/w3c/epubcheck/releases

# Verify
python3 --version          # 3.10+
pandoc --version           # 3.x+
epubcheck --version        # 5.x+
Enter fullscreen mode Exit fullscreen mode

Step 1: Create the chapter manifest

mkdir my_ebook && cd my_ebook
mkdir chapters assets
Enter fullscreen mode Exit fullscreen mode

Create outline.json:

{
  "title": "Your Book Title",
  "author": "Your Name",
  "language_primary": "en",
  "language_secondary": "es",
  "chapters": [
    {
      "number": 1,
      "title": "Introduction and Architecture Overview",
      "slug": "chapter-01-intro",
      "word_target": 2200,
      "code_file": "script_01_intro.py",
      "learning_objective": "Reader will understand the pipeline architecture and be able to set up the project structure"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Validate it parses correctly:

python3 -c "import json; data=json.load(open('outline.json')); print(f'✅ {len(data[\"chapters\"])} chapters loaded')"
# Expected: ✅ 10 chapters loaded
Enter fullscreen mode Exit fullscreen mode

Step 2: Generate chapters

python3 generate_chapters.py \
  --outline outline.json \
  --output-dir chapters/ \
  --api-key $ANTHROPIC_API_KEY \
  --model claude-opus-4-5

# Expected output:
# [chapter-01] PENDING → RUNNING
# [chapter-01] Generating... (est. 45s)
# [chapter-01] Validating syntax...  ✅
# [chapter-01] Validating execution... ✅
# [chapter-01] RUNNING → DONE (2,247 words, 1 script)
# [chapter-02] PENDING → RUNNING
# ...
# [chapter-09] RUNNING → NEEDS_REVIEW (execution failed: ModuleNotFoundError)
# [chapter-10] PENDING → RUNNING
# ...
# Done. 9 DONE, 1 NEEDS_REVIEW.
Enter fullscreen mode Exit fullscreen mode

If a chapter hits NEEDS_REVIEW:

# Check the error log
cat chapters/chapter-09/error.log
# Example: ModuleNotFoundError: No module named 'pandas'

# Re-run that specific chapter with adjusted prompt
python3 generate_chapters.py \
  --outline outline.json \
  --output-dir chapters/ \
  --api-key $ANTHROPIC_API_KEY \
  --chapter chapter-09 \
  --hint "Use only Python stdlib — no third-party imports"

# Expected:
# [chapter-09] NEEDS_REVIEW → PENDING (manual reset)
# [chapter-09] PENDING → RUNNING
# [chapter-09] Validating execution... ✅
# [chapter-09] RUNNING → DONE
Enter fullscreen mode Exit fullscreen mode

Step 3: Validate all code (final check)

python3 validate_ast.py --chapters-dir chapters/

# Expected:
# Checking chapter-01/script_01_intro.py... ✅ syntax OK
# Checking chapter-02/script_02_state.py... ✅ syntax OK
# ...
# All 10 chapters: syntax valid.

python3 run_subprocess.py --chapters-dir chapters/ --timeout 30

# Expected:
# Running chapter-01/script_01_intro.py... exit code 0 ✅
# Running chapter-02/script_02_state.py... exit code 0 ✅
# ...
# All 10 scripts: clean execution.
Enter fullscreen mode Exit fullscreen mode

If any script fails here (it shouldn't — the pipeline already validated during generation), go back to Step 2 for that chapter.

Step 4: Generate Spanish translation

python3 translate_qa.py \
  --chapters-dir chapters/ \
  --source-lang en \
  --target-lang es \
  --api-key $ANTHROPIC_API_KEY

# Expected:
# [chapter-01] Translating EN → ES...
# [chapter-01] Code fence check: EN=8 fences, ES=8 fences ✅
# [chapter-01] Word ratio: EN=2247, ES=2489 (ratio=1.11) ✅
# ...
# Translation complete. 10/10 chapters passed QA.

# If fence mismatch:
# [chapter-05] Code fence check: EN=12 fences, ES=10 fences ❌
# Chapter 05 ES saved to chapters/chapter-05/chapter-05-es-REVIEW.md
Enter fullscreen mode Exit fullscreen mode

Fix translation issues manually in the -REVIEW.md file, then rename it to chapter-05-es.md.

Step 5: Assemble EPUBs

# Concatenate EN chapters
python3 assemble_epub.py \
  --chapters-dir chapters/ \
  --lang en \
  --output book_en.md

# Expected:
# Sorting chapters... found 10 files
# Concatenating... 22,847 words total
# Written to book_en.md ✅

# Generate EN EPUB
pandoc book_en.md \
  --output book_en.epub \
  --metadata-file metadata_en.yaml \
  --epub-cover-image assets/cover.png \
  --table-of-contents \
  --toc-depth=2 \
  --epub-chapter-level=1

# Expected: (no output = success)
# Verify:
ls -lh book_en.epub
# Expected: -rw-r--r-- 1 user group 847K book_en.epub

# Validate EPUB structure
epubcheck book_en.epub

# Expected:
# Validating using EPUB version 3.x rules.
# No errors or warnings detected.
# Messages: 0 fatals / 0 errors / 0 warnings / 0 infos

# Repeat for Spanish
pandoc book_es.md \
  --output book_es.epub \
  --metadata-file metadata_es.yaml \
  --epub-cover-image assets/cover.png \
  --table-of-contents \
  --toc-depth=2 \
  --epub-chapter-level=1

epubcheck book_es.epub
Enter fullscreen mode Exit fullscreen mode

If epubcheck reports errors:

  • OPF-055: Missing metadata field → check metadata_en.yaml
  • PKG-007: Missing resource → cover image path issue
  • RSC-005: Malformed HTML → usually a code block not properly closed in Pandoc

Step 6: Create Gumroad listing

python3 gumroad_create.py \
  --token $GUMROAD_TOKEN \
  --title "Your Book Title" \
  --price 1299 \
  --description-file gumroad_description.md

# Expected:
# Creating product...
# ✅ Product created!
#    URL: https://yourusername.gumroad.com/l/your-slug
#    ID: xxxxxxxxxxxxxxxx
#    Price: $12.99
Enter fullscreen mode Exit fullscreen mode

Upload the EPUB manually (Gumroad REST API doesn't support binary file upload):

  1. Open the URL from the output
  2. Edit Product → Files → Upload book_en.epub and book_es.epub
  3. Save

Total time to this point: ~4–6 hours (including active monitoring and fixing NEEDS_REVIEW chapters).

Step 7: Submit to Amazon KDP (manual)

# Prepare KDP metadata (from the pipeline output)
cat kdp_metadata.json
# {
#   "title": "Your Book Title",
#   "subtitle": "...",
#   "description": "...",
#   "keywords": ["python", "automation", "ebook", ...],
#   "categories": ["Computers & Technology", "Programming"],
#   "price_usd": 9.99
# }
Enter fullscreen mode Exit fullscreen mode

KDP doesn't have an API. Manual steps:

  1. kdp.amazon.com → Add New Title → eBook
  2. Fill from the JSON above
  3. Upload book_en.epub
  4. Upload cover (1600×2560px minimum)
  5. Set price to $9.99 (70% royalty tier)
  6. Submit for review (takes 24–72 hours)

The Full Sequence as a Shell Script

#!/bin/bash
set -e  # exit on any error

echo "=== AI Publishing Pipeline Run ==="
echo "Started: $(date)"

# Step 1: Validate manifest
python3 -c "import json; json.load(open('outline.json'))" && echo "✅ outline.json valid"

# Step 2: Generate
python3 generate_chapters.py --outline outline.json --output-dir chapters/ --api-key $ANTHROPIC_API_KEY

# Step 3: Final validation
python3 validate_ast.py --chapters-dir chapters/
python3 run_subprocess.py --chapters-dir chapters/ --timeout 30

# Step 4: Translate
python3 translate_qa.py --chapters-dir chapters/ --source-lang en --target-lang es --api-key $ANTHROPIC_API_KEY

# Step 5: Assemble
python3 assemble_epub.py --chapters-dir chapters/ --lang en --output book_en.md
python3 assemble_epub.py --chapters-dir chapters/ --lang es --output book_es.md

pandoc book_en.md -o book_en.epub --metadata-file metadata_en.yaml --epub-cover-image assets/cover.png --toc --toc-depth=2
pandoc book_es.md -o book_es.epub --metadata-file metadata_es.yaml --epub-cover-image assets/cover.png --toc --toc-depth=2

epubcheck book_en.epub && echo "✅ EN EPUB valid"
epubcheck book_es.epub && echo "✅ ES EPUB valid"

# Step 6: Publish
python3 gumroad_create.py --token $GUMROAD_TOKEN --title "Your Book Title" --price 1299 --description-file gumroad_description.md

echo ""
echo "=== Done ==="
echo "Completed: $(date)"
echo "Manual: upload EPUBs to Gumroad and submit to KDP"
Enter fullscreen mode Exit fullscreen mode

Save as run_pipeline.sh, chmod +x run_pipeline.sh, and run it.


The full codebase (all 10 scripts): germy5.gumroad.com/l/xhxkzz ($12.99, 30-day refund).


Further Reading

Top comments (0)