\omitir mal colocado. \multispan com \newcommand definido com argumento opcional

\omitir mal colocado. \multispan com \newcommand definido com argumento opcional

Estou tentando construir meu próprio estilo de livro de receitas, que tem um ingrediente makro. Às vezes os ingredientes deveriam estar separados e ter um título, então tentei com um argumento opcional. Um exemplo mínimo é assim:

\documentclass{scrartcl}
\newcommand{\ingredient}[3][]{
    #1 #2 & #3 \\
}
\begin{document}
    \begin{tabular}{r|l}        
        \ingredient[\multicolumn{2}{l}{Head} \\]{test1}{test2}
        \ingredient[test3]{test4}{test5}
        \ingredient{test6}{test7}
    \end{tabular}
\end{document}

O que há de errado com esse código? Eu recebi a seguinte mensagem de erro:

! Misplaced \omit.
\multispan ->\omit 
                   \@multispan 
l.7 ...[\multicolumn{2}{l}{Head} \\]{test1}{test2}

Responder1

O material tabular érealmenteexigente sobre o que é permitido passar "antes" de uma linha. Em particular, deve ser totalmente expansível.

Daí, mesmo oatribuiçãoo que \ingredientprecisa ser feito para verificar seu argumento opcional é suficiente para iniciar a linha e então \multicolumnnão pode mais aparecer.

A maneira mais fácil de remediar isso é tornar o primeiro argumento \ingredientobrigatório:

\documentclass{scrartcl}
\newcommand{\ingredient}[3]{
    #1 #2 & #3 \\
}
\begin{document}
    \begin{tabular}{r|l}        
        \ingredient{\multicolumn{2}{l}{Head} \\}{test1}{test2}
        \ingredient{test3}{test4}{test5}
        \ingredient{}{test6}{test7}
    \end{tabular}
\end{document}

Responder2

Vocêpodemantenha sua sintaxe original e tenha uma única macro com um parâmetro opcional se você usar \DeclareExpandableDocumentCommanda partir doxparsepacote.

Código:

\documentclass{scrartcl}
\usepackage{xparse}

\DeclareExpandableDocumentCommand{\ingredient}{O{} m m}{%
    #1 #2 & #3 \\%
}%

\begin{document}
    \begin{tabular}{r|l}        
        \ingredient[\multicolumn{2}{l}{Head} \\]{test1}{test2}
        \ingredient[test3]{test4}{test5}
        \ingredient{test6}{test7}
    \end{tabular}
\end{document}

Responder3

Você pode usar "criativamente" noalignpara implementar a funcionalidade. No código a seguir, defino uma função \NewDocumentCommandOptionalInTabularque funciona de forma semelhante à de, \NewDocumentCommandexceto que vocêpodeuse o argumento opcional (ou estrela) como desejar.

\documentclass{scrartcl}

% ======== copy paste this part ========
\ExplSyntaxOn
\cs_new_protected:Npn \NewDocumentCommandOptionalInTabular #1 #2 #3 {
  \NewDocumentCommandOptionalInTabular_aux:xnnn {\exp_not:c{\cs_to_str:N #1-aux}} #1 {#2} {#3}
}

\cs_new_protected:Npn \NewDocumentCommandOptionalInTabular_aux:nnnn #1 #2 #3 #4 {
  \cs_new:Npn #2 { \noalign \bgroup #1 }
  \NewDocumentCommand #1 {#3} { \egroup #4 }
}
\cs_generate_variant:Nn \NewDocumentCommandOptionalInTabular_aux:nnnn {x}
\ExplSyntaxOff
% ======== end ========


% then you can just use \NewDocumentCommandOptionalInTabular to replace \NewDocumentCommand
\NewDocumentCommandOptionalInTabular \ingredient {O{} m m}{
    #1 #2 & #3 \\
}

\begin{document}
    \begin{tabular}{r|l}        
        \ingredient[\multicolumn{2}{l}{Head} \\]{test1}{test2}
        \ingredient[test3]{test4}{test5}
        \ingredient{test6}{test7}
    \end{tabular}
\end{document}

Inspirado porresposta da egrégia.

informação relacionada