此代码在底部留下一个空行:
\documentclass{article}
\usepackage{etoolbox}
\def\somedef{foo}
\begin{document}
\begin{tabular}{|l|}
\hline
First row, not important \\ \hline
\ifdefstring{\somedef}{bar}{never used \\ \hline}{}%
\end{tabular}
\end{document}
结果表如下所示:
----------------------------
| First row, not important |
+--------------------------+
| |
我想删除的是底部那个虚假的空行。
我知道我可以通过用类似的东西替换来完成这项工作\ifdefstring
:
\ifnum\pdfstrcmp{\somedef}{bar}=0 never used \\ \hline \else\fi
但我有兴趣坚持使用 etoolbox,它似乎是一个相当全面的软件包,有许多相对容易阅读的宏(对于程序员,我的受众来说)。我还对在表格中使用条件内联感兴趣,因为这似乎最容易阅读和维护。(如果有更好的、同样全面的软件包,我应该使用它,并且它没有上述问题,我也很想听听。)
我怎样才能在这里使用 etoolbox\ifdefstring
而不添加额外的行?
我怀疑 etoolbox 要么 (a) 有错误(缺少一些%
),要么 (b) 插入了类似 的内容\relax
。有没有办法丢弃/吃掉\ifdefstring
看似不可见但却创建行的输出?
答案1
这不是 etoolbox 中的错误。您的问题是,它\ifdefstring
不能在 TeX 的口中完全展开(它不能,因为它需要做什么),而 TeX 的口中展开是宏执行您想要的操作所必需的。
这一切都归结为 TeX 如何解析数据\halign
:为了解析列的数据,它会读取一个标记和宏扩展,然后检查该标记(如果它是\span
或其他需要特殊处理的标记),然后扫描标记没有宏扩展直到下一个&
或\cr
(在此上下文中\\
算作\cr
),然后将所有收集到的标记作为当前列的数据进行处理。
因此,如果一个宏不打算生成一行,而它又可能在表中生成一行,那么它就需要扩展为零,但是它\ifdefstring
却不这样做。
答案2
我看到 Harald 已经涵盖了其中的一些内容,但我希望这也能提供一些信息。
etoolbox
使用 e-TeX,但据我所知,没有使用任何其他扩展。所以\pdfsctrcmp
在这里(对于etoolbox
)。所以如果你读过代码,就会发现有一个\edef
内部函数\ifdefstring
可以进行比较。这是不可扩展的,所以它会强制使用一个新单元。你会看到同样的情况
\begin{tabular}{|l|}
\hline
First row, not important \\ \hline
\edef\test{}%
\end{tabular}
因此,我不确定您是否可以在没有定义\ifdefstring
的情况下避免此问题\pdfstrcmp
。 (在 LaTeX3 中,我们决定要求它,\pdfstrcmp
因为它可以帮助完成许多原本无法扩展的测试。)
答案3
为了其他人(也可能是我自己)将来的参考,为了明确展示 Joseph Wright 和 Will Robertson 留下的评论,这也有效并且可能更容易阅读:
\documentclass{article}
\usepackage{expl3}
\def\somedef{foo}
\begin{document}
\ExplSyntaxNamesOn
\begin{tabular}{|l|}
\hline
First row, not important \\ \hline
\str_if_eq:nnTF{\somedef}{bar}{never used \\ \hline}{}%
\end{tabular}
\ExplSyntaxNamesOff
\end{document}
\ExplSyntaxNamesOn
制作_
和:
“字母”,以便您可以在 csnames 中使用它们(或者至少我是这么认为的)。 \ExplSyntaxNamesOff
相反。(注意:不要将它们放在周围,tabular
否则\str_if_eq:nnTF
您仍然会得到空单元格。)
这一切都归功于 Joseph 和 Will。谢谢!