Работу, начатую здесь и здесь, решил оформить в виде плагина vim (страница на гитхабе и страница на www.vim.org). Полная документация доступна по ссылкам, а также внутри плагина. Плагин состоит из двух частей. Первая часть - это собственно скрипт на viml, в котором определены команды MakeHtmlCodeHighlight (переименованная и улучшенная MakeBlogArticle) и MakeTexCodeHighlight (тоже улучшенная по сравнению с первой реализацией). Вторая часть написана на haskell и представляет собой фильтр для pandoc (фильтры доступны в pandoc начиная с версии 1.12), который позволяет подменять исходные блоки кода (CodeBlock) внутри абстрактного синтаксического дерева, представляющего документ, на неформатированные блоки (RawBlock), содержащие подсвеченный с помощью vim код.
Для того, чтобы показать как это работает, возьмем оригинальный пример из руководства пользователя pandoc, в котором приведена классическая реализация быстрой сортировки на haskell, и добавим туда еще пару образцов кода.
### Original example from [*Pandoc User's Guide*](http://johnmacfarlane.net/pandoc/README.html#fenced-code-blocks)
~~~~ {#mycode .haskell .numberLines hl="vim" startFrom="100"}
qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++
qsort (filter (>= x) xs)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Small C++ code sample
~~~~ {.cpp hl="vim"}
G4UIQt * qtSession( dynamic_cast< G4UIQt * >( session ) );
if ( qtSession )
{
qtSession->AddMenu( histoMenuHandle, histoMenuLabel );
BuildMenuTree( qtSession, histoMenuHandle, gDirectory->GetList() );
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Content of my *~/.vimrc.pandoc*
~~~~ {#vimrc_pandoc .vim .numberLines hl="vim"}
syntax on
filetype on
filetype indent on
filetype plugin on
filetype plugin indent on
let g:lucius_style = 'light'
let g:lucius_contrast = 'high'
let g:lucius_contrast_bg = 'high'
set nocp " for line breaks with backslashes
colorscheme lucius
let g:PhCtrlTrans = 0
let g:PhHtmlPreAttrs = 'style="white-space: pre-wrap;"'
runtime plugin/publish_helper.vim
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Это синтаксическая подсветка цветовой схемы lucius для типа файла pandoc, который будет доступен, если вы установите плагин для pandoc отсюда. Я вставил ее сюда из vim дословно с помощью команды MakeHtmlCodeHighlight.
Идем дальше. Сохраняем этот пример в файле example.md и генерируем HTML файл example.html с помощью pandoc и фильтра vimhl из нашего плагина.
pandoc --standalone -t html -F vimhl -o example.html example.md
Получаем файл example.html с таким содержимым:
100 qsort [] = []
101 qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++
102 qsort (filter (>= x) xs)
Small C++ code sample
G4UIQt * qtSession( dynamic_cast< G4UIQt * >( session ) );
if ( qtSession )
{
qtSession->AddMenu( histoMenuHandle, histoMenuLabel );
BuildMenuTree( qtSession, histoMenuHandle, gDirectory->GetList() );
}
Content of my ~/.vimrc.pandoc
1 syntax on
2
3 filetype on
4 filetype indent on
5 filetype plugin on
6 filetype plugin indent on
7
8 let g:lucius_style = 'light'
9 let g:lucius_contrast = 'high'
10 let g:lucius_contrast_bg = 'high'
11
12 set nocp " for line breaks with backslashes
13 colorscheme lucius
14
15 let g:PhCtrlTrans = 0
16 let g:PhHtmlPreAttrs = 'style="white-space: pre-wrap;"'
17
18 runtime plugin/publish_helper.vim
Это цвета схемы lucius с правильной подсветкой синтаксиса всех образцов. А теперь создадим аналогичный PDF документ.
pandoc --standalone -t latex -F vimhl -o example.tex example.md
Открываем файл example.tex и вставляем в преамбулу строки
\usepackage{color}
\usepackage{xcolor}
\usepackage{fancyvrb}
\newcommand{\VerbBar}{|}
\newcommand{\VERB}{\Verb[commandchars=\\\{\}]}
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
\usepackage{framed}
\newenvironment{Shaded}{
\definecolor{shadecolor}{rgb}{1.0, 1.0, 0.9}
\setlength\parskip{0cm}
\setlength\partopsep{-\topsep}
\addtolength\partopsep{0.2cm}
\begin{shaded}
\scriptsize
}{\end{shaded}}
Зачем это нужно, вы можете прочесть в документации к плагину. Завершаем генерацию example.pdf.
latexmk -pdf example
Вот скриншот получившегося документа: