# Latex command exists check condition

How to check condition if \commandtwo presented in the tex file \commandone \if condition should be process otherwise \else condition should be process? How to make a condition?

Note: \commandtwo{XXX} may or may not present in the tex file that is after \begin{document}, but definitions of \def\commandone#1{#1}, \def\commandtwo#1{#1} and \def\commandthree#1{#1} in the preamble.

MWE file is as follows:

\documentclass{book}

\makeatletter
%\commandtwo present in the file \if condition should be process if not presented in the file \else condition should be process
\def\commandone#1{\ifx\@ScndArg\@empty{\Huge#1}\else{\tiny#1}\fi}

\def\commandtwo#1{\def\@ScndArg{#1}#1}

\def\commandthree#1{#1}
\makeatother

\begin{document}

\commandone{AAA}

\commandtwo{BBB}

\commandthree{CCC}

\end{document}

• No, only a condition \commondtwo{xx} presented after the \begin{document} Pointsize need to be updated within \def\commnadone#1{#1} macros. Dec 24 '20 at 17:21
• \commandtwo presented \def\commandone#1{\tiny#1} otherwise \def\commandone#1{\Huge#1} Dec 24 '20 at 17:22

Since \commandtwo could appear after \commandone, you need to consider using the .aux for storing content that will be used in a secondary compilation. Below \commandtwo writes \gdef\commandtwopresent{} into the .aux that will be read upon the next compilation. Even though it's defined to be nothing, it can be used to condition via \ifcsname...\endcsname.

\documentclass{article}

\makeatletter
%\commandtwo present in the file \if condition should be process if not presented in the file \else condition should be process
\def\commandone#1{\ifcsname commandtwopresent\endcsname {\Huge#1}\else{\tiny#1}\fi}

\def\commandtwo#1{%
\immediate\write\@auxout{\gdef\string\commandtwopresent{}}%
#1}

\def\commandthree#1{#1}
\makeatother

\begin{document}

\commandone{AAA}

\commandtwo{BBB}

\commandthree{CCC}

\end{document}

• Excellent Answer, Thank you Werner. Dec 24 '20 at 19:06

Werner suggested defining a macro via the .aux-file, the macro being defined indicating whether in the previous LaTeX-run \commandtwo was carried out.

Following this suggestion, I offer a variant where instead a cross-referencing label is written which yields either "true" or "false" and which can be used in a \csname..\endcsname expression that yields either \iftrue or \iffalse.

An advantage of this variant is that you are informed via the console and the .log-file if you have to recompile because something has changed, because the change is accompanied by the change of said cross-referencing label while changes of cross-referencing labels are tracked by the LaTeX kernel.

A disadvantage of this variant is that an additional package, the package atveryend, is needed for hooking in at the right moment in time for writing the said cross-referencing label.

\documentclass{book}
\usepackage{atveryend}
%\usepackage{hyperref}

