
Parece impossível envolver \rowcolor
uma macro definida com \NewDocumentCommand
, enquanto está tudo bem com \newcommand
. É possível consertar isso?
\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}
Como o erro só aparece com \NewDocumentCommand
acho que xparse
causa o problema e não \rowcolor
em si…
Responder1
A definição de \rowcolor
in colortbl.sty
é
\def\rowcolor{%
\noalign{\ifnum0=`}\fi
\global\let\CT@do@color\CT@@do@color
\@ifnextchar[\CT@rowa\CT@rowb}
Assim, vemos que começa com \noalign
. Quando o TeX está fazendo um alinhamento (com o primitivo \halign
, como é o caso do tabular
), quando ele escaneou um \cr
que finaliza uma linha (incluindo aquela gerada pelo preâmbulo da tabela) ele expande o próximo token para ver se \omit
ou \noalign
vem junto . É assim que \hline
o argumento opcional para \\
ou \multicolumn
funciona. O TeX continua expandindo tokens até encontrar \noalign
/ \omit
ou outro token não expansível.
Você tem que saber que \NewDocumentCommand
usa o recurso e-TeX chamado \protected
; uma macro definida com o \protected
prefixo se comportará como se fosse um token não expansível no que diz respeito ao mecanismo de varredura acima: será considerada equivalente por \relax
enquanto, mas será expandida normalmente após o término desta pesquisa preliminar.
(O mesmo comportamento acontece com \protected
macros em um arquivo \edef
.)
Então,nuncadefinir com \NewDocumentCommand
macros que contenham (no início do texto de substituição) coisas quedeveser o primeiro em uma célula de alinhamento, como \multicolumn
, \hline
, \cline
(o mesmo se aplica aos comandos de criação de regras de booktabs
) ou \rowcolor
de colortbl
.
A mesma limitação acima se aplica a comandos definidos com \newcommand
para terem um argumento opcional, porque eles são expandidos de forma atrasada, o que interromperia a varredura de \omit
/ \noalign
.
Use \newcommand
(sem argumentos opcionais) ou, se você realmente precisar de um argumento opcional, \DeclareExpandableDocumentCommand
of xparse
(mas verifique a documentação para saber as limitações neste caso, por exemplo, você precisa de um argumento obrigatório após um argumento opcional).