总结:我尝试编写一个有条件地显示/隐藏表格行的类。当某行在\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 \\
此外,输出没有跨越两列的实际单元格,但第一列也以某种方式添加。
有趣的是,如果禁用该行B
并启用C
(只需切换宏名称),效果似乎不会发生。所以我怀疑我触发了\multicolumn
宏的问题。
看完之后这个帖子并尝试使用 的方法DeclareExpandableDocumentCommand
,我怀疑问题出在\ifthenelse
结构上。我是否需要在这里使用基本 (普通) TeX?
编辑1:
我得到了一些答案/评论(谢谢!)但我的问题是,我无法简单地将这些扩展到我的需求(以我的知识水平)。所以我可能需要更明确地指定我需要哪些测试:首先,您必须知道时间条目不止一个,而是两个(称它们为HoursX
和HoursExtX
)。如果以下任何一项为真,则应删除该行:
- 任务名称(
TaskX
)为空 - 任务名称未定义(可选)
- 这
HoursX
和为零HoursExtX
- 这
HoursX
和是HoursExtX
空的 - 可选地,如果
HoursX
和HoursExtX
都未定义
所以我需要选项来生成逻辑语句并检查空字符串和数字零。
答案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}