Special cmidrule with booktabs – colored and custom spacing with cmidrule

booktabstables

I would like to create a gray cmidrule a la booktabs. I have created a gray midrule gmidrule (extends entire table width) with different tighter space via

\newcommand{\gmidrule{\arrayrulecolor{lightgray}\specialrule{\lightrulewidth}{0.4\aboverulesep}{0.6\belowrulesep}\arrayrulecolor{black}}

Now, I would like to apply a light gray color, and identical separation as shown above, for a cmidrule (partial rule), and call this variation gcmidrule.

First issue is that the cmidrules are staggered. I would like to resolve this, but also adust the above and below rule sep.

\documentclass{article}

\usepackage{xparse}
\usepackage{booktabs}
\usepackage[table]{xcolor}

\newcommand{\gmidrule}{\arrayrulecolor{lightgray}\specialrule{\lightrulewidth}{0.4\aboverulesep}{0.6\belowrulesep}\arrayrulecolor{black}}

\NewExpandableDocumentCommand{\gcmidrule}{ O{} D(){} m }{%
    %% I would like to reduce the distance here as well, but the midrules are staggered
    \arrayrulecolor{lightgray}%
    \cmidrule{#3}%
    %  \cmidrule[#1](#2){#3}% supposed to be like this, but causes error. I'll worry about this later
    \arrayrulecolor{black}%
}

\begin{document}

    \begin{tabular}{lllll}\toprule
        a & b & c & d & e \\\gmidrule
        a & b & c & d & e \\\gcmidrule{1-2}\gcmidrule{4-5} % notice the stagger
        a & b & c & d & e \\\bottomrule
    \end{tabular}

\end{document}

Update:

This question is slightly helpful in that it helps align the cmidrules, however it does not adjust the above and below sep: How to omit vertical realignment when using cmidrule in different colors?

%% added this
% Correct for \cmidrule colour adjustment/vertical skip
\newcommand{\corcmidrule}[1][0pt]{% \corcmidrule[<len>]
  \\[\dimexpr-\normalbaselineskip-\belowrulesep-\aboverulesep-#1\relax]%
}

%% add this in gcmidrule

\corcmidrule%

Still staggered, and adjusting the [0pt] still leaves staggered.

enter image description here

Best Answer

\cmidrule is written in a way to check if more \cmidrules follow it. If that is the case, it purposefully performs a vertical readjustment so the \cmidrules follow on the same line. So using (say)

\gcmidrule[<A>](<B>){<C>}\gcmidrule[<D>](<E>){<F>}`

in your way would effectively translate to

\arrayrulecolor{lightgray}% ----\
\cmidrule[<A>](<B>){<C>}%       | = First \gcmidrule
\arrayrulecolor{black}% --------/
\arrayrulecolor{lightgray}% ----\
\cmidrule[<D>](<E>){<F>}%       | = Second \gcmidrule
\arrayrulecolor{black}% --------/

While it's not incorrect to switch colours back-and-forth, the first \cmidrule just doesn't find that it is followed by another \cmidrule. Hence, there's no vertical correction.

The easiest way that makes the most sense is to copy the original definition(s) if \cmidrule (and subsidiary commands) and change them to show as \gcmidrule (and subsidiaries), including the "checking ahead" part.

enter image description here

\documentclass{article}

\usepackage{booktabs}
\usepackage[table]{xcolor}

\newcommand{\gmidrule}{%
  \arrayrulecolor{lightgray}%
  \specialrule{\lightrulewidth}{0.4\aboverulesep}{0.6\belowrulesep}%
  \arrayrulecolor{black}%
}

% Copy \cmidrule from
%  http://mirrors.ctan.org/macros/latex/contrib/booktabs/booktabs.dtx
% and modify it for insertion of \arrayrulecolor{lightgray} at the start,
% and \arrayrulecolor{black} at the end
\makeatletter
\def\gcmidrule{\arrayrulecolor{lightgray}% Switch colour to lightgray
    \noalign{\ifnum0=`}\fi
    \@ifnextchar[{\@gcmidrule}{\@gcmidrule[\cmidrulewidth]}}
\def\@gcmidrule[#1]{\@ifnextchar({\@@gcmidrule[#1]}{\@@gcmidrule[#1]()}}
\def\@@gcmidrule[#1](#2)#3{\@@@gcmidrule[#3]{#1}{#2}}
\def\@@@gcmidrule[#1-#2]#3#4{\global\@cmidla#1\relax
    \global\advance\@cmidla\m@ne
    \ifnum\@cmidla>0\global\let\@gtempa\@cmidrulea\else
    \global\let\@gtempa\@cmidruleb\fi
    \global\@cmidlb#2\relax
    \global\advance\@cmidlb-\@cmidla
    \global\@thisrulewidth=#3
    \@setrulekerning{#4}
    \ifnum\@lastruleclass=\z@\vskip \aboverulesep\fi
    \ifnum0=`{\fi}\@gtempa
    \noalign{\ifnum0=`}\fi\futurenonspacelet\@tempa\@xgcmidrule}
\def\@xgcmidrule{%
   \ifx\@tempa\gcmidrule
       \vskip-\@thisrulewidth
       \global\@lastruleclass=\@ne
   \else \ifx\@tempa\morecmidrules
       \vskip \cmidrulesep
       \global\@lastruleclass=\@ne\else
       \vskip \belowrulesep
       \global\@lastruleclass=\z@
   \fi\fi
   \ifnum0=`{\fi}
  \arrayrulecolor{black}}% Switch colour back to black
\makeatother

\begin{document}

\begin{tabular}{ *{5}{c} }
  \toprule
  a & b & c & d & e \\
  \gmidrule
  a & b & c & d & e \\
  \gcmidrule{1-2}\gcmidrule{4-5}
  a & b & c & d & e \\
  \bottomrule
\end{tabular}

\end{document}
Related Question