Готовое решение markdown2pdf с исходным кодом для Linux

habr.png

Предисловие

Markdown это прекрасный способ написать небольшую статью, а иногда и достаточно объемный текст, с несложным форматированием в виде курсива и толстого шрифта. Также Markdown неплох для написания статей с включением исходного кода. Но иногда хочется без потерь, танцев с бубном перегнать его в обычный, хорошо оформленный файл PDF, и чтобы не было проблем при конвертации, какие, например были у меня — нельзя писать по русски в комментариях исходного кода, слишком длинные строки не переносятся, а обрезаются и прочие мелкие проблемы. Инструкция позволит быстро настроить конвертер md2pdf не особенно вникая как это работает. Скрипт для более менее автоматической установки ниже в соотвествующем разделе.

Мой пример TeX шаблона для конвертации использует пакет шрифтов PSCyr, который включает поддержку Microsoft шрифтов, а именно Times New Roman. Такие уж требования к диплому по ГОСТу были. Если умеете, можете модифицировать шаблон под свои нужды. В моей же инструкции придется предварительно поморочится с настройкой PSCyr в TexLive. Настройка производится в дистрибутиве Linux Mint Mate, для других дистрибутивов, возможно, придется погуглить стандартные папки пакета TexLive для вашей системы.


Установка TexLive

Разумеется, можно установить только нужные части данного пакета. Но лично мне было откровенно лень искать минимально необходимую рабочую инсталляцию. Чтобы все точно работало, устанавливаем весь пакет TexLive. Он называется texlive-full и весит чуть больше 2х гигабайт, имейте данный факт в виду. Выполняем команду:

user@hostname:~$ sudo apt install texlive-full -y

После достаточно долгой установки можно переходить к следующему пункту.


Установка конвертера Pandoc

Pandoc — пакет Linux, позволяющий преобразовывать некоторые текстовые форматы в другие. В нем много интересных возможностей, с которыми вы можете ознакомится самостоятельно в интернете. Нас же интересует только возможность преобразование markdown файла в PDF. Проверим установлен ли Pandoc и если нет, то установим его. Например так:

user@hostname:~$ dpkg -s pandoc

Если в выводе написано что не установлен — устанавливаем:

user@hostname:~$ sudo apt install pandoc -y


Установка пакета PSCyr для TexLive

Для начала нужно скачать PSCyr. Пока что еще он доступен по этой ссылке, если на момент прочтения статьи она по каким то причинам не доступна, не отчаивайтесь, его несложно найти вместе с инструкцией по установке, набрав в Гугле что то вроде «Установка PsCyr texlive». Если же доступна, то вам же проще, скачивайте и будем считать, что вы распаковали архив в домашнюю папку и таким образом путь к папке, содержащейся в архиве, выглядит как ~/PSCyr. Тогда заходим в Терминал и последовательно выполняем команды:

