4

I have the following code with a command that creates rows for a tabular:

\documentclass[letterpaper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{xstring}

\newcommand*{\condrow}[2]{
\IfEqCase{#1}{
 {l}{#2 & & \\}
 {r}{ & & #2 \\}
 {c}{ & #2 & \\}
 {m}{\multicolumn{3}{c}{#2} \\}
}[\PackageError{condrow}{Undefined option: #1}{}]
}

\begin{document}
\begin{tabular}{|c|c|c|}
 \condrow{l}{left}
 \condrow{r}{right}
 \condrow{c}{center}
 \multicolumn{3}{c}{manual multi} \\ % WORKS
 \condrow{m}{condrow multi} % FAILS
\end{tabular}
\end{document}

While using the \multicolumn directly in the tabular works, using \multicolumn through the command \condrow fails. My guess is that \IfEqCase in \condrow prepends something to the beginning of the \multicolumn command, triggering the following error:

! Misplaced \omit.
\multispan ->\omit 
                   \@multispan 
l.20  \condrow{m}{condrow multi}
                                 % FAILS

Prepending \\ before \multicolumn in the command makes the error disappear, but inserts an empty row. The problem Misplaced \omit. \multispan with \newcommand is similar. However, the answers do not solve my case. I have tried using the ifthen package for branching without success.

Any ideas how to fix this?

3

An expl3 solution:

\documentclass[letterpaper,10pt]{article}
\usepackage{xparse}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\condrow}{ m m }
 {
  \str_case:nnF { #1 }
   {
    { l } { #2 &    &    \\ }
    { r } {    &    & #2 \\ }
    { c } {    & #2 &    \\ }
    { m } { \multicolumn{3}{c}{#2} \\ }
   }
   { \PackageError{condrow}{Undefined~option:~#1}{<explanation>} }
 }
\ExplSyntaxOff

\begin{document}
\begin{tabular}{|c|c|c|}
  \condrow{l}{left}
  \condrow{r}{right}
  \condrow{c}{center}
  \condrow{m}{condrow multi}
\end{tabular}
\end{document}

This has the advantage of being more easily extended to accept new options.

enter image description here

|improve this answer|||||
  • The code gives me ! Undefined control sequence. \condrow #1#2-&gt;\str_case:nnF {#1}{{l}{#2&&\\}{r}{&&#2\\}{c}{&#2&\\}{m}{\mult... l.20 \condrow{l}{left} – faf0 Aug 29 '13 at 17:05
  • 1
    @faf0 Upgrade your TeX installation. Which one are you using? – egreg Aug 29 '13 at 17:06
  • I am using texlive-full on Ubuntu 12.04. – faf0 Aug 29 '13 at 17:10
  • @faf0 Sorry, but the Ubuntu/Debian TeX distribution is really outdated. – egreg Aug 29 '13 at 17:25
5

As Werner said you need an expandable test. As you are just comparing single letters an alternative to \pdfstrcmp is \if

\documentclass[letterpaper,10pt]{article}

\newcommand*{\condrow}[2]{%
       \if l#1 #2 & & \\%
  \else\if r#1 &  & #2 \\%
  \else\if c#1 & #2 & \\%
  \else\if m#1\multicolumn{3}{c}{#2} \\%
  \else\PackageError{condrow}{Undefined option: #1}{}%
  \fi\fi\fi\fi%
}


\begin{document}
\begin{tabular}{|c|c|c|}
  \condrow{l}{left}
  \condrow{r}{right}
  \condrow{c}{center}
  \multicolumn{3}{c}{manual multi} \\ % WORKS
  \condrow{m}{condrow multi} % WORKS
\end{tabular}
\end{document}
|improve this answer|||||
4

This is exactly the same error as in Misplaced \omit. \multispan with \newcommand - it's just not that visible. The problem is that xstring's \IfEqCase is not expandable since it makes assignments to perform the comparison. Instead, using a trick from On testing two fully expanded character strings for equality, you can utilize pdfTeX's \pdfstrcmp to compare strings in an expandable way:

enter image description here

\documentclass[letterpaper,10pt]{article}
\makeatletter
\newcommand*{\condrow}[2]{%
  \ifnum\pdfstrcmp{#1}{l}=\z@ #2 & & \\
  \else\ifnum\pdfstrcmp{#1}{r}=\z@ & & #2 \\
  \else\ifnum\pdfstrcmp{#1}{c}=\z@ & #2 & \\
  \else\ifnum\pdfstrcmp{#1}{m}=\z@ \multicolumn{3}{c}{#2} \\
  \else\PackageError{condrow}{Undefined option: #1}{}%
  \fi\fi\fi\fi%
}
\makeatother

\begin{document}
\begin{tabular}{|c|c|c|}
  \condrow{l}{left}
  \condrow{r}{right}
  \condrow{c}{center}
  \multicolumn{3}{c}{manual multi} \\ % WORKS
  \condrow{m}{condrow multi} % WORKS
\end{tabular}
\end{document}
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.