Metadata-Version: 2.5
Name: pro-ledin-docling-ebook
Version: 0.2.0
Summary: Docling backend extension for EPUB, FB2, MOBI, AZW, and AZW3 ebooks.
Project-URL: Homepage, https://github.com/ledin-pro/docling-ebook
Project-URL: Repository, https://github.com/ledin-pro/docling-ebook
Author: mxl
License-Expression: MIT
License-File: LICENSE
Keywords: azw3,docling,ebook,epub,fb2,markdown,mobi,ocr
Requires-Python: <4,>=3.10
Requires-Dist: docling-slim<3,>=2.121
Requires-Dist: pillow>=10
Requires-Dist: pro-ledin-ebook-import<0.5,>=0.3
Provides-Extra: dev
Requires-Dist: hypothesis>=6; extra == 'dev'
Requires-Dist: jsonschema<5,>=4.25; extra == 'dev'
Requires-Dist: pytest-cov>=6; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Provides-Extra: ocr
Requires-Dist: pro-ledin-ocr<0.8,>=0.7; extra == 'ocr'
Description-Content-Type: text/markdown

# pro-ledin-docling-ebook

Open Docling backend extension for structured ebook conversion.

It converts EPUB, FB2, compressed FB2, and DRM-free MOBI-family books into a
native `DoclingDocument`, then exports through Docling to Markdown, JSON, or
HTML.

- Inputs: `.epub`, `.fb2`, `.fb2.zip`, `.fbz`, `.mobi`, `.azw`, `.azw3`
- Python package: `pro.ledin.docling_ebook`
- CLI: `docling-ebook`
- License: MIT
- Proprietary dependencies: none

## Install

```bash
pip install pro-ledin-docling-ebook
pip install 'pro-ledin-docling-ebook[ocr]'  # optional pro-ledin-ocr adapter
```

The package uses the official `docling-slim` distribution because ebook
conversion needs the Docling document model and backend contracts, not PDF
layout, OCR, or VLM models.

EPUB and FB2 work immediately. DRM-free MOBI/AZW/AZW3 require one external
converter. `mobitool` is preferred; Calibre is the fallback. Every conversion
must explicitly choose an image policy:

```bash
brew install libmobi
sudo apt install libmobi-tools
```

Calibre downloads: https://calibre-ebook.com/download

```bash
docling-ebook doctor --json
```

## CLI

```bash
docling-ebook book.fb2 --images skip --to md --output-dir ./out
docling-ebook book.mobi --images referenced --to json --output-dir ./out
docling-ebook one.epub two.azw3 --images referenced --to html --output-dir ./out
```

Preview parsing without writing outputs:

```bash
docling-ebook book.fb2 --images referenced --dry-run
```

Image policies:

```bash
docling-ebook book.fb2 --images skip
docling-ebook book.fb2 --images referenced
docling-ebook book.fb2 --images ocr \
  --ocr-prompt "Read all visible text faithfully and preserve table structure"
```

`referenced` writes the original images to `<stem>_artifacts/` and uses relative
links in Markdown, JSON, and HTML. `skip` imports no source image assets and
emits no picture items.

OCR requires a prompt and replaces every picture, including the cover, with
text in a checkpointed `DoclingDocument`. The default adapter uses an
OpenAI-compatible vision endpoint through `pro-ledin-ocr`:

```bash
export OCR_VISION_API_URL="http://127.0.0.1:8000/v1"
export OCR_VISION_API_KEY="local-key"
export OCR_VISION_MODEL="my-vision-model"
docling-ebook book.fb2 --images ocr \
  --ocr-prompt-file prompt.txt \
  --ocr-timeout 300 \
  --ocr-max-attempts 3
```

The default checkpoint is `./out/book.json`. Override it with
`--ocr-checkpoint`; use `--restart-ocr` after changing the source, prompt, or
callback configuration.

Use a custom trusted callback factory without changing the package:

