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

LXF94:LaTeX

Материал из Linuxformat
(Различия между версиями)
Перейти к: навигация, поиск
(Счётчики и другие переменные)
(Создаём свой пакет)
Строка 155: Строка 155:
  
 
=== Создаём свой пакет ===
 
=== Создаём свой пакет ===
 +
 +
Предположим, что вы уже владеете искусством программирования в среде LaTeX. Чтобы распространить свои наработки, следует организовать исходные тексты в удобном для дальнейшей поддержки, передаче и установке виде. Можно и не стараться, если вас не интересует конечный результат, но знать, как правильно устроен пакет, полезно и новичку, так как эффективное обучение программированию напрямую связано с изучением уже существующего кода.
 +
 +
В LaTeX-сообществе принято распространять свои пакеты и документацию к ним в виде автономных файлов с расширением dtx (DTX-файлы). Для автоматической установки пакетов используются инструкции, записанные в файлах с расширением ins (INS-файлы). Для более подробной информации следует обратиться к инструкции «How to Package Your LaTeX Package», созданной Скотом Пакиным [Scott Pakin]. Файл dtxtut.pdf, как обычно, можно найти в стандартной поставке LaTeX или на CTAN. Вместе с документацией идут файлы примеров [c]skeleton.dtx и [c]skeleton.ins.
 +
 +
За работу с DTX-файлами отвечает пакет doc и сопутствующая ему утилита DOCSTRIP (файл docstrip.pdf). Основная идея пакета doc состоит в совмещении кода с документацией, что облегчает поддержку и развитие пакета.
  
 
==== Установочный INS-файл ====
 
==== Установочный INS-файл ====
 +
 +
Для извлечения кода и документации из DTX-пакета следует написать специальный установочный файл. Набор инструкций достаточно
 +
стереотипен:
 +
 +
%% Стандартный копирайт по выбору (рекомендуется LPPL/GPL)
 +
%%
 +
%% Первый шаг - загрузка DOCSTRIP.
 +
\input docstrip.tex
 +
%% Подробный отчёт о каждом шаге хорош только когда пакет
 +
%% отлаживается.
 +
\keepsilent
 +
%% Директория, в которую устанавливается пакет. Имя
 +
%% директории является относительным по отношению к
 +
%% базовой директории $(TEXMF).
 +
\usedir{tex/latex/{«имя пакета»}}
 +
%% Определение преамбулы, которая вставляется во все
 +
%% сгенерированные файлы. Обычно это информация об авторе
 +
%% и пожелания пользователям.
 +
\preamble
 +
  Текст преамбулы
 +
\endpreamble
 +
%% Извлечение файлов пакета из dtx. Основной шаг,
 +
%% который может повторяться несколько раз.
 +
\generate{\file{«извлекаемый файл»}{\from{«dtx-файл»}{метка}}}
 +
 +
 +
%% Информация для пользователя. Всегда что-то полезно сказать
 +
%% после установки.
 +
\obeyspaces
 +
\Msg{******************************************************
 +
**}
 +
\Msg{* Здорово, что Вы поставили этот пакет. *}
 +
\Msg{* Прочитайте документацию перед использованием! *}
 +
\Msg{******************************************************
 +
**}
 +
%% Метка конца установочного файла.
 +
\endbatchfile
  
 
==== Пакетный DTX-файл ====
 
==== Пакетный DTX-файл ====

Версия 19:04, 16 марта 2008

Содержание

Начала программирования

ЧАСТЬ 11 Завершая этот длинный цикл статей, Евгений Балдин посмотрит на LaTeX глазами профессионального программиста.

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

Создаём свои …

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

\newcommand{\ee}{\ensuremath{e^{+}e^{-}}\xspace}

Новые команды часто создаются для комбинаций, используемых исключительно в математическом окружении. Команда \ensuremath обеспечивает это окружение независимо от текущего режима:

(thumbnail)
Рис. 1.
\(J/\psi\to\ee\) является одним из подвидов \ee-рассеяния.

Команда \xspace из одноимённого пакета добавляет в конце команды пробел в случае, если за ней не следует знаков препинания, то есть избавляет от необходимости самому вставлять явный пробел после команды.

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

\newcommand{«команда»}[N][«зн. по ум.»]{«определение»}
\renewcommand{«команда»}[N][«зн. по ум.»]{«определение»}
\providecommand{«команда»}[N][«зн. по ум.»]{«определение»}

\newcommand определяет новую команду. Если такая команда уже существует, то при компиляции генерируется ошибка. \renewcommand переопределяет уже существующую команду. В свою очередь, \providecommand создаёт новую команду, если на момент описания такой команды не было, и ничего не делает в противном случае.

В каждом из этих макросов есть два обязательных параметра: это имя команды и её описание. Если команде необходимо передать параметр/параметры, то первый необязательный аргумент (N) должен принять значение от одного (1) до девяти (9). В LXF85 (см. прилагаемый диск) обсуждался макрос для дублирования знака в формуле при переносе её на следующую строку (\(a+b\hm{=}c\)):

\newcommand*{\hm}[1]{#1\nobreak\discretionary{}%
 {\hbox{$\mathsurround=0pt #1$}}{}}

Вместо знака решётки (#) с цифрой после него при компиляции макроса подставляется соответствующий параметр. В данном случае параметр был только один, и можно сказать, что его значение сохраняется в «переменной» #1.

Звёздочка (*) в конце макроса \newcommand налагает на передаваемый параметр команды \hm дополнительное условие: в нем не должно быть пустых строк и команды \par. В некоторых случаях это упрощает отладку кода.

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

(thumbnail)
Рис. 2.
\newcommand{\exmpl}[1][умолчанию]%
           {<<значение по #1>>}
Сравните \exmpl{} и \exmpl[требованию].

Для определения нового окружения используется команда \newenvironment, например:

(thumbnail)
Рис. 3.
\newenvironment{outlined}{\hrule\begin{center}}%
                 {\end{center}\smallskip\hrule}
\begin{outlined}
  Выделенный текст.
\end{outlined}

Формальное описание этой команды похоже на описание \newcommand:

\newenvironment{«окружение»}[N][«зн. по ум.»]%
                {«код, открывающий окружение»}%
                {«код, закрывающий окружение»}

Точно так же, как и в случае \newcommand, созданному окружению можно передавать параметры. Подставлять параметры можно только в коде, открывающем окружение. Кроме создания нового окружения, можно также переопределять уже имеющиеся с помощью аналогичной команды \renewenvironment.

В разделе, посвящённом описанию презентационного класса beamer (LXF85), упоминалось ещё об одной возможности создавать новые именованные окружения с помощью команды \newtheorem:

(thumbnail)
Рис. 4.
\newtheorem{Texmpl}{Пример}
\begin{Texmpl}[Теорема Пифагора]\label{th:1}
  Пифагоровы штаны во все стороны равны.
\end{Texmpl}
\begin{Texmpl}\label{th:2}
  Мудрость ограничена, а глупость бесконечна.
\end{Texmpl}
Можем сослаться первую теорему:~\ref{th:1},
а можно и на вторую:~\ref{th:2}

Команда \newtheorem имеет две формы:

\newtheorem{«теорема»}[«существующая теорема»]{«заголовок»}
\newtheorem{«теорема»}{«заголовок»}[«имя счётчика»]

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

Счётчики и другие переменные

«Другие переменные» уже обсуждались в разделе Определённые «размеры» и переменные «длины» (LXF89). Операции с этими переменными выполнялись с помощью команд \newlength, \setlength и \addtolength. Аналогично, в LaTeX представлена и целочисленная арифметика с использованием счётчиков в качестве переменных:

(thumbnail)
Рис. 5.
\newcounter{MyCount}\setcounter{MyCount}{5}
Значение MyCount равно \arabic{MyCount},
или~\alph{MyCount}, или \Asbuk{MyCount}.\par
\addtocounter{MyCount}{1550}
\arabic{MyCount} эквивалентно \Roman{MyCount}.

Новый счётчик создаётся с помощью команды \newcounter. При создании он инициализируется нулём. Создание счётчика является глобальной операцией, то есть при компиляции информация о нём не исчезнет, даже если новый счётчик был определён внутри окружения. Для присвоения счётчику другого значения используется команда \setnewcounter, а для изменения на какое-то определённое число – \addtocounter.

В отличие от длин, основная роль которых – помнить размеры определённого бокса, счётчики используются для отображения какой-либо структурной информации. Поэтому особое внимание уделяется представлению значения счётчика в тексте. Чтобы просто отобразить численное значение счётчика с помощью арабских цифр, используется команда \arabic{счётчик}. Для римской числовой нотации необходимо воспользоваться командой \Roman и \roman – заглавные и строчные буквы соответственно. Счётчик может быть также представлен буквой алфавита: \alph – латинская строчная, \asbuk – кириллическая строчная и \Asbuk – кириллическая заглавная.

В стандартных классах уже определён набор счётчиков, в которых хранятся номера страницы (счётчик page), раздела (соответственно, счётчики part, chapter, section, subsection, subsubsection и т.д.), подстрочного примечания (счётчик footnote), плавающих окружений (счётчики figure и table) и формул (equation). При создании счётчика также автоматически создаётся команда с префиксом \the перед именем счётчика. Вызов такой команды выводит значение счётчика. При выводе номера раздела, плавающего объекта, уравнения и тому подобного используются именно такого рода команды, поэтому, переопределив \the-команду, можно немного изменить стиль, например, следующая команда предписывает в дальнейшем маркировать все страницы в римском стиле:

\renewcommand{\thepage}{\Roman{page}}

На базе счётчиков можно организовывать иерархические структуры, то есть можно указывать зависимости:

(thumbnail)
Рис. 6.
\newcounter{Main}\addtocounter{Main}{10}
\newcounter{Dep}[Main]\addtocounter{Dep}{10}
Было: \theMain.\theDep\par
\stepcounter{Main}
Стало: \theMain.\theDep

При создании нового счётчика можно создать связь с уже существующим, указав имя существующего счётчика в качестве необязательного параметра. В примере выше счётчик Dep зависит от счётчика Main. Эта связь проявляется в том, что при увеличении значения базового счётчика (Main) на единицу с помощью команды \stepcounter подчинённый счётчик (Dep) обнуляется. Обычно новый счётчик устанавливают в подчинение счётчикам разделов (section).

Команда \refstepcounter{счётчик} отличается от \stepcounter тем, что помимо обнуления всех зависимых счётчиков, \refstepcounter опреде- ляет значение, выводимое командой ссылки \ref, как текст, создаваемый \the-командой:

% окружение “Задача”
\newcounter{Problem}[section]
\renewcommand{\theProblem}{\thesection.\arabic{Problem}}
\newenvironment{Problem}[0]{%
\par\refstepcounter{Problem}%
\theProblem\,}%
{\par}%

Здесь определено окружение Problem и одноимённый счётчик. Счётчик Problem зависит от счётчика раздела. Вывод счётчика \theProblem переопределён как номер раздела, за которым следует уже сам счётчик. Внутри окружения счётчик Problem увеличивается на единицу с помощью команды \refstepcounter{счётчик}. Результат использования нового окружения представлен в следующем примере:

(thumbnail)
Рис. 7.
\begin{Problem}\label{ex:1}
  Задача раз
\end{Problem}
\begin{Problem}\label{ex:2}
  Задача два
 \end{Problem}
Ссылки на раз~\ref{ex:1} и два~\ref{ex:2}.

При работе с переменными LaTeX также могут помочь следующие пакеты:

  • calc Макропакет из коллекции tools для арифметических вычислений, уже упоминавшийся в разделе calc (LXF89). Этот пакет переопределяет команды типа \newcounter так, что в них можно использовать арифметические выражения, хотя и с некоторыми ограничениями. Подробности в файле calc.pdf.
  • ifthen Макропакет, в котором определены команды условного перехода \ifthenelse и цикла \whiledo. Подробности в файле ifthen.pdf. Также

можно присмотреться к усовершенствованной версии этого пакетаxifthen.

  • fmtcount Представляет различные форматы (двоичный, восьмеричный, шестнадцатеричный и т.д.) отображения счётчиков (fmtcount.pdf).
  • multido Определяет оператор цикла \multido (multido.pdf).
  • tokenizer Позволяет разбивать текстовые списки на элементы (tokenizer.pdf).
  • totpages Даёт возможность узнать число страниц в документе и тому подобную информацию (totpages.pdf).
  • xkeyval Улучшенная версия пакета keyval, который позволяет передавать/принимать в качестве параметров пары значений «key=value» (xkeyval.pdf).

Создаём свой пакет

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

В LaTeX-сообществе принято распространять свои пакеты и документацию к ним в виде автономных файлов с расширением dtx (DTX-файлы). Для автоматической установки пакетов используются инструкции, записанные в файлах с расширением ins (INS-файлы). Для более подробной информации следует обратиться к инструкции «How to Package Your LaTeX Package», созданной Скотом Пакиным [Scott Pakin]. Файл dtxtut.pdf, как обычно, можно найти в стандартной поставке LaTeX или на CTAN. Вместе с документацией идут файлы примеров [c]skeleton.dtx и [c]skeleton.ins.

За работу с DTX-файлами отвечает пакет doc и сопутствующая ему утилита DOCSTRIP (файл docstrip.pdf). Основная идея пакета doc состоит в совмещении кода с документацией, что облегчает поддержку и развитие пакета.

Установочный INS-файл

Для извлечения кода и документации из DTX-пакета следует написать специальный установочный файл. Набор инструкций достаточно стереотипен:

%% Стандартный копирайт по выбору (рекомендуется LPPL/GPL)
%%
%% Первый шаг - загрузка DOCSTRIP.
\input docstrip.tex
%% Подробный отчёт о каждом шаге хорош только когда пакет
%% отлаживается.
\keepsilent
%% Директория, в которую устанавливается пакет. Имя
%% директории является относительным по отношению к
%% базовой директории $(TEXMF).
\usedir{tex/latex/{«имя пакета»}}
%% Определение преамбулы, которая вставляется во все
%% сгенерированные файлы. Обычно это информация об авторе
%% и пожелания пользователям.
\preamble
 Текст преамбулы
\endpreamble
%% Извлечение файлов пакета из dtx. Основной шаг,
%% который может повторяться несколько раз.
\generate{\file{«извлекаемый файл»}{\from{«dtx-файл»}{метка}}}
…
…
%% Информация для пользователя. Всегда что-то полезно сказать
%% после установки.
\obeyspaces
\Msg{******************************************************
**}
\Msg{* Здорово, что Вы поставили этот пакет. *}
\Msg{* Прочитайте документацию перед использованием! *}
\Msg{******************************************************
**}
%% Метка конца установочного файла.
\endbatchfile

Пакетный DTX-файл

Пролог
Пользовательская документация
Код с комментариями

Пакетирование

Напутствие

Документируйте каждый шаг. Пишите как можно больше качественного текста, так как его мало не бывает. Живучесть программы определяется не только кодом, но и описанием. «Светлое будущее» за грамотным программированием.

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

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