Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have experience where empty spaces cause unwanted effects. It is not easy to trace the cause of these unwanted effects. In order to eliminate any doubt, I often overuse % as follows.

\usepackage%
[%
left=3cm,
right=3cm%
]%
{geometry}

or

\newcommand{\mycommand}%
{%
This is my command.%
}

I got an extreme example that will break what Leo Liu said

In fact, only spaces which would be output have to be removed by comment.

The following code does not produce output, but we cannot remove the % and leave a blank line between two elements of a list below.

\newpsstyle{gridstyle}
{
gridwidth=0.4pt,
%
griddots=0
}

Shortly speaking, where are the necessary places to be appended with % to remove unwanted spaces?

share|improve this question
6  
I think I've answered this somewhere else here already. Basically, spaces are always ignored after control words (i.e., control sequences consisting of `` followed by letters). In the preamble (or in vertical mode more generally), spaces aren't important except in things like the replacement text of a macro. –  TH. Jun 5 '11 at 5:59
4  
@TH. : This previous question? What is the use of percent signs at the end of lines? –  Leo Liu Jun 5 '11 at 7:24
1  
a blank line is not a space, but is converted into \par. –  egreg Jun 5 '11 at 19:39
    
@Leo: Yeah, that's the one. –  TH. Jun 6 '11 at 8:29
    
This answer overused %! –  xport Aug 5 '11 at 3:57

3 Answers 3

up vote 35 down vote accepted

In fact, only spaces which would be output have to be removed by comment. And remember, spaces after a all-letter control sequence (also known as a control word as opposed to a control symbol) are ignored.

You can use:

\usepackage
[
  left  = 3cm,
  right = 3cm
]
{geometry}

It's Okey, no spaces will be output.

But you have to use:

\newcommand\foo
{% the space in \foo will be output when you use it in the text
  foo.%
}

That's why in TeX, package writers often use:

\newcommand\foo{%
  foo.}

In LaTeX3 macro syntax, all spaces (even between words) are ignored to ease macro writers. For example,

\RequirePackage{expl3,xparse}
\ExplSyntaxOn
\DeclareDocumentCommand \hello { m }
{
  hello~#1.
}
\ExplSyntaxOff

The tilde ~ here is a normal space char.


In some packages, like CJK, writers use

\endlinechar \m@ne

to ignore the extra spaces introduced by newlines. Then you can use:

\newcommand\foo{
  foo.
}

and after all macros,

\endlinechar `\^^M
share|improve this answer
    
+1. It is a good answer but I will wait for a couple of days to get other answers with which your answer will be compared. –  xport Jun 5 '11 at 7:10

What Leo Liu said is general true. In general a line break is equivalent to a white space. But a blank line is not. A blank line is usually interpreted as the same as \par.

And without \long a \def containing a \par will break. And this why a blank line will break many code if no % is appended. It is not about white space but about \par.

I suggest you read the chapter 20 of The TeXbook for a general knowledge of macro definitions. If it is not available, the book TeX by Topic, which is distributed with TeXLive, also has a good introduction to how TeX read in your input.

In summary, TeX is much a free-form language just like C/C++. The only main difference is that TeX interpret the special characters (new line, etc) based on the context (sometimes they are white space, sometimes they are \par, and sometimes they can be anything by assigning catcode). Knowing all these will help you to see clearly when you should use a % to comment out the newline.

share|improve this answer
    
Welcome to tex.sx! A tip: you can use backticks ` to mark your inline code‌​. –  Caramdir Jun 5 '11 at 20:34

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.

share|improve this answer
3  
Maybe it's better to use \relax after a number, especially a glue. For example, 1pt plus 1pt\relax, then a minus after it will be safe. –  Leo Liu Jun 5 '11 at 15:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.