# Special cmidrule with booktabs - colored and custom spacing with cmidrule

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.

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

\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
\ifnum\@cmidla>0\global\let\@gtempa\@cmidrulea\else
\global\let\@gtempa\@cmidruleb\fi
\global\@cmidlb#2\relax
\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}

• If I wanted to change the space later, say 0.2\aboverulesep and 0.6\belowrulesep, how would I do so? It's not obvious in the solution. Thank you. Aug 18 '21 at 0:35

I will give a possible solution with the new LaTeX3 package tabularray. You can also adjust abovesep and belowsep in a similar way.

\documentclass{article}
\usepackage[a6paper,margin=15mm]{geometry}
\usepackage{tabularray}
\UseTblrLibrary{booktabs}
\usepackage{xcolor}

\ExplSyntaxOn
\NewChildSelector { mainfive }
{
\int_step_inline:nnnn {2} {5} { \l_tblr_childs_total_tl }
{ \clist_put_right:Nn \l_tblr_childs_clist {##1} }
}
\NewChildSelector { subfive }
{
\int_step_inline:nnnn {3} {5} { \l_tblr_childs_total_tl }
{
\clist_put_right:Nx \l_tblr_childs_clist
{
##1, \int_eval:n {##1 + 1 }, \int_eval:n {##1 + 2 }, \int_eval:n {##1 + 3 }
}
}
}
\ExplSyntaxOff

\begin{document}

\begin{longtblr}[
caption = {Long Title},
label = {tblr:test},
]{
rowhead = 1, cells = {c},
hline{mainfive} = {0.05em,lightgray},
hline{subfive} = {1-2,4-5}{0.03em,lightgray},
hline{1,Z} = {0.08em,black}, % Z stands for the last
}
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
a    & b    & c    & d    & e    \\
\end{longtblr}

\end{document}
`

• Thank you for the effort and solution, however my question is asking for a command. I will have to look into this tabularray package Aug 16 '21 at 3:33