14

In this answer egreg used the macros \DeclareTextSymbol, \DeclareTextCommandDefault and \UndeclareTextCommand where I had previously (and unsuccessfully) tried a simple \newcommand or \let.

Could someone please elaborate on the correct use of these commands and the difference to the standard \newcommand etc.?

1 Answer 1

14

Some commands are able to choose their action based on the current output encoding.

The simplest example is that of accents. One wants that \" behaves differently when the output encoding (which is a correspondence between the available glyphs and their position in the font) is OT1 or T1.

In the first case, \"u would compose the output from an accent and a character, with T1 it will directly typeset a precomposed character (this difference is very important when hyphenation is considered).

So, rather than maintaining a list of commands to change the definition of when switching encodings, a command can be defined with \DeclareTextSymbol or alike functions.

Let's look at \textborn. It is undefined in base LaTeX, but textcomp provides a definition of it:

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

It's not important to know what the replacement text is supposed to do, but this defines \textborn as

\?-cmd \textborn \?\textborn

(three tokens, the last is a single token whose expansion is the above replacement text \tc@check@symbol2\textborn and can be accessed at by doing \csname ?\string\textborn\endcsname).

Later on, when ts1enc.def is loaded, because textcomp.sty implicitly calls \usepackage[TS1]{inputenc}), LaTeX will find

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

that will do a similar trick as before, defining \textborn as

\TS1-cmd \textborn \TS1\textborn

(again three tokens). This is the most important part. How does a command like this work?

At expansion of \textborn, if LaTeX is in a place where a character is expected to be typeset, the current output encoding will be checked against TS1. If it is, then just glyph number 98 of the current font will be used; otherwise a group is opened, the encoding switched to TS1, character 98 is typeset and the group is closed.

Such a command is always robust, meaning that if found in moving arguments it will produce itself instead of expanding when write operations are involved.

This should explain your perplexity when doing

\let\oldtextborn\textborn

before loading kpfonts and then seeing no difference between the output produced by \textborn and \oldtextborn. The kpfonts package doesn't redefine \textborn, but rather associates a new font to the TS1 encoding based on the chosen font family name. So \oldtextborn and \textborn are still the same.

For defining \textborn to use the cmr family one has to be careful, because a strategy like

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

is not guaranteed to be safe. For instance, if \textborn appears in a moving argument, say in a section title or a caption, the .aux file will contain

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

where the command appears to be expanded a few times. In other circumstances this might even lead to infinite loops.

A strategy involving \UndeclareTextCommand is definitely safer.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .