我需要定义一个宏,它可以插入包含 的表格行\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}