
Enesterespuesta egreg usó las macros \DeclareTextSymbol
, \DeclareTextCommandDefault
y \UndeclareTextCommand
donde previamente había probado (y sin éxito) un simple \newcommand
o \let
.
¿Podría alguien explicarnos más detalladamente el uso correcto de estos comandos y la diferencia con el estándar, \newcommand
etc.?
Respuesta1
Algunos comandos pueden elegir su acción según la codificación de salida actual.
El ejemplo más sencillo es el de los acentos. Uno quiere que \"
se comporte de manera diferente cuando la codificación de salida (que es una correspondencia entre los glifos disponibles y su posición en la fuente) es OT1 o T1.
En el primer caso, \"u
componería la salida a partir de un acento y un carácter, con T1 directamente componería un carácter precompuesto (esta diferencia es muy importante cuando se considera la separación de palabras).
Entonces, en lugar de mantener una lista de comandos para cambiar la definición al cambiar de codificación, se puede definir un comando con \DeclareTextSymbol
funciones similares.
Miremos a \textborn
. No está definido en LaTeX base, pero textcomp
proporciona una definición del mismo:
% textcomp.sty, line 225
\DeclareTextCommandDefault{\textborn}{\tc@check@symbol2\textborn}
No es importante saber qué se supone que debe hacer el texto de reemplazo, pero esto se define \textborn
como
\?-cmd \textborn \?\textborn
(tres tokens, el último es un token único cuya expansión es el texto de reemplazo anterior \tc@check@symbol2\textborn
y se puede acceder a él haciendo \csname ?\string\textborn\endcsname
).
Más adelante, cuando ts1enc.def
se cargue, porque textcomp.sty
implícitamente llama a \usepackage[TS1]{inputenc}
), LaTeX encontrará
\DeclareTextSymbol{\textborn}{TS1}{98}
que hará un truco similar al anterior, definiendo \textborn
como
\TS1-cmd \textborn \TS1\textborn
(nuevamente tres fichas). Esta es la parte más importante. ¿Cómo funciona un comando como este?
En la expansión de \textborn
, si LaTeX está en un lugar donde se espera que se escriba un carácter, la codificación de salida actual se comparará con TS1. Si es así, sólo se utilizará el glifo número 98 de la fuente actual; de lo contrario, se abre un grupo, la codificación cambia a TS1, se escribe el carácter 98 y se cierra el grupo.
Un comando de este tipo siempre es robusto, lo que significa que si se encuentra en argumentos en movimiento, se producirá por sí mismo en lugar de expandirse cuando se trate de operaciones de escritura.
Esto debería explicar su perplejidad al hacer
\let\oldtextborn\textborn
antes de cargar kpfonts
y luego no ver ninguna diferencia entre la salida producida por \textborn
y \oldtextborn
. El kpfonts
paquete no redefine \textborn
, sino que asocia una nueva fuente a la codificación TS1 según el nombre de la familia de fuentes elegida. Entonces \oldtextborn
y \textborn
siguen siendo los mismos.
Para definir \textborn
el uso de la cmr
familia hay que tener cuidado, porque una estrategia como
\let\oldtextborn\textborn
\renewcommand\textborn{{\fontfamily{cmr}\selectfont\oldtextborn}}
No se garantiza que sea seguro. Por ejemplo, si \textborn
aparece en un argumento en movimiento, digamos en el título de una sección o en un título, el .aux
archivo contendrá
\@writefile{toc}{\contentsline {section}{\numberline {1}{\fontfamily {cmr}\selectfont {\fontfamily {cmr}\selectfont \textborn }}}{1}}
donde el comando parece expandirse varias veces. En otras circunstancias, esto podría incluso conducir a bucles infinitos.
Una estrategia que involucra \UndeclareTextCommand
es definitivamente más segura.