Журнал LinuxFormat - перейти на главную

LXF87-88:LaTeX

Материал из Linuxformat
Перейти к: навигация, поиск


Компьютерные TeXнологии Учимся использовать культовую систему вёрстки

Содержание

Документация и программный код

ЧАСТЬ 4: TeX, как известно, был создан для представления кода и алгоритмов. Так постигайте же замысел создателя и его последователей вместе с Евгением Балдиным!
+++ Ошибка Деления На Огурец.
Переустановите Вселенную И Перезагрузитесь +++
Так зависает Гекс.
Источник: «Санта-Хрякус» от Терри Пратчетта

Программирование под Linux – вполне естественное занятие. Написание документации – неотъемлемая часть этого процесса. LaTeX достоин быть включённым в технологическую цепочку по выпуску программного продукта.

Если вспомнить историю, то Д.Э. Кнут создал TeX именно для целей представления кода и алгоритмов в своём глобальном пятитомнике «Искусство программирования».

Спецсредства

Чтобы украсить инструкцию, надо добавлять в неё «пятна». Злоупотреблять этим не стоит, но пару мыслей выделить вполне реально. Упомянутые ниже приёмы – далеко не всё, что может предложить LaTeX: это просто демонстрация возможностей.

keystroke

Иногда в тексте необходимы фразы вида: «Для выхода из программы нужно нажать клавишу Esc.» Макрос \keystroke, определённый в одноимённом пакете keystroke, позволяет выделить название клавиши, примерно следующим образом:

LXF88_latex01.png

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

Клавиши, определенные в keystroke

LCD-дисплей

LCD-дисплеи сейчас встроены даже в кофемолки. Они легко узнаваемы, поэтому нет необходимости копировать их вид в документацию с помощью фотографий – достаточно нарисовать что-то похожее. Изобразить вид дисплея можно с помощью пакета lcd.

LXF88_latex03.png

Для определения цветов используется макрос \definecolor из пакета color. Команда \LCDcolors формирует цвет букв и фона, а макрос \textLCD выводит LCD-подобный текст на экран. \textLCD понимает стандартные команды изменения размера шрифта, поэтому его можно использовать совместно с обычным текстом внутри абзаца.

По умолчанию определены только латинские буквы, цифры и некоторые из стандартных символов. Для определения других символов можно воспользоваться макросом \DefineLCDchar. Макросу передаётся имя символа и битовая маска, определяющая картинку 5x7 точек. Имя символа может быть однобуквенным, тогда соответствующая буква замещается новым рисунком, или многобуквенным, тогда созданный рисунок кодируется указанным словом в фигурных скобках. Другие размеры матрицы в пакете отсутствуют, но при желании его вполне можно доработать.

Определяем Ё для LCD

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

LXF88_latex05.png

Битовые поля

Для описания сетевых протоколов, а так же для бинарных форматов данных удобнее всего представить последовательность битов графически, то есть в виде таблицы. Это специализация пакета bytefield. В пакете определено одноимённое окружение bytefield, в качестве обязательного аргумента которому передаётся ширина таблицы в битах:

 \begin{bytefield}{«битовая ширина поля»}
   «битовые поля»
 \end{bytefield}

В окружении bytefield работают команды \wordbox и \bitbox, которые формируют поля, занимающие всю ширину таблицы или только часть её, соответственно:

 \wordbox[«рамка»]{«число строк»}{«текст»}
 \bitbox[«рамка»]{«число занимаемых битов»}{«текст»}

Необязательный параметр «рамка» позволяет сформировать обрамление для текущего битового поля. Значение по умолчанию [lrtb] означает, что рамка рисуется со всех сторон поля: l – слева, r – справа, t – сверху и b – снизу. Строки разделяются двойной обратной чертой \\.

Формат пакета сетевого протокола UDP можно описать примерно следующим образом:

 \begin{bytefield}{32}
 \bitheader{0,15,16,31}\\
 \wordgroupr{Заголовок}
 \bitbox{16}{Порт отправителя}\bitbox{16}{Порт получателя}\\
 \bitbox{16}{Размер}\bitbox{16}{Контрольная сумма}
 \endwordgroupr\\
 \wordbox[lrt]{1}{Данные}\\
 \skippedwords\\
 \wordbox[lrb]{1}{до 65{.}527 байт}
 \end{bytefield}

Формат пакета UDP

Кроме уже упомянутых команд создания полей при описании формата UDP использовалась команда нумерации столбцов \bitheader, конструкция для создания группы \wordgroupr и макрос \skippedwords для формирования «разрыва».

В качестве обязательного аргумента команде \bitheader передаётся список нумеруемых битов, при этом можно передавать диапазоны чисел, например, {0-31}. В пакете определены два окружения для группировки битовых полей, \wordgroupr и \wordgroupl – отличие этих команд в том, что для первой заголовок группы вводится справа, а для второй – слева. Для более подробной информации следует обратиться к документации пакета.

Форматирование кода

LaTeX может использоваться не только для набора математики. Хотя набор математики, безусловно, вершина типографского искусства, существует масса задач со сравнимой сложностью форматирования. Представление исходных текстов программ – это весьма непростое занятие, особенно если хочется сделать код читаемым.

verbatim

Самый простой способ включить код в текст – это заключить его в стандартное окружение verbatim, которое просто выводит данный текст на печать с отступами пользователя. При этом исчезает возможность делать акценты в избранных местах.

Небольшие вставки можно делать с помощью команды \verb!текст!. Сразу после \verb должен идти группирующий символ (в данном случае, «!»), который указывает окончание действия команды. Группирующий символ может быть любым, кроме пробела или звёздочки «*».

Пакет verbatim из коллекции tools переопределяет стандартную команду так, что внутри окружения можно вставлять тексты неограниченного размера. Кроме этого, пакет предоставляет команду \verbatiminput, которой в качестве основного аргумента можно передать имя внешнего файла.

Кроме упомянутых окружения и макросов определены такие же, но со звёздочкой в конце имени, то есть окружение verbatim* и команды \verb* и \verbatiminput*. *-форма отличается от базовой тем, что все пробелы визуализируются.

LXF88_latex07.png

Стандартный пакет alltt – это почти то же самое, что и verbatim, но с возможностью использовать внутри окружения команды LaTeX. Правда, шрифт в любом случае остаётся фиксированной ширины, как для печатной машинки.

LXF88_latex08.png

Гораздо более разнообразные средства управления выводом неформатированного текста предоставляет пакет fancyvrb. За подробной информацией следует обратиться к документации пакета.

listings

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

Для загрузки пакета listings необходимо добавить в заголовок следующие инструкции:

LXF88_latex09.png


Сразу после загрузки пакета рекомендуется «подгрузить» используемые в тексте языки программирования (см. врезку) с помощью макроса \lstloadlanguages. В квадратных скобочках перед названием языка можно указать желательный диалект.

Команда \lstset позволяет устанавливать значения по умолчанию. Некоторые из полезных умолчаний перечислены ниже:

  • Для того, чтобы можно было печатать кириллицу, например в комментариях, следует определить переменную extendedchars=true (Если это не сработает, то необходимо обновить пакет до последней версии или сменить дистрибутив LaTeX на более подходящий).
  • Опция escapechar позволяет при наборе кода пользоваться услугами LaTeX напрямую. Всё, что находится между выбранными символами, обрабатывается средствами LaTeX. Естественно, если выбранный символ (в данном случае «|») используется в отображаемом языке, то могут возникнуть проблемы при компиляции. Для того, чтобы обнулить escapechar, достаточно ничего не писать за знаком равно при следующем переопределении.
  • Инструкция frame=<POSITION> позволяет рисовать рамку вокруг сегмента кода. На вход принимаются буквы t – обрамление сверху, b – снизу, l и r – слева и справа, соответственно. В случае frame=trbl будет

