\rowcolor em \NewDocumentCommand

\rowcolor em \NewDocumentCommand

Parece impossível envolver \rowcoloruma 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 \NewDocumentCommandacho que xparsecausa o problema e não \rowcolorem si…

Responder1

A definição de \rowcolorin 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 \crque finaliza uma linha (incluindo aquela gerada pelo preâmbulo da tabela) ele expande o próximo token para ver se \omitou \noalignvem junto . É assim que \hlineo argumento opcional para \\ou \multicolumnfunciona. O TeX continua expandindo tokens até encontrar \noalign/ \omitou outro token não expansível.

Você tem que saber que \NewDocumentCommandusa o recurso e-TeX chamado \protected; uma macro definida com o \protectedprefixo se comportará como se fosse um token não expansível no que diz respeito ao mecanismo de varredura acima: será considerada equivalente por \relaxenquanto, mas será expandida normalmente após o término desta pesquisa preliminar.

(O mesmo comportamento acontece com \protectedmacros em um arquivo \edef.)

Então,nuncadefinir com \NewDocumentCommandmacros 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 \rowcolorde colortbl.

A mesma limitação acima se aplica a comandos definidos com \newcommandpara 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, \DeclareExpandableDocumentCommandof 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).

informação relacionada