Fuera de lugar \omitir. \multispan con \newcommand definido con argumento opcional

Fuera de lugar \omitir. \multispan con \newcommand definido con argumento opcional

Estoy intentando crear mi propio estilo de libro de cocina, que tiene un ingrediente makro. A veces los ingredientes deben estar separados y tener un título, así que probé con un argumento opcional. Un ejemplo mínimo se ve así:

\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}

¿Qué hay de malo en este código? Recibo el siguiente mensaje de error:

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

Respuesta1

El material tabular esen realidadexigente con lo que se permite ir "antes" de una línea. En particular, tiene que ser completamente ampliable.

Por lo tanto, incluso elasignaciónlo que \ingredientse debe hacer para verificar su argumento opcional es suficiente para comenzar la línea y luego \multicolumnya no se le permite aparecer.

La forma más sencilla de remediar esto es hacer que el primer argumento sea \ingredientobligatorio:

\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}

Respuesta2

poderconserve su sintaxis original y tenga una sola macro con un parámetro opcional si usa \DeclareExpandableDocumentCommanddesde elxparsepaquete.

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}

Respuesta3

Puede utilizarlo "creativamente" noalignpara implementar la funcionalidad. En el siguiente código, defino una función \NewDocumentCommandOptionalInTabularque funciona similar a la de\NewDocumentCommand excepto quepoderuse el argumento opcional (o estrella) como desee.

\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 porla respuesta de egreg.

información relacionada