TeX's (and hence LaTeX's) control sequence names can either contain of arbitrary many letters, i.e., characters with category code 11, or of
one character with another category code. This is the reason for
\makeatletter
: it gives
@
the category code 11 (letter),
\makeatother
gives it category code 12 (other) again.
When you have
Code: Select all
\makeatletter
\ifdefined \r@snowflake2 snowflake2 defined \else snowflake2 undefined \fi
\makeatother
you test if the control sequence
\r@snowflake
is defined. If it is
2 snowflake2 defined
is left in the input stream:
Code: Select all
\documentclass{article}
\begin{document}
\label{snowflake}
\makeatletter
\ifdefined \r@snowflake2 snowflake2 defined \else snowflake2 undefined \fi
\makeatother
\end{document}
Now you don't want to change the category code of
2
directly (although it is of course possible). The way around is to use TeX's primitive
\csname ...\endcsname
or in this case eTeX's
\ifcsname ... \endcsname ... \fi
.
\csname <tokens>\endcsname
builds a command sequence name of
<tokens>
.
Code: Select all
\documentclass{article}
\begin{document}
\label{snowflake2}
\makeatletter % not needed, strictly speaking: the @ will be part of the csname
\expandafter\ifdefined\csname r@snowflake2\endcsname
snowflake2 defined%
\else
snowflake2 undefined%
\fi
\ifcsname r@snowflake2\endcsname
snowflake2 defined%
\else
snowflake2 undefined%
\fi
\makeatother
\end{document}
It might be more convenient to use etoolbox's wrappers around this:
Code: Select all
\documentclass{article}
\usepackage{etoolbox}
\begin{document}
\label{snowflake2}
\makeatletter % not needed, strictly speaking: the @ will be part of the csname
\ifcsdef{r@snowflake2}
{snowflake2 defined}
{snowflake2 undefined}
\makeatother
\end{document}
Regards