Создание новых команд
Создавать макросы полезно не только для сокращения числа нажатий на клавиши при наборе формул. Вот пример, когда макросы помогают и при наборе обычного текста. Предположим, в нашем тексте много задач, причем условие каждой из задач начинает новый абзац (как обычно и бывает). Предположим также (временно), что эти задачи никак не нумеруются. Слово "Задача", с которого начинается условие, хочется как-то выделить в тексте; предположим, мы решили выделять его жирным шрифтом. Давайте создадим макрос, который будет делать все это за нас, чтобы можно было не печатать каждый раз слово "Задача", а просто написать \z. Первым обычно приходит в голову что-нибудь такое:
\newcommand{\z}{\bfseries Задача}
Посмотрите, что из этого выйдет:
? |
\z. Пять парней за пять дней съели пять окуней. За сколько дней пятнадцать парней съедят пятнадцать окуней? |
Почему же жирным шрифтом напечаталось не только слово "Задача", но и весь дальнейший текст? Ответ: TeX опять пунктуально заменил \z на "замещающий текст", в результате чего получилось вот что:
\bfseries Задача. Пять парней ...
Команда \bfseries оказалась не внутри группы, и весь текст напечатался жирным шрифтом. Чтобы не попадаться в такую ловушку, надо помнить, что при развертывании макроса фигурные скобки, ограничивающие замещающий текст в команде \newcommand, отбрасываются. Правильнее было бы дать такое определение:
\newcommand{\z}{\bfseries {Задача}}"
На сей раз \z будет заменяться на {\bfseries Задача} (отбрасывается внешняя пара фигурных скобок, ограничивающая второй аргумент команды \newcommand, и только она!). А можно (это, пожалуй, даже лучше) написать и так:
\newcommand{\z}{\textbf{Задача}}
Впрочем, наш макрос \z еще не идеален. Во-первых, после слова, напечатанного жирным шрифтом, точку лучше поставить тоже жирным шрифтом, поэтому разумно и ее включить в макроопределение. Далее, согласно общему правилу игнорирования пробелов после имени команды, состоящего из букв, в тексте при этом нельзя будет написать
\z Пять парней...
так как при этом пропадет пробел между словом "Задача." и следующим словом. Можно этот пробел, как водится, всякий раз специально организовывать и писать
\z{} Пять парней...
но лучше вставить и пробел прямо в определение:
\newcommand{\z}{\textbf{Задача. }}
Теперь запись \z Пять парней... даст то, что нужно. Впрочем, если угодно, вот еще один штрих. Если вы в какой-нибудь момент забудете оставить пустую строку перед очередной задачей, то слово "Задача" при этом будет не начинать абзац, а продолжать предшествующий текст. Чтобы этого раз и навсегда избежать, можно вставить команду "закончить абзац" в наше макроопределение. Как вы помните, эта команда называется \par:
\newcommand{\z}{\par\textbf{Задача. }}
Если перед нашим макросом \z пустая строка все-таки будет, то лишняя команда \par ни на что не повлияет, а если ее не будет, то \par сыграет роль недостающей пустой строки.
Если какой-то элемент текста оформлен с помощью макроса, становится удобно менять это оформление. Например, если вдруг понадобилось оформлять все задачи так, чтобы соответствующие абзацы начинались без отступа, достаточно внести небольшое изменение в наше определение команды \z:
\newcommand{\z}{\par\noindent\textbf{Задача. }}
Если бы каждую задачу мы оформляли вручную, нам пришлось бы перед каждым словом "Задача" вписывать команду \noindent. В дальнейшем, познакомившись с LaTeX'овскими " счетчиками", мы усовершенствуем наш макрос \z таким образом, чтобы он еще и автоматически нумеровал задачи.
Мы уже говорили, что переопределить значение уже существующей команды с помощью \newcommand невозможно. Иногда, однако, это бывает необходимо. Пример тому приведен в "лекции 3" : если мы хотим, чтобы в заголовках глав печаталось именно слово "Глава", а не " Chapter", то необходимо определить по-новому команду \chaptername. Для такого рода целей используется команда \renewcommand. Она устроена точно так же, как \newcommand, с тем отличием, что в качестве ее первого аргумента надо указывать имя уже существующей команды; в этом случае по выполнении команды \newcommand значение этой команды изменится: она превратится в сокращенное обозначение для текста, указанного в качестве ее второго аргумента. Например, если написать
\renewcommand{\alpha}{Ку-ку}
то команда \alpha будет генерировать не то, что обычно (букву в математической формуле и сообщение об ошибке, если эта команда употреблена вне математической формулы), а текст "Ку-ку".
Если команда \renewcommand дана внутри группы, то созданное ею переопределение значения команды забудется по выходе из этой группы. Если в качестве первого аргумента команды \renewcommand указать имя несуществующей команды, то вы получите сообщение об ошибке.
Команда \renewcommand при неаккуратном обращении может привести к неприятностям. Дело в том, что нередко команды LaTeX'а определяются в терминах других команд LaTeX'а, причем знать эти сложные связи рядовой пользователь вовсе не обязан. На практике такое незнание может привести к тому, что безобидное на первый взгляд использование в своих целях имени какой-нибудь команды, которая в вашем тексте ни разу не встречается, вызовет необъяснимо неправильную работу других команд. Поэтому используйте \renewcommand только тогда, когда вы полностью отдаете себе отчет в своих действиях.
Выше мы часто называли макросы просто командами, и это — не просто небрежность речи: на самом деле принципиальной разницы между макросами и TeX'овскими командами почти нет. В частности, почти все команды LaTeX'а, о которых говорилось и еще будет говориться в нашей книге, являются именно макросами; в отличие от макросов, создаваемых нами с помощью \newcommand, их смысл уже известен TeX'у к моменту запуска программы, так что определять их каждый раз не нужно. Макросы, в свою очередь, могут ссылаться на другие макросы (кстати, команда \stackrel, на которую ссылалась наша команда \eqdef, также является макросом) - и так далее, пока не дойдет до так называемых "примитивных команд" TeX'а. Из команд, о которых мы вам рассказывали, примитивными являются считанные единицы: \left, \right, \noindent и некоторые другие.