1

I want to define a special case of the tabular environment where each column heading is underlined, but there is a gap between each underline, like this:

\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}

But I would like this to work for an arbitrary number of columns without having to repeat the \cmidrule lines.

The problems I need to solve are:

  1. How to count how many columns are in the table?
  2. Define a macro to execute \cmidrule that number of times

2 Answers2

4

There's no counter that keeps track of the number of columns in a tabular. There's also a complication due to the fact that \cmidrule looks forward to see whether another \cmidrule command follows and the literal token must be found.

If you are happy with a command \cmidrules that has an argument specifying the number of columns, then this can be done in a sneaky way, by preparing a token list inside a \noalign and delivering it at once after closing this \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}

enter image description here

I used expl3 just for the convenience of using \int_step_inline:nnnn, but a “classical” version can be defined:

\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
egreg
  • 1,121,712
0

A tiny expansion over egreg's solution that accepts \cmidrules{2-5}, \cmidrules{3} and \cmidrules{1,3,7-9,12-15,18}, etc.

\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
Manuel
  • 27,118