![我如何定义一个宏来有条件地插入“\multicolumn”?](https://linux22.com/image/411928/%E6%88%91%E5%A6%82%E4%BD%95%E5%AE%9A%E4%B9%89%E4%B8%80%E4%B8%AA%E5%AE%8F%E6%9D%A5%E6%9C%89%E6%9D%A1%E4%BB%B6%E5%9C%B0%E6%8F%92%E5%85%A5%E2%80%9C%5Cmulticolumn%E2%80%9D%EF%BC%9F.png)
我需要定义一个宏,它可以插入包含 的表格行\multicolumn
。它应该通过评估其参数上的一些 LaTeX3 代码来决定是否插入它。
这是一个最小的非工作示例:
\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\clist_gset:Nn \g_tmpa_clist { foo, bar }
\DeclareExpandableDocumentCommand{\MaybeATableRow}{m}{%
\clist_if_in:NnTF \g_tmpa_clist { #1 }
{\multicolumn{2}{c}{#1}\cr}
{}
}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{ll}
\MaybeATableRow{foo}
A & B \\
\MaybeATableRow{qux}
X & Y \\
\end{tabular}
\end{document}
这给出了一个众所周知的错误:
! Misplaced \omit.
\multispan ->\omit
\@multispan
l.20 \MaybeATableRow{foo}
据我了解,这是由于之前存在不可扩展的代码而\multicolumn
导致单元过早启动所致。
在这种情况下,不可扩展的宏(根据手册)是\clist_if_in:NnTF
。
在我的实际用例中,逻辑要复杂得多,我不能放弃像clist
s 这样的复杂数据结构(几乎所有相关的宏都是不可扩展的)。
有没有办法定义这样的宏?
答案1
Skillmon 答案的变体。
\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\clist_gset:Nn \g_tmpa_clist { foo, bar }
\NewExpandableDocumentCommand{\MaybeATableRow}{m}
{
\noalign
{
\clist_if_in:NnTF \g_tmpa_clist { #1 }
{
\cs_gset:Npn \__paolo_mc: {\multicolumn{2}{c}{#1}\\}
}
{
\cs_gset_eq:NN \__paolo_mc: \prg_do_nothing:
}
\group_insert_after:N \__paolo_mc:
}
}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{ll}
\MaybeATableRow{foo}
A & B \\
\MaybeATableRow{qux}
X & Y \\
\end{tabular}
\end{document}
需要\noalign
才能不开始新行。它形成一个隐式组,因此我们可以使用\group_insert_after:N
(即\aftergroup
)将某些内容偷偷带出它。
避免使用\DeclareExpandableDocumentCommand
,因为它不检查命令是否已定义。还应\cr
使用\\
。
答案2
诀窍是将不可扩展的代码放在里面\noalign
,但这样你的代码只能放在一行的开头,并且必须构建整行(就像你的 MWE 中的情况一样)。
\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\clist_gset:Nn \g_tmpa_clist { foo, bar }
\cs_new:Npn \paolo_noalign_start:
{
\tex_noalign:D { \if_int_compare:w 0 = `} \fi:
}
\cs_new:Npn \paolo_noalign_end:
{
\if_int_compare:w 0 = `{ \fi: }
}
\NewExpandableDocumentCommand{\MaybeATableRow}{m}{%
\paolo_noalign_start:
\clist_if_in:NnTF \g_tmpa_clist { #1 }
{
\paolo_noalign_end:
\multicolumn{2}{c}{#1}\cr
}
{ \paolo_noalign_end: }
}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{ll}
\MaybeATableRow{foo}
A & B \\
\MaybeATableRow{qux}
X & Y \\
\end{tabular}
\end{document}