Статьи

Создание PDF-файлов из Markdown с помощью Pandoc и LaTeX

создание PDF-файлов

Если вы читали некоторые из моих предыдущих постов в SitePoint или где-то еще, вы можете знать, что я работаю над настольной игрой. В игре под названием Chip Shop вы управляете компьютерной компанией в Америке 1980-х годов.

Как часть проекта, я пытаюсь открыть исходный код всей игры, насколько это возможно. После нескольких неудачных попыток я выбрал базовую структуру Markdown для большинства компонентов игры — особенно для карт и руководства.

Поскольку веб-сайт игры использует Jekyll , веб-сайт для игры создается из файлов Markdown. Я намереваюсь иметь премиум-версии игры в готовом и печатном виде, и для этого мне нужно создавать PDF-файлы из файлов Markdown.

Что я пытаюсь достичь

Мой идеальный рабочий процесс — создавать файлы PDF одновременно с созданием веб-сайта, а не создавать файлы по запросу посетителей. Это исключает мою обычную опцию генерации PDF, wkhtmltopdf , так как она генерирует PDF-файлы из уже сгенерированного HTML. Другая причина, по которой это не вариант, заключается в том, что я хочу, чтобы версии карточек PDF выглядели не так, как HTML-страницы, а в Jekyll отсутствует какая-либо функция режима просмотра, чтобы выполнить это, не прибегая к сложным правилам CSS.

Файл шаблона Markdown для карт в игре Chip Shop содержит множество полей начального содержания Markdown для игровой механики. Не все используются на каждой карте. Для удобства печати мне нужно разместить как можно больше карточек на странице формата А4, в данном случае — сетку 3 × 3. В конце концов, страницы должны быть двусторонними, но я этого еще не реализовал.

Введите Pandoc и LaTeX

Любой поиск в Интернете в поисках решений для создания PDF-файлов из Markdown приведет вас к пути Pandoc . Pandoc — это инструмент преобразования разметки ножей Swiss Army с открытым исходным кодом, который поддерживает широкий и постоянно растущий набор форматов разметки ввода и вывода.

Для создания PDF-файлов с помощью Pandoc необходим LaTeX . LaTeX имеет свои корни в научно-исследовательском сообществе и является системой декларирования и оформления документов. Объединение Pandoc и LaTeX позволяет нам использовать переменные и, таким образом, генерировать PDF-файлы из серии файлов Markdown и поддерживать основы Markdown.

Несмотря на мощь Pandoc и LaTeX, я не смог найти способа объединить несколько PDF-файлов (карточек) на одной странице, особенно при использовании переменных из файлов Markdown. После долгих исследований я остановился на PDFJam , простом инструменте командной строки для этого требования.

Установка зависимостей

уценка

Вам не нужно никакого дополнительного программного обеспечения для Markdown, кроме, может быть, редактора, и их так много, я предлагаю вам прочитать несколько сообщений SitePoint, чтобы сделать свой выбор.

Джекил

Я продолжу использовать Jekyll в примерах, взятых из моей игры, чтобы проиллюстрировать процесс сборки, но это не является важной частью создания PDF, если вам не нужен веб-сайт.

Pandoc

На моем Mac я установил Pandoc с Homebrew , но есть варианты для всех операционных систем .

Латекс

Существует множество мнений о том, как лучше всего установить LaTeX, в зависимости от того, что вам нужно или вы собираетесь с ним делать. Полная установка его общих инструментов и библиотек может составить около 2 ГБ, но для большинства целей будет достаточно минимальной установки. Прочитайте страницу загрузки проекта, чтобы найти лучший вариант для вас.

В этом уроке мы будем использовать движок xelatex , так как я использую пользовательские шрифты. Но вы можете выбрать любой движок, который предоставит вам определенные функции.

PDFJam

В зависимости от того, как вы установили LaTeX, у вас может быть уже установлен PDFJam. (Проверьте, набрав, which pdfjam в терминале.) Если у вас его нет, найдите подробности по установке здесь .

Процесс сборки

После некоторых размышлений сценарий bash, который я запускаю локально, пока кажется лучшим вариантом. Существуют лучшие методы, но они работают, и я могу улучшить процесс позже, перенеся его в систему непрерывной интеграции или в Git Hooks.

Посмотрите скрипт bash на GitHub .

Давайте теперь пройдемся по этому сценарию.

Настроить

 bundle install bundle update rm -dfr _site rm -dfr pod 

Эти команды гарантируют, что зависимости Ruby, необходимые Jekyll для создания веб-сайта, являются актуальными, и что мы удаляем все существующие веб-сайты и папки для печати.

Создайте сайт

 jekyll build mkdir -p pod/pdf/cards 

Далее мы создаем сайт и создаем папку для печатных версий карточек.

Создание PDF-файлов из Markdown

