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

LXF87-88:LaTeX

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


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

Содержание

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

LaTeX

Листинги и текст на сайте автора

ЧАСТЬ 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

Языки программирования

Текущая версия пакета 1.3c поддерживает следующие языки (в скобках указаны диалекты): ABAP, ACSL, Ada (83, 95), Algol (60, 68), Ant, Assembler (x86masm), Awk (gnu, POSIX), bash, Basic (Visual), C (ANSI, Handel, Objective, Sharp), C++ (ANSI, GNU, ISO, Visual), Caml (light, Objective), Clean, Cobol (1974, 1985, ibm) Comal 80, csh, Delphi, Eiffel, Elan, erlang, Euphoria, Fortran (77, 90, 95), GCL, Gnuplot, Haskell, HTML, IDL (empty, CORBA), inform, Java (empty, AspectJ), JVMIS, ksh, Lisp (empty, Auto), Logo, make (empty, gnu), Mathematica (1.0, 3.0), Matlab, Mercury, MetaPost, Miranda, Mizar, ML, Modula-2, MuPAD, NASTRAN, Oberon-2, OCL (decorative, OMG), Octave, Oz, Pascal (Borland6, Standard, XSC), Perl, PHP, PL/I, Plasm, POV, Prolog, Promela, Python, R, Reduce, Rexx, RSL, Ruby, S (empty, PLUS), SAS, Scilab, sh, SHELXL, Simula (67, CII, DEC, IBM), SQL, tcl (empty, tk), TeX (AlLaTeX, common, LaTeX, plain, primitive), VBScript, Verilog, VHDL (empty, AMS), VRML (97), XML, XSLT.

Сразу после загрузки пакета рекомендуется «подгрузить» используемые в тексте языки программирования (см. врезку) с помощью макроса \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

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