2

I have had to typeset several block matrixes lately. So I thought of defining abbreviations of \multirow and \multicolumn so as to avoid having to remember the former needs {*} and the latter {r} and just give the content of the \multi-thing and the number(s) of rows and/or columns that content should occupy. I came to this code, showing two possibilities to define the same command:

\documentclass[a4paper]{report}
\usepackage{multirow,xparse}
\NewDocumentCommand{\multi}{moo}
{\IfNoValueTF#3
        {\IfNoValueTF#2
                {\errmessage{Too few arguments}\errhelp{You must specify either the number of columns or that of rows but not neither.}}
                {\multirow{#2}{*}{#1}}}
        {\if#2n
                \multicolumn{#3}{r}{#1}
        \else
                \multicolumn{#3}{r}{\multirow{#2}{*}{#1}}
        \fi}
}
\newcommand{\mr}[1]{\multirow{#1}{*}}
\newcommand{\mc}[1]{\multicolumn{#1}{r}}
\newcommand{\mrc}[3]{\mc{#2}{\mr{#1}{#3}}}
\newcommand{\xmulti}[3][n]{
    \if#1n
        \mc{#2}{#3}
    \else
        \if#2n
            \mr{#1}{#3}
        \else
            \mrc{#1}{#2}{#3}
        \fi
    \fi
}

\begin{document}
$$\begin{array}{cccccccc}
%\multi{mapu}[n][3]&\multi{mu}[4]\\
%\multi{gungu}[2][5]
\end{array}$$
$$\left(\begin{array}{cccccccc}
\multicolumn{3}{r}{mapu}&\multirow{4}{*}{mu} \\
\multicolumn{5}{r}{\multirow{2}{*}{gungu}}
\end{array}\right)$$
$$\begin{array}{cccccccc}
\mc{3}{mapu}&\mr{4}{mu}\\
\mrc{2}{5}{gungu}
\end{array}$$
$$\begin{array}{cccccccc}
\xmulti{3}{mapu}&\xmulti[4]{n}{mu}\\
\xmulti[2][5]{gungu}
\end{array}$$
\end{document}

Trouble is, both commands, no matter what, give the same error:

Misplaced \omit.
\multispan ->\omit 
                   \@multispan 
l.43 \xmulti{3}{mapu}
                     &\multi[4]{n}{mu}\\

What does it mean, and how do I correct it? Shouldn't those commands both expand to the explicitly typed thing in the middle? Stranger still, \multi{foo}[bar] (bar being a number) seems to invariably fall into the \else branch of the \if#2n conditional, since commenting the instruction there solves the problem, with a NValue or the likes being typesetted, whereas it should fall into the true value of the \IfNoValueTF#3 conditional and the false branch of the therein nested \IfNoValueTF#2 conditional. The same (with due changes to the conditionals) goes for \xmulti{bar}{foo}, with bar a number. Why does that happen?

Update: I've worked on the code, turning it into:

\DeclareExpandableDocumentCommand{\multi}{omm}
{\IfNoValueTF#2
        {\IfNoValueTF#1
                {\errmessage{Too few arguments}\errhelp{You must specify either the number of columns or that of rows but not neither.}}
                {\multirow{#1}{*}{#3}}}
        {\if#1n
                \multicolumn{#2}{r}{#3}
        \else
                \multicolumn{#2}{r}{\multirow{#1}{*}{#3}}
        \fi}
}

That works. Only of course it never falls into the \IfNoValueTF#2 branch, since #2 is mandatory. So I tried changing the conditional, getting to:

\DeclareExpandableDocumentCommand{\multi}{omm}
{\if#2n
        {\IfNoValueTF#1
                {\errmessage{Too few arguments}\errhelp{You must specify either the number of columns or that of rows but not neither.}}
                {\multirow{#1}{*}{#3}}}
\else
        {\if#1n
                \multicolumn{#2}{r}{#3}
        \else
                \multicolumn{#2}{r}{\multirow{#1}{*}{#3}}
        \fi}
\fi}

And suddenly I'm back with the misplaced \omit. Why?

  • No, you can't use \NewDocumentCommand for defining an abbreviation of \multicolumn. I'm pretty sure this has already been discussed. See here for example; you can use an optional argument, but only in the first position with \DeclareExpandableDocumentCommand – egreg Mar 29 '14 at 20:11
  • In addition to egreg's comment: tex.stackexchange.com/questions/503/why-is-preferable-to – Paul Gessler Mar 29 '14 at 20:14
  • @egreg I have updated the question. Why can I use an optional argument only in the first position? – MickG Mar 30 '14 at 12:08
  • @MickG It's a limitation of \DeclareExpandableDocumentCommand, but you can use {oom} as argument specifier; the important thing is that a mandatory argument comes last. – egreg Mar 30 '14 at 12:30
  • @egreg OK that works. Could you take a look at tex.stackexchange.com/questions/167593/…? It hasn't been answered in 5 days now, so I'm starting to think no-one has seen it. Thanks. – MickG Mar 30 '14 at 13:02
3

You must use \DeclareExpandableDocumentCommand:

\documentclass[a4paper]{report}
\usepackage{multirow,xparse}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\multi}{oom}
 {
  \IfNoValueTF{#2}
   {
    \IfNoValueTF{#1}
     {
      \errmessage{Too few arguments}
      \errhelp{You must specify either the number of columns or that of rows but not neither.}
     }
     {
      \multirow{#1}{*}{#3}
     }
   }
   {
    \str_if_eq:nnTF{#1}{n}
     {
      \multicolumn{#2}{r}{#3}
     }
     {
      \multicolumn{#2}{r}{\multirow{#1}{*}{#3}}
     }
   }
 }
\ExplSyntaxOff
\begin{document}
\[
\begin{array}{cccccccc}
1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\
\multi[n][3]{mapu}&\multi[4]{mu}\\
1 & 2 & 3 & \\
1 & 2 & 3 & \\
1 & 2 & 3 & \\
\multi[2][5]{gungu} & 6 & 7 & 8 \\
&&&&&6 & 7 & 8 \\
&&&&&6 & 7 & 8 \\
&&&&&6 & 7 & 8 \\
&&&&&6 & 7 & 8 \\
\end{array}
\]
\end{document}

enter image description here

However, I believe you're wasting your time trying to make catch-all commands that are more difficult to use than the original ones.

  • I'm surprised that you are willing to give an answer for a \multirow question ;) – yo' Mar 30 '14 at 13:24
  • @Manuel thanks for the link. So they are for \str_if_eq:nnTF{#1}{n}, which answers point 2 of the other question I linked. @egreg why do you say they are «more difficult to use than the original ones"? I think they are easier in fact, because one doesn't need to remember that \multicolumn goes before \multirow, that the former requires {<col num>}{r} and the latter {<row num>}{*}, three things that have caused me quite a few typesetting errors lately. And @tohecz why are you so surprised? – MickG Mar 30 '14 at 13:36

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.