Неправильно указан \omit. \multispan с \newcommand, определенным с необязательным аргументом

Неправильно указан \omit. \multispan с \newcommand, определенным с необязательным аргументом

Я пытаюсь создать свой собственный стиль кулинарной книги, в котором есть макрос ингредиента. Иногда ингредиенты должны быть разделены и иметь заголовок, поэтому я попробовал с необязательным аргументом. Минимальный пример выглядит так:

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

Что не так с этим кодом? Я получаю следующее сообщение об ошибке:

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

решение1

Табличный материалДействительноразборчивы в том, что разрешено размещать "перед" строкой. В частности, она должна быть полностью расширяемой.

Следовательно, даженазначениекоторый \ingredientнеобходимо сделать для проверки того, что его необязательный аргумент достаточен для начала строки, а затем \multicolumnбольше не допускается к появлению.

Самый простой способ исправить это — сделать первый аргумент \ingredientобязательным:

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

решение2

Тыможетсохраните исходный синтаксис и используйте один макрос с необязательным параметром, если вы используете \DeclareExpandableDocumentCommandизxparseупаковка.

Код:

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

решение3

Вы можете "творчески" использовать noalignдля реализации функциональности. В следующем коде я определяю функцию, \NewDocumentCommandOptionalInTabularкоторая работает аналогично функции\NewDocumentCommand за исключением того, что выможетиспользуйте необязательный аргумент (или звездочку) по своему усмотрению.

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

Вдохновленответ egreg.

Связанный контент