fb2html.py — третий вход в конвейер. FB2 в домашней библиотеке основной формат
(704 тысячи файлов), и без него конвейер до них не дотягивался. Разметка fb2
семантическая, поэтому задача та же, что у epub2html.py: свести чужие теги к
нашим. Уровень заголовка берётся из вложенности section.
pack_epub.py: --series и --series-index. Пишутся в двух видах — calibre-совместимый
meta понимают почти все читалки, belongs-to-collection требует EPUB 3. Без них
читалка не выстраивает книги цикла по порядку.
Ручная настройка block_kind() под каждую книгу оказалась неприменима: у части
изданий имена шрифтов вычищены до «Fd820825», а флаги стилей у всех спанов
равны 4, то есть ни курсива, ни моноширинности по ним не видно. Пороги теперь
считаются из самого файла:
- кегль основного текста — по гистограмме символов;
- кегль глав — по частоте блочных кеглей, а не множителем от текста: иначе
подзаголовки разделов попадают в главы и оглавление пухнет до трёхсот пунктов;
- глава отличается от раздела положением в верхней трети полосы, и правило
применяется, только если глав так набирается хотя бы пять;
- красная строка — по распределению x0.
Листинг опознаётся флагом моноширинности, а при его отсутствии — кеглем мельче
основного текста плюс плотностью кодовой пунктуации.
Отсев картинок: мельче 24 pt (линейки и буллеты) и крупнее 60% площади полосы
(подложка отсканированной страницы). На «Программисте-прагматике» второе
правило убрало 370 сканов полос и уменьшило EPUB со 124 МБ до 17 МБ.
pack_epub.py собирает EPUB на стандартной библиотеке: calibre для упаковки не
нужен, а его установка требует root. Книга режется по h1, оглавление NCX
строится само. Тест test_pack_epub.py проверяет несжатый mimetype первым файлом,
экранирование разметки в метаданных, сохранение переносов в листинге и то, что
преамбула до первой главы не теряется.