\makeatletter
\AfterLastShipout{%
\immediate\write\@auxout{\string\newlabel{CommandTwoUsed}{\CommandTwoUsed}}%
}%
\newcommand\CommandTwoUsed{false}
\AtBeginDocument{%
\expandafter\newcommand
\expandafter\CheckWhetherCommandTwoUsed
\expandafter{%
\csname if\@ifundefined{r@CommandTwoUsed}{false}{\r@CommandTwoUsed}\endcsname
\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}%
}%
\newcommand\commandtwo[1]{\gdef\CommandTwoUsed{true}#1}
\newcommand\commandone[1]{\CheckWhetherCommandTwoUsed{{\Huge#1}}{{\tiny#1}}}
\newcommand\commandthree[1]{#1}
\makeatother

\begin{document}

\commandone{AAA}

\commandtwo{BBB}

\commandthree{CCC}

\end{document}


What exactly does "present" mean in the phrase "\commandtwo present in the file"?

Assume the .tex-input-file in question (or some other file processed via \input or \include, belonging to the document in question?) contains
\verb|\commandtwo...| and/or
 % This is a comment containing \commandtwo.

Would the condition of \commandtwo being present in the file be fulfilled in this case?

If you only wish to know whether \commandtwo was already carried out/was not(yet) carried out while assuming that there are no other ways of defining \@ScndArg but carrying out \commandtwo, then you can check if \@ScndArg is defined/is undefined.

Werner already showed in his answer how to do this via \ifcsname..\endcsname in case ε-TeX-extensions are available.

For the sake of having fun you can implement testing whether a macro argument has a first token which is a control sequence which is undefined by checking whether the \meaning of that token contains the phrase "undefined". This way it is not needed to rely on the availability of whatsoever TeX-extension:

\errorcontextlines=10000
\documentclass{article}

\makeatletter
%%=============================================================================
%% Paraphernalia:
%%    \UD@firstoftwo, \UD@secondoftwo, \UD@Exchange,  \UD@CheckWhetherNull,
%%    \UD@stopromannumeral
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@Exchange[2]{#2#1}%
\@ifdefinable\UD@stopromannumeral{\chardef\UD@stopromannumeral=\^^00}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}%
{\expandafter\UD@stopromannumeral\UD@firstoftwo}%
}%
%%=============================================================================
%% Check whether brace-balanced argument has a first token which is an
%% undefined control sequence.
%% (Only with undefined control sequences the \meaning has the leading phrase
%% "undefined"; besides this \meaning never delivers no tokens at all)
%%.............................................................................
%% \CheckWhetherLeadingUndefined{<Argument which is to be checked>}%
%%                              {<Tokens to be delivered in case <argument
%%                                 which is to be checked> has a 1st token
%%                                 which is undefined>}%
%%                              {<Tokens to be delivered in case <argument
%%                                which is to be checked> does not have a 1st
%%                                token which is undefined>}%
\begingroup
\endgroup
\romannumeral\expandafter\UD@secondoftwo\expandafter{\expandafter{%
\string##1X}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\UD@stopromannumeral\UD@secondoftwo}{%
% Let's nest things into \UD@firstoftwo{...}{} to make sure they are nested in braces
% and thus do not disturb when the test is carried out within \halign/\valign:
\expandafter\UD@firstoftwo\expandafter{%
\expandafter\expandafter\expandafter\UD@stopromannumeral
\romannumeral\expandafter\UD@secondoftwo
}{}%
}%
}%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}##1}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\expandafter\expandafter\expandafter\UD@stopromannumeral
\expandafter\expandafter\expandafter}%
\expandafter\UD@secondoftwo\expandafter{\string}%
}%
}%
}%
\escapechar=-1\relax
\makeatother

\begin{document}

\medskip\hrule\medskip

The sequence \verb|abc|
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

The sequence \verb|\TeX abc|
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

The empty sequence
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

The blank sequence  \verb*| |
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

The sequence  \verb|\else|
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

The sequence \verb|{\UnDefIneD} abc|
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

The sequence \verb|{}\UnDefIneD abc|
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

The sequence \verb*| \UnDefIneD abc|
\CheckWhetherLeadingUndefined{ \UnDefIneD abc}{does have}{does not have}
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

The sequence \verb|\UnDefIneD \fi \csname abc|
\CheckWhetherLeadingUndefined{\UnDefIneD \fi \csname abc}{does have}{does not have}
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

The sequence \verb|\UnDefIneD abc|

Another approach could be re-reading the entire input-file in question under verbatim-catcode-régime for checking via delimited arguments if the phrase \commandtwo is present. But this could be outmanoeuvred by having a comment containing that phrase. In case of having input file A and input file B, both belonging to the same document and input file A being processed before processing input file B, this could within input file B also be outmanoeuvred by input file A containing \let\foobar=\commandtwo and input file B containing \foobar instead of \commandtwo`.