Стадия перевода: мост к book_translator без модификации стороннего репозитория

This commit is contained in:
Илья Поляков
2026-08-03 07:59:12 +03:00
parent 0a98e7cf65
commit 9c7658df5e
4 changed files with 371 additions and 1 deletions
+48 -1
View File
@@ -1,6 +1,6 @@
---
name: pdf-to-kindle
description: Convert a text-layer PDF (usually one generated by calibre from an ebook) into EPUB/AZW3 for Kindle while preserving italics, bold, chapter headings, sidebars/journal blocks, images and cross-page paragraphs. Use when the user asks to read a PDF book on Kindle or another e-reader, to convert a PDF to EPUB/AZW3/MOBI, or complains that a converted book lost its italics, merged its chapters, or reflows badly on the device. Not for scanned PDFs (no text layer) — those need OCR first.
description: Convert a text-layer PDF (usually one generated by calibre from an ebook) into EPUB/AZW3 for Kindle while preserving italics, bold, chapter headings, sidebars/journal blocks, images and cross-page paragraphs. Use when the user asks to read a PDF book on Kindle or another e-reader, to convert a PDF to EPUB/AZW3/MOBI, or complains that a converted book lost its italics, merged its chapters, or reflows badly on the device. Not for scanned PDFs (no text layer) — those need OCR first. Also covers translating such a book into another language before packing it, delegated to the external book_translator project.
---
# PDF to Kindle
@@ -92,6 +92,53 @@ EOF
After packing, confirm the EPUB: `ebook-meta` for metadata, and the `.ncx`
navPoint count for the TOC size.
## Optional stage: translation
Only when the user asks for a translated book. It slots between step 6 and
step 7 — translate the XHTML, then pack the translated file with calibre.
Translation is delegated to an external project,
[`vetermanve/book_translator`](https://github.com/vetermanve/book_translator)
(DeepSeek or a local Ollama model). **Never modify that repository** — it is
driven through its documented CLI and file formats only. `scripts/translate.py`
is the bridge: it writes the repo's input format, shells out to
`03_translate_parallel.py --all`, and reads the repo's output format back.
1. **Check the book actually needs translating.** The script does this first
and refuses to burn API credits on a book already in the target language:
`python scripts/translate.py book.html out.html --repo <clone> --workdir <dir> --check-only`
It reports block/chapter/character counts and the detected source language.
`--force` overrides the refusal.
2. **Set up the external repo once** (a plain clone; never edit it), and its
credentials — `DEEPSEEK_API_KEY` in the environment or a `.env` in the
working directory, or `USE_OLLAMA` for a local model. Its `requirements.txt`
omits `openai`, which `deepseek_translator.py` imports — install it too.
3. **Translate:**
`python scripts/translate.py book.html book.ru.html --repo <clone> --workdir <dir> --workers 12`
Resumable: the external repo tracks completed chapters and skips them on a
re-run, so an interrupted run costs nothing to restart.
4. **Read the reported counts.** "без перевода" above zero means a chapter came
back with a different paragraph count and kept its original text; "разметка
потеряна" counts paragraphs where the model mangled the inline-tag markers
and the italics were dropped rather than corrupted. Both are expected to be
near zero — a large number means the translator misbehaved, not that the
bridge is broken.
5. Pack `book.ru.html` with `--language=ru` and translated `--title`/`--authors`.
How formatting survives a translator that only speaks plain text: inline `<i>`
and `<b>` become `⟦i⟧…⟦/i⟧` markers before the text leaves, and are restored
after. Every paragraph's markers are balance-checked on the way back. Images,
`<h1>`/`<h2>` structure, and block order never leave this side — only the text
of each block round-trips, and blocks are reassembled by index.
`scripts/test_translate.py` covers the marker round-trip, the broken-marker
fallback, language detection, and a full split/rebuild against a faked
translator response — no network, no API key. Run it after touching the bridge.
## What the script does
- style from span font names (`-It`, `Italic`, `Bold`, `Semibold`) → `<i>`/`<b>`;