\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_x:nnTF { #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. – Florian Echtler Dec 21 '17 at 8:22

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.