Ошибка многоколоночности при использовании в новой команде с \@ifstar

Ошибка многоколоночности при использовании в новой команде с \@ifstar

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

\newcommand{\topics}{\@ifstar{\topicsStar}{\topicsNoStar}}
\newcommand{\topicsNoStar}[1]{\multicolumn{2}{|p{2in}|}{test}}
\newcommand{\topicsStar}{&&}

Когда я звоню

\topicsNoStar{stuff} 

вывод правильный.

Когда я звоню

\topics{stuff} 

Я получаю сообщение об ошибке:!Misplaced \omit. \multispan ->\omit \@multispan

Меня сбивает с толку разница между этими двумя вызовами — по моему мнению, они должны делать одно и то же, но результат получается разный.

Теперь я планирую включить @'s в команды выше в финальной версии, но для отладки я хотел иметь возможность вызывать их вне файла стиля. Кроме того, аргумент NoStar не используется, он будет помещен в multicolumn, как только это заработает правильно.

решение1

Это решение основано на требовании, предложенном Хайко в! Неправильно указанная \omitошибка.

etextoolsпредоставляет полностью расширяемые команды кондиционирования, позволяющие \multicolumnрассматривать его как «первый элемент в ячейке». В вашем примере это пока не так, поскольку \@ifstarне полностью расширяемый, в то время как \FE@ifstarявляется Fполностью Eрасширяемой версией:

введите описание изображения здесь

\documentclass{article}
\usepackage{etextools}% http://ctan.org/pkg/etextools
\makeatletter
\newcommand{\topics}[1]{%
  \FE@ifstar{#1}
    {test & test}% starred
    {\multicolumn{2}{|p{2in}|}{#1}\@gobble}}% non-starred
\makeatother
\begin{document}
\begin{tabular}{|p{1in}p{1in}|}
  \topics{stuff} \\
  \topics* \\
  \topics{some more stuff} \\
  \topics* \\
  \topics*
\end{tabular}
\end{document}

решение2

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

\documentclass{article}
\newcommand{\topics}[1]{%
  \if*\detokenize{#1}%
    &%
  \else
    \multicolumn{2}{|p{2in}|}{#1}%
  \fi
}
\begin{document}
\begin{tabular}{|p{1in}p{1in}|}
  \topics{stuff} \\
  \topics* \\
  \topics{some more stuff} \\
  \topics* \\
  \topics*
\end{tabular}
\end{document}

решение3

Это альтернатива, использующая мой \NewDocumentCommandOptionalInTabularмакрос вдругой ответ.

\documentclass{article}

% ======== 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 ========


\NewDocumentCommandOptionalInTabular \topics {s} {\IfBooleanTF{#1}{\topicsStar}{\topicsNoStar}}
\newcommand{\topicsNoStar}[1]{\multicolumn{2}{|p{2in}|}{#1}}
\newcommand{\topicsStar}{test & test}

\begin{document}
\begin{tabular}{|p{1in}p{1in}|}
  \topics{stuff} \\
  \topics* \\
  \topics{some more stuff} \\
  \topics* \\
  \topics*
\end{tabular}
\end{document}

Результат соответствует вашим ожиданиям.

выход


Пример, в котором тест расширяемой звезды нарушает кернинг в следующем символе:

%! TEX program = pdflatex
\documentclass{article}
\usepackage{etextools}% http://ctan.org/pkg/etextools
\makeatletter
\newcommand{\test}[1]{%
  \FE@ifstar{#1}
    {123}
    {456}}
\makeatother

\begin{document}

\test VA  % ← see the space between V and A here is much larger than that of...

VA  % the space between V and A in this line.

\end{document}

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