Erro de múltiplas colunas quando usado em um novo comando com \@ifstar

Erro de múltiplas colunas quando usado em um novo comando com \@ifstar

Sou novo em escrever pacotes e estou me deparando com um erro que não consigo desvendar. Agradeço qualquer ajuda que você possa fornecer. Estou escrevendo algumas macros que devem ser usadas em um ambiente tabular:

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

Quando eu ligo

\topicsNoStar{stuff} 

a saída está correta.

Quando eu ligo

\topics{stuff} 

Recebo a mensagem de erro:!Misplaced \omit. \multispan ->\omit \@multispan

O que está me confundindo é a diferença entre as duas chamadas - na minha opinião, elas deveriam estar fazendo a mesma coisa, mas a saída não é a mesma.

Agora, pretendo incluir @nos comandos acima na versão final, mas, para depurar, queria poder chamá-los fora do arquivo de estilo. Além disso, o argumento para NoStar não é usado, ele será colocado na multicoluna assim que estiver funcionando corretamente.

Responder1

Esta solução é baseada no requisito sugerido por Heiko em! \omitErro extraviado.

etextoolsfornece comandos de condicionamento totalmente expansíveis para permitir \multicolumnser considerado como "o primeiro elemento da célula". Atualmente, este não é o caso do seu exemplo, pois \@ifstarnão é totalmente expansível, embora \FE@ifstarseja uma versão Fully Expandable:

insira a descrição da imagem aqui

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

Responder2

\multicolumndeve ser a primeira coisa em uma célula da tabela e um comando com uma variante em estrela definida da maneira usual se esconde \multicolumnapós algum token não expansível. Sem pacotes você pode fazer da seguinte maneira:

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

Responder3

Esta é uma alternativa, usando minha \NewDocumentCommandOptionalInTabularmacro emoutra resposta.

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

A saída é como você espera.

saída


Um exemplo onde o teste de estrela expansível quebra o kerning no seguinte caractere:

%! 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}

informação relacionada