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}
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
.
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}
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}
Answered by Ulrich Diez on February 11, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP