为什么使用 xithen 隐藏表格行会导致多行对齐中断?

为什么使用 xithen 隐藏表格行会导致多行对齐中断?

总结:我尝试编写一个有条件地显示/隐藏表格行的类。当某行在\multicolumn使用前被隐藏时,会触发错误。

为了便于讨论,我首先给出一个 M(N)WE:

\documentclass{article}
\RequirePackage{xifthen}
% Put some data in macros. This wil be imported later using \input{...}
\newcommand{\TaskA}{Some description comes here}
\newcommand{\TaskB}{Some other description}
\newcommand{\TaskC}{}
\newcommand{\HoursA}{1}
\newcommand{\HoursB}{3}
\newcommand{\HoursC}{0}

\newcommand{\printline}[1]{\ifthenelse{ \equal{\csname Task#1\endcsname}{} }{}{%
    #1 & \csname Task#1\endcsname & \csname Hours#1\endcsname & 42 \\%
}}

\begin{document}
\section{Correct behavior}
\begin{tabular}{|l l | c c }
A & Some description comes here & 1 & 42 \\
B & Some other description & 3 & 42 \\
\multicolumn{2}{|r|}{Sum:} & 4 & 82 \\
\end{tabular}

\section{Error is created}
\begin{tabular}{| l l | c c }
\printline{A}
\printline{B}
\printline{C}
\multicolumn{2}{|r|}{Sum:} & 4 & 82 \\
\end{tabular}
\end{document}

我想编写一个类,根据一组宏的值输出一个表。为了简单起见,我在这里放弃了迭代部分,并明确地写了它。如果满足条件(在 MWE 中只检查空任务名称,但在最后一个类中检查更复杂),则应该隐藏完整的行。

我添加了一个完全手动渲染的表格,它工作得很好。但是,一旦我使用宏来排版一行,它就不再按预期工作了。首先,我收到 LaTeX 错误

Misplaced \omit.
\multispan ->\omit 
                   \@multispan 
l.28 \multicolumn{2}{|r|}{Sum:}
                                & 4 & 82 \\

此外,输出没有跨越两列的实际单元格,但第一列也以某种方式添加。

测试代码的 LaTeX 输出

有趣的是,如果禁用该行B并启用C(只需切换宏名称),效果似乎不会发生。所以我怀疑我触发了\multicolumn宏的问题。

看完之后这个帖子并尝试使用 的方法DeclareExpandableDocumentCommand,我怀疑问题出在\ifthenelse结构上。我是否需要在这里使用基本 (普通) TeX?


编辑1:
我得到了一些答案/评论(谢谢!)但我的问题是,我无法简单地将这些扩展到我的需求(以我的知识水平)。所以我可能需要更明确地指定我需要哪些测试:首先,您必须知道时间条目不止一个,而是两个(称它们为HoursXHoursExtX)。如果以下任何一项为真,则应删除该行:

  • 任务名称(TaskX)为空
  • 任务名称未定义(可选)
  • HoursX 为零HoursExtX
  • HoursX HoursExtX空的
  • 可选地,如果HoursXHoursExtX都未定义

所以我需要选项来生成逻辑语句并检查空字符串和数字零。

答案1

您需要一个可扩展的测试,但\ifthenelse它不是其中之一。

\documentclass{article}
\usepackage{etoolbox}
% Put some data in macros. This wil be imported later using \input{...}
\newcommand{\TaskA}{Some description comes here}
\newcommand{\TaskB}{Some other description}
\newcommand{\TaskC}{}
\newcommand{\HoursA}{1}
\newcommand{\HoursB}{3}
\newcommand{\HoursC}{0}

\newcommand{\printline}[1]{%
  \ifcsempty{Task#1}{}{#1 & \csname Task#1\endcsname & \csname Hours#1\endcsname & 42 \\}%
}

\begin{document}

\section{Correct behavior}

\begin{tabular}{|l l | c c }
A & Some description comes here & 1 & 42 \\
B & Some other description & 3 & 42 \\
\multicolumn{2}{|r|}{Sum:} & 4 & 82 \\
\end{tabular}

\section{No error}

\begin{tabular}{| l l | c c }
\printline{A}
\printline{B}
\printline{C}
\multicolumn{2}{|r|}{Sum:} & 4 & 82 \\
\end{tabular}

\end{document}

在此处输入图片描述

在更高级别的实现中,我们还检查是否\Task#1未定义,因此您不需要将其定义\TaskC为空。

\documentclass{article}


% Put some data in macros. This wil be imported later using \input{...}
\newcommand{\TaskA}{Some description comes here}
\newcommand{\TaskB}{Some other description}
\newcommand{\HoursA}{1}
\newcommand{\HoursB}{3}
\newcommand{\HoursC}{0}

\ExplSyntaxOn

\prg_generate_conditional_variant:Nnn \tl_if_blank:n { v } { p,T,F,TF }

\NewExpandableDocumentCommand{\printline}{m}
 {
  \bool_lazy_and:nnT
   { \tl_if_exist_p:c { Task#1 } } % \Task#1 exists
   { ! \tl_if_blank_p:v { Task#1 } } % \Task#1 is not empty
   { #1 & \csname Task#1\endcsname & \csname Hours#1\endcsname & 42 \\}
 }

\ExplSyntaxOff

\begin{document}

\section{Correct behavior}

\begin{tabular}{|l l | c c }
A & Some description comes here & 1 & 42 \\
B & Some other description & 3 & 42 \\
\multicolumn{2}{|r|}{Sum:} & 4 & 82 \\
\end{tabular}

\section{No error}

\begin{tabular}{| l l | c c }
\printline{A}
\printline{B}
\printline{C}
\multicolumn{2}{|r|}{Sum:} & 4 & 82 \\
\end{tabular}

\end{document}

相关内容