5

It seems to be impossible to wrap \rowcolor in a macro defined with \NewDocumentCommand, while everything is fine with \newcommand. Is ist possible to fixe this?

\documentclass{article}

\usepackage[table]{xcolor}
\usepackage{xparse}

\NewDocumentCommand{\rowI}{}{
    \rowcolor{blue}
}
%\newcommand{\rowI}{
%   \rowcolor{green}
%}

\begin{document}
\begin{tabular}{lll}
    \rowI 1 & 2 & 3 \\
    1 & 2 & 3 \\
\end{tabular}
\end{document}

Since the error only appears with \NewDocumentCommand I guess xparse causes the problem and not \rowcolor itself …

  • macros defined with \NewDocumentCommand are e-TeX protected which I guess is the problem. Have you tried with \DeclareExpandableDocumentCommand? – clemens May 11 '14 at 14:50
7

The definition of \rowcolor in colortbl.sty is

\def\rowcolor{%
  \noalign{\ifnum0=`}\fi
  \global\let\CT@do@color\CT@@do@color
  \@ifnextchar[\CT@rowa\CT@rowb}

Thus we see that it starts with \noalign. When TeX is doing an alignment (with the primitive \halign, as is the case with tabular), when it has scanned a \cr that ends a row (including the one generated by the table preamble) it expands the next token in order to see if \omit or \noalign comes along. This is how \hline the optional argument to \\ or \multicolumn work. TeX continues expanding tokens until either it finds \noalign/\omit or another unexpandable token.

You have to know that \NewDocumentCommand uses the e-TeX feature called \protected; a macro defined with the \protected prefix will behave as if it were an unexpandable token as far as the scanning mechanism above is concerned: it will be considered equivalent to \relax for the time being, but it will be expanded normally after this preliminary lookup has ended.

(The same behavior happens for \protected macros in an \edef.)

So, never define with \NewDocumentCommand macros that contain (at the start of their replacement text) things that must be first in an alignment cell, such as \multicolumn, \hline, \cline (the same applies for the rule making commands of booktabs) or \rowcolor of colortbl.

The same limitation above applies for commands defined with \newcommand to have an optional argument, because they are expanded in a delayed fashion that would break the scanning for \omit/\noalign.

Use \newcommand (without optional arguments) or, if you really need an optional argument, \DeclareExpandableDocumentCommand of xparse (but check the documentation for the limitations in this case, for instance you need a mandatory argument after an optional argument).

  • Thanks for your explanations, but doesn’t “never define …” contradict “Use \newcommand …”. So what is best practice for defining a command for my table headings and isn’t it bad practice to mix up \newcommand and \DeclareDocumentCommand ins a sty file? – Tobi May 12 '14 at 10:23
  • @Tobi You're right: some bits of the answer remained in my head. – egreg May 12 '14 at 11:50
  • Now it makes sense … but what is the/your advice? Stick to xparse and use \DeclareExpandableDocumentCommand or mix “old” and “new“ syntax … – Tobi May 12 '14 at 11:53
  • @Tobi It's not “old and new”. Use \DeclareExpandableDocumentCommand (I hope it will be given a better name), if you want; or stick to \newcommand, which I hope will not be an alias of \NewDocumentCommand in view of these glitches. But LaTeX3 is still quite far away. – egreg May 12 '14 at 11:56
  • Thanks again. I know that it’s not really “old and new” :-) – Tobi May 12 '14 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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