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?

\NewDocumentCommandfor 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\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\ExplSyntaxOnand\ExplSyntaxOff? – MickG Mar 30 '14 at 13:19