3

Many times is handy to define \newcommand for short notation for \multicolumn. For this purposes I test two definition for such commands:

\newcommand\my[2]{\multicolumn{1}{#1}{#2}}
\newcommand\mx[2][c]{\multicolumn{1}{#1}{#2}}

Meanwhile first definition works fine, the second throw error:

! Misplaced \omit.
\multispan ->\omit 
                   \@multispan 
l.9 \mx{A}
                &   \mx[c|]{B}  \\

at testing with the following MWE:

\documentclass[margin=3mm]{standalone}
\newcommand\mx[2][c]{\multicolumn{1}{#1}{#2}}
\newcommand\my[2]{\multicolumn{1}{#1}{#2}}

\begin{document}
\begin{tabular}{|c|c|}
  \hline
\mx{A}      &   \mx[c|]{B}  \\
\my{c}{A}   &   \my{c|}{B}  \\
  \hline
\end{tabular}
\end{document}

Is there a way to fix definition for \mx?

Zarko
  • 296,517
  • 1
    Apparently I need an intensive course how to search for something in this site. I spend almost all my spare time in last two days and didn't discover this question/answer :-(. Thank you! – Zarko May 22 '19 at 16:23

1 Answers1

2

\multicolumn works by inserting an \omit to ignore the table column template, and it works because at the start of a table cell TeX expands tokens (thus expanding \multicolumn) until it finds an unexpandable token or \omit.

The problem is that commands defined with LaTeX's \newcommand aren't expandable if they have an optional argument, so TeX doesn't find the \omit when it's looking for one. Later, when it does find \omit it's too late, and you get a Misplaced \omit error.

Using xparse's \NewExpandableDocumentCommand you can make a command that has an optional argument and is expandable:

\documentclass[margin=3mm]{standalone}
\usepackage{xparse}
\NewExpandableDocumentCommand\mx{O{c}m}
  {\multicolumn{1}{#1}{#2}}
\newcommand\my[2]{\multicolumn{1}{#1}{#2}}

\begin{document}
\begin{tabular}{|c|c|}
  \hline
\mx{A}      &   \mx[c|]{B}  \\
\my{c}{A}   &   \my{c|}{B}  \\
  \hline
\end{tabular}
\end{document}