```bash
docling-ebook book.fb2 --images ocr \
  --ocr-prompt "Read visible text" \
  --ocr-callback my_callback:factory \
  --ocr-callback-config callback.json
```

MOBI backend selection:

```bash
docling-ebook book.azw3 --mobi-backend auto
docling-ebook book.azw3 --mobi-backend mobitool
docling-ebook book.azw3 --mobi-backend calibre
```

Footnotes default to Markdown-compatible native markers. Use an inline fallback
when a downstream Docling consumer does not preserve footnote references:

```bash
docling-ebook book.fb2 --footnote-mode inline --to md
```

## Python API

```python
from pro.ledin.docling_ebook import EbookConverter

result = EbookConverter(
    source_image_mode="import",
    mobi_backend="auto",
).convert("book.fb2")

document = result.document
result.save_as_markdown("book.md")
document.save_as_json("book.json")
```

OCR is available through the public transformer and a caller-supplied callback:

```python
from pro.ledin.docling_ebook import transform_pictures_with_ocr

transformed = transform_pictures_with_ocr(
    result,
    callback=my_callback,
    prompt="Read visible text faithfully",
    checkpoint="book.json",
)
transformed.document.save_as_html("book.html")
```

Streams require a filename so the ebook format can be detected:

```python
from io import BytesIO
from pro.ledin.docling_ebook import convert_ebook

result = convert_ebook(BytesIO(payload), filename="book.fb2")
```

## Native document mapping

The backend maps the typed `pro-ledin-ebook-import` model directly into
`DoclingDocument`:

- book title and metadata
- chapter and nested-section groups
- headings and paragraphs
- mixed emphasis, bold, strike, links, code, subscript, and superscript
- epigraphs, citations, poems, stanzas, and verse lines
- tables with row/column spans
- content and cover pictures, or OCR text replacements
- footnote references and definitions
- ordered and unordered lists

Warnings, OCR checkpoint status, and MOBI converter provenance remain available
in the conversion result instead of being inserted into book text.

## Docling extension boundary

Docling's third-party plugin entry point currently registers OCR, layout,
table-structure, and picture-description models. It does not register new input
formats or document backends. This package therefore provides the public
`EbookDocumentBackend`, `EbookConverter`, and `docling-ebook` CLI rather than an
irrelevant model-plugin entry point.

The stock command below is not provided by an external backend package:

```bash
docling --from fb2 book.fb2
```

Native support for that syntax requires new `InputFormat` and CLI mappings in
Docling upstream. This extension uses only public `InputDocument` and
`DeclarativeDocumentBackend` APIs and does not call private Docling methods or
model pipelines. The converter invokes the public
`DeclarativeDocumentBackend.convert()` contract directly, so `docling-slim`
does not pull PDF/OCR/VLM dependencies. OCR is an explicit optional integration
and is not enabled by ordinary conversion.

An alternative commercial project, `aspose-words-docling`, supports some ebook
formats through Aspose.Words. This package instead uses the open
`pro-ledin-ebook-import` parser and libmobi/Calibre subprocess boundary.

## Safety

- FB2 XML rejects DTD and entity expansion.
- FB2.ZIP/FBZ archives enforce path, size, member-count, and compression limits.
- External converters run without a shell in temporary directories.
- Ordinary conversion does not contact remote Docling services or load external model plugins; prompt-driven OCR is an explicit opt-in callback.
- The package never removes DRM and rejects encrypted books.
- KFX, AZW4 Print Replica, and PRC are unsupported.

## Development

```bash
uv sync --extra dev
uv run --extra dev pytest -q -m "not external"
uv run --extra dev pytest \
  --cov=pro.ledin.docling_ebook --cov-branch --cov-report=json
uv run python scripts/check_coverage.py coverage.json
uv build
```

Run real MOBI converter integration when both tools are installed:

```bash
DOCLING_EBOOK_EXTERNAL_TESTS=1 \
  uv run --extra dev pytest tests/test_real_mobi_tools.py
```

## License

MIT
