# \ifthenelse + \equal behaves weirdly

Here's a minimal example of my issue:

% test.tex
\documentclass{article}
\usepackage{ifthen}
\begin{document}
\ifthenelse{\equal{\string\jobname}{test}} {TRUE} {FALSE}
\ifthenelse{\equal{test}{test}} {TRUE} {FALSE}
\typeout{.\jobname.}
\end{document}


When I run pdflatex test.tex, the resulting PDF contains "FALSE TRUE". On the commandline, I see .test., so \jobname should indeed be "test", but the comparison fails nevertheless.

I'm overlooking something, but I don't get it. Note: also fails when I don't use \string...

There are two kinds of problem here, actually three. Consider the following document echtler.tex.

\documentclass{article}
\usepackage{ifthen}

\begin{document}

\textbf{jobname}

\ifthenelse{\equal{\string\jobname}{echtler}} {TRUE} {FALSE}

\ifthenelse{\equal{\jobname}{echtler}} {TRUE} {FALSE}

\ifthenelse{\equal{\jobname}{\detokenize{echtler}}} {TRUE} {FALSE}

\ifthenelse{\equal{echtler}{echtler}} {TRUE} {FALSE}

\bigskip

\textbf{macro}

\newcommand{\echtler}{echtler}

\ifthenelse{\equal{\string\echtler}{echtler}} {TRUE} {FALSE}

\ifthenelse{\equal{\echtler}{echtler}} {TRUE} {FALSE}

\ifthenelse{\equal{\echtler}{\detokenize{echtler}}} {TRUE} {FALSE}

\ifthenelse{\equal{echtler}{echtler}} {TRUE} {FALSE}

\end{document}


As you see, the first attempt, with \string, returns false in every case. Indeed, it compares the characters (not the commands) \jobname or \echtler with echtler and the two are obviously different.

The second attempt returns false in the jobname case and true in the macro case. This is because the expansion of \jobname is indeed echtler, but with “stringified characters” (TeXnically, with category code 12 instead of the standard 11).

In the third attempt, the comparison string is “detokenized”, operation that converts character in “stringified form”, so the jobname case succeeds and the macro case doesn't.

How to get a comparison test that works independently?

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\stringsequalTF}{mmmm}
{
\str_if_eq:eeTF { #1 } { #2 } { #3 } { #4 }
}
\ExplSyntaxOff

\begin{document}

\newcommand{\echtler}{echtler}

\stringsequalTF{\jobname}{echtler} {TRUE} {FALSE}

\stringsequalTF{\echtler}{echtler} {TRUE} {FALSE}

\stringsequalTF{echtler}{echtler} {TRUE} {FALSE}

\end{document}


• Thank you, an excellent explanation. I've never heard about \detokenize and category codes before, and the ifelse docs also didn't really contain anything about this. Dec 21, 2017 at 8:22
• Today (August 26, 2021) I got the error message that \str_if_eq_x:nnTF is deprecated and should be replaced by \str_if_eq:eeTF, don't ask me why… I did it and it works, maybe the author of this very useful solution should update the code… Aug 26, 2021 at 17:28
• @yannis Thanks for the reminder. Aug 26, 2021 at 17:38

A test for \equal{\string\jobname}{test} will never yield what you're after. If you want to compare and see whether you're better off using something like

\ifnum\pdfstrcmp{\jobname}{test}=0
TRUE%
\else
FALSE%
\fi


where \pdfstrcmp{<strA>}{<strB>} provides an expandable text comparison between <strA> and <strB>. The result - a number - equals 0 if they are the same, -1 if <strA> < <strB> lexicographically, and +1 otherwise.