bachotex2006-bernd-raichle-pearl4.tex
bachotex2006-bernd-raichle-pearl4.tex
—
TeX document,
1 KB (1932 bytes)
File contents
%%% Bernd Raichle: check if defined, no side effects % LaTeX and other macro packages include a test if a control sequence is % already defined using \csname...\endcsname. In principle the following % definition is used: \def\@ifundefined#1#2#3{% \expandafter\ifx\csname#1\endcsname\relax#2\else#3\fi} % The use of \csname...\endcsname has the side effect that an undefined control % sequence will be defined as \relax and a simple test using % \ifx<control sequence>\undefined ... will fail. % To avoid this side effect, you can change the definition % above introducing a group ``around'' \csname: \def\@ifundefined#1#2#3{% \begingroup \expandafter\expandafter\expandafter \endgroup \expandafter\ifx\csname#1\endcsname\relax#2\else#3\fi} % Note: This definition is not fully expandable, thus it will fail in % expansion-only contexts where the original definition will work. % % If you are using eTeX, the new \ifcsname ...\endcsname % primitive can be used instead. %%%% % During the presentation of this pearl at the BachoTeX 2006 pearls session, % two alternatives to this trick has been proposed. Worthy to note, that the % macro above use more \expandafter's then actually needed. Once we say \def\@ifundefined#1#2#3{% \begingroup \expandafter \ifx\csname#1\endcsname\relax\endgroup#2\else\endgroup#3\fi} % we get exactly the same effect in a bit more efficient way. But there is one % more sticky problem in all the constructions above; every control sequence % defined as \relax (and \relax itself) is treated as undefined. The solution % seems to be \def\@ifundefined#1#2#3{% \begingroup \expandafter \endgroup \expandafter \ifx\csname#1\endcsname\undefined#2\else#3\fi} % Here we expand \csname...\endcsname before \endgroup, but the condition is % fixed outside the group. Thus, \undefined instead of \relax can be used for % comparison. \end
Document Actions