Assuming \<cs>
passes the first two tests of \ifdefempty
(is defined and is parameterless), the next test - is the replacement text empty - is performed within \etb@ifdefempty
. This test checks whether the \meaning
of \<cs>
is "blank":
\def\etb@ifdefempty#1{%
\expandafter\expandafter
\expandafter\ifblank
\expandafter\expandafter
\expandafter{%
\expandafter\strip@prefix\meaning#1}}
The "blank" here is checked against a \strip@prefix
of the \meaning
of #1
. This just strips the macro:->
part from the output of \meaning
(so macro:->\relax
is changed to \relax
). So, in the case of
\myempty
, the check is \ifblank{}
which is true.
\myrelax
, the check is \ifblank{\relax}
which is false.
\myemptyempty
, the check is \ifblank{\myempty}
, which is false.
The following updated version of \ifdefempty
actually shows you what the comparisons are performed against:
\makeatletter
\renewcommand{\ifdefempty}[1]{
{\ttfamily\expandafter\strip@prefix\meaning#1\quad}%
\ifundef{#1}
{\@secondoftwo}
{\ifdefmacro{#1}
{\ifdefparam{#1}
{\@secondoftwo}
{\etb@ifdefempty{#1}}}
{\@secondoftwo}}}
\makeatother
The inner-workings of \ifdefvoid
is similar since it uses the same inner-most function for testing, namely \etb@ifdefempty
. The following updated version of \ifdefvoid
highlights what the tests are performed against:
\makeatletter
\renewcommand{\ifdefvoid}[1]{%
{\ttfamily\expandafter\strip@prefix\meaning#1\quad}%
\ifundef{#1}
{\@firstoftwo}
{\ifdefmacro{#1}
{\ifdefparam{#1}
{\@secondoftwo}
{\etb@ifdefempty{#1}}}
{\@secondoftwo}}}
\makeatother
You can't define a macro \ifdef
that can work with nested conditionals, because of the way TeX keeps track of \else
and \fi
. With a naive definition such as
\def\ifdef#1{\ifx#1\undefined}
one could surely say
\ifdef\CheckMe
\string\CheckMe\space is not defined
\else
\string\CheckMe\space is defined
\fi
but a construction such as
\ifnum\Acount=\Bcount
something else
\else
\ifdef\CheckMe
\string\CheckMe\space is not defined
\fi
\fi
will break if \Acount
is equal to \Bcount
, leaving a stray \fi
: the \else
will be matched to the first \fi
, not to the second, because TeX doesn't expand tokens that are skipped in the true or false branch of a conditional; since \ifdef
is a macro and not a conditional, the mismatch will bite you.
A workaround (tracing back to Knuth himself) is to define a macro in the following way:
\def\isundefined#1{TT\fi\ifx#1\undefined}
and call it as
\if\isundefined\CheckMe
\string\CheckMe\space is not defined
\else
\string\CheckMe\space is defined
\fi
This works also in nested conditionals because TeX will see the \if
and match it with the correct \else
or \fi
. When expanded, \if TT\fi
will do exactly nothing, leaving control to the following \ifx
.
If e-TeX is allowed, there's an \ifdefined
conditional that avoids choosing a macro name and trusting it will remain undefined:
\ifdefined\CheckMe
\string\CheckMe\space is defined
\else
\string\CheckMe\space is not defined
\fi
(notice the reversal of the conditions).
Best Answer
If you redefine the user command
\author
and the internal command\@author
, you can make them do what you want them to. You can set them up in a way that you can test. A simple example is below, explained in the comments.