9

Taking a look at the code of the package ifxetex, I found the following:

\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname ProvidesPackage\endcsname\relax\else
  \ProvidesPackage{ifxetex}
    [2010/09/12 v0.6 Provides ifxetex conditional]
\fi

I perfectly understand someone may want to check if LaTeX is being used or not before invoking \ProvidesPackage, so as to make the file usable by plain TeX too. However, I don't see the point in the first line. What is the reason behind a group containing only three \expandafters which seem to be there exclusively to get the \if done before the \endgroup? Why not simply remove that group?

  • Fine-grained expansion control. I think there's three expandafters because you want two levels of expansion. – 1010011010 Apr 6 '15 at 12:25
  • What does that line change in the effect of the code? I mean, suppose I remove it. To me, nothing changes. Obviously, there mus be something changing: I trust a package author knows better than to put a useless line of code in their work. So exactly what changes @1010011010? – MickG Apr 6 '15 at 12:39
9

A group is started, then

\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname ProvidesPackage\endcsname\relax\else
  \ProvidesPackage{ifxetex}
    [2010/09/12 v0.6 Provides ifxetex conditional]
\fi

remains. Now the first \expandafter is expanded, which causes the third to act, which expands the fourth and finally \csname ProvidesPackage\endcsname forms the \ProvidesPackage token, making it equivalent to \relax if not defined.

Now we're left with

\expandafter\endgroup
\ifx\ProvidesPackage\relax\else
  \ProvidesPackage{ifxetex}
    [2010/09/12 v0.6 Provides ifxetex conditional]
\fi

The remaining \expandafter expands \ifx. If \ProvidesPackage had no previous definition, the test returns true and

\endgroup\else\ProvidesPackage{ifxetex}[2010/09/12 v0.6 Provides ifxetex conditional]\fi

remains. The group is closed, undoing the assignment of a meaning to \ProvidesPackage. Then \else is expanded, which means that TeX skips all tokens up to the matching \fi which eventually disappears.

If there was a previous definition for \ProvidesPackage existed, TeX skips all tokens up to and including \else, so we remain with

\endgroup\ProvidesPackage{ifxetex}[2010/09/12 v0.6 Provides ifxetex conditional]\fi

The group is closed and \ProvidesPackage is executed (with the necessary expansion steps). The trailing \fi has null expansion.

The moral is that if \ProvidesPackage was not defined when the code is found, it won't be at the end of the process.

Without the \begingroup\expandafter\expandafter\expandafter\endgroup trickery, the code would end up with \ProvidesPackage being equivalent to \relax, if not defined previously.

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.