Как оформить исходный код программ в LaTeX без адских страданий

Иногда в документ LaTeX нужно вставить кусок программного кода или псевдокод, поясняющий алгоритм. В зависимости от языка программирования и целей, подсветка кода в LaTeX достигается подключаемыми пакетами расширений разной степени кривизны и безумия документации.

Пост подвергался чистке и правке после публикации:
Автор заходил править этот пост 16 августа 2013 года.


Как просто вставить программный код в LaTeX без боли и страданий?
Именно такой вопрос однажды получил автор этих строк в свой ящик электропочты. Ответ: если хочется quick-and-dirty решения, можно воспользоваться пакетом verbatim, который запрещает LaTeX обрабатывать вставленный код и просто отображает код как есть.  Дёшево и сердито:
\begin{verbatim}
int main(void)
{
int i, j;

for (i=0; i<3; ++i) {
for (j=0; j<3; ++j) printf("%5.1f", m[i*3+j]);
putchar('\n');
}

cblas_dgemv(CblasRowMajor, CblasNoTrans, 3, 3, 1.0, m, 3, x, 1, 0.0, y, 1);


for (i=0; i<3; ++i) printf("%5.1f\n", y[i]);

return 0;
}
\end{verbatim}

Перед вставкой можно сделать так:
cat -n code.c | fold -w 60
Такая комбинация берёт исходный код в файле code.c и расставляет номера строк (ключ -n), перенося длинные строки (ключ -w 60 для ширины в 60 символов). Вот как это будет выглядеть в итоге:


Просто, дёшево, сердито и безболезненно.


Verbatim с оформлением - alltt
Ещё есть пакет под звучным названием alltt, который добавляет окружение alltt - это тот же verbatim, только в нём доступно оформление  цветом, полужирным и т.д. Вот пример:

 А вот для него код:

\documentclass[a4paper,10pt]{article}

\usepackage[T2A]{fontenc}
\usepackage[koi8-r]{inputenc}

\usepackage[usenames,dvipsnames]{color}

\usepackage{alltt}

\begin{document}

\section{C code via alltt}
\begin{alltt}
     \textit{1   int main(void)}
     2  {
     3    int i, j;
     4
     5    for (i=0; i<3; ++i) {
     6      for (j=0; j<3; ++j) printf("%5.1f", m[i*3+j]);
     7      putchar('\\n');
     8    }
     9
    10    cblas_dgemv(CblasRowMajor, CblasNoTrans, 3, 3, 1.0
, m, 3, x, 1, 0.0, y, 1);
    11
    12
    14
    15    return 0;
    16  }
\end{alltt}


\end{document} 
 
Нюанс: в alltt eсть проблема c экранированием специальных символов типа \ и { поскольку alltt начинает воспринимать их как элементы оформления. Документация состоит из двух страниц.



Как оформить псевдокод в LaTeX?
Часто приводить дословно  исходный код программы не требуется, но нужно пояснить общий ход алгоритма псевдокодом. Для оформления псевдокодов и алгоритмов наиболее вменяемый пакет называется algorithm2e доступный отсюда.

Скачиваем стилевой файл algorithm2e.sty и прописываем его в преамбуле документа:
\usepackage[linesnumbered,boxed]{algorithm2e}

Здесь я включил следующие полезные параметры:
  • linesnumbered - включает нумерацию строк в алгоритме.
  • boxed - рисует рамку вокруг алгоритма.
Про остальные параметры можно узнать из отличной документации algorithm2e.pdf в разделе 6 The options of the package.

Вот как выглядит алгоритм, оформленный пакетом algorithm2e::

А вот для него код с комментариями (здесь комментарии, показанные серым цветом - для латеха и они не будут видны в алгоритме,  а комментарии с двойной косой чертой - для показа в алгоритме):

\begin{algorithm}[H]
\SetAlgoLined %% Это соединяет линиями логические части
%% алгоритма типа if-then-else

\KwData{ experiment.data} %% здесь можно указать исходные параметры

\KwResult{ output, xoptimal } %% результат работы программы

x=0;

\While{ $\tau_{norm} > \varepsilon_{tol}$ }{

$s_{k-1} \leftarrow x_k - x_{k-1}$;

// Step lenght computation: %% это комментарий, который будет виден.

\eIf{$k$ is even}{
$ \alpha_k^{ABB} = \frac{ s_{k-1}^T y_{k-1}}{y_{k-1}^T y_{k-1}}$
}{ %% ELSE
$\alpha_k^{ABB} = \frac{ s_{k-1}^T s_{k-1}}{s_{k-1}^T y_{k-1}}$
} %% END \eIf{$k$ is even}{

$k \leftarrow k + 1$;

\For{ i = 1}{
$x_{i+1} = P_\Omega(x_i - \alpha_k^{ABB}*g_k)$;

} %% END \For{ i = 1}{

// Compute the termination constant %% это комментарий, который будет виден.

$\tau_{norm} = abs ( \,\,\, ||x_{k}||_2 - ||x_{k-1}||_2 \,)$

} %% END \While{ $\tau_{norm} > \varepsilon_{tol}$ }{

\caption{Pseudo-code for basic algorithm.}
\label{alg:generalGP}
\end{algorithm}

На алгоритм можно ссылаться, как и на другие объекты в ЛаТеХе -  пакет algorithm2e поддерживает ссылки обычной командой \label{alg:generalGP} и соответственно ссылкой \ref{alg:generalGP}.

Стоит отметить на удивление хорошую документацию: в справочном файле algorithm2e.pdf есть всё, что нужно настоящему джигиту ЛаТеХнику для оформления псевдокодов. Так, нужные параметры приведены в разделе 6, а в разделе 3.2 приведён беспощадный пример, в котором показаны чуть ли не все элементы, которые умеет воспроизводить algorithm2e.


Как вставить код MATLAB в документ LaTeX
Для подсветки синтаксиса и вставки программного кода MATLAB в LaTeX есть специальный пакет расширений под незамысловатым названием mcode. Для использования этого пакета добавляем строчку в преамбулу:
\usepackage[usenames,dvipsnames]{color}
\usepackage[numbered,framed]{mcode}
Обращаю внимание на то, что mcode должно идти после упоминания пакета color. Теперь, у mcode есть несколько параметров, а именно:
  • bw - по умолчанию код будет раскрашен так, как он видится в редакторе MATLAB, с зелёными комментариями. Параметр bw сделает весь код в оттенках серого.
  • numbered - включает нумерацию строк в коде (удобно, если вы обсуждаете в статье детали алгоритма).
  • framed -  рисует вокруг кода рамку.
Дальше всё просто - вставляем  кусок программного кода на MATLAB:
\begin{lstlisting}
% Example Matlab code for calculating hypotenuse
% $c = \sqrt{a^2+b^2}$ §
a = 3;
b = 4;
c = sqrt(a^2+b^2);
\end{lstlisting}
И вот что мы увидим в документе:


На самом деле, всё, что делает mcode, это конфигурирует пакет расширений listings - просто вся черновая работа делается за вас. Вот сейчас начнётся настоящий хардкор, ибо мы переходим к пакету listings...


Оформление исходного кода программ в LaTeX с помощью listings
Самый мощный и кошмарный пакет LaTeX - listings, который может почти всё (кроме заваривания кофе), но самая большая проблема - выяснить, как и что со всем этим делать.  В этом посте я просто приведу пример применения пакета listings и описание его настроек, чтобы самому не пришлось перечитывать кошмарную документацию listings.pdf

Для примера вставим исходный код программы на С в документ LaTeX с помощью listings.
Сразу скажу: всё нижеперечисленное приведено для английского языка, чтобы не огрести проблем ещё и с кириллицей. С языком осин и берёз listings дружит плохо, и кроме того, не переваривается latex2rtf - это важно, когда документ будет конвертироваться в ворд.

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

\documentclass[a4paper,10pt]{article}

\usepackage{color} %% это для отображения цвета в коде
\usepackage{listings} %% собственно, это и есть пакет listings

\usepackage{caption}
\DeclareCaptionFont{white}{\color{white}} %% это сделает текст заголовка белым
%% код ниже нарисует серую рамочку вокруг заголовка кода.
\DeclareCaptionFormat{listing}{\colorbox{gray}{\parbox{\textwidth}{#1#2#3}}}
\captionsetup[lstlisting]{format=listing,labelfont=white,textfont=white}
\begin{document}

Теперь уже внутри документа настраиваем вид оформление исходника   программы на С. Здесь я привёл основные параметры с пояснениями, что они делают:

\lstset{ %
language=C,                 % выбор языка для подсветки (здесь это С)
basicstyle=\small\sffamily, % размер и начертание шрифта для подсветки кода
numbers=left,               % где поставить нумерацию строк (слева\справа)
numberstyle=\tiny,           % размер шрифта для номеров строк
stepnumber=1,                   % размер шага между двумя номерами строк
numbersep=5pt,                % как далеко отстоят номера строк от подсвечиваемого кода
backgroundcolor=\color{white}, % цвет фона подсветки - используем \usepackage{color}
showspaces=false,            % показывать или нет пробелы специальными отступами
showstringspaces=false,      % показывать или нет пробелы в строках
showtabs=false,             % показывать или нет табуляцию в строках
frame=single,              % рисовать рамку вокруг кода
tabsize=2,                 % размер табуляции по умолчанию равен 2 пробелам
captionpos=t,              % позиция заголовка вверху [t] или внизу [b] 
breaklines=true,           % автоматически переносить строки (да\нет)
breakatwhitespace=false, % переносить строки только если есть пробел
escapeinside={\%*}{*)}   % если нужно добавить комментарии в коде
}

Вставляем приведённые выше заклинания в тело документа и после этого куска кода вставляем, собственно, оформление исходника:

\begin{lstlisting}[label=some-code,caption=Some Code]
int main(void) // main routine
{
int i, j; // Initialisation of counters

// The code below prints the 3x3 matrix
for (i=0; i<3; ++i) {
for (j=0; j<3; ++j) printf("%5.1f", m[i*3+j]);
putchar('\n');
}

cblas_dgemv(CblasRowMajor, CblasNoTrans,
3, 3, 1.0, m, 3, x, 1, 0.0, y, 1);

// The code below prints the 3x3 matrix - result of multiplication
for (i=0; i<3; ++i) printf("%5.1f\n", y[i]);

return 0;
}
\end{lstlisting}

Это всё должно скомпилироваться и выдать следующий результат:


Сравнительно красиво, в цвете и с кучей настроек. Остальные 1350 тумблеров, настроек и параметров вы найдёте в документации listings.pdf
Замечание: Оказывается, algortithm2e очень не любит, когда вставляют разрыв строк - ругается, что пропущен параграф:
[LaTeX] digest-optimizationActiveSet.tex => digest-optimizationActiveSet.dvi (latex)
[LaTeX] finished with exit status 1
digest-optimizationActiveSet.tex:0:File ended while scanning use of \algocf@For.
[LaTeX] 1 error, 0 warnings, 0 badboxes

Listings и Хохруссиш... 
не созданы друг для друга. Можно попробовать рецепт в виде:
\lstset{language=Java,inputencoding=utf8x, extendedchars=\true ...
предложенный здесь (в комментариях), но listings не работает нормально с русским текстом, состоящим более, чем из одного слова

Зато listings работает с олдскульной и ортодоксальной koi8-r. Для это вставляем в преамбулу:

\usepackage[T2A]{fontenc}
\usepackage[koi8-r]{inputenc}%включаем свою кодировку: koi8-r или utf8 в UNIX, cp1251 в Windows
\renewcommand{\lstlistingname}{Листинг}

и далее меняем оформление исходника на это:

\begin{lstlisting}[label=some-code,caption={Это крутой исходный код}]
int main(void) // главная программа
{
int i, j; // инициализация счётчиков

// Сей код множит матрицу величиною 3x3
for (i=0; i<3; ++i) {
for (j=0; j<3; ++j) printf("%5.1f", m[i*3+j]);
putchar('\n');
}

// Вызов басурманской библиотеки BLAS
cblas_dgemv(CblasRowMajor, CblasNoTrans,
3, 3, 1.0, m, 3, x, 1, 0.0, y, 1);

// Подаём челобитную на экран
for (i=0; i<3; ++i) printf("%5.1f\n", y[i]);

return 0;
}
\end{lstlisting}

В итоге мы получим кириллизованный фрагмент кода:



Нашедшие рабочий рецепт с listings и комментариями на русском в utf8 приглашаются им поделиться в комментариях.
Итоги дискуссии по оформлению программного кода с русскими комментариями в listings: решение в использовании команд escapechar=  или конвертацией документа в koi8/cp1251. Больше подробностей по этим ссылкам. Спасибо Роману Химову и Alexanius за ценные замечения в комментариях.
Тем не менее, listings, хотя и не идеален, но представляет собой наиболее гибкое решение.


Альтернативы
Есть и другие способы добиться от LaTeX большой и чистой любви раскраски и подсветки исходного кода.

highlight
Среди альтернатив выделяется во всех смыслах программа highlight, которая может быть использована для генерации LaTeX-разметки из исходника. Хорошая новость - у highlight проблем с UTF8 нет. Плохая новость в том, что highlight преобразует код таким образом, что его сложно корректировать вручную.

source-highlight
Другой вариант - использовать программу source-highlight, которая имеется в частности в репозиториях Debian. Установка не отнимет много сил и времени:
apt-get install source-highligh
и далее в командной строке пишем:
source-highlight --input code.c --out-format latexcolor --src-lang=C  --line-number > code.tex
То есть раскрасить исходный код из файла и выдать в теховский файл code.tex для вставки в документ. Выхлоп source-highlight выглядит вот так:

\noindent
\mbox{}\texttt{\textcolor{Black}{01:}} \ \textcolor{ForestGreen}{int}\ \textbf{\textcolor{Black}{main}}\textcolor{BrickRed}{(}\textcolor{ForestGreen}{void}\textcolor{BrickRed}{)} \\
\mbox{}\texttt{\textcolor{Black}{02:}} \textcolor{Red}{\{} \\
\mbox{}\texttt{\textcolor{Black}{03:}} \ \ \textcolor{ForestGreen}{int}\ i\textcolor{BrickRed}{,}\ j\textcolor{BrickRed}{;} \\
\mbox{}\texttt{\textcolor{Black}{04:}} \\
\mbox{}\texttt{\textcolor{Black}{05:}} \ \ \textbf{\textcolor{Blue}{for}}\ \textcolor{BrickRed}{(}i\textcolor{BrickRed}{=}\textcolor{Purple}{0}\textcolor{BrickRed}{;}\ i\textcolor{BrickRed}{\textless{}}\textcolor{Purple}{3}\textcolor{BrickRed}{;}\ \textcolor{BrickRed}{++}i\textcolor{BrickRed}{)}\ \textcolor{Red}{\{} \\
\mbox{}\texttt{\textcolor{Black}{06:}} \ \ \ \ \textbf{\textcolor{Blue}{for}}\ \textcolor{BrickRed}{(}j\textcolor{BrickRed}{=}\textcolor{Purple}{0}\textcolor{BrickRed}{;}\ j\textcolor{BrickRed}{\textless{}}\textcolor{Purple}{3}\textcolor{BrickRed}{;}\ \textcolor{BrickRed}{++}j\textcolor{BrickRed}{)}\ \textbf{\textcolor{Black}{printf}}\textcolor{BrickRed}{(}\texttt{\textcolor{Red}{"{}\%5.1f"{}}}\textcolor{BrickRed}{,}\ m\textcolor{BrickRed}{[}i\textcolor{BrickRed}{*}\textcolor{Purple}{3}\textcolor{BrickRed}{+}j\textcolor{BrickRed}{]);} \\
\mbox{}\texttt{\textcolor{Black}{07:}} \ \ \ \ \textbf{\textcolor{Black}{putchar}}\textcolor{BrickRed}{(}\texttt{\textcolor{Red}{'}}\texttt{\textcolor{CarnationPink}{\textbackslash{}n}}\texttt{\textcolor{Red}{'}}\textcolor{BrickRed}{);} \\
\mbox{}\texttt{\textcolor{Black}{08:}} \ \ \textcolor{Red}{\}} \\
\mbox{}\texttt{\textcolor{Black}{09:}} \\
\mbox{}\texttt{\textcolor{Black}{10:}} \ \ \textbf{\textcolor{Black}{cblas$\_$dgemv}}\textcolor{BrickRed}{(}CblasRowMajor\textcolor{BrickRed}{,}\ CblasNoTrans\textcolor{BrickRed}{,}\ \textcolor{Purple}{3}\textcolor{BrickRed}{,}\ \textcolor{Purple}{3}\textcolor{BrickRed}{,}\ \textcolor{Purple}{1.0}\textcolor{BrickRed}{,}\ m\textcolor{BrickRed}{,}\ \textcolor{Purple}{3}\textcolor{BrickRed}{,}\ x\textcolor{BrickRed}{,}\ \textcolor{Purple}{1}\textcolor{BrickRed}{,}\ \textcolor{Purple}{0.0}\textcolor{BrickRed}{,}\ y\textcolor{BrickRed}{,}\ \textcolor{Purple}{1}\textcolor{BrickRed}{);} \\
\mbox{}\texttt{\textcolor{Black}{11:}} \\
\mbox{}\texttt{\textcolor{Black}{12:}} \\
\mbox{}\texttt{\textcolor{Black}{13:}} \ \ \textbf{\textcolor{Blue}{for}}\ \textcolor{BrickRed}{(}i\textcolor{BrickRed}{=}\textcolor{Purple}{0}\textcolor{BrickRed}{;}\ i\textcolor{BrickRed}{\textless{}}\textcolor{Purple}{3}\textcolor{BrickRed}{;}\ \textcolor{BrickRed}{++}i\textcolor{BrickRed}{)}\ \ \textbf{\textcolor{Black}{printf}}\textcolor{BrickRed}{(}\texttt{\textcolor{Red}{"{}\%5.1f}}\texttt{\textcolor{CarnationPink}{\textbackslash{}n}}\texttt{\textcolor{Red}{"{}}}\textcolor{BrickRed}{,}\ y\textcolor{BrickRed}{[}i\textcolor{BrickRed}{]);} \\
\mbox{}\texttt{\textcolor{Black}{14:}} \\
\mbox{}\texttt{\textcolor{Black}{15:}} \ \ \textbf{\textcolor{Blue}{return}}\ \textcolor{Purple}{0}\textcolor{BrickRed}{;} \\
\mbox{}\texttt{\textcolor{Black}{16:}} \textcolor{Red}{\}}

В общем, запасайтесь дьяволы гробами. Выглядит результат вот так:


Автор source-highlight явно покуривает что-то очень весёлое и бодрящее, на что легко может возбудиться ФСКН :-) Для работы всей этой светомузыки в преамбуле документа должна быть команда:
\usepackage[usenames,dvipsnames]{color}
В целом, это костыль, конечно, но он, скажем так, работает.


Ссылки...
... приведены в посте выше, хотя это не предел человеческой фантазии, и имеют место быть альтернативы:
  • пакет fancyvrb для создания более продвинутого окружения verbatim;
  • пакет minted, основанный на Pygments, тоже может раскрашивать код.
Если уважаемые комментаторы накопают другие методы оформления кода в латех - просьба делиться в комментариях.

32 комментариев: |высказаться!| RSS-лента дискуссии.|
iv_vl комментирует...

В описании mcode, не рисунке красуется заглавие "MATAB Code", так и задумано?
Джигиты используют listings, который не только не поддерживает раскраску некоторых современных языков (виват, JavaScript!), но и с кириллицей почти никак. Тем не менее, приведу свои параметры:
inputencoding=utf8, extendedchars=\true, keepspaces=true

И тут весь такой в белом выходит пакет minted. Устанавливаешь дополнительно Pygments, можно дополнять его расширениями - minted всё подхватит (при компиляции задать -shell-escape). Кроме кириллицы, етить её налево. Вот как раз из благих побуждений подружить minted с кириллицей я и настраивал XeTeX, зато работают они в паре без задоринки - нативная поддержка юникода, это не хухры-мухры. Только тормозит minted, ибо дергает внешнюю прогу на питоне.

Теперь шнапс с тебя, или что вы там пьёте в иноземье ;-)

Иван Шихалев комментирует...

Есть такой хороший пакет alltt, который дает окружение alltt, которое лично я для кода использую вместо verbatim, поскольку в нем можно выделять цветом, жирным и т.д., тогда как переносы строк и пробелы вполне «вербатимные». Лично мне это удобнее, чем то, что автоматом делает listings. И с русским языком никаких проблем.

grazor комментирует...

Для решения проблемы listing с пробелами перенес код в отдельные файлы и преобразовал их в cp1251. При этом нужно в lstset указать кодировку:
inputencoding=cp1251
а код добавлять командой:
\lstinputlisting{main.cpp}


virens комментирует...

@iv_vl комментирует…
В описании mcode, не рисунке красуется заглавие “MATAB Code”, так и задумано?

Ошиблася я :-)

Джигиты используют listings
Да это-то понятно: джигиты они и на С напишут раскраску. Документация у пакета, скажем мягко, писана давно и неправда.

не поддерживает раскраску некоторых современных языков (виват, JavaScript!)
Ху из ит, Дринкинс?! :-) Да разве это язык, чтоб его ещё поддерживать? Там вон маркдаун-то не все поддерживают (Kate не знает), а тут какой-то яваскрипт….

в белом выходит пакет minted. Устанавливаешь дополнительно Pygments
Не хотеть. Не дОлжно требовать сторонних костылей (и на пистоне!) для такой простой вещи. Ты ещё давай предложи календарик генерить в латехе вызовом шел-скрипта с cal -3

Кроме кириллицы, етить её налево
Язык каких-то азиатских варваров - кому он сдался?! Inglish is our everifing :-))

Только тормозит minted, ибо дергает внешнюю прогу на питоне.

внешнюю прогу на питоне.

на питоне.

Ну ты понял, да? :-)


