Skip to main content

Convert EPUB and PDF ebooks to Obsidian-compatible markdown, with optional vault image compression.

Project description

obsibooks

Convert a library of EPUB and PDF books into an Obsidian vault — one folder per book, one markdown file per chapter, an index with YAML frontmatter, and optional in-place image compression to WebP.

My Vault/
├── My First Book/
│   ├── 00 - My First Book.md      ← index with YAML frontmatter + [[wiki-links]]
│   ├── 01 - Introduction.md
│   ├── 02 - Chapter One.md
│   ├── ...
│   └── assets/
│       └── cover.webp
└── My Second Book/
    ├── 00 - My Second Book.md
    ├── ...
    └── assets/

Each index file has editable metadata fields ready for Obsidian:

---
title: My First Book
author: Author Name
publisher: Publisher
year: 2021
read: false
rating: null
tags:
  - book
---

Install

Pick one of three paths.

1. From PyPI (recommended)

pip install obsibooks            # CLI only
pip install "obsibooks[gui]"     # also install the customtkinter GUI

This puts an obsibooks command on your PATH.

2. Prebuilt binary (no Python install)

Download the single-file executable for your OS from the latest GitHub release — assets are named obsibooks-windows.exe, obsibooks-macos, obsibooks-linux. Drop it anywhere on PATH and run it.

3. From source

git clone https://github.com/flochrislas/obsibooks.git
cd obsibooks
pip install -e .

External requirement: Pandoc

EPUB conversion calls Pandoc, regardless of how obsibooks itself is installed:

# Windows
winget install --id JohnMacFarlane.Pandoc

# macOS
brew install pandoc

Or download from pandoc.org. PDF-only runs do not need Pandoc.

Usage

Command line

# Single file (format auto-detected from extension)
python obsibooks.py path/to/book.epub
python obsibooks.py path/to/book.pdf

# Whole folder — converts every .epub and .pdf inside
python obsibooks.py path/to/library/

# Write output to a specific vault folder (default: next to each source file)
python obsibooks.py path/to/library/ -d path/to/vault/

# Re-convert books whose output folder already exists
python obsibooks.py path/to/library/ -d path/to/vault/ --overwrite

# Restrict to one format
python obsibooks.py path/to/library/ --epub-only
python obsibooks.py path/to/library/ --pdf-only

# Convert + compress vault images in one go
python obsibooks.py path/to/library/ -d path/to/vault/ --compress

# Preview what compression would do, without touching files
python obsibooks.py path/to/library/ -d path/to/vault/ --compress --dry-run

# Tighter compression budget
python obsibooks.py path/to/library/ -d vault/ --compress \
    --max-kb 300 --max-width 1280 --max-height 1280 --quality 80

Each book's output folder is named after the source filename (not the book's metadata title), so renaming an .epub or .pdf before conversion controls the output folder name. Re-running skips books whose folder already exists, so partial batches can resume safely; pass --overwrite to force re-conversion.

Flags

Flag Default Description
path EPUB/PDF file, or folder containing either
-d, --output-dir DIR next to each source Vault root for converted books
-o, --overwrite off Re-convert already-converted books
--epub-only both run Folder mode: skip PDFs
--pdf-only both run Folder mode: skip EPUBs
--compress off Compress vault images after conversion
--max-kb N 500 Compression: file-size threshold (kB)
--max-width N 1024 Compression: pixel width limit
--max-height N 1024 Compression: pixel height limit
--quality N 85 Compression: WebP lossy quality (1–100)
--dry-run off Compression: list-only, no changes

--epub-only and --pdf-only are mutually exclusive. Compression flags are ignored unless --compress is set.

GUI

pythonw obsibooks-gui.pyw

Or double-click obsibooks-gui.bat on Windows.

The window has:

  • Input — a single .epub/.pdf (via File) or a folder of them (via Folder).
  • Output — vault directory; leave empty to write alongside each source file.
  • Overwrite / Convert EPUBs / Convert PDFs — toggles. Uncheck a format to skip it in folder mode.
  • Compress images — when ticked, the four entries underneath become editable: max kB, max width, max height, quality. Dry run lists images that would be processed without touching anything.
  • Convert — runs the pipeline in a worker thread; the main area streams the conversion log.

When you pick an input, the main area first shows a preview listing the books that will be converted given the current toggles (already-converted books are hidden when Overwrite is off). The same area then streams the live log once you click Convert.

Image compression

When --compress is set, every image under vault/*/assets/ that exceeds the size threshold or the pixel limits is converted to WebP, the markdown references in the book's notes are rewritten, and the original is deleted.

Source format Treatment
.png Lossless WebP first. If the result is still over --max-kb, falls back to lossy at --quality. The size cap takes priority over preserving lossless quality.
.jpg / .jpeg / .bmp / .tiff / .tif / .webp Lossy WebP at --quality.
.gif Skipped — would lose animation.

If an image wasn't resized and the WebP encoding ended up no smaller than the original, the WebP is discarded and the source kept as-is. Resized images are always kept regardless of byte count — the goal there is dimensions.

Project layout

  • obsibooks.py — CLI and the single run_pipeline() orchestrator function.
  • obsibooks-gui.pyw — customtkinter GUI. Driven by the same run_pipeline().
  • obsibooks-gui.bat — Windows launcher.
  • pepub.py — EPUB → markdown. Also runnable on its own (python pepub.py …).
  • pepdf.py — PDF → markdown. Also runnable on its own.
  • compress_images.py — vault image compression. Also runnable on its own when you want compression without conversion.

The three underlying scripts are imported as modules and reused without modification, so any of them can still be used in isolation if that's all you need.

License

See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

obsibooks-0.1.1.tar.gz (37.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

obsibooks-0.1.1-py3-none-any.whl (39.6 kB view details)

Uploaded Python 3

File details

Details for the file obsibooks-0.1.1.tar.gz.

File metadata

  • Download URL: obsibooks-0.1.1.tar.gz
  • Upload date:
  • Size: 37.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for obsibooks-0.1.1.tar.gz
Algorithm Hash digest
SHA256 64cb5dd2412bd51bd2998d470fbcc30cd67ff8967364cdfefeabe0c7d5ba1856
MD5 d896710615b62a7135274ee579bbf166
BLAKE2b-256 0efdd1ef4fbab732c4e00b638d08869b1dc64b544a0340b842c8c792d88046c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for obsibooks-0.1.1.tar.gz:

Publisher: release.yml on flochrislas/Obsibooks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file obsibooks-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: obsibooks-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 39.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for obsibooks-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 cbd8663eaa44d8122d71f01684e70971eec6fdfeb9492fb0159744efec5ae56a
MD5 b24849329157b24f66676054ad36ad0d
BLAKE2b-256 c12c41be22a290e8580487b019778daf08393d041e8a9eb0e3c825cca620991a

See more details on using hashes here.

Provenance

The following attestation bundles were made for obsibooks-0.1.1-py3-none-any.whl:

Publisher: release.yml on flochrislas/Obsibooks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page