Опубликован: 07.02.2007 | Доступ: свободный | Студентов: 4012 / 1340 | Оценка: 4.56 / 3.95 | Длительность: 23:09:00
Специальности: Художник
Лекция 9:

Модификация стандартных классов

Теперь рассмотрим, как в стандарте определяются записи в оглавлении, соответствующие самым крупным разделам ( \chapter в классах book и report, \section в двух других классах). Вот (в адаптированном виде, как водится) определение команды \l@chapter из стандартного класса book. Чтобы было понятно, о чем идет речь, напомним, что в этом определении на место #1 подставляется информация о номере (если главы нумеруются) и названии главы, а на место #2 — номер страницы.

\newcommand{\l@chapter}[2]%
{\pagebreak[3]
 \vspace{1em plus 1pt}% отбивка перед строкой оглавления
   \@tempdima=1.5em % место для номера главы
   {% Дальнейшее происходит внутри группы...
     \rightskip=\@pnumwidth % см. ниже
     \parfillskip=-\@pnumwidth
     \noindent\bfseries % Начать абзац, установить шрифт
     \addtolength{\leftskip}{\@tempdima}% см. ниже
     \hspace{-\leftskip}#1\nolinebreak
     \hfil\nolinebreak
     \hbox to \@pnumwidth {\hss #2}\par
     \nopagebreak[3] % лучше бы здесь не рвать страницу...
   }% конец этой группы
}% конец определения

Определение, как видите, длинное и сложное, к тому же автору не удалось полностью изгнать из него не упоминавшиеся ранее TeX'овские конструкции. Приведено оно здесь не для того, чтобы вы самостоятельно создавали подобные определения "с нуля", но чтобы вы при необходимости смогли в нем кое-что осторожно изменить. Разберем определение по порядку. В начале встречаются не рассматривавшиеся нами параметры \rightskip и \leftskip. Эти параметры со значением длины (по умолчанию они равны нулю) имеют следующий смысл: все строки абзаца начинаются с отступом \leftskip от левого поля и кончаются с отступом \rightskip от правого поля (если речь идет о последней строке, то в дополнение к отступу \parfillskip ). У нас \rightskip устанавливается равным длине, записанной в определении команды \@pnumwidth (именно столько места будет отведено на номер страницы), а \leftskip устанавливается равным значению переменной \@tempdima, определяющей, сколько места будет отведено на номер главы. С другой стороны, параметр \parfillskip устанавливается равным отрицательной величине - \@pnumwidth. Тем самым, если название главы длинное и не поместится в одну строку оглавления, произойдет следующее: все строки, кроме последней, будут заканчиваться на расстоянии \@pnumwidth от правого края, а последняя строка, содержащая номер страницы, закончится на расстоянии

\leftskip + \parfillskip =  @pnumwidth - \@pnumwidth =0,

от края, так что номер страницы будет все-таки прижат вправо.

Между \@pnumwidth и \@tempdima есть существенная разница. Команда \@pnumwidth всегда определяет только место, отводимое на номер страницы, и эту команду можно переопределять в стилевом пакете. С другой стороны, параметр \@tempdima используется LaTeX'ом для самых разных целей (в основном — для временного хранения различных длин в процессе каких-то вычислений), и он может измениться в процессе выполнения очень многих LaTeX'овских команд, так что присваивать ему какое-то значение в стилевом пакете совершенно бессмысленно — все равно после этого оно сто раз изменится. Как мог заметить читатель, значение этому параметру присваивается в начале исполнения команды \l@chapter, и именно это значение принимается в расчет в дальнейшем. Поэтому, если вы захотите отводить на номер главы, скажем, 2em вместо 1.5em, то вам придется переопределить команду \l@chapter, заменив третью строку на

\@tempdima=2em

Нужда в таком переопределении \l@chapter возникает, например, если мы переопределяем команду \thechapter, чтобы номер печатался римскими цифрами (как в книге, которую вы читаете). Далее, #1 - это, как уже было сказано, номер и заглавие главы. Точнее говоря, на месте #1 печатается такой текст (будем считать, что глава называется "Все о слонах"):

\makebox[\@tempdima][l]{\thechapter}Все о слонах

Таким образом, величина отступа от левого поля до названия главы всегда равна \@tempdima ; если номер занимает больше места, чем \@tempdima, то он наложится на название.

Команда \hfil в двенадцатой строке обеспечивает пробел между названием главы и номером страницы. Если вы хотите заполнить этот пробел лидерами, можете в определении \l@chapter заменить \hfil на, скажем,

\leaders\hbox to .5em{\hss.\hss}\hfil

(автор не гарантирует, что именно при таком выборе параметров лидеры будут выглядеть красиво).

Наконец, команды \pagebreak[3] в начале и \nopagebreak[3] в конце играют следующую роль: первая из них призывает LaTeX не печатать, по возможности, строку оглавления, соответствующую главе, внизу страницы, а вторая — не разрывать страницу сразу после строки, посвященной главе (опять же по возможности).

Имейте также в виду, что мы удалили из нашего упрощенного определения \l@chapter проверку значения счетчика tocdepth, так что если вы в какой-то момент решите не включать главы в оглавление, эту команду надо будет переопределить на "ничего не делать" так:

\renewcommand{\l@chapter}[2]{}

Команды, определяющие вид записей в списке иллюстраций (соответствующих плавающим иллюстрациям) и списке таблиц (соответствующих плавающим таблицам) называются \l@figure и \l@table соответственно и определяются в стандарте с помощью \@dottedtocline.

До сих пор речь шла о сборке материала для оглавления, списка иллюстраций и т.п. Однако же и у самого оглавления есть заголовок, и его оформление тоже можно менять. Чтобы было понятно, как это делать, опишем, как определена команда \tableofcontents стандартное определение} в стандартном стиле article:

\newcommand{\tableofcontents}%
{\section*{\contentsname}\@starttoc{toc}}

Здесь \contentsname — это уже знакомая нам команда, которую при работе с русскими текстами приходится переопределять. Как видите, заголовок оглавления оформляется просто как заголовок ненумерованного раздела. Вы можете вместо этого оформить заголовок, скажем, с помощью \subsection, или еще каким-либо образом. Новой для вас будет команда \@starttoc. У этой команды предусмотрен один обязательный аргумент. Этим аргументом должен быть toc (для оглавления), либо lot или lof (для списка таблиц или иллюстраций соответственно). Команда \@starttoc читает toc- (соответственно, lot- или lof-) файл и создает оглавление как таковое.

На самом деле в определении \tableofcontents присутствует еще команда, позволяющая задать текст для включения в колонтитулы (вспомним, что \section* сама по себе никакой информации для колонтитулов не дает). Мы не будем здесь вдаваться в скучные подробности. Когда вы научитесь задавать такие команды, вы сможете соответствующим образом переопределить и \tableofcontents.

Нина Казачек
Нина Казачек
Василий Майоров
Василий Майоров