Error de varias columnas cuando se usa dentro de un nuevo comando con \@ifstar

Error de varias columnas cuando se usa dentro de un nuevo comando con \@ifstar

Soy nuevo en la escritura de paquetes y me encuentro con un error que no puedo resolver. Agradecería cualquier ayuda que puedan brindarme. Estoy escribiendo algunas macros destinadas a usarse dentro de un entorno tabular:

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

cuando llamo

\topicsNoStar{stuff} 

la salida es correcta.

cuando llamo

\topics{stuff} 

Recibo el mensaje de error:!Misplaced \omit. \multispan ->\omit \@multispan

Lo que me confunde es la diferencia entre las dos llamadas: en mi opinión, deberían hacer lo mismo, pero el resultado no es el mismo.

Ahora, planeo incluir @'s' en los comandos anteriores en la versión final, pero, para depurar, quería poder llamarlos fuera del archivo de estilo. Además, el argumento de NoStar no se utiliza; se colocará en la columna múltiple una vez que funcione correctamente.

Respuesta1

Esta solución se basa en el requisito sugerido por Heiko en! \omiterror fuera de lugar.

etextoolsproporciona comandos de acondicionamiento totalmente ampliables para permitir \multicolumnser considerado como "el primer elemento de la celda". Actualmente, este no es el caso en su ejemplo, ya que \@ifstarno es completamente expandible, mientras que \FE@ifstares una versión Ftotalmente Eexpandible:

ingrese la descripción de la imagen aquí

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

Respuesta2

\multicolumndebe ser lo primero en una celda de la tabla y un comando con una variante de estrella definida de la manera habitual se esconde \multicolumndespués de algún token no expandible. Sin paquetes puedes hacerlo de la siguiente manera:

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

Respuesta3

Esta es una alternativa, usando mi \NewDocumentCommandOptionalInTabularmacro enotra respuesta.

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

El resultado es el esperado.

producción


Un ejemplo en el que la prueba de estrella expandible rompe el interletraje en el siguiente carácter:

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

información relacionada