\IfEqCase 中的 \omit 和 \multicolumn 放错了位置

\IfEqCase 中的 \omit 和 \multicolumn 放错了位置

我有以下代码以及为表格创建行的命令:

\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}

\multicolumn虽然在表格中直接使用可以工作,但\multicolumn通过命令使用\condrow会失败。我猜想 会\IfEqCase\condrow命令开头添加一些内容\multicolumn,从而引发以下错误:

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

加在\\前面\multicolumn会使错误消失,但会插入一个空行。问题放错了 \omit。\multispan 和 \newcommand类似。但是,答案并不能解决我的问题。我尝试使用该ifthen包进行分支,但没有成功。

任何想法如何解决这一问题?

答案1

解决方案expl3

\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}

这样做的好处是更容易扩展以接受新的选项。

在此处输入图片描述

答案2

正如 Werner 所说,您需要一个可扩展的测试。由于您只是比较单个字母,因此替代方案\pdfstrcmp\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}

答案3

这与以下错误完全相同:放错了地方\omit\multispan\newcommand- 只是不那么明显。问题是xstring\IfEqCase不可扩展,因为它会进行赋值来执行比较。相反,使用来自测试两个完全展开的字符串是否相等,您可以利用 pdfTeX\pdfstrcmp以可扩展的方式比较字符串:

在此处输入图片描述

\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}

答案4

供参考,如果您使用{NiceTabular}nicematrix及其内置命令\Block而不是\multicolumn,您可以直接获得所需的输出(因为\Block是一个按原样工作的受保护命令)。

nicematrix但是,由于底层使用了 PGF/Tikz 节点,因此您需要进行多次编译。

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

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

\begin{document}
\begin{NiceTabular}{|c|c|c|}
 \condrow{l}{left}
 \condrow{r}{right}
 \condrow{c}{center}
 \multicolumn{3}{c}{manual multi} \\ 
 \condrow{m}{condrow multi}
\end{NiceTabular}
\end{document}

上述代码的输出

相关内容