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?

  • ifthen is not expandable. – Ulrike Fischer Aug 23 '21 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 '21 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. – David Carlisle Aug 23 '21 at 15:13
  • 2
    look at the \pdfstrcmp pdftex primitive for the stated use case – David Carlisle Aug 23 '21 at 15:15
  • Thank you for the accepted answer. Please see my SUPPLEMENT for more generality, if your Yes/No actions grow more complex. – Steven B. Segletes Aug 23 '21 at 17:08

1 Answers1

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