Теперь шнапс с тебя, или что вы там пьёте в иноземье ;-)
А за что шнапс-то? Ты давай выкладывай на своём мегапортале про minted, и как ты всё это делал. С примерами. А то ишь, заскочил, посветил издалека костылями на питоне и уж ему тут шнапс наливай. Реквестирую руководство к действию по Pygment и minted для солдат и беременных женщин :-)


@Иван Шихалев комментирует…
Есть такой хороший пакет alltt, который дает окружение alltt, которое лично я для кода использую вместо verbatim
О, это ценное замечание. Надо бы его в пост воткнуть.

Лично мне это удобнее, чем то, что автоматом делает listings.
Проблема listings в том, что это большая помойка: оно много чего может, но мало кто знает, как от него этого добиться. А кто знает, тот молчит и посылает в маны. А там посылают ещё дальше.

@grazor комментирует…
Для решения проблемы listing с пробелами перенес код в отдельные файлы и преобразовал их в cp1251
Гразор, тебя здесь за это подвергнут анафеме и напустят страшных проклятий. За koi8r ещё простят, но за 1251 - однозначно на кол :-)

Если серьёзнее, то да: с юникодом есть проблемы, часто приходится втыкать кои8, чтобы оно заработало. Хотя мне чаще всего приходится писать на latin1, а там всё работает.