нарисована простейшая одинарная рамка. Опция frame= эквивалентна отказу от обрамления. Если вместо прописных букв указать заглавные frame=TRBL, то рамка будет двойная. В пакете есть возможность сделать рамки посложнее.

Все команды, определённые в пакете listings, начинаются с префикса lst. Команда для включения небольших кусочков кода \lstinline!код! аналогична по действию команде \verb!текст!.

Сегмент кода оформляется с помощью окружения lstlisting:

LXF88_latex10.png

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

Файлы можно включать с помощью команды \lstinputlisting:

%установка значений по умолчанию
 \lstset{numbers=left, language=MetaPost,
       backgroundcolor=\color{yellow},
       frame=shadowbox, rulesepcolor=\color{black}}
%вставка файла
 \lstinputlisting[firstline=16, lastline=24,
   emph={forsuffixes,text,bpath},emphstyle={\color{red}},
   emph={[2]fill,unfill},emphstyle={[2]\bfseries\underbar},
 ]{intro.mp}

LXF88_latex11.png

С помощью опций firstline и secondline можно указать диапазон строк, который следует вывести. В зависимости от выбора языка форматирование существенно меняется. Инструкция numbers=left нумерует строки слева.

Для работы с цветами лучше загрузить уже упоминавшийся ранее пакет color. Цвета хороши для выделения каких-то ключевых слов и подложки, за которую отвечает опция backgroundcolor. Возможности для определения своих «словариков» предоставляет опции emph=<список ключевых слов>. В начале списка может идти его метка в квадратных скобках, таким образом, можно поддерживать несколько списков одновременно. С помощью опции emphstyle можно определить способ выделения ключевых слов.

Обычно код располагается прямо по месту основного текста, так как обсуждение «исходников» можно производить в самом коде, благо есть комментарии. При желании можно воспользоваться опцией float, чтобы из фрагмента кода получился полноценный «плавающий» объект.

Пакет поддерживает свыше сотни распространённых языков программирования и разметки (с учётом диалектов), так что вам, скорее всего, не придётся определять свой язык с помощью инструкции \lstdefinelanguage. Но если очень хочется, то и это возможно.

Представление алгоритмов

Собственно говоря, это именно то, ради чего Д.Э. Кнут и создал TeX. Поэтому пакеты для облегчения записи алгоритмов в LaTeX существовали с самого его рождения. На текущий момент, даже число стандартных пакетов, подпадающих под эту тематику, больше десятка. Здесь рассмотрена только малая часть из них.

algorithm

Пакет algorithm ориентирован на описание алгоритмов, а не на представление кода. Это позволяет отрешиться от форматирования и сосредоточиться на основной задаче. Пакет определяет окружение algorithmic. Для использования в преамбуле следует загрузить одноимённый стиль.

Пример использования пакета algorithm

Если необязательный аргумент определён, то осуществляется нумерация строк. Если аргумент равен 1, то нумеруются все строки, если 2 – то каждая вторая, а далее по индукции.

Команда \STATE определяет простое утверждение. Условный оператор представлен командами \IF{<условие>}, \ELSIF{<условие>}, \ELSE и \ENDIF. Циклы представлены операторами \FOR и \FORALL, которые закрываются командой \ENDFOR. Аналогично присутствуют пары \WHILE{<условие>}\ENDWHILE, \REPEAT\UNTILL{<условие>} и бесконечный цикл \LOOP\ENDLOOP. Кроме уже перечисленных конструкций определены предварительное условие для корректного выполнение алгоритма \REQUIRE, постусловие, которое должно выполняться при корректной работе алгоритма, \ENSURE, возвращение результата \RETURN, промежуточная печать \PRINT и комментарий \COMMENT.

