2

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}
2
  • No, only a condition \commondtwo{xx} presented after the \begin{document} Pointsize need to be updated within \def\commnadone#1{#1} macros.
    – Rajesh N
    Commented Dec 24, 2020 at 17:21
  • \commandtwo presented \def\commandone#1{\tiny#1} otherwise \def\commandone#1{\Huge#1}
    – Rajesh N
    Commented Dec 24, 2020 at 17:22

3 Answers 3

6

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.

enter image description here

\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}
1
  • Excellent Answer, Thank you Werner.
    – Rajesh N
    Commented Dec 24, 2020 at 19:06
1

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}

enter image description here

0

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:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\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
\def\CheckWhetherLeadingUndefined#1{%
  \endgroup
  \newcommand\CheckWhetherLeadingUndefined[1]{%
    \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
         \string{\expandafter\UD@CheckWhetherLeadingUndefinedB\expandafter.\meaning##1X#1}{}%
       }{}%
    }%
  }%
  \@ifdefinable\UD@CheckWhetherLeadingUndefinedB{%
    \long\def\UD@CheckWhetherLeadingUndefinedB##1#1{%
      \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
\expandafter\CheckWhetherLeadingUndefined\expandafter{\string\undefined}%
\makeatother

\begin{document}

\medskip\hrule\medskip

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

\medskip\hrule\medskip

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

\medskip\hrule\medskip

The empty sequence 
\CheckWhetherLeadingUndefined{}{does have}{does not have}
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

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

\medskip\hrule\medskip

The sequence  \verb|\else|
\CheckWhetherLeadingUndefined{\else}{does have}{does not have}
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 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 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|
\CheckWhetherLeadingUndefined{\UnDefIneD abc}{does have}{does not have}
a leading token which is an undefined control sequence.

\medskip\hrule\medskip

\end{document}

enter image description here

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.

Therefore I am not elaborating on this unless you write a comment which indicates that you are interested in this approach despite its shortcomings.

You must log in to answer this question.

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