P.S> Норма по троллингу выполнена, к конструктивным дебатам готов :-)

Yaroslav Klyuyev комментирует...

About listings and Russian:
\usepackage{listingsutf8}
\lstset{columns=fixed,language=Python,%
basicstyle=\scriptsize,breaklines=true,inputencoding=utf8/cp1251}
\lstinputlisting{clear.py}

iv_vl комментирует...

@virens комментирует...
> (виват, JavaScript!)
Ху из ит, Дринкинс?! :-) Да разве это язык, чтоб его ещё поддерживать?

Табличка "сарказм" где? Или дебианщики настолько суровы, что отключают JavaScript при входе в Gmail? В listings и Python нету, удачи с ним!

Не дОлжно требовать сторонних костылей (и на пистоне!) для такой простой вещи.
Ты уже нашёл способ подружить TeX'овские варианты с кириллицей и утаиваешь эту волшебную таблетку от нас? Вывод listings для более-менее объемного текста на русском заставлял меня ругаться очень нехорошими словами. Ты книгу Кнута "Всё про TeX" читал? А я читал, и считаю, что на нём писать могут только ну очень большие энтузиасты.

> на питоне.
Ну ты понял, да? :-)

Один раз прогнать так, чтобы научник прибалдел, будет достаточно.

> alltt, которое лично я для кода использую вместо verbatim
О, это ценное замечание. Надо бы его в пост воткнуть.

