根据表格环境中的列数执行宏

根据表格环境中的列数执行宏

我想定义表格环境的一个特殊情况,其中每个列标题都有下划线,但每个下划线之间都有间隙,如下所示:

\begin{tabular}{c c c c c}
Col1 & Col2 & Col3 & Col4 & Col5\\
\cmidrule(l{\tabcolsep}r{\tabcolsep}){1-1}
\cmidrule(l{\tabcolsep}r{\tabcolsep}){2-2}
\cmidrule(l{\tabcolsep}r{\tabcolsep}){3-3}
\cmidrule(l{\tabcolsep}r{\tabcolsep}){4-4}
\cmidrule(l{\tabcolsep}r{\tabcolsep}){5-5}
data1 & data2 & data3 & data4 & data5\\
\end{tabular}

但我希望它能够适用于任意数量的列,而不必重复 \cmidrule 行。

我需要解决的问题是:

  1. 如何计算表中有多少列?
  2. 定义一个宏来执行 \cmidrule 的次数

答案1

没有计数器可以跟踪 中的列数tabular。由于\cmidrule期待查看是否还有另一个\cmidrule命令跟随并且必须找到文字标记,因此也存在复杂性。

\cmidrules如果您对具有指定列数的参数的命令感到满意,则可以以一种偷偷摸摸的方式完成此操作,方法是在内部准备一个令牌列表\noalign,并在关闭后立即传递它\noalign

\documentclass{article}
\usepackage{booktabs}
\usepackage{expl3}

\ExplSyntaxOn
\tl_new:N \g_michael_cmidrules_tl

\cs_new:Npn \cmidrules #1
 {
  \noalign
   {
    \tl_gclear:N \g_michael_cmidrules_tl
    \int_step_inline:nnnn { 1 } { 1 } { #1 }
     {
      \tl_gput_right:Nn \g_michael_cmidrules_tl
       {
        \cmidrule(l{\tabcolsep}r{\tabcolsep}){##1-##1}
       }
     }
   }
   \tl_use:N \g_michael_cmidrules_tl
}
\ExplSyntaxOff

\begin{document}

\begin{tabular}{c c c c c}
Col1 & Col2 & Col3 & Col4 & Col5\\
\cmidrules{5}
data1 & data2 & data3 & data4 & data5\\
\end{tabular}

\end{document}

在此处输入图片描述

我使用expl3只是为了方便使用\int_step_inline:nnnn,但可以定义一个“经典”版本:

\makeatletter
\newtoks\MD@cmidrules
\newcommand{\cmidrules}[1]{%
  \noalign{%
    \global\MD@cmidrules={}%
    \toks@={\cmidrule(l{\tabcolsep}r{\tabcolsep})}%
    \count@=\z@
    \loop\ifnum\count@<#1\relax
      \advance\count@\@ne
      \edef\MD@temp{\the\toks@{\the\count@-\the\count@}}%
      \global\MD@cmidrules\expandafter{\the\expandafter\MD@cmidrules\MD@temp}%
    \repeat
  }%
  \the\MD@cmidrules
}
\makeatother

答案2

对 egreg 的解决方案进行微小的扩展,它接受\cmidrules{2-5}\cmidrules{3}\cmidrules{1,3,7-9,12-15,18}等。

\ExplSyntaxOn
\tl_new:N \g_michael_cmidrules_tl

\cs_new:Npn \cmidrules #1
 {
  \noalign
   {
    \tl_gclear:N \g_michael_cmidrules_tl
    \clist_map_inline:nn { #1 }
     {
      \tl_if_in:nnTF { ##1 } { - }
       {
        \seq_set_split:Nnn \l_tmpa_seq { - } { ##1 }
        \int_step_inline:nnnn
         { \seq_item:Nn \l_tmpa_seq { 1 } } { 1 } { \seq_item:Nn \l_tmpa_seq { 2 } }
         {
          \tl_gput_right:Nn \g_michael_cmidrules_tl
           {
            \cmidrule(l{\tabcolsep}r{\tabcolsep}){####1-####1}
           }
         }
       }
       {
        \tl_gput_right:Nn \g_michael_cmidrules_tl
         {
          \cmidrule(l{\tabcolsep}r{\tabcolsep}){##1-##1}
         }
       }
     }
   }
  \tl_use:N \g_michael_cmidrules_tl
 }
\ExplSyntaxOff

相关内容