End-to-end pipeline that takes an English EPUB and produces a translated,
print-ready PDF for self-publishers. Tested with printto.ua;
provider requirements (page sizes, file-size limits, even-page rules) are
externalised in providers/*.yaml so other shops (Lulu, Blurb, Amazon KDP)
can be added without code changes.
Result: a physical Russian translation of Speed Secrets (Ross Bentley) has been produced with this pipeline and submitted to printto.ua.
EPUB (source)
│
▼
1. translate_html — body text via Google / DeepL / Claude
2. translate_toc — toc.ncx via Claude batched call
3. clean_epub — drop legacy sections, translate OPF <guide>
4. covers — install front and/or back cover PNGs
5. typography — print-quality CSS (justify, text-indent, orphans/widows)
6. block_only — produce a covers-less EPUB for separate-cover printing
│
▼ (external: Calibre EPUB → PDF)
│
7. pdf_replace_covers — render PNGs full-bleed onto first and last pages
8. pdf_make_even — append blank if page count is odd
9. pdf_audit — quick smell-test
10. final_audit — pre-flight check against provider config
DocTranslator.com handles step 1 (and 11 other formats) well but stops there. This pipeline is the only one that takes you all the way to a print-ready, typography-correct PDF with full-bleed covers and an even-page guarantee — the actual deliverables a print shop wants.
pip install -r requirements.txt
# Free, no API key:
python runner.py book.epub --front cover_front.png --back cover_back.png
# Best quality:
export ANTHROPIC_API_KEY=sk-ant-...
python runner.py book.epub \
--engine claude --source en --target ru \
--front cover_front.png --back cover_back.png \
--translate-toc --book-context "racing book"Outputs land in ./out/:
book_ru.epub— translated book with covers and print typographybook_ru_block.epub— covers stripped, ready for separate-cover printing
After converting both EPUBs to PDF (Calibre), run the PDF-side steps:
python -m epub_translator.steps.pdf_replace_covers \
--pdf out/book_ru.pdf --front cover_front.png --back cover_back.png \
--width-mm 148 --height-mm 210
python -m epub_translator.steps.pdf_make_even --pdf out/book_ru.pdf
python -m epub_translator.steps.final_audit \
--epub out/book_ru.epub \
--pdf "A5_with_covers:out/book_ru.pdf" \
--pdf "A5_block:out/book_ru_block.pdf" \
--front cover_front.png --back cover_back.png \
--format A5 --provider printtoepub_translator/
├── epub_utils.py extract / repack / find_opf / find_content_files
├── pdf_utils.py page_size_mm / render_image_pdf / ensure_even_pages
├── engines/
│ ├── base.py TranslationEngine ABC with chunked _split_text
│ ├── google.py free, no key
│ ├── deepl.py 500k free chars/month
│ └── claude.py highest quality, requires ANTHROPIC_API_KEY
└── steps/
├── translate_html.py body-text translation
├── translate_toc.py toc.ncx translation via Claude
├── clean_epub.py legacy-section removal + OPF guide translation
├── covers.py add-front | add-back | replace subcommands
├── typography.py print-quality CSS injection (--no-important supported)
├── block_only.py covers-less EPUB for the book block
├── pdf_replace_covers.py full-bleed cover pages via ReportLab
├── pdf_make_even.py append blank if odd
├── pdf_audit.py empty / short / broken-sentence detection
└── final_audit.py full pre-flight against providers/<name>.yaml
providers/
└── printto.yaml page sizes, max file size, language hints
runner.py end-to-end orchestrator
providers/printto.yaml declares page formats, file-size limit, and the
language hints used by final_audit to spot residual English text. Add a new
shop by dropping a YAML file with the same shape, no code change needed.
| Engine | Cost | Quality | Setup |
|---|---|---|---|
google |
free, no key | good for genre fiction | none |
deepl |
500k chars/month free | very good for European languages | DEEPL_API_KEY |
claude |
paid (claude-sonnet-4-6) |
best for technical terminology | ANTHROPIC_API_KEY |
Engines share TranslationEngine.translate(text) from engines/base.py:
sentence-bounded chunking, safe fallback to original on error.
- Python 3.11+
- macOS (FFmpeg/Calibre installed via Homebrew)
- printto.ua A5 (148x210 mm) and printto B5 custom (170x240 mm)
Built with Claude Code as an AI-assisted development exercise: pipeline architecture, EPUB / PDF internals, and provider-specific tuning were iterated against real printto.ua submission feedback over ~7 cycles.
MIT. See LICENSE.