0

I'm trying to write this if statement

\def\x{y}
if x==y
yes
else
no
end

How can I write such a code in latex

Diana
  • 1,285
  • 7
  • 12

1 Answers1

2

The basic approach for this would use an \ifx comparison. \ifx compares the definition of the following two macros (if the arguments are macros that is, it could also compare other tokens). The important thing is that \ifx doesn't expand the following tokens.

How could we use this to compare two texts? Well, we use two temporary macros which we define to store the texts, then compare these temporary macros. To keep the temporary macros temporary, we define them inside of \begingroup...\endgroup, and to do the comparison before the end of the group restores their prior definition (or undefines them) we use \expandafter (this evaluates the \ifx, then closes the group, and only then executes the true or false branch of \ifx).

Inside these two branches we use \expandafter\@firstoftwo or \expandafter\@secondoftwo, the effect is that the \else or \fi gets expanded and only after that the next two arguments, which are the true and false branches from the users point of view get read and reinserted. This way the complete \ifx...\fi block is processed before any user code gets inserted (this gives better stability in general).

\newcommand\iftexteqTF[2]
  {%
    \begingroup
      \def\tmpa{#1}%
      \def\tmpb{#2}%
      \expandafter
    \endgroup
    \ifx\tmpa\tmpb
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
  }

The drawback of this comparison is that this is not expandable (so, if we were doing everything correct we wouldn't use \newcommand there, but would want the definition of \iftexteqTF to be \protected, so better would be \@ifdefinable\iftexteqTF{\protected\long\def\iftexteqTF#1#2{<definition>}}). Also, this way the text in the first two arguments can't contain # (the implementation in the MWE below fixes this by using \edef\tmpa{\unexpanded{#1}} instead of \def\tmpa{#1}).

We could as well use an expandable test. There is such an expandable test built into the several engines (or implemented in Lua in the case of LuaLaTeX). To get use this engine independent we can just use the implementation provided by LaTeX3:

\ExplSyntaxOn
\cs_new_eq:NN \ifstreqTF \str_if_eq:nnTF
\ExplSyntaxOff

The slightly different name indicates an important difference: This compares the string representation of its arguments, so category codes aren't taken into consideration. This difference is often unimportant (and sometimes even advantageous).

A complete document using both variants:

\documentclass[]{article}

\makeatletter @ifdefinable\iftexteqTF {% \protected\long\def\iftexteqTF#1#2% {% \begingroup \edef\tmpa{\unexpanded{#1}}% \edef\tmpb{\unexpanded{#2}}% \expandafter \endgroup \ifx\tmpa\tmpb \expandafter@firstoftwo \else \expandafter@secondoftwo \fi }% } \ExplSyntaxOn \cs_new_eq:NN \ifstreqTF \str_if_eq:nnTF \ExplSyntaxOff \makeatother

\begin{document} \iftexteqTF{abc}{abc}{True}{False} \par \iftexteqTF{abc}{ABC}{True}{False} \par

\bigskip \ifstreqTF{abc}{abc}{True}{False} \par \ifstreqTF{abc}{ABC}{True}{False} \end{document}


In case you were wondering, the first variant is also provided by LaTeX3, in the form of \tl_if_eq:nnTF, so we could as well have used the following instead:

\ExplSyntaxOn
\cs_new_eq:NN \iftexteqTF \tl_if_eq:nnTF
\ExplSyntaxOff
Skillmon
  • 60,462