11

I am new to writing packages and am coming across an error that I can't unravel, I would appreciate any help that you can provide. I am writing a few macros which are meant to be used within a tabular environment:

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

When I call

\topicsNoStar{stuff} 

the output is correct.

When I call

\topics{stuff} 

I get the error message: !Misplaced \omit. \multispan ->\omit \@multispan

What is confusing me is the difference between the two calls - in my mind, they should be doing the same thing, but the output is not the same.

Now, I do plan to include @'s in the commands above in the final version, but, to debug, I wanted to be able to call them outside the style file. Also, the argument to NoStar is not used, it will be placed into the multicolumn once this is working correctly.

user202729
  • 7,143

3 Answers3

6

\multicolumn must be the first thing in a table cell and a command with a star variant defined in the usual way hides \multicolumn after some unexpandable token. Without packages you can do in the following way:

\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}
David Carlisle
  • 757,742
egreg
  • 1,121,712
4

This solution is built on the requirement suggested by Heiko in ! Misplaced \omit error.

etextools provides fully-expandable conditioning commands to allow \multicolumn to be considered as "the first element in the cell". This is not currently the case in your example, since \@ifstar is not fully expandable, while \FE@ifstar is a Fully Expandable version:

enter image description here

\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}
Moriambar
  • 11,466
Werner
  • 603,163
0

This is an alternative, using my \NewDocumentCommandOptionalInTabular macro in another answer.

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

Output is as you expect.

output


An example where the expandable star test breaks the kerning in the following character:

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

user202729
  • 7,143