我今天遇到了一个很奇怪的问题。
我想用自动生成的数据填充表格。因此,我设计了一个宏,它需要四个参数(其中一个是可选的)。参数 1 和 4 可以为空,因此我\ifx#1\@empty
在代码中加入了测试。
这是我的第一个版本的宏:
\newcommand{\admin}[4][]{%
#2&
\def\@rzid{#4}\ifx\@rzid\@empty\relax ./. \else \texttt{\@rzid}\fi&
\def\@ldap{#1}\ifx\@ldap\@empty\relax
yes
\else
& no
\fi%
\\%
}
我很惊讶地发现,LaTeX 没有编译。结果如下:
! 额外的 \fi。
\\admin ...ldap @empty \relax yes \else & no \fi
\\
! 不完整 \ifx;第 51 行之后的所有文本均被忽略。
< 插入的文本>
\fi
经过两个小时的折腾,我发现,& 符号才是导致问题的原因。这个宏可以正常工作,并且 LaTeX 不会抛出错误:
\newcommand{\admin}[4][]{%
#2&
\def\@rzid{#4}\ifx\@rzid\@empty\relax ./. \else \texttt{\@rzid}\fi&
\def\@ldap{#1}\ifx\@ldap\@empty\relax
yes
\else
no
\fi%
\\%
}
缺点是,“否”这个词现在站在了错误的列中。:-( 我的 MWA(最小解决方法)现在如下,但我想知道哪里出了问题以及如何避免我想出的额外 if 子句。
\documentclass{article}
\makeatletter
%% This did not work due to the "&". Removing the ampersand will get
%% the macro working, but than the word "No" from the ifclause will be
%% printed in the wrong column.
% \newcommand{\admin}[4][]{%
% #2&
% \def\@rzid{#4}\ifx\@rzid\@empty\relax ./. \else \texttt{\@rzid}\fi&
% \def\@ldap{#1}\ifx\@ldap\@empty\relax
% yes
% %% The error starts here. Comment out the next two lines, and the
% %% error vanishes. Remove the ampersand & and its also gone!
% \else
% & no
% %% This would work
% % \else
% % no
% \fi%
% \\%
% }
%% Now: this works, but you have to have an extra if-clause!
\newcommand{\admin}[4][]{%
#2&%
\def\@rzid{#4}\ifx\@rzid\@empty\relax ./. \else \@rzid\fi&%
\def\@ldap{#1}\ifx\@ldap\@empty\relax
Yes
\fi
&
\newcommand{\admin}[4][]{%
#2&%
\def\@rzid{#4}\ifx\@rzid\@empty\relax ./. \else \@rzid\fi&%
\def\@ldap{#1}\ifx\@ldap\@empty\relax
Yes
\fi
&
\ifx\@ldap\@empty\relax\else
No
\fi%
\\%
\def\@ldap{#1}\ifx\@ldap\@empty\relax\else
No
\fi%
\\%
}
\makeatother
\begin{document}
\begin{tabular}{@{}lllcc@{}}
\hline
\multicolumn{2}{@{}c}{Anwender}
& \multicolumn{1}{c}{RZ-ID}
& \multicolumn{2}{c@{}}{LDAP} \\
\multicolumn{1}{@{}c}{Vorname}
& \multicolumn{1}{c}{Nachname}
&
& \multicolumn{1}{c}{Yes}
& \multicolumn{1}{c@{}}{No} \\
\hline
\admin{First}{Lastname}{fl19}
\admin{Some}{Othername}{so97}
\admin[false]{Not}{Listed}{}
\hline
\end{tabular}
\end{document}
附言:这是一个最小的例子。在我的实际文档中,宏更加复杂,因为我在倒数第二列和最后一列中添加了更多信息。因此,建议使用 \multicolumn{2}{c}{Yes}
或\multicolumn{2}{c}{NO}
跨越最后两列以避免使用“与”符号,这对我来说是行不通的。
答案1
请注意,在您的实际 MWA 中(我喜欢这样!:-D
)您将获得
这可能不是预期的结果。其背后的原因与第一个解决方案失败的原因相同:单元格是组,并且您的单元格\def\@ldap
被限制在第四列。您应该改用\gdef
来使其正常工作。
我个人认为没有必要不惜\if
一切代价避免双重处罚,但这可能是一种可行的方法
\newcommand{\admin}[4][]{%
#2&%
\def\@rzid{#4}\ifx\@rzid\@empty\relax ./. \else \@rzid\fi &
\def\@ldap{#1}%
\ifx\@ldap\@empty\relax % I prefer \if\relax\detokenize{#1}\relax
\def\@tempa{\textcolor{green}{\ding{51}}&}%
\else
\def\@tempa{&\textcolor{red}{\ding{55}}}%
\fi
\@tempa
\\
}
基本上,\if
只是设定了的定义,只有在解决了\@tempa
之后才会进行扩展。\if
答案2
条件语句不能跨越对齐单元格,但您可以在发出之前删除条件&
;该技术使用\@firstoftwo
和\@secondoftwo
。请参阅为什么使用 \expandafter\@firstoftwo 习语?
\documentclass{article}
\makeatletter
\newcommand{\admin}[4][]{%
#2&%
\if\relax\detokenize{#4}\relax
./.%
\else
#4%
\fi&%
\if\relax\detokenize{#1}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{Yes}{&No}%
\\%
}
\makeatother
\begin{document}
\begin{tabular}{@{}lllcc@{}}
\hline
\multicolumn{2}{@{}c}{Anwender}
& \multicolumn{1}{c}{RZ-ID}
& \multicolumn{2}{c@{}}{LDAP} \\
\multicolumn{1}{@{}c}{Vorname}
& \multicolumn{1}{c}{Nachname}
&
& \multicolumn{1}{c}{Yes}
& \multicolumn{1}{c@{}}{No} \\
\hline
\admin{First}{Lastname}{fl19}
\admin{Some}{Othername}{so97}
\admin[false]{Not}{Listed}{}
\hline
\end{tabular}
\end{document}
我还删除了两个辅助宏,选择使用不同的安全空值测试。