4

In this minimal example, an uppercase number is different of the same lowercase number. Why?

\documentclass{memoir}

\begin{document}

\def\testone{\MakeUppercase{1}}
\def\testtwo{\MakeLowercase{1}}

\ifx\testone\testtwo
    Equal
\else
    Diff
\fi

\end{document}

Prints: Diff

9

Like Donald Hosek said, \ifx doesn’t expand its arguments. You’re comparing the unexpanded macros \MakeUppercase{1} and \MakeLowercase{1}. You could fix this by fully expanding the macros you compare.

However, that doesn’t give you a complete solution, because \MakeUppercase and \MakeLowercase are not expandable. So, \edef\upperone{{\MakeUppercase 1}} will fail. You should instead use the expl3 functions that are fully-expandable, and that also support Unicode.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
    
\ExplSyntaxOn
\edef\upone{\text_uppercase:n {1}}
\edef\lowone{\text_lowercase:n {1}}
\ExplSyntaxOff
    
\begin{document}
{\upone} and {\lowone} are
\ifx\upone\lowone
  identical.
\else
  different.
\fi
    
\end{document}

This gives you, “1 and 1 are identical.”

Edit

Joseph Wright brings up that you might really be after a case-insensitive comparison. For that, you should be using \str_fold_case:n, which supports Unicode on LuaTeX or XeTeX, but only ASCII on PDFTeX.

| improve this answer | |
  • 1
    All fair, but \text_<name>case:n is for typesetting. I suspect the comparison is string-based here, and even more so it's often the case that's what really wanted is case-folding. – Joseph Wright Jul 22 at 7:16
  • @JosephWright Very possible! – Davislor Jul 22 at 8:50
  • 1
    @DonaldHosek Apologies for the typo in your name! Good answer, too, although I wanted to expand on it with a solution. – Davislor Jul 22 at 18:41
11

You're going to get different results because you're comparing the definitions of the two macros. \MakeUppercase{1} is not the same as \MakeLowercase{1} It's worth noting that the \MakeUppercase and \MakeLowercase macros are themselves complicated enough that the naïve approaches to trying to expand them to get the results in plain text will still not give expected results (so doing, e.g., \edef or multiple \expandafters won't get you what you might have been hoping for).

| improve this answer | |
  • So, what's the best way to compare strings without macro interferences? – EVANDSON DANTAS Jul 22 at 3:41
  • 2
    For most things, what you've done would work fine. The problem is with \MakeUppercase and \MakeLowercase whose output is not a simple string—note, for example, that it has to be able to handle things like correctly uppercasing na\"\i ve to NA\"IVE, to pick one example. What are you trying to accomplish? – Don Hosek Jul 22 at 3:51
6

The test fails to show equality on (at least) two levels.

First level

\MakeUppercase and \MakeLowercase are instructions to print the uppercased or lowercased versions of their arguments. They don't “directly” transform their arguments.

Second level

\ifx only compares the “surface meaning” of two tokens without any macro expansion. In particular, two macros (every token defined with \def is a macro) are considered equal by \ifx if and only if

  1. they have the same status with respect to \long, \outer and \protected;
  2. their parameter texts are the same;
  3. their top level expansions are equal.

In your case subtests 1 and 2 pass, but subtest 3 doesn't, because the top level expansions are

\MakeUppercase{1}

and

\MakeLowercase{1}

respectively, which are different sequences of tokens.


A perhaps simpler example is given by

\def\firstX{X}
\def\secondX{X}
\def\testA{\firstX}
\def\testB{\secondX}

The conditional \ifx\firstX\secondX will return true, but \ifx\testA\testB will return false.

Another example: with

\def\first#1{#1}
\def\second#1{#1}
\def\testA{\first{X}}
\def\testB{\second{X}}

the conditional \ifx\testA\testB will return false because the top level expansions of \testA and \testB are different even if ultimately \first{X} and \second{X} will deliver the same result. But TeX doesn't look at the “ultimate” effect when doing \ifx comparisons, just the surface.

| improve this answer | |

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.