2

(preface: this lua stuff is just the motivation the real issue is with pure LaTeX)

I'm currently in some package writing in particular with LuaLaTeX. Since I'm often having a/some commands which collect some data to store data in a table to print it later (after e.g. doing some sorting or grouping). Therefore these commands just invoke \directlua and expand effectively to nothing.

Now when working with tables, I noticed that such commands produce extra space in a cell (even though the expand to nothing) if an optional argument is involved, see this example with some variations:

\documentclass{article}
\parindent0pt
\begin{document}
\newcommand{\myCmd}[2][]{}
With opt arg:\\
\begin{tabular}{|l|}
    x \\
    \myCmd{x}
    \myCmd{x}
    \myCmd{x}
    x \\
\end{tabular}
\vspace{.5cm}

\renewcommand{\myCmd}[1]{}
Without opt arg:\\
\begin{tabular}{|l|}
    x \\
    \myCmd{x}
    \myCmd{x}
    \myCmd{x}
    x \\
\end{tabular}
\vspace{.5cm}

\renewcommand{\myCmd}[2][]{}
Outside of a table with opt arg:\\
x \\
\myCmd{x}
\myCmd{x}
\myCmd{x}
x \\
\vspace{.5cm}

\renewcommand{\myCmd}[1]{}
Outside of a table without opt arg:\\
x \\
\myCmd{x}
\myCmd{x}
\myCmd{x}
x \\
\end{document}

Example

(compiled with pdflatex, but lualatex looks almost the same)

Now I for some part I know where the spacing comes from, since when I suffix the lines just containing the \myCmd with a % (or put the lines all in one line) the space is gone.

What I definitely don't understand why this corresponds to having optional arguments.

But most importantly my question is how to get rid of the spacing (in the best case without adding something like % in the "normal" code since it would be nice to hide this in the implementation of my package).

1
  • 1
    A simple fix is to use \newcommand{\myCmd}[2][]{\ignorespaces}. Commented Nov 18, 2021 at 23:05

1 Answer 1

2

At the beginning of a cell spaces are gobbled using \ignorespaces. This is a primitive that expands tokens and discards space tokens until a nonspace token is found.

When the macro is defined without optional spaces its expansion is empty and the spaces coming from the endlines after \myCmd{x} are gobbled by \ignorespaces.

This doesn't happen when the macro is defined with an optional argument, because during expansion TeX encounters something unexpandable which does not produce text, but ends the job of \ignorespaces nonetheless.

If you want that a command ignores spaces (and endlines) after it, end its definition with \ignorespaces. But of course the best strategy is to mask the endlines you don't want to produce spaces with %.

5
  • So you'd suggest doing the % instead of using \ignorespaces in the end of the macro definition. Is there a particular reason for this (because having to put % everywhere doesn't look nice, is prone to errors and takes some effort)?
    – atticus
    Commented Nov 18, 2021 at 23:18
  • 1
    @atticus Add spaces where you want them. But you have to judge according to the particular situation. For instance, macros in picture mode make so that spaces are ignored.
    – egreg
    Commented Nov 19, 2021 at 7:56
  • 1
    @atticus The end-of-line becomes a "space" (=glue) because in the code file you can type three lines text<newline> \commandname[options]{cyx}{abc}<newline> text for legibility and ease of maintenance and will be processed as one logical line. So two end-of-lines mark a paragraph.
    – Cicada
    Commented Nov 19, 2021 at 9:03
  • Hm ok thanks so far, my issue is solved. This is just out of curiosity, why is this only an issue in the tabular environment?
    – atticus
    Commented Nov 19, 2021 at 11:33
  • 1
    @atticus Because in normal text spaces at the beginning of a line are removed in the typesetting phase. A table cell is a horizontal box, so no such removal happens, unless \ignorespaces has done its work previously.
    – egreg
    Commented Nov 19, 2021 at 12:46

You must log in to answer this question.

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