user@hostname:~$ cd
user@hostname:~$ mkdir ./PSCyr/fonts/map ./PSCyr/fonts/enc
user@hostname:~$ cp ./PSCyr/dvips/pscyr/*.map ./PSCyr/fonts/map/
user@hostname:~$ cp ./PSCyr/dvips/pscyr/*.enc ./PSCyr/fonts/enc/
user@hostname:~$ echo "fadr6t AdvertisementPSCyr \"T2AEncoding ReEncodeFont\"" > ./PSCyr/fonts/map/pscyr.map

Дальше узнаем, где находится локальный каталог texmf. Выполняем команду:

user@hostname:~$ kpsewhich -expand-var='$TEXMFLOCAL'

Скорее всего этот каталог у вас — /usr/local/share/texmf/, и тогда мы выполняем:

user@hostname:~$ sudo cp -R ./PSCyr/* /usr/local/share/texmf/

Ну или можно не заморачиваться и выполнить команду которая скопирует в папку texmf где бы она не была:

user@hostname:~$ sudo cp -R ./PSCyr/* $(kpsewhich -expand-var='$TEXMFLOCAL')

Шрифты PSCyr установлены, подключаем в TexLive:

user@hostname:~$ sudo texhash
user@hostname:~$ updmap --enable Map=pscyr.map
user@hostname:~$ sudo mktexlsr


LaTeX шаблон для конвертации md2pdf

Я не стану описывать, как именно настроен данный шаблон, и просто приведу его под спойлером без особых пояснений. Достаточно сказать, что настроен он неплохо, по крайней мере то как он обрабатывает тексты с множеством исходного кода. Если вас не устраивают размеры отступов, междустрочные интервалы, отсутствие нумерации разделов и подразделов, то на мой взгляд это достаточно легко нагуглить вопросом в интернете «как в Latex сделать…» и дальше ваша необходимость. Если совсем непонятно, пишите в комментариях, я постараюсь вникнуть в собственные настройки 4хлетней давности в расписать, какая строчка шаблона за что отвечает. Пока же, я распишу как сделал я у себя на ПК, а вы вольны повторить или модифицировать под себя.

Создаем файл template.tex в каталоге /usr/share/texlive/:

user@hostname:~$ sudo touch /usr/share/texlive/template.tex

Задаем ему права на чтение:

user@hostname:~$ sudo chmod 444 /usr/share/texlive/template.tex

открываем под рутом и вставляем в него содержимое спрятанное под спойлером ниже:

user@hostname:~$ sudo nano /usr/share/texlive/template.tex


Содержимое шаблона /usr/share/texlive/template.tex
\documentclass[oneside,final,14pt]{extreport}
\usepackage{extsizes}
\usepackage{pscyr}
\renewcommand{\rmdefault}{ftm}
\usepackage[T2A]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{mathtext}
\usepackage{multirow}
\usepackage{listings}
\usepackage{ucs}
\usepackage{hhline}
\usepackage{tabularx}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{titlesec}
\usepackage{hyperref}
\usepackage{graphicx}
\usepackage{setspace}
\usepackage[center,it,labelsep=period]{caption}
\usepackage[english,russian,ukrainian]{babel}
\usepackage{vmargin}
\newcommand{\specialcell}[2][c]{%
    \begin{tabular}[#1]{@{}c@{}}#2\end{tabular}}
\setpapersize{A4}
\setmarginsrb {1cm}{1cm}{1cm}{1cm}{0pt}{0mm}{0pt}{13mm}
\usepackage{indentfirst}
\setlength\parindent{1cm}
\renewcommand{\baselinestretch}{1}
\renewcommand\thechapter{}
\renewcommand\thesection{}
\renewcommand\thesubsection{}
\renewcommand\thesubsubsection{}
\titleformat
{\chapter} % command
{\bfseries\normalsize\centering} % format
{\thechapter} % label
{0.5ex} % sep
{
    \centering
}
[
\vspace{-1.5ex}
] % after-code
\titleformat
{\section}
[block]
{\normalfont\bfseries}
{\thesection}{0.5em}{}
\sloppy
\let\oldenumerate\enumerate
\renewcommand{\enumerate}{
  \oldenumerate
  \setlength{\itemsep}{1pt}
  \setlength{\parskip}{0pt}
  \setlength{\parsep}{0pt}
}
\let\olditemize\itemize
\renewcommand{\itemize}{
  \olditemize
  \setlength{\itemsep}{1pt}
  \setlength{\parskip}{0pt}
  \setlength{\parsep}{0pt}
}
\providecommand{\tightlist}{%
  \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}

\titlespacing{\subsubsection}{\parindent}{3mm}{3mm}
\titlespacing{\subsection}{\parindent}{3mm}{3mm}
\usepackage{color}

\lstset{
    basicstyle=\footnotesize\ttfamily,
    inputencoding=utf8,
    extendedchars=\true,
    showspaces=false,
    keepspaces=true
    showstringspaces=false,
    showtabs=false,
    tabsize=4,
    captionpos=b,
    breaklines=true,
    breakatwhitespace=true,
    breakautoindent=true,
    linewidth=\textwidth
}

\begin{document}
$if(title)$
\maketitle
$endif$
$if(abstract)$
\begin{abstract}
$abstract$
\end{abstract}
$endif$

$for(include-before)$
$include-before$

$endfor$
$if(toc)$
{
$if(colorlinks)$
\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$black$endif$}
$endif$
\setcounter{tocdepth}{$toc-depth$}
\tableofcontents
}
$endif$
$if(lot)$
\listoftables
$endif$
$if(lof)$
\listoffigures
$endif$
$body$

$if(natbib)$
$if(bibliography)$
$if(biblio-title)$
$if(book-class)$
\renewcommand\bibname{$biblio-title$}
$else$
\renewcommand\refname{$biblio-title$}
$endif$
$endif$
\bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$}

$endif$
$endif$
$if(biblatex)$
\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$

$endif$
$for(include-after)$
$include-after$

$endfor$
\end{document}

Сохраняем файл /usr/share/texlive/template.tex и пишем скрипт который будет конвертировать Makrdown файл в PDF, создавая в той же папке файл с названием Markdown файла с приставкой .pdf, то есть после конвертации filename.md в папке появится filename.md.pdf. Скрипт назовем md2pdf и положим по пути /usr/bin. Выполним последовательно команды:

user@hostname:~$ cd
user@hostname:~$ touch md2pdf
user@hostname:~$ echo "#!/bin/bash" > md2pdf
user@hostname:~$ echo "pandoc --output=$1.pdf --from=markdown_github --latex-engine=pdflatex --listings --template=/usr/share/texlive/template.tex $1" >> md2pdf
user@hostname:~$ sudo cp md2pdf /usr/bin/
user@hostname:~$ sudo chmod 111 /usr/bin/md2pdf

В 4й строке собственно указана команда конвертации. Обратите внимание на --from=markdown_github. GitHub версия Markdown обратно совместима с оригинальным Markdown, так что если ваш текст написан на нем, то можно не переживать. Если же ваш MD файл написан на специфическом диалекте Markdown, то то почитайте мануал по Pandoc (man pandoc), удостоверьтесь, что ваша реализация им поддерживается, и подправьте /usr/bin/md2pdf при необходимости.


Скрипт для более менее автоматической установки

Если вам не слишком хочется что то настраивать вообще, и у вас Ubuntu-подобный дистрибутив, можете попробовать создать скрипт с содержимым, спрятанным под спойлером, и скорей всего все установится само, единственно, TeX-шаблон, выложенный под спойлером выше, скопируете куда надо сами. Откройте Терминал и выполните:

user@hostname:~$ cd
user@hostname:~$ touch installmd2pdf.sh

Дальше заполните его таким содержимым:


Содержимое скрипта $HOME/installmd2pdf.sh
#!/bin/bash
cd /tmp
sudo apt install texlive-full pandoc -y
wget http://blog.harrix.org/wp-content/uploads/2013/02/PSCyr.zip
unzip -qq PSCyr.zip
cd
mkdir ./PSCyr/fonts/map ./PSCyr/fonts/enc
cp ./PSCyr/dvips/pscyr/*.map ./PSCyr/fonts/map/
cp ./PSCyr/dvips/pscyr/*.enc ./PSCyr/fonts/enc/
echo "fadr6t AdvertisementPSCyr \"T2AEncoding ReEncodeFont\"" > ./PSCyr/fonts/map/pscyr.map
sudo cp -R ./PSCyr/* $(kpsewhich -expand-var='$TEXMFLOCAL')
sudo texhash
updmap --enable Map=pscyr.map
sudo mktexlsr
sudo touch /usr/share/texlive/template.tex
touch md2pdf
echo "#!/bin/bash" > md2pdf
echo "pandoc --output=$1.pdf --from=markdown_github --latex-engine=pdflatex --listings --template=/usr/share/texlive/template.tex $1" >> md2pdf
sudo cp md2pdf /usr/bin/
sudo chmod 111 /usr/bin/md2pdf

Запустите его с помощью команды:

user@hostname:~$ sudo bash $HOME/installmd2pdf.sh

Не забывайте, что /usr/share/texlive/template.tex нужно заполнить указанным в разделе »LaTeX шаблон для конвертации md2pdf» содержимым.


Использование md2pdf

Просто откройте папку с Markdown файлом (some_file.md) в Терминале, и выполните команду:

user@hostname:~$ md2pdf some_file.md

В результате в папке появится файл some_file.md.pdf.


Заключение

На базе описанного метода можно построить какой угодно стиль PDF файлов, также можно конвертировать вместо md другие форматы, любые поддерживаемые Pandoc. Смею надеятся что однажды это инструкция пригодится 3 с половиной людям.

© Habrahabr.ru