3

The problem

Let's say I want to have more than rules in two different colors in the same row ... how can I make it work?

Here is a minimal example:

\documentclass{article}
\usepackage{colortbl}
\usepackage{booktabs}

\begin{document}

\begin{table}[ht]
    \begin{tabular}{llll}
        \toprule
        A & B & alpha & beta\\
        \arrayrulecolor{black} \cmidrule[1pt](l){1-1} \arrayrulecolor{red} \cmidrule[1pt](r){2-2} \arrayrulecolor{black} \cmidrule[1pt](l){3-3} \arrayrulecolor{black} \cmidrule[1pt](r){4-4}
        1 & 5 & 10 &    100\\
        2 & 6 & 11 &    101\\
        2 & 7 & 12 &    102\\
        3 & 8 & 13 &    103\\
        \bottomrule
    \end{tabular}
\end{table}

\end{document}

What happens is that with each call of \arrayrulecolor{}, the corresponding cmidrule is moved down.

result

The solution is a macro that corrects the positioning, but there is a problem with it.

The problem with the earlier solution

The solution mentioned here: How to omit vertical realignment when using cmidrule in different colors? does not handle varying widths correctly

\documentclass{article}
\usepackage{colortbl}
\usepackage{booktabs}

\newcommand{\corcmidrule}[1][2pt]{% \corcmidrule[<len>] \[\dimexpr-\normalbaselineskip-\belowrulesep-\aboverulesep-#1\relax]% }

\begin{document}

\begin{table}[ht]
    \begin{tabular}{llll}
        \toprule
        A &amp; B &amp; alpha &amp; beta\\
        \arrayrulecolor{black}\cmidrule[1pt](l){1-1} 
        \corcmidrule[2pt]\arrayrulecolor{black}\cmidrule[2pt](r){2-2} 
        \corcmidrule[5pt]\arrayrulecolor{black}\cmidrule[5pt](l){3-3} 
        \corcmidrule[1pt]\arrayrulecolor{black}\cmidrule[1pt](r){4-4}
        1 &amp; 5 &amp; 10 &amp;    100\\
        2 &amp; 6 &amp; 11 &amp;    101\\
        2 &amp; 7 &amp; 12 &amp;    102\\
        3 &amp; 8 &amp; 13 &amp;    103\\
        \bottomrule
    \end{tabular}
\end{table}

\end{document}

enter image description here

What's wrong with this? Consider what it looks like without the macro:

\documentclass{article}
\usepackage{colortbl}
\usepackage{booktabs}

\newcommand{\corcmidrule}[1][2pt]{% \corcmidrule[<len>] \[\dimexpr-\normalbaselineskip-\belowrulesep-\aboverulesep-#1\relax]% }

\begin{document}

\begin{table}[ht]
    \begin{tabular}{llll}
        \toprule
        A &amp; B &amp; alpha &amp; beta\\
        \arrayrulecolor{black}\cmidrule[1pt](l){1-1} 
        \cmidrule[2pt](r){2-2} 
        \cmidrule[5pt](l){3-3} 
        \cmidrule[1pt](r){4-4}
        1 &amp; 5 &amp; 10 &amp;    100\\
        2 &amp; 6 &amp; 11 &amp;    101\\
        2 &amp; 7 &amp; 12 &amp;    102\\
        3 &amp; 8 &amp; 13 &amp;    103\\
        \bottomrule
    \end{tabular}
\end{table}

\end{document}

enter image description here

It seems that these would be the right adjustments.

\begin{table}[ht]
    \begin{tabular}{llll}
        \toprule
        A & B & alpha & beta\\
                         \arrayrulecolor{black}\cmidrule[1pt](l){1-1} 
        \corcmidrule[1pt]\arrayrulecolor{black}\cmidrule[2pt](r){2-2} 
        \corcmidrule[3pt]\arrayrulecolor{black}\cmidrule[5pt](l){3-3} 
        \corcmidrule[5pt]\arrayrulecolor{black}\cmidrule[1pt](r){4-4}
        1 & 5 & 10 &    100\\
        2 & 6 & 11 &    101\\
        2 & 7 & 12 &    102\\
        3 & 8 & 13 &    103\\
        \bottomrule
    \end{tabular}
\end{table}

A bigger example

\begin{table}[ht]
    \begin{tabular}{lllll}
        \toprule
        A & B & alpha & beta & gamma\\
        \arrayrulecolor{black}\cmidrule[1pt](l){1-1} 
        \corcmidrule[1pt]\arrayrulecolor{black}\cmidrule[2pt](){2-2} 
        \corcmidrule[2pt]\arrayrulecolor{black}\cmidrule[2pt](){3-3} 
        \corcmidrule[2pt]\arrayrulecolor{black}\cmidrule[5pt](){4-4} 
        \corcmidrule[5pt]\arrayrulecolor{black}\cmidrule[1pt](){5-5}
        1 & 5 & 10 &    100 & 1\\
        2 & 6 & 11 &    101 & 1\\
        2 & 7 & 12 &    102 & 1\\
        3 & 8 & 13 &    103 & 1\\
        \bottomrule
    \end{tabular}
\end{table}

Could this be put into a macro? One needs to pull the width of the previous rule.

  • Welcome to TeX SX! Why not simply do that with hhline? – Bernard Jan 30 '21 at 17:17
  • I need trimming. \cmidrule makes it easy, trim left, right or both. This is for programmatically creating tables. Inserting the right widths at the right place is not a problem, however, it doesn't help readability. So I want to create a table programmatically, but keep enough readability for manual tweaking. – Inferrator Jan 30 '21 at 17:31

1 Answers1

3

Here is a programmation of a command \MyRule which might do the job in the environments {NiceTabular} of nicematrix.

The syntax of \MyRule is as follow : \MyRule[#1](#2){#3-#4}

The arguments #1 and #2 are optional.

  • #1 is a list of key-value pairs. As of now, there is two keys: color and width;
  • #2 contains r, l or both (for specifying trimming);
  • #3 is the number of the first column;
  • #4 is the number of the last column.

\documentclass{article}
\usepackage{nicematrix}
\usepackage{tikz}

\ExplSyntaxOn

\keys_define:nn { MyRule } { color .tl_set:N = \l__MyRule_color_tl , color .value_required:n = true , width .dim_set:N = \l__MyRule_width_dim , width .value_required:n = true , width .initial:n = \arrayrulewidth , style .value_required:n = true , style .tl_set:N = \l__MyRule_style_tl }

\NewDocumentCommand { \MyRule } { O { } D ( ) { } m } { \exp_args:Nx __MyRule_i:nnnn { \int_use:c { c@iRow } } { #1 } { #2 } { #3 } }

\cs_new_protected:Nn __MyRule_i:nnnn { \tl_gput_right:Nn \g_nicematrix_code_after_tl { __MyRule_ii:nnnn { #1 } { #2 } { #3 } { #4 } } \peek_remove_spaces:n { } }

\cs_new_protected:Nn __MyRule_ii:nnnn { \group_begin: \keys_set:nn { MyRule } { #2 } __MyRule_iii:w #4 \q_stop \begin { tikzpicture } \pgfsetlinewidth { \l__MyRule_width_dim } \tl_if_empty:NF \l__MyRule_color_tl
{ \pgfsetstrokecolor { \l__MyRule_color_tl } } \tl_if_in:nnTF { #3 } { l } { \dim_set:Nn \l_tmpa_dim { 1 mm } } { \dim_zero:N \l_tmpa_dim } \tl_if_in:nnTF { #3 } { r } { \dim_set:Nn \l_tmpa_dim { 1 mm } } { \dim_zero:N \l_tmpa_dim } \tl_if_empty:NF \l__MyRule_line_style_tl { \tikzset { every~path/.style = \l__MyRule_style_tl } } \draw ([xshift=\l_tmpa_dim,yshift=-\l__MyRule_width_dim/2] #1 -| \int_use:N \l_tmpa_int ) -- ([xshift=-\l_tmpa_dim,yshift=-\l__MyRule_width_dim/2] #1 -| \int_use:N \l_tmpb_int ) ; \end { tikzpicture } \group_end: }

\cs_new_protected:Npn __MyRule_iii:w #1 - #2 \q_stop { \int_set:Nn \l_tmpa_int { #1 } \int_set:Nn \l_tmpb_int { #2 + 1 } }

\ExplSyntaxOff

\begin{document}

\renewcommand{\arraystretch}{1.4} \begin{NiceTabular}{ccccc} AAA & BBBBBB & CCC & DDDDDDD & EEEE \ \MyRulecolor=red{2-2} \MyRulecolor=blue,width=1pt{3-3} \MyRulewidth=2pt{4-5} QQQQQ & CCCC & DDDDDDD & JJJJJJJJ & KKK\ \MyRule[color=red,style=dotted,width=1pt]{2-3} QQQQQ & CCCC & DDDDDDD & JJJJJJJJ & QQQQQ \end{NiceTabular}

\end{document}

You need several compilations (because nicematrix uses PGF/Tikz nodes).

Output of the above code

F. Pantigny
  • 40,250
  • This is pretty nice! (pun intended). Your \MyRule command is versatile and super easy to use. I thought about using booktabs, but this looks like it generates the desired output as well. I am just wondering about the first column: why aren't the 'QQQQQ' aligned? – Inferrator Jan 31 '21 at 23:30
  • 1
    @Inferrator: You are right. There was a problem. I have solve it by adding \peek_remove_spaces:n{ } and so, all spaces avec a command \MyRule will be discarded. – F. Pantigny Feb 01 '21 at 08:19
  • Very good. I noticed one more thing. With differing widths, the rules are aligned at the center. If you do this with booktabs, rules are aligned at the top. It might be a matter of taste, but aligning at the top seems to make more sense to me. – Inferrator Feb 01 '21 at 17:30
  • 1
    @Inferrator: OK. I have modified my answer. – F. Pantigny Feb 01 '21 at 19:41
  • Now this is really, really nice. While I don't use it often, is it possible to add vertical and dotted lines in a similar fashion? – Inferrator Feb 02 '21 at 15:32
  • 1
    @Inferrator: I have added a key style. It's possible to give to that key whatever Tikz key you want such as dotted, dashed, etc. For the vertical rules, there is a question of syntax. Which syntax do you want. For the horizontal rules, we put the command between two rows but, for the vertical rules, it's possible to put the command between two columns... – F. Pantigny Feb 03 '21 at 16:59
  • Wow, nice. It's not what I had in mind first (booktabs) but it's more flexible and great for programmatic output to TeX. Thanks much! – Inferrator Feb 03 '21 at 17:13
  • For vertical lines: This is tricky, having to consider all eventualities. It could be a \MyVerticalRule[color=red](width){position={lrtb})} command, where lrtb=left-right-top-bottom. It could be placed within the cells, or there could be a row specified, sort of tranposed version of MyRule. I am not sure how this would play with multirow/multicolumn. – Inferrator Feb 03 '21 at 20:35