Turning scanned PDFs into large-print PDF and EPUB editions
For Knigopoisk, a Russian-language e-book and audiobook store, we built a pipeline that converts a scanned PDF book with an OCR text layer into accessible editions: a large-print PDF at a chosen point size, a reflowable EPUB and a cover image in the 2:3 format the storefront's book cards expect. It is internal production tooling rather than a customer-facing feature.
How the pipeline works
- Extract —
extract.pyreads the PDF with PyMuPDF and writes every text line with its page coordinates torows.json. - Rebuild structure —
build3.pyglues lines into paragraphs, removes soft hyphens and repairs typical OCR confusions, such as misread Cyrillic letters and Latin characters inside Cyrillic words. It detects parts, chapters and sections from heading font sizes and extracts figures into images by their "Рис. N" captions. - Write outputs —
make_outputs.pyturns the block list into sections and an EPUB. - Typeset —
make_pdf.py <pt>sets the book with ReportLab on A4 in DejaVu Sans. At 18 pt and above it builds the large-print edition with tighter margins; smaller sizes produce a regular reading edition. Headings scale from the body size, widows and orphans are suppressed, and every page gets a number, with PDF outline bookmarks for navigation. - Cover —
make_cover.pyrenders the source title page at 300 dpi, trims the scan's margins down to the type block and frames it as an 800×1200 JPEG.
Results on the first book
We ran the pipeline end to end on a scanned Russian-language management book of more than 250 pages. Extraction produced 10,004 text lines; the structure pass rebuilt 1,589 paragraphs, 4 parts, 15 chapters and 14 figures; and the output step wrote 29 sections and a 1.6 MB EPUB. Each stage logs its counts, which makes the output easy to review before anything reaches the catalog.
Related work
This tooling sits alongside our other AI integration and automation work for Knigopoisk, including the AI audiobook generation pipeline and the Knigopoisk partner widget.



