3

I was trying to define a command to behave differently when the text is italic, and I came across a difference between \newcommand and \newcommand* (or rather, I think, a behavior of \long definitions or of \ifx) that I don't understand. Basically, I define a command \@it to be it. Then, I want to check whether the text is italic or not using \ifx\f@shape\@it. This test works when \@it is defined using \def or \newcommand*, but not when \@it is defined using \long\def or \newcommand.

The following example should make everything clear.

\documentclass{article}
\makeatletter
\def\@defit{it}
\long\def\@longdefit{it}
\newcommand{\@ncit}{it}
\newcommand*{\@ncsit}{it}
\newcommand{\itcheck}{%
    \ifx\f@shape\@defit
        The test from \textnormal{\textbackslash\texttt{def}} found the italic shape.
    \else
        The test from \textnormal{\textbackslash\texttt{def}} did not found the italic shape.
    \fi\par
    \ifx\f@shape\@longdefit
        The test from \textnormal{\textbackslash\texttt{long}\textbackslash\texttt{def}} found the italic shape.
    \else
        The test from \textnormal{\textbackslash\texttt{long}\textbackslash\texttt{def}} did not found the italic shape.
    \fi\par
    \ifx\f@shape\@ncit
        The test from \textnormal{\textbackslash\texttt{newcommand}} found the italic shape.
    \else
        The test from \textnormal{\textbackslash\texttt{newcommand}} did not found the italic shape.
    \fi\par
    \ifx\f@shape\@ncsit
        The test from \textbackslash\textnormal{\texttt{newcommand*}} found the italic shape.
    \else
        The test from \textbackslash\textnormal{\texttt{newcommand*}} did not found the italic shape.
    \fi%
}
\makeatother
\begin{document}
\itshape\itcheck
\end{document}

I would have expected all tests to return true. Why is it not the case?

5
  • 2
    a long definition is never ifx equal to a non long one. Commented May 24, 2020 at 20:34
  • 1
    There is no reason to define a macro without parameter as long. Its behavior is exactly the same as no-long version of such macro. This is the reason, why \f@shape is defined as no-long. And your long definition of macros without parameters are irrelevant.
    – wipet
    Commented May 25, 2020 at 19:00
  • @wipet That seems indeed very logical. Thanks! I should probably just take the time to read a proper introduction to TeX one of these days.
    – Vincent
    Commented May 26, 2020 at 2:15
  • ... to read a proper introduction to TeX: I wrote TeX in a Nutshell at these days. It is released at CTAN.
    – wipet
    Commented May 26, 2020 at 4:20
  • @wipet Interesting, I'll take a look! :-)
    – Vincent
    Commented May 26, 2020 at 16:20

1 Answer 1

2

With plain TeX, which is simpler: the code

\def\shortfoo{foo}
\long\def\longfoo{foo}

\ifx\shortfoo\longfoo\message{EQUAL}\else\message{DIFFERENT}\fi
\bye

will show DIFFERENT on the terminal.

Two macros are considered equal by \ifx if

  1. their parameter text is the same;
  2. their replacement text is the same;
  3. their status with respect to \long and \outer is the same.

With e-TeX there is also another status to keep in mind: \protected.

If you're sure that your macros expand to character tokens, then

\ifnum\pdfstrcmp{\shortfoo}{\longfoo}=0

will return true. The pdftex primitive is called \strcmp in XeTeX and is missing from LuaTeX (the package pdftexcmds provides a Lua replacement). You can \usepackage{pdftexcmds} (or \input pdftexcmds.sty in plain TeX) and call it as \pdf@strcmp in the three engines.

1
  • Thanks! It seems clearer to me now. So I understand that the tests in my example failed because \f@shape is not \long. Maybe this will seem to be a weird question for a more experienced user, but is there some kind of rule of thumb to know which commands are \long and which are not? I only knew the \f@shape command from this answer, should I have guessed it was not \long?
    – Vincent
    Commented May 25, 2020 at 2:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .