6

I am starting to use \newif in a LaTeX class definition to finally stop carrying around all my definitions and imports from article to article.

Since I am trying to define options, I am ending defining a lot of switches. One thing I don't understand is why this works:

\if@myswitch
   \renewcommand{\myquietcommand}[1]{{}}
\fi

but this doesn't:

\if@myswitch{
   \renewcommand{\myquietcommand}[1]{{}}
}\fi

I am sure this has to do with the way LaTeX parses a document, but I am wondering how to produces the equivalent effect (of providing my editor indentation hints for what is contained inside the "if macro block").

2

2 Answers 2

11

You can happily put a brace group inside a primitive conditional, but it has no special syntactic meaning. Instead, it simply forms a group in the same way it would outside of a conditional. Thus when

\if@myswitch{
   \renewcommand{\myquietcommand}[1]{{}}
}\fi

is expanded, and assuming \if@myswitch is true, we end up with

{
  \renewcommand{\myquietcommand}[1]{{}}
}

This starts a group, inserts a space (after {), executes the \renewcommand, inserts another space (after {{}}) and then closes the group. The end of the group means that the definition of \myquietcommand reverts to that before the group opened.

If you are using TeX conditionals (\if@...) only use a brace group if you want an extra group. LaTeX conditionals such as \IfFileExists, in contrast, take two arguments in brace groups.

6

One of the great mysteries of LaTeX is

{\ifnum0=`}\fi

to be paired with its sibling

\ifnum0=`{\fi}

but one can also find

\iftrue{\else}\fi
\iffalse{\else}\fi

These are perfectly legal TeX constructs. Both {\ifnum0=`}\fi and \iftrue{\else}\fi contribute, when expanded, an open brace. The TeXnical reason for {\ifnum0=`}\fi is rather complex; I'll describe a possible usage of \iftrue{\else}\fi.

Suppose you want to build a braced token list, step by step, but this list should consist of braced sublists.

\def\initlist#1{%
  \def#1{\iftrue{\else}\fi}
}
\def\addtolist#1#2{%
  \listappend#1{\unexpanded{#2}}%
}
\def\addbreaktolist#1{%
  \listappend#1{%
    \iffalse{\else}\fi\iftrue{\else}\fi
  }%
}
\def\finishlist#1{%
  \listappend#1{%
    \iffalse{\else}\fi
  }%
  \edef#1{#1}%
}

\def\listappend#1#2{%
  \expandafter\def\expandafter#1\expandafter{#1#2}%
}

\initlist\foo

\addtolist\foo{abc}
\addtolist\foo{def}
\addbreaktolist\foo
\addtolist\foo{ghi}
\finishlist\foo

\show\foo

(this has \unexpanded that could be dispensed with).

The result on the terminal is

> \foo=macro:
->{abcdef}{ghi}.

At no time there were unbalanced braces and the token list comes out as expected, thanks to the final \edef that gets rid of \iftrue and \iffalse, leaving just the desired braces.


What's the above example for? It's aimed to show that, for TeX, conditionals and braces are completely independent of each others. TeX conditionals don't rely on braces to delimit the true and false text. The general form is

<if><test><true text>\else<false text>\fi

where <if> stands for one of the primitive conditionals (and your \if@myswitch is either \iftrue or \iffalse), <test> consists of the appropriate tokens relative to the particular <if> (for \iftrue and \iffalse the <test> is empty) that TeX tries to discover with expansion. The <true text> and <false text> can be almost arbitrary list of tokens; as seen in the example above they can contain braces.

Of course one has to be confident with how TeX matches \else and \fi with the initial <if>, but this has been described elsewhere.

So what does your example do?

Assuming \if@myswitch returns “true”,

\if@myswitch{
   \renewcommand{\myquietcommand}[1]{{}}
}\fi

will leave

{ \renewcommand{\myquietcommand}[1]{{}} }\fi

on the main input stream (with the spaces, that could be relevant). The \fi will disappear when expanded. Otherwise it just leaves \fi.

Doing a \renewcommand in a group like in the above “true” case is just a complicated way to do nothing.

You must log in to answer this question.

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