\DeclareTextSymbol и \DeclareTextCommandDefault в отличие от стандартных \newcommand и др.

\DeclareTextSymbol и \DeclareTextCommandDefault в отличие от стандартных \newcommand и др.

Вэтотответ egreg использовал макросы \DeclareTextSymbol, \DeclareTextCommandDefaultи \UndeclareTextCommandтам, где я ранее (и безуспешно) пробовал простое \newcommandили \let.

Может ли кто-нибудь пояснить правильное использование этих команд и разницу со стандартом \newcommandи т. д.?

решение1

Некоторые команды могут выбирать свое действие на основе текущей кодировки вывода.

Самый простой пример — акценты. Хочется, чтобы они \"вели себя по-разному, когда выходная кодировка (соответствие между доступными глифами и их положением в шрифте) — OT1 или T1.

В первом случае \"uбудет сформирован вывод из ударения и символа, в то время как в случае с T1 он будет напрямую набирать предварительно составленный символ (это различие очень важно при рассмотрении переносов).

Таким образом, вместо того, чтобы поддерживать список команд для изменения определения при переключении кодировок, можно определить команду с помощью \DeclareTextSymbolили подобных функций.

Давайте рассмотрим \textborn. Он не определен в базовом LaTeX, но textcompдает его определение:

% textcomp.sty, line 225
\DeclareTextCommandDefault{\textborn}{\tc@check@symbol2\textborn}

Неважно знать, что должен делать заменяющий текст, но это определяет \textbornкак

\?-cmd \textborn \?\textborn

(три токена, последний — одиночный токен, расширением которого является приведенный выше текст замены, \tc@check@symbol2\textbornи к которому можно получить доступ, выполнив \csname ?\string\textborn\endcsname).

Позже, когда ts1enc.defбудет загружен, поскольку textcomp.styнеявно вызывается \usepackage[TS1]{inputenc}), LaTeX найдет

\DeclareTextSymbol{\textborn}{TS1}{98}

который будет делать тот же трюк, что и раньше, определяя \textbornкак

\TS1-cmd \textborn \TS1\textborn

(снова три жетона). Это самая важная часть. Как работает такая команда?

При расширении \textborn, если LaTeX находится в месте, где ожидается набор символа, текущая выходная кодировка будет проверена на соответствие TS1. Если это так, то будет использоваться только глиф номер 98 текущего шрифта; в противном случае группа открывается, кодировка переключается на TS1, символ 98 набирается и группа закрывается.

Такая команда всегда надежна, то есть если она обнаружена в перемещаемых аргументах, она будет создана сама собой, а не расширяться при выполнении операций записи.

Это должно объяснить ваше недоумение при выполнении

\let\oldtextborn\textborn

до загрузки kpfontsи затем не видим разницы между выводом, созданным \textbornи \oldtextborn. kpfontsПакет не переопределяет \textborn, а скорее связывает новый шрифт с кодировкой TS1 на основе выбранного имени семейства шрифтов. Так что \oldtextbornи \textbornостаются теми же.

При определении \textbornиспользования cmrсемейства нужно быть осторожным, потому что такая стратегия, как

\let\oldtextborn\textborn
\renewcommand\textborn{{\fontfamily{cmr}\selectfont\oldtextborn}}

не гарантируется безопасность. Например, если \textbornпоявляется в движущемся аргументе, скажем, в заголовке раздела или подписи, .auxфайл будет содержать

\@writefile{toc}{\contentsline {section}{\numberline {1}{\fontfamily  {cmr}\selectfont  {\fontfamily  {cmr}\selectfont  \textborn }}}{1}}

где команда, по-видимому, расширяется несколько раз. В других обстоятельствах это может даже привести к бесконечным циклам.

Стратегия, включающая в себя, \UndeclareTextCommandопределенно безопаснее.

Связанный контент