最近我不得不排版几个块矩阵。因此,我想到定义和的缩写,\multirow
以\multicolumn
避免必须记住前者的需求{*}
和后者{r}
,而只需给出内容的内容\multi
以及内容应占据的行数和/或列数。我找到了这段代码,它显示了定义相同命令的两种可能性:
\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}
问题是,无论如何,这两个命令都会给出相同的错误:
Misplaced \omit.
\multispan ->\omit
\@multispan
l.43 \xmulti{3}{mapu}
&\multi[4]{n}{mu}\\
这是什么意思?我该如何纠正它?这些命令不应该都扩展到中间明确输入的内容吗?更奇怪的是,\multi{foo}[bar]
(bar
是一个数字)似乎总是落入\else
条件分支\if#2n
,因为注释那里的指令解决了问题,用 aNValue
或类似的排版,而它应该落入条件true
的值\IfNoValueTF#3
和false
其中嵌套的\IfNoValueTF#2
条件的分支。同样的(对条件进行了适当的更改)也适用于\xmulti{bar}{foo}
,带有bar
数字。为什么会这样?
更新: 我对代码进行了修改,将其变成:
\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}
}
这可行。当然,它永远不会落入\IfNoValueTF#2
分支,因为#2
这是强制性的。所以我尝试更改条件,得到:
\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}
突然我又回到了misplaced \omit
。为什么?
答案1
您必须使用\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}
然而,我相信您在尝试制作比原始命令更难使用的万能命令时浪费了时间。