Давайте создадим папку, содержащую PDF-версию каждого файла Markdown:

 for filename in _cards/*.md; do echo $filename pandoc --from=markdown+yaml_metadata_block --template _layouts/cards.latex -o pod/pdf/cards/"$(basename "$filename" .md)".pdf --latex-engine=xelatex $filename done 

Сценарий обрабатывает каждый файл Markdown в каталоге _cards , _cards соблюдением полей фронта Markdown. Используя шаблон cards.latex (мы рассмотрим это далее), правильный движок LaTeX выводит PDF-файл с соответствующим именем.

Файл LaTeX

Большая часть волшебства для создания файлов карт из Pandoc происходит в шаблоне LaTeX .

Просмотрите шаблон LaTeX на GitHub .

LaTeX является новым для меня, но это не слишком сложно. Я объясню, что я изменил из файла LaTeX по умолчанию (находится в Pandoc_install_dir/data/templates/default.latex ), чтобы заставить работать карты. Я рекомендую sharelatex.com для предварительного просмотра файлов LaTeX при их редактировании.

 \usepackage[paperheight=9.0cm,paperwidth=5.7cm,margin=0.5cm]{geometry} % Set page size \usepackage{multicol} % We need column layouts \usepackage{amsthm,amsmath,amssymb} \usepackage{graphicx} % We want images in our layout \graphicspath{{/Users/chrisward/Workspace/cs_jk/_site/assets/images/cards/}} % Where are images located \usepackage{float} \usepackage[utf8]{inputenc} \usepackage{fontspec} \setmainfont{VT323} % We want to use a custom font installed on our local system, so add that package and select the font 

Нам нужен определенный размер страницы, и мы будем использовать столбцы позже для определения стоимости и количества карт. Мы используем графику и пользовательские шрифты, поэтому нам нужны эти пакеты .

Мы пытаемся создать простой макет, понятный и беспрепятственный. Вот как мы это сделали:

 \begin{document} \begin{flushright} {$title$} \end{flushright} $if(image)$ \begin{figure}[H] \centering \includegraphics[height=2cm]{$image$} \end{figure} $endif$ \begin{flushleft} \scriptsize{$body$} \end{flushleft} \scriptsize \begin{tabular}{ ll } Costs & Scores \\ $if(staffcost)$ Staff: {$staffcost$} $endif$ & $if(loyaltyscore)$ Loyalty: {$loyaltyscore$} $endif$ \\ $if(rdcost)$ RandD: {$rdcost$} $endif$ & $if(profitscore)$ Profit: {$profitscore$} for {$profitlength$} turns $endif$ \\ $if(marketingcost)$ Marketing: {$marketingcost$} $endif$ & $if(longevityscore)$ Longevity: {$longevityscore$} $endif$ \\ $if(longevitycost)$ Longevity: {$longevitycost$} $endif$ & \\ $if(moneycost)$ Money: {$moneycost$} $endif$ & \end{tabular} \begin{flushleft} $if(specialscore)$ Special: {$specialscore$} $endif$ \end{flushleft} \begin{center} $if(legal)$ \tiny{$legal$} $endif$ \end{center} \end{document} 

Я чувствую, что многое из вышесказанного достаточно понятно для любого, кто использовал код или разметку. Мы создаем элементы карты, выравниваем их, устанавливаем размеры шрифтов и проверяем, есть ли значения перед их выводом, чтобы карта не заканчивалась пустыми полями.

Мы изменяем размеры изображения до определенного размера и центрируем его. Значения затрат и баллов представлены в виде двух столбцов, которые задаются командой begin{tabular} а количество столбцов — числом l s.

Одиночная карта

Объединение карт на одной странице

Мы используем PDFJam для создания большого файла PDF, объединяющего каждую из отдельных карт PDF:

 pdfjam pod/pdf/cards/*.pdf --no-landscape --frame true --nup 3x3 --suffix complete --outfile ./cards.pdf mv cards pod/cards_complete.pdf 

С помощью этой команды мы уточним следующее:

  • что ориентация страницы всегда должна быть портретной
  • что каждый отдельный PDF должен быть оформлен
  • размер сетки
  • суффикс имени файла
  • имя файла

PDFJam может выдавать сообщение об ошибке, если вы не выводите его в рабочий каталог, поэтому я переместил файл туда, где я на самом деле его хочу (надеюсь, это будет решено в будущем). Здесь мы также можем удалить отдельные файлы PDF, если мы не хотим их.

И это все — у нас есть веб-сайт и печатный PDF с карточками игр.

Открытки 9up

Запуск сценария

Я запускаю скрипт сборки с помощью ./build.sh . Поскольку обработка изображений и PDF занимает много времени, это занимает от пяти до десяти минут. Затем у меня есть отдельный скрипт, который развертывает эти папки на веб-сервере.

Что дальше

Этот процесс занял у меня некоторое время, чтобы разобраться в этом, но теперь он достаточно хорош, чтобы двигаться вперед и оттачивать процесс и макеты после игрового тестирования.

Я надеюсь, что вы найдете мои исследования и эксперименты полезными для ваших проектов. Пожалуйста, дайте мне знать, если у вас есть какие-либо комментарии или предложения.