Skip to main content

PDF to Markdown converter with OCR support — local, fast, accurate.

Project description

Sahaf

CI PyPI License: GPL v3

Local PDF & EPUB to Markdown converter with automatic digital/scanned detection, OCR support, smart splitting, and page-range selection. Converts books to clean, self-contained Markdown files with embedded images using Marker (95.67% accuracy) and Surya OCR (90+ languages). No cloud APIs — runs entirely on your hardware.

Features

  • PDF & EPUB support — handles both formats natively
  • Automatic PDF classification — detects digital, scanned, or mixed PDFs via PyMuPDF
  • High-accuracy conversion — Marker with 95.67% benchmark accuracy
  • Built-in OCR — Surya OCR supports 90+ languages (Turkish, English, Arabic, etc.)
  • Page/chapter range selection — convert only a specific section of the book (e.g. pages 19-88)
  • Smart splitting — split output into N parts, cutting at heading/paragraph boundaries instead of mid-sentence
  • Self-contained output — images embedded as base64 directly in Markdown, no separate files
  • Split preview — see exactly how parts will be divided before downloading
  • Bilingual UI — Turkish / English interface with one-click toggle
  • Dark/light theme — lavender-toned design, persistent toggle
  • Drag & drop UI — clean single-page web interface

Install

pip install sahaf

Or from source:

git clone https://github.com/arikusi/sahaf.git
cd sahaf
pip install -e .

Marker models (~2-3GB) are downloaded automatically on first conversion.

Quick Start

sahaf

Open http://localhost:8000 in your browser.

How It Works

  1. Upload — drag & drop a PDF or EPUB file
  2. Classify — PyMuPDF analyzes PDF type; EPUB chapters are counted
  3. Select range (optional) — pick specific pages or chapters to convert
  4. Convert — Marker processes PDF; ebooklib + markdownify handles EPUB
  5. Split (optional) — choose how many parts to split the output into
  6. Download — get a single .md or a ZIP with split parts, all images embedded inline

API

Method Path Description
POST /api/upload Upload PDF/EPUB, returns task_id
GET /api/classify/{task_id} Detect PDF type + page count, or EPUB chapter count
POST /api/convert/{task_id}?page_from=&page_to= Start conversion (optional page range)
GET /api/status/{task_id} Poll conversion progress
GET /api/result/{task_id} Get markdown + image list
GET /api/download/{task_id} Download .md with embedded images
GET /api/download/{task_id}/zip?parts=N Download ZIP with N split .md files
GET /api/split-preview/{task_id}?parts=N Preview split structure before download

Tech Stack

  • Backend: FastAPI + Uvicorn
  • PDF Classification: PyMuPDF
  • PDF Conversion: Marker (marker-pdf) + Surya OCR
  • EPUB Conversion: ebooklib + markdownify
  • Smart Splitting: Custom algorithm — heading/HR/paragraph boundary detection
  • Frontend: Vanilla HTML/CSS/JS + marked.js
  • i18n: TR/EN with client-side toggle

Requirements

  • Python 3.10+
  • 4-6GB RAM (when Marker models are loaded)
  • GPU strongly recommended for PDF — CPU-only is extremely slow (~1 hour for a 27-page mixed PDF on i5 + 40GB RAM). A CUDA-capable GPU converts the same file in minutes.
  • EPUB conversion is lightweight — no GPU needed, runs instantly

License

GPL-3.0

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

sahaf-0.2.1.tar.gz (28.5 kB view details)

Uploaded Source

Built Distribution

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

sahaf-0.2.1-py3-none-any.whl (27.4 kB view details)

Uploaded Python 3

File details

Details for the file sahaf-0.2.1.tar.gz.

File metadata

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

File hashes

Hashes for sahaf-0.2.1.tar.gz
Algorithm Hash digest
SHA256 f0b0f33a591ff71f8c5afaff03d6e3b82d0c45e47477925ba2dace01ec9fa1b2
MD5 8a10db056f534b6dd143ef4af9471e1d
BLAKE2b-256 e580ae213d40fbb587608e73b62669fcff0f267ae1c8751f01ceab74617559e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for sahaf-0.2.1.tar.gz:

Publisher: publish.yml on arikusi/sahaf

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

File details

Details for the file sahaf-0.2.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for sahaf-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4cf6ad1aa2d385f59a2547b024be49fc52774b49e44f237190f11b53176c9bc0
MD5 1e7e86f69021598089d9e30c1d583191
BLAKE2b-256 cf1f002a4625b5225d6a377ee3226ed76cd72b8eddc03b0f409268c19ab3f32c

See more details on using hashes here.

Provenance

The following attestation bundles were made for sahaf-0.2.1-py3-none-any.whl:

Publisher: publish.yml on arikusi/sahaf

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