Текст в PDF
Попалась задача — преобразовать огромный (полтора миллиона строк) тестовый файл в кодировке UTF-8 в PDF. Не ожидал с ней каких-то сложностей, но оказалось, что это не так-то просто.
Проблемы две — объём текста и кодировка. Графические утилиты на таком объёме умирают, а с кодировкой UTF, как оказалось, работают далеко не все утилиты командной строки.
Перебрал несколько, с задачей справилась только утилита paps. Хочу себе это записать, чтобы не пришлось заниматься перебором, если в будущем столкнусь с такой же задачей.
Ещё в моей задаче первый лист должен быть пустым и на каждом листе должен быть номер страницы. В результате строка запуска выглядит так:
paps --footer --footer-center={page_idx} <(printf \\f;cat listing.txt) -o listing.pdf
Небольшое примечание: при помощи printf я вставляю текстовый символ разрыва страницы (\f), чтобы первая страница оказалась пустой.
В принципе, pandoc (https://pandoc.org/) справляется, но заставить его сделать первый лист пустым — очень нетривиальная задача, проще приклеить пустую страницу к готовому файлу.
Я пробовал, у меня не справился. Уже не помню в чём там дело было.
А пронумеровать потом, после этого?
А первая (пустая) страница должна тоже быть пронумерована? Тогда надо как-то это объяснить пандоку. Я так понимаю, что он через латех все компилирует, а в латехе все оптимизировано, чтобы подавлять ненужные пустые места в документе, особенно на первой странице. Можно это обойти, например, скомандовав ему разместить на первой странице прозрачную картинку или другим подобным способом, надо немножко над этим подумать.
Если первая страница может быть без номера, а нумерация остальных может начинаться с единицы, то как-то так будет работать (не знаю, как код размечать):
tr -cd 'a-zA-Z ' < /dev/urandom | head -c8000000 | fold -w80 > /tmp/2.txt | ( echo "Пандок" && cat ) | sed G | pandoc -o /tmp/1.pdf --pdf-engine=xelatex --variable mainfont="Unifont" --variable "geometry=margin=1in"
Тут важно прописать, что для сборки PDF используется xelatex, потому что используемый по умолчанию pdflatex не работает с юникодом, и указать шрифт, который содержит нужные символы — здесь Unifont, потому что он покрывает очень значительную часть юникода. Ну и ’sed G’ нужно, чтобы разделять строки пустыми строками, потому что иначе переносы строк будут проигнорированы.
В этом примере 100 тысяч строк, но я не думаю, что от масштабирования что-то сломается.
Увы, никак :-(
Резюме: через paps проще.
Paps еще и быстрее раза в три.