Собственно говоря, всё. Псевдокод автоматически разбивается на строки и форматируется в соответствии с общепринятыми представлениями. Очевидно также, что навыки набора математики будут здесь очень кстати. Подробности по настройке пакета следует выяснять в документации к нему: algorithms.pdf.

Для того, чтобы сделать из объекта algorithmic «плавающий объект» можно воспользоваться окружением algorithm, для его использования следует загрузить одноимённый стиль в преамбуле. Внутри algorithm можно использовать команды \caption и \label.

Клоны algorithms

С использованием имеющихся наработок пакета algorithms был создан algorithmicx. Этот пакет предоставляет более расширенный набор команд. Кроме того, пользователю предоставляются команды, с помощью которых можно формировать свои алгоритмические конструкции.

Автор также предоставил вариант форматирования отступов, принятый в Pascal, что позволяет относительно легко приводить программы на этом языке к виду, годному для красивой распечатки. Пакет работает с теми же окружениями, что используюся в пакете algorithms. Это приводит к их несовместимости.

Решение схожей функциональности предоставляет пакет algorithm2e. Форматирование C-подобно. Предоставлен избыточный набор конструкций и возможность самому создавать новые структуры. Есть зачатки локализации. Пакет использует окружение algorithm, Это приводит к несовместимости как с пакетом algorithms, так и с пакетом algorithimcx.

clrscode

Пакет clrscode представляет возможность набирать псевдокод, как это делали авторы книги «Алгоритмы: построение и анализ» Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест и Клиффорд Штайн (Introduction to algorithms, Second Edition. Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein.). Для работы с пакетом необходимо загрузить одноимённый стиль. Это прекрасный пример того, как можно адаптировать LaTeX для создания книг по программированию.

Пример использования пакета clrscode.

pseudocode

Профессора Дональд Л. Крехер [Donald L. Kreher] и Дуглас Р. Стинсон [Douglas R. Stinson] написали книгу «Combinatorial Algorithms: Generation, Enumeration and Search». Специально для представления псевдокода в этой книге они создали пакет, который так и назвали: pseudocode. Дональд Л. Крехер использовал одноимённое окружение и в своей следующей книге по алгоритмам, выпущенной уже в 2005 году. Пакет поддерживается до сих пор.

Пример использования пакета pseudocode.

К сожалению, в книгах по LaTeX редко рассматриваются структуры, полезные для представления программных текстов или псевдокода. Здесь я попытался восполнить этот зияющий пробел. Тема настолько обширна, что разрабатывать её можно почти бесконечно. LaTeX сам по себе код, поэтому программистам, по идее, должно быть уютно в его окружении. LXF

LaTeX и контроль версий

Исходный текст LaTeX тоже представляет собой код. И как всякий код, он достоин жить в системе контроля версий. Часто бывает любопытно узнать текущую версию документа и время его последнего обновления. Если в качестве системы контроля версий используется Subversion, то для начала следует загрузить пакет svn.

\usepackage{svn}
\SVN $Date$
\SVN $Rev$

При этом в текст следует добавить метки, предваряемые командой \SVN. Для интерполяции меток в системе Subversion при обновлении файла следует выполнить команды вида:

> svn propset svn:keywords “Date Rev” «имя файла»
> svn commit -m “интерполяция меток”

При этом svn передаётся информация о том, какие именно метки требуется обновлять при выполнении commit. В данном случае, это метки Date и Rev — дата и номер ревизии, соответственно. Более подробную информацию можно получить с помощью команды

> svn help propset

Команда \SVN $Date$ определяет команды \SVNDate и \SVNTime, ответственные за календарную дату и время. Все остальные команды вида \SVN $Keyword$, где Keyword — одна из интерполируемых меток svn, определяют команды \SVNKeyword.

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

Схожую функциональность предоставляет пакет svninfo.

LXF88_latex15.png

Персональные инструменты
купить
подписаться
Яндекс.Метрика