4

I've seen several posts and users recommend avoiding the ifthen package, however, I see it was recently updated (2020).

One feature I'm trying to exploit from it is an expanded string comparison. etoolbox offers unexpanded string comparison via \ifstrequal (I suppose the intention is to use this in macros to check argument strings?), or it can expand a string in the first argument (only one expansion?) via \ifdefstring. My needs would require full expansion, say for concatenating two definitions. Please see MWE below

\documentclass{scrartcl}

\usepackage{ifthen}
\usepackage{etoolbox}

% \newcommand{\ifstringeqx}[4]{% will not work in section here, use robust cmd
\newrobustcmd{\ifstringeqx}[4]{%
\ifthenelse%
    {\equal{#1}{#2}}%
    {#3}%
    {#4}%
}


\begin{document}

\def\hello{Hi}
\def\world{Earth}

\section{\ifstringeqx{\hello\world}{HiEarth}{Yes}{No}}

\def\world{Saturn}
\def\planet{Saturn}
\ifstringeqx{\hello\world}{Hi\planet}{Yes}{No}

\ifstringeqx{\hello\world}{HiJupiter}{Yes}{No}

\end{document}

10 year old post: Why is the ifthen package obsolete?

5
  • ifthen is not expandable. Aug 23, 2021 at 14:42
  • As far as I can see the code hasn't changed. The only changes in the file are the copyright statements, since the package is part of base.
    – campa
    Aug 23, 2021 at 14:49
  • 3
    apart from documentation updates there was one minor code change in 2001 but other than that it's unchanged since I made the latex2e version in 1993, (using the syntax of an old 2.09 file but a new implementation) but I don't think I have ever used it in all that time. Aug 23, 2021 at 15:13
  • 2
    look at the \pdfstrcmp pdftex primitive for the stated use case Aug 23, 2021 at 15:15
  • Thank you for the accepted answer. Please see my SUPPLEMENT for more generality, if your Yes/No actions grow more complex. Aug 23, 2021 at 17:08

1 Answer 1

3

David's suggestion satisfies all the requirements. \pdfstrcmp expands its arguments before comparison and is itself expandable.

Note the implementation is engine specific and so an extra package needs loading if lualatex is used.

\documentclass{scrartcl}
%%%%%%%%%%%%% WORKS FOR LUA + XELATEX + PDFLATEX ENGINES
\usepackage{pdftexcmds}
\makeatletter
\let\strcmp\pdf@strcmp
\makeatother
%%%%%%%%%%%%% WORKS ONLY FOR PDFLATEX AND XELATEX ENGINES
%\let\strcmp\pdfstrcmp
%%%%%%%%%%%%% END

\newcommand{\ifstringeqx}[4]{%
    \ifnum\strcmp{#1}{#2}=0 #3\else#4\fi
}
\begin{document}
\def\hello{Hi}
\def\world{Earth}

\section{\ifstringeqx{\hello\world}{HiEarth}{Yes}{No}}

\def\world{Saturn}
\def\planet{Saturn}
\ifstringeqx{\hello\world}{Hi\planet}{Yes}{No}

\edef\isitexpandable{\ifstringeqx{\hello\world}{HiJupiter}{Yes}{No}}

---$>$ \isitexpandable
\end{document}

enter image description here


SUPPLEMENT

If one is concerned with the \else and/or \fi in the definition of \ifstringeqx getting in the way of #3 and #4 doing their thing (for example, if they need to absorb tokens located beyond the \fi), we can copy/paste a little bit of logic from the tokcycle package to perform the \ifnum while removing the influence of \else and \fi:

\makeatletter
\long\def\tctestifnum#1{\tctestifcon{\ifnum#1\relax}}
\long\def\tctestifcon#1{#1\expandafter\tc@exfirst\else\expandafter\tc@exsecond\fi}
\long\def\tc@exfirst#1#2{#1}
\long\def\tc@exsecond#1#2{#2}
\makeatother

\newcommand{\ifstringeqx}[4]{%
    \tctestifnum{\strcmp{#1}{#2}=0}{#3}{#4}}

Here's an example where the original definition with \else and \fi won't work, but this revised definition works fine.

\documentclass{scrartcl}
%%%%%%%%%%%%% WORKS FOR LUA + XELATEX + PDFLATEX ENGINES
\usepackage{pdftexcmds}
\makeatletter
\let\strcmp\pdf@strcmp
\makeatother
%%%%%%%%%%%%% WORKS ONLY FOR PDFLATEX AND XELATEX ENGINES
%\let\strcmp\pdfstrcmp
%%%%%%%%%%%%% END

\makeatletter
\long\def\tctestifnum#1{\tctestifcon{\ifnum#1\relax}}
\long\def\tctestifcon#1{#1\expandafter\tc@exfirst\else\expandafter\tc@exsecond\fi}
\long\def\tc@exfirst#1#2{#1}
\long\def\tc@exsecond#1#2{#2}
\makeatother

\newcommand{\ifstringeqx}[4]{%
    \tctestifnum{\strcmp{#1}{#2}=0}{#3}{#4}}


\def\Yes#1{#1 yes!}
\def\No#1{#1 no!}
\begin{document}
\def\hello{Hi}
\def\world{Earth}

\section{\ifstringeqx{\hello\world}{HiEarth}{\Yes}{\No}{Hell}}

\def\world{Saturn}
\def\planet{Saturn}
\ifstringeqx{\hello\world}{Hi\planet}{Yes}{No}

\edef\isitexpandable{\ifstringeqx{\hello\world}{HiJupiter}{\Yes}{\No}{Absolutely}}

---$>$ \isitexpandable
\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.