\DeclareTextSymbol y \DeclareTextCommandDefault en contraste con el estándar \newcommand et al

\DeclareTextSymbol y \DeclareTextCommandDefault en contraste con el estándar \newcommand et al

Enesterespuesta egreg usó las macros \DeclareTextSymbol, \DeclareTextCommandDefaulty \UndeclareTextCommanddonde previamente había probado (y sin éxito) un simple \newcommando \let.

¿Podría alguien explicarnos más detalladamente el uso correcto de estos comandos y la diferencia con el estándar, \newcommandetc.?

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, \"ucomponerí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 \DeclareTextSymbolfunciones similares.

Miremos a \textborn. No está definido en LaTeX base, pero textcompproporciona 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 \textborncomo

\?-cmd \textborn \?\textborn

(tres tokens, el último es un token único cuya expansión es el texto de reemplazo anterior \tc@check@symbol2\textborny se puede acceder a él haciendo \csname ?\string\textborn\endcsname).

Más adelante, cuando ts1enc.defse cargue, porque textcomp.styimplícitamente llama a \usepackage[TS1]{inputenc}), LaTeX encontrará

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

que hará un truco similar al anterior, definiendo \textborncomo

\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 kpfontsy luego no ver ninguna diferencia entre la salida producida por \textborny \oldtextborn. El kpfontspaquete 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 \oldtextborny \textbornsiguen siendo los mismos.

Para definir \textbornel uso de la cmrfamilia 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 \textbornaparece en un argumento en movimiento, digamos en el título de una sección o en un título, el .auxarchivo 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 \UndeclareTextCommandes definitivamente más segura.

información relacionada