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 singlerun_pipeline()orchestrator function.obsibooks-gui.pyw— customtkinter GUI. Driven by the samerun_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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64cb5dd2412bd51bd2998d470fbcc30cd67ff8967364cdfefeabe0c7d5ba1856
|
|
| MD5 |
d896710615b62a7135274ee579bbf166
|
|
| BLAKE2b-256 |
0efdd1ef4fbab732c4e00b638d08869b1dc64b544a0340b842c8c792d88046c6
|
Provenance
The following attestation bundles were made for obsibooks-0.1.1.tar.gz:
Publisher:
release.yml on flochrislas/Obsibooks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
obsibooks-0.1.1.tar.gz -
Subject digest:
64cb5dd2412bd51bd2998d470fbcc30cd67ff8967364cdfefeabe0c7d5ba1856 - Sigstore transparency entry: 1598556950
- Sigstore integration time:
-
Permalink:
flochrislas/Obsibooks@a61d810d053a92c906b6a988957d312ae0345922 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/flochrislas
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a61d810d053a92c906b6a988957d312ae0345922 -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cbd8663eaa44d8122d71f01684e70971eec6fdfeb9492fb0159744efec5ae56a
|
|
| MD5 |
b24849329157b24f66676054ad36ad0d
|
|
| BLAKE2b-256 |
c12c41be22a290e8580487b019778daf08393d041e8a9eb0e3c825cca620991a
|
Provenance
The following attestation bundles were made for obsibooks-0.1.1-py3-none-any.whl:
Publisher:
release.yml on flochrislas/Obsibooks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
obsibooks-0.1.1-py3-none-any.whl -
Subject digest:
cbd8663eaa44d8122d71f01684e70971eec6fdfeb9492fb0159744efec5ae56a - Sigstore transparency entry: 1598557117
- Sigstore integration time:
-
Permalink:
flochrislas/Obsibooks@a61d810d053a92c906b6a988957d312ae0345922 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/flochrislas
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a61d810d053a92c906b6a988957d312ae0345922 -
Trigger Event:
push
-
Statement type: