我如何定义一个宏来有条件地插入“\multicolumn”?

我如何定义一个宏来有条件地插入“\multicolumn”?

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

在我的实际用例中,逻辑要复杂得多,我不能放弃像clists 这样的复杂数据结构(几乎所有相关的宏都是不可扩展的)。

有没有办法定义这样的宏?

答案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}

相关内容