TransWikia.com

Latex command exists check condition

TeX - LaTeX Asked by Rajesh N on February 11, 2021

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 defcommandone#1{#1}, defcommandtwo#1{#1} and defcommandthree#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
defcommandone#1{ifx@ScndArg@empty{Huge#1}else{tiny#1}fi}

defcommandtwo#1{def@ScndArg{#1}#1}

defcommandthree#1{#1}
makeatother

begin{document}

commandone{AAA}

commandtwo{BBB}

commandthree{CCC}

end{document}

3 Answers

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 gdefcommandtwopresent{} 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
defcommandone#1{ifcsname commandtwopresentendcsname {Huge#1}else{tiny#1}fi}

defcommandtwo#1{%
  immediatewrite@auxout{gdefstringcommandtwopresent{}}%
  #1}

defcommandthree#1{#1}
makeatother

begin{document}

commandone{AAA}

commandtwo{BBB}

commandthree{CCC}

end{document}

Answered by Werner on February 11, 2021

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
%%=============================================================================
newcommandUD@firstoftwo[2]{#1}%
newcommandUD@secondoftwo[2]{#2}%
newcommandUD@Exchange[2]{#2#1}%
@ifdefinableUD@stopromannumeral{chardefUD@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>
newcommandUD@CheckWhetherNull[1]{%
  romannumeralexpandafterUD@secondoftwostring{expandafter
  UD@secondoftwoexpandafter{expandafter{string#1}expandafter
  UD@secondoftwostring}expandafterUD@firstoftwoexpandafter{expandafter
  UD@secondoftwostring}expandafterUD@stopromannumeralUD@secondoftwo}%
  {expandafterUD@stopromannumeralUD@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
defCheckWhetherLeadingUndefined#1{%
  endgroup
  newcommandCheckWhetherLeadingUndefined[1]{%
    romannumeralexpandafterUD@secondoftwoexpandafter{expandafter{%
    string##1X}expandafterUD@firstoftwoexpandafter{expandafter
    UD@secondoftwostring}expandafterUD@stopromannumeralUD@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:
       expandafterUD@firstoftwoexpandafter{%
         expandafterexpandafterexpandafterUD@stopromannumeral
         romannumeralexpandafterUD@secondoftwo
         string{[email protected]##1X#1}{}%
       }{}%
    }%
  }%
  @ifdefinableUD@CheckWhetherLeadingUndefinedB{%
    longdefUD@CheckWhetherLeadingUndefinedB##1#1{%
      expandafterUD@CheckWhetherNullexpandafter{UD@firstoftwo{}##1}%
      {UD@Exchange{UD@firstoftwo}}{UD@Exchange{UD@secondoftwo}}%
      {expandafterexpandafterexpandafterUD@stopromannumeral
       expandafterexpandafterexpandafter}%
       expandafterUD@secondoftwoexpandafter{string}%
    }%
  }%
}%
escapechar=-1relax
expandafterCheckWhetherLeadingUndefinedexpandafter{stringundefined}%
makeatother

begin{document}

medskiphrulemedskip

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

medskiphrulemedskip

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

medskiphrulemedskip

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

medskiphrulemedskip

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

medskiphrulemedskip

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

medskiphrulemedskip

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

medskiphrulemedskip

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

medskiphrulemedskip

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

medskiphrulemedskip

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.

medskiphrulemedskip

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

medskiphrulemedskip

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 letfoobar=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.

Answered by Ulrich Diez on February 11, 2021

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{%
  immediatewrite@auxout{stringnewlabel{CommandTwoUsed}{CommandTwoUsed}}%
}%
newcommandCommandTwoUsed{false}
AtBeginDocument{%
  expandafternewcommand
  expandafterCheckWhetherCommandTwoUsed
  expandafter{%
    csname if@ifundefined{r@CommandTwoUsed}{false}{r@CommandTwoUsed}endcsname
    expandafter@firstoftwoelseexpandafter@secondoftwofi
  }%
}%
newcommandcommandtwo[1]{gdefCommandTwoUsed{true}#1}
newcommandcommandone[1]{CheckWhetherCommandTwoUsed{{Huge#1}}{{tiny#1}}}
newcommandcommandthree[1]{#1}
makeatother

begin{document}

commandone{AAA}

commandtwo{BBB}

commandthree{CCC}

end{document}

enter image description here

Answered by Ulrich Diez on February 11, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP