2

What does the exclamation marks (!) around the \@subheader command do in the following?

\renewcommand\maketitle{
...
\if!\@subheader!\else\noindent{\trfont{\@subheader}}\fi
...
}

Can someone please explain what is going on here? I think what it should do is something like

  1. If \@subheader is empty, do nothing.
  2. Else use the specified font to typset the subheader.

but I do not understand the meaning of the !...!

Just for context, the \@subheader is defined earlier as

\def\@subheader{\@empty}
\newcommand{\subheader}[1]{\gdef\@subheader{#1}}

I have checked both reference books on TeX and LaTeX but I cannot find any explanation.

  • What is the source of this code? – Andrew Swann Mar 21 '19 at 08:37
  • Related: https://tex.stackexchange.com/q/286902/35864 – moewe Mar 21 '19 at 08:40
  • 1
    Roughly: If \@subheader is empty (or \@empty) \if compares the two !s which yields false and means that nothing happens since the <true> branch is otherwise empty. If \@subheader is not empty, \if compares ! to the first 'thing' in \@subheader. The test relies on the assumption that this comparison is false. Then the \else/<false> branch is executed. You can confuse this test if you start your \@subheader with an !. Note that \if expands the stuff that follows it until it gets two unexpandable tokens (for example letters). – moewe Mar 21 '19 at 08:42
  • The source is a slightly modified version of this class: link – JezuzStardust Mar 21 '19 at 09:15
  • @moewe OK, but why is the ! after the \@subheader needed? Is it correct that it comapares the character "!" with the characters found in \@subheader? In the link above I read that everything after \if will be expanded until you get two unexpandable tokens. Would you please explain what happens if \@subheader is set to the word hello, what would happen then? – JezuzStardust Mar 21 '19 at 09:48
  • 2
    Related: https://tex.stackexchange.com/q/33823/4427 – egreg Mar 21 '19 at 10:39
  • 1
    The real question is why they didn't use \ifx\@empty\@subheader\relax – John Kormylo Mar 21 '19 at 15:11

1 Answers1

3

LaTeX \if condition has a good explanation of \if and a link to TeX by Topic explaining it a bit more already, so we can probably focus on this particular example here.

The test

\if!\@subheader!\else\noindent{\trfont{\@subheader}}\fi

is indeed intended to check if \@subheader is empty. It relies on the assumption that the contents of \@subheader will never start with !.

\documentclass{article}

\newcommand*{\mytest}{%
  \if!\foo!
    empty
  \else
    \emph{not} empty
  \fi    
}


\begin{document}
\def\foo{\empty}
\mytest

\def\foo{}
\mytest

\def\foo{Hello}
\mytest

\def\foo{!oohh, nasty}
\mytest

\def\foo{That works! Phew!}
\mytest

\def\foo{ }
\mytest
\end{document}

empty//empty//not empty//oohh, nasty empty//not empty//not empty

shows a few examples of the conditional in action.

\if expands the following content until it finds two unexpandable tokens. Those tokens are then compared.

The ! is already an unexpandable token, so the test compares ! to the first unexpandable token that occurs when \@subheader! is expanded.

Suppose \@subheader is empty in the sense that it expands to nothing (if it is fully expanded). This happens for example if we have \def\@subheader{} or even \def\@subheader{\@empty}, where \@subheader is defined to expand to \@empty, which in turn expands to nothing. Then \if!\@subheader! compares ! to ! since \@subheader expands to nothing and just vanishes. That test is true and so we get the <true> branch, which does nothing in the original code.

Suppose \@subheader is not empty and that its first token after full expansion is not !. If for example \@subheader is \def\@subheader{Hello}, then \if!\@subheader! compares ! with H and the rest of the expansion and the trailing ! (ello!) live on in the <true> branch. Since ! and H are different, we get the <false> branch, though and don't get to see the excess letters.

Suppose \@subheader expands to something which contains ! as the first token, e.g. \def\@subheader{!oohh, nasty} Then \if!\@subheader! compares ! to ! and enters the <true> branch. The expanded rest of the \@subheader (oohh, nasty) lives on there and produces unwanted additional output.


If there was no trailing ! in \if!\@subheader! TeX would have to keep looking for the second token in case \@subheader expands to nothing.

moewe
  • 175,683