Михаил, только распиши, что там к чему, а то по листку документации я ничего не понял.

А кто знает, тот молчит и посылает в маны.
Ты не поверишь... но в манах написано всё, что он умеет.

@Yaroslav Klyuyev комментирует...
\usepackage{listingsutf8}
Краткость - сестра таланта. Он еще что-нибудь делает, чем просто переводит из кодировки UTF-8 (в cp1251 в примере)?

virens комментирует...

@Иван Шихалев комментирует...

Есть такой хороший пакет alltt
Посмотрел. В общем, это тот же вербатим, только с возможностью форматирования текста. Иван, вот тут есть проблема: alltt начало жевать мой сишный код, см. скриншот (и в посте тоже). Жуёт \n - в виде переноса строки. Документация две странички. Что делать? (С)


@Yaroslav Klyuyev комментирует...
About listings and Russian

Hmm... Yaroslav, the problem is that \usepackage{listingsutf8} just converts the code from UTF8 to other encoding. This trick does not solve the problem, actually, because the code (and comments) might contain special symbols (and I'm not sure that they will be converted to, say cp1251 properly).

Furthermore, in my case it doesn't work at all. Apparently, I'm not the only one, and the solution there is far from obvious.

Anyway, thanks for sharing.

BTW, your Google+ page consumes enormous bandwidth for some reason.

virens комментирует...

@iv_vl комментирует...
Табличка "сарказм" где?
Еда! :-) Извини, я не мог удержаться.

Вывод listings для более-менее объемного текста на русском
В общем, да это проблема. Я стараюсь не писать код с кириллическими комментариями. Ярослав выше присоветовал listingsutf8, но работает оно, скажем так, не очень. У меня, например, оно с комментариями на русском в питоновском скрипте не заработало.

Михаил, только распиши, что там к чему, а то по листку документации я ничего не понял.
Вы заказали - мы сыграли. Пост обновил. Это просто вербатим с возможностью оформления. На сишном коде оно споткнулось, и я сходу не нашёл, как это заэкранировать.

И да, Йоханес Браамс (автор alltt) там жжот глаголом, аж на целых две страницы:

This package defines the alltt environment, which is like the verbatim environment except that \, {, and } have their usual meanings.

their usual meanings.

Ну мы поняли всё. Как и название пакета, которое хорошо вписывается в опенсорц-стиль, вместе с cdparanoia, brainfuck, qtpfsgui, pornview и gimp.

Ты не поверишь... но в манах написано всё, что он умеет.
Дык, отец, в том и проблема: там всё написано, но этого так много, и оно свалено в такую кучу, что разобраться в этом получается не сразу.

Краткость - сестра таланта.
Человек пришёл и поделился. Не все же гобелены выкладывают, как виренсы, что ты в самом деле.


Да, пост обновил. Добавил alltt, поправил скриншот с mcode, убрал арфаграфицские ашыпки (Minory, где ты, когда ты так нужен?!). Если есть ещё идеи разной степени косяковости - добавляйте в комментарии.

Alex комментирует...

Немного с опозданием , но очень полезно для меня оказалось. Спасибо!
Только вот, наверное, стоит подправить: "Зато listings работает с олдскульной и ортодоксальной koi8-r. Для это вставляем в преам_У_булу:"

iv_vl комментирует...

Михаил, ты используешь моноширинный Computer Modern, у него отсутствует полужирное начертание (21 век на дворе!). Вынужден был искать альтернативный моноширинный шрифт, но тут без XeTeX никуда. Плюс к тому плюшки от UTF-8 в связке с minted, плюс которого в расширяемости, к нему и подсветку Markdown прикрутить - не проблема. Вместе, очень красивое оформление получается. Чтобы не быть обвинённым в троллинге, отмечу, что пока XeTeX в альфа стадии и не заменяет LaTeX.

Valdos the Fat Troll комментирует...

стиль подачи поста оценил :) автору респект

слава богу, мне пока с LaTeX-ом не приходилось сталкиваться…)

virens комментирует...

@Alex комментирует...

Немного с опозданием , но очень полезно для меня оказалось. Спасибо!

Пожалуйста. Пост на самом деле был готов неделю назад, и написан сравнительно быстро (мне тут пришлось для публикации выискивать оформление кода).

Кстати, код, показанный в разделе про algorithm2e - настоящий, это алгоритм для box-constrained quadratic optimization под названием Barzilai-Borwein. Очень быстрый, кстати, и очень простой (потому и быстрый).

Только вот, наверное, стоит подправить
Да, поправил. Спасибо.

@iv_vl комментирует...
Михаил, ты используешь моноширинный Computer Modern
А мне, надо сказать, это индифферентно. Выводит нужное - и хорошо.

Плюс к тому плюшки от UTF-8 в связке с minted, плюс которого
...знаешь только ты :-)

Серьёзно: было бы здорово, если бы ты написал про это небольшую заметку. Мне с minted разбираться не очень нужно (algorithm2e для меня - решает), а ты в этом деле дока. Я бы поставил ссылку на это описание (и добавил в пост, если оно не очень длинное).


@Valdos the Fat Troll комментирует...
стиль подачи поста оценил :)
Валдос, это жЫзнь :-) Куча костылей, и не знаешь, как по-быстрому, без перечитывания томика квантовой физики, сделать то, что нужно. Этот пост - итог моих (и не только) страданий по теме.

слава богу, мне пока с LaTeX-ом не приходилось сталкиваться
Он не так страшен, как ты думаешь. В основном беда из-за расширений, которые налабали нерадивые скубенты и прочая школота (beamerposter, listings, moderncv...). А так оно rock solid. Вон я даже всю систему GTD в нём реализовал.


Пост ещё немного поправлен, убраны очепятки и немного лирики.

alexanius комментирует...

Касательно lstlistings. Мне удалось получить примерно такой результат с utf8. Т.е. единственной проблемой осталась кривая подсветка синтаксиса, но если всё делать одним цветом, то сойдёт. Если в кратце, то добился этого так:

\lstset{tabsize=2,
breaklines,
columns=fullflexible,
flexiblecolumns,
numbers=left,
numberstyle={\footnotesize},
extendedchars=\true
}
\lstdefinelanguage{MyC}{
language=C,
ndkeywordstyle=\color{darkgray}\bfseries,
identifierstyle=\color{black},
morecomment=[n]{/**}{*/},
commentstyle=\color{blue}\ttfamily,
stringstyle=\color{red}\ttfamily,
morestring=[b]",
showstringspaces=false,
morecomment=[l][\color{gray}]{//},
keepspaces=true,
escapechar=\%,
texcl=true
}

Анонимный комментирует...

Вообще через escapechar можно отдавать куски на обработку латеху
например выделить строки курсивом и окружить кавычками:
\lstset{escapechar=",escapebegin={\it ''},escapeend={\it ''}}

единственное но -- это может покривить отображение:
Note: Any escape to LATEX may disturb the column alignment since the package
can't control the spacing there.

Роман комментирует...

Latex, кириллица и listings. Кажется, было здесь:
http://roman.khimov.ru/2011/05/19/latex-listings-cyrillic/

[OpenID чего-то не захотел работать для "подписи"]

alexanius комментирует...

@Роман

Пытался делать таким способом, не получилось. Мои потуги есть здесь если что.

Роман комментирует...

@alexanius: Если проблема именно в цвете, то в моём специфичном случае он не был нужен, поэтому я проблемы с цветом не увидел. Касаемо однобайтности, в стандартном латехе, ЕМНИП, всё равно шрифты выходят однобайтные, поэтому работает при использовании utf8 на входе и шрифтах T2A. Это уже в XeTeX полноценный ввод-вывод юникодный.

virens комментирует...

@alexanius, @Роман

Это очень полезная дискуссия - ссылки я добавил в пост. В своё время пользовался переводом документов в кодироваку koi8r (я и сейчас её кое-где использую). Просто думал, что escapechar это костыль, мало ли, кто решение нашёл...

@Анонимный комментирует...
Вообще через escapechar можно отдавать куски
Анонимус, это вообще-то костыли, к которым хотелось бы не прибегать вообще. Тем не менее, спасибо, что поделился.


@Роман комментирует...
Latex, кириллица и listings.
Странно, я этот пост проморгал, хотя на твой фид подписан.

[OpenID чего-то не захотел работать для "подписи"]
Обычно он работает.


Если ещё что-то найдёте - пишите в комменты, не стеняясь.

iv_vl комментирует...

Итоги дискуссии по оформлению программного кода с русскими комментариями в listings: решение в использовании команд escapechar= или конвертацией документа в koi8/cp1251.

Решение чего? С моими параметрами (см. выше) listings испытывает проблемы с многострочными комментариями, а так - всё работает. Что вы там решаете, да ещё такими жуткими костылями? Хотелось бы экшена, т.е., картинок.

Я посмотрел, оказывается этот alltt - классная штука.
"This package defines the alltt environment, which is like the verbatim environment except that \, {, and } have their usual meanings."
Т.е. позволяет напрямую в коде использовать команды LaTeX, как пример, ты, virens, жалуешься:
Жуёт \n - в виде переноса строки.
Магия LaTeX: замени putchar('\\n') на putchar('\textbackslash{}n').

iv_vl комментирует...

И еще, как ты подписи от руки делал на примере с alltt? Моя хотеть уметь так же.

virens комментирует...

@iv_vl комментирует...

Решение чего? С моими параметрами (см. выше) listings испытывает проблемы с многострочными комментариями
Решение проблемы вставки кириллицы в комментариях кода. Частичное, хотя бы.

Что вы там решаете, да ещё такими жуткими костылями?
Не важно, насколько жуткие костыли - важно, что они помогают решить проблему. Это как КДЕ4: мне плевать, насколько у них там красивая архитектура, но по крайней мере КДЕ4, которое в Сквизи, тупо не работает. [еда]

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

Я посмотрел, оказывается этот alltt - классная штука.
Да, особенно документация там забойная. До утра прям читал :-)

По теме alltt: у автора оного творения не хватило мозгов проверить это даже на Си, где оно не работает вообще. Можно было бы придумать что-то пооригинальнее, и чтобы оно код не жевало.

Магия LaTeX: замени putchar('\\n') на putchar('\textbackslash{}n').
Я как бы в курсе, но вот это и есть жуткий костыль. Не дОлжно править код, оно должно быть as is.

И еще, как ты подписи от руки делал на примере с alltt? Моя хотеть уметь так же.
Патентованный метод, 500 баксов роялти в кассу :-)

На самом деле это сделано в Gimp с помощью стилуса моего ноутбука с тачскрином. Латеховский выхлоп конвертим в PS, открываем Гимп и рисуем. Ручная работа! %-)

iv_vl комментирует...

@virens комментирует...
Решение проблемы вставки кириллицы в комментариях кода.
Михаил, не поверишь, ради тебя проверил твой пример с кириллицей - всё работает! Вот преамбула:

\documentclass[11pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T2A]{fontenc}
\usepackage[english,russian]{babel}
\usepackage{listings}
\lstset{inputencoding=utf8,extendedchars=false,keepspaces=true}
\renewcommand{\lstlistingname}{Листинг}

У вас какие-то специфичные проблемы дебианщиков, чини локаль. УМВР, локаль UTF-8, inputencoding указана та же.

по крайней мере КДЕ4, которое в Сквизи, тупо не работает. [еда]
Увы, нет еды. Gentoo и KDE 4.9.3 просто работают.

МПо теме alltt: у автора оного творения не хватило мозгов проверить это даже на Си, где оно не работает вообще.
С какой стати проверять на Си? Это ведь не пакет для подсветки синтаксиса, не listings, а простой verbatim с плюшками. Поведение пакета alltt предсказуемо, LaTeX код внутри интерпретируется как положено. Всё, большего не надо.

Iskander комментирует...

KDE 4.9.3
...
просто работают
Мда... Надо было дожить до беты ПЯТОЙ версии Qt, чтобы KDE ПРОСТО заработало (впрочем это не может не радовать)!
А по теме, спасибо автору, самому намедни пришлось поколупаться со вставкой кода в LaTeX, моим решением данной проблемы оказался тупой и незатейливый PrintScreen (да-да, начинаем дружно показывать пальцем и ржать в голос), в оправдание таких топорных методов могу сказать лишь, что кусочек кода был небольшим, кусочек времени еще меньше, а почти все остальное было уже готово...

virens комментирует...

@iv_vl комментирует...
Это ведь не пакет для подсветки синтаксиса, не listings, а простой verbatim с плюшками.
ОК, согласен.

iv_vl, реквестирую описание minted в твоём неподражаемом исполнении ("для настоящих мужЫков"). Ты в нём дока, я смотрю - народЪ хочет почитать про это.

[И да, ссылочку на свой мегапортал в readme на гитхабе я бы очень попросил поставить.]

@Iskander комментирует...
Надо было дожить до беты ПЯТОЙ версии Qt, чтобы KDE ПРОСТО заработало
Искандер, вот ты подожди: красноглазые сейчас это всё на планшеты воткнут и с удивлением обнаружат, что приложений (кроме браузера) у них нету, а падающая плазма на планешете - очень даже не смешно. Цирк откроет свои двери :-)

моим решением данной проблемы оказался тупой и незатейливый PrintScreen
Ну, как бы, если оно работает и устраивает - и ладно.

Кстати, я добавил ещё немножко ссылок в конец поста.

iv_vl комментирует...

@virens комментирует...
iv_vl, реквестирую описание minted в твоём неподражаемом исполнении ("для настоящих мужЫков")
Хотелось бы научить minted понимать явное указание кодировки, поскольку по умолчанию Pygments использует latin1, и кириллические комментарии в пролете. Уже появилать возможность указать кодировку в Pygments, но в minted ее не включили. Призываются в комментарии специалисты по TeX'y. Я читал "Все про TeX", поэтому, возможно, управлюсь сам (но времени нужно больше), вот тогда будет описание "для настоящих мужЫков".

iv_vl комментирует...

Воссоздал minted на GitHub, посмотрим, что выйдет.

Анонимный комментирует...

Наиболее неприятное, с чем столкнулся в listings -- адские извращения для моноширинного шрифта. При оформлении любой курсовой листинг должен быть именно такой.

Рома комментирует...

Расскажите, как выделять цветом в пакете altt? И вопрос, есть ли возможность какая-нибудь подружить mcode с русским языком?

Ruslan Kiianchuk комментирует...

Ссылки для algorithm2e пакета ведут на 404.

Что-то неясно с версиями -- в документации написано, что можно изменить caption separator командой
\SetAlgoCaptionSeparator{---}
а сам TeXLive ругается, что undefined sequence :(

virens комментирует...

@Анонимный комментирует...

Наиболее неприятное, с чем столкнулся в listings -- адские извращения для моноширинного шрифта. При оформлении любой курсовой листинг должен быть именно такой.

А разницы, какой шрифт? Главное, чтобы было читабельно. Это как здесь, в Австралии, с диссертациями: 11-12 шрифт любого вменяемого начертания (Таймс\Ариал) и поля по 2 см, а всё остальное - на усмотрение автора. Форма не должна загораживать содержимое.

@Рома комментирует...
Расскажите, как выделять цветом в пакете altt?

Честно - не знаю. Можно попробовать извратиться с textcolor, но я не уверен, что с Verbatim оно будет работать.

И вопрос, есть ли возможность какая-нибудь подружить mcode с русским языком?

I write all my documents in English, therefore, I don't really care...

@Ruslan Kiianchuk комментирует...
Ссылки для algorithm2e пакета ведут на 404.

Оп-па, и точно. Спасибо, что нашли - исправлено.

Что-то неясно с версиями -- в документации написано, что можно изменить caption separator командой
\SetAlgoCaptionSeparator{---}


У меня это

texlive-science - TeX Live: Typesetting for natural and computer sciences

Version: 2009-10

Там оно работает. В других версиях не проверял.

Andrey Akinshin комментирует...

Оказалось, что связка «minted + UTF-8 + русские буквы» делается не совсем очевидно. Для этого нужно добавить немного магии в преамбулу.

Дмитрий Киселёв комментирует...

Очень интересная статья, но мне бы что-нибудь попроще, я с латехом недавно знаком :) Верстаю книжку на околоматематическую тему, и в тексте часто встречаются примеры разных задачек. Хочется их оформить красиво, чтобы в рамочке и в уголке подпись "пример № такой-то", и ещё чтобы всё это не было ограничено одной страницей. Не подскажете, как реализовать такое попроще?

Отправить комментарий

Подписаться на RSS-ленту комментариев к этому посту.