I'd add some remarks to the nice answer by Leo Liu. Let's take a line from a package (it's not important to know which one)
\newcommand{\period@active}[1]{\begingroup\mathcode`\.="8000\ensuremath{#1}\endgroup}
This shows a common mistake that in the present example is actually innocuous, but only by chance, because \ensuremath
expands to \protect\ensuremath
and usually \protect
is unexpandable (or its expansion gives something that doesn't start with a number).
The command \mathcode
requires two numbers (with an optional equals between them); it's the second one that's more important: since "8000
is followed by a control sequence, TeX wants to expand it in order to see if its expansion starts with a (hexadecimal) digit. Were \ensuremath
not robustified, its expansion would be
\ifmmode ... \else ... \fi
and the conditional would be evaluated at a possibly wrong time.
The moral of this is: always leave a space after a constant (i.e. an explicit number required by TeX's syntax). This space will be ignored and the following control sequence will not be expanded before the assignment.
A proper way to write that definition would be
\newcommand{\period@active}[1]{\begingroup\mathcode`\.="8000
\ensuremath{#1}\endgroup}
(the end of line counts as a space, in this case).
There are cases when the constant mustn't be followed by a space, for example when we want to exploit \romannumeral
or \number
capabilities to expand everything that follows until finding something that can't be interpreted as a digit. However these are advanced LaTeX programming techniques (Ulrich Diez is a master in this field).
In the example case a \relax
after the number would have done and it's commonly used for terminating assignments. It's definitely required after an incomplete glue assignment
\myskip=1pt plus 3pt\relax
which is the real equivalent to LaTeX's \setlength{\myskip}{1pt plus 3pt}
.
However there are cases where \relax
must be avoided: when comparing numbers or lengths, we frequently are in a complete expansion context and \relax
would remain, since it's unexpandable: suppose we have a macro that must call different macros depending on the current value of a parameter \X
\def\xyz{\csname do\ifnum\X=10\relax a\else b\fi\endcsname}
would throw an error when \X
holds the value 10. Of course this might be solved in many different ways, but
\def\xyz{\csname do\ifnum\X=10 a\else b\fi\endcsname}
is correct anyway.
Returning to the main question, there are some cases that sometimes fail to be considered. TeX always ignores spaces when looking for undelimited arguments. All macros defined with \newcommand
use undelimited arguments, so
\parbox {3cm} {text}
\parbox
{3cm}
{text}
are perfectly equivalent. Also
\newcommand{\foo}
{something}
is free of problems. For example, I usually suggest to set environment definitions like
\newenvironment{foo}[1]
{begin}
{end}
Of course if begin
or end
must be split into more than one line, the same rules about protecting from end-of-line characters hold.
One potential source of head scratching doesn't come from spurious spaces in the definition, but from TeX reading rules. Whenever the begin
text in an environment typesets something or, more generally, starts a paragraph, the begin
text must be terminated by \ignorespaces
. Example: suppose that we want to add in front of a quotation a "title"; we can pass it to the new environment xquotation
as
\newenvironment{xquotation}[1]
{\begin{quotation}\noindent\textbf{#1} --- \ignorespaces}
{\end{quotation}
Without \ignorespaces
the input
\begin{xquotation}{Murphy}
If something can fail, it will.
\end{xquotation}
would have two spaces between the dash and "If". This space is exactly the end-of-line after the argument, which is not considered if \ignorespaces
is in force. This problem does not appear if the environment ends a paragraph in its begin
part and does not start one, since spaces are ignored in vertical mode.
\par
. – egreg Jun 5 '11 at 19:39%
! – xport Aug 5 '11 at 3:57