TransWikia.com

Why does ifx consider MakeUppercase{1} and MakeLowercase{1} different?

TeX - LaTeX Asked on August 23, 2021

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

documentclass{memoir}

begin{document}

deftestone{MakeUppercase{1}}
deftesttwo{MakeLowercase{1}}

ifxtestonetesttwo
    Equal
else
    Diff
fi

end{document}

Prints: Diff

3 Answers

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, edefupperone{{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
edefupone{text_uppercase:n {1}}
edeflowone{text_lowercase:n {1}}
ExplSyntaxOff
    
begin{document}
{upone} and {lowone} are
ifxuponelowone
  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.

Correct answer by Davislor on August 23, 2021

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).

Answered by Don Hosek on August 23, 2021

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

deffirstX{X}
defsecondX{X}
deftestA{firstX}
deftestB{secondX}

The conditional ifxfirstXsecondX will return true, but ifxtestAtestB will return false.

Another example: with

deffirst#1{#1}
defsecond#1{#1}
deftestA{first{X}}
deftestB{second{X}}

the conditional ifxtestAtestB 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.

Answered by egreg on August 23, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP