Convert EPUB books into Markdown chapter files.
epub2md is a small CLI for turning an EPUB navigation tree into readable
GitHub-flavored Markdown, with local EPUB images copied beside the output.
| Source | Markdown | Images |
|---|---|---|
book.epub |
book/*.md |
book/images/* |
book.epub out |
out/*.md |
out/images/* |
pip install epub2mdRequires Python 3.8+ and pandoc.
epub2md book.epub
epub2md book.epub outputoutput/
├── 01-introduction.md
├── 02-chapter-1.md
├── 03-chapter-2.md
└── images/
├── figure-1.png
└── .gitignore
Images are git-ignored by default. Remove output/images/.gitignore if you
want generated images committed with the Markdown.
| Area | Contract |
|---|---|
| Chapters | Uses EPUB nav.xhtml or NCX order, with OPF spine fallback |
| Filenames | Prefixes files with stable numeric order and truncates long slugs |
| Markdown | Emits GitHub-flavored Markdown through pandoc |
| Images | Copies EPUB-local images to images/ and rewrites image refs |
| Remote media | Not fetched |
| Safety | Rejects archive traversal, symlinks, oversized archives, and unsafe paths |
EPUB files are treated as untrusted archives.
| Risk | Control |
|---|---|
| ZIP path traversal | Archive paths are validated before extraction |
| Archive symlinks | Rejected before conversion |
| Host file reads | TOC and image paths must resolve inside the EPUB |
| Pandoc option injection | Chapter paths are passed after -- |
| Pandoc file access | Runs with --sandbox |
| Current limit | Notes |
|---|---|
| Cross-chapter links | May remain as original EPUB .xhtml hrefs |
| Fragment TOC entries | Split into separate Markdown files when anchors are present |
| Image formats | EPUB-local files are copied as-is |
| Layout fidelity | Output favors readable Markdown over exact EPUB layout |
python3 -m unittest discover -v
uv buildMIT