6

I need to find a package or else learn how to make a tex command definition that does something very similar to the \rowcolors command for tables, for creating a table with alternating background color stripes, but with a couple of key differences.

First, although this is largely cosmetic, I would very much like the content of a cell to be vertically centered in the background. I notice that \rowcolor tends to leave a larger margin at the bottom than it does at the top, and this looks weird when you have a striped table. All the text seems to be offset vertically from where it is looks like it should be.

More importantly, I want to be able to define the size of the group of row to color, so that unlike \rowcolors where it alternates between two backgrounds each and every row, I want to be able to specify how many rows to group together. So while \rowcolors would effective use a group size of only 1 row, I would like to be able to specify groups of two, three or four rows to group together, for example, and so alternate colors every two, three, or four rows, respectively. This question, which I initially thought was asking the exact same question I am, requires much more explicit coding throughout the table than what I was hoping for, where I was wanting something where I could easily just define all of my tables normally, and then easily go back to it and specify alternating color groups on the tables that needed it (as well as the size of the group to use for the table, of course). The aforementioned question I have linked to here seems to require that I explicitly mark the start of each group, and uses an additional command to actually generate each individual row.

I need the ability to specify which row of a table to start alternating the colors on, as well as a way to have different sizes of groups for different tables (or to turn it off completely). Whether this is done before the table starts or embedded into the row where the alternating colors begin is not important.

It is also of great importance to me that the solution must have a single solid block of unbroken color across all adjacent rows and columns with the same background specified. That is, there can be no thin bars of the normal page background separating the columns or rows. I mention this because I have seen both \rowcolor and \columncolor exhibit this behavior, although I have come to believe that this may be a matter of which tool I am using to render the resulting pdf.

If I have to define my own command for this, I'm going to have no idea how to begin. I'm a complete TeX newbie here, so I'm really hoping that either this already exists out there somewhere, or else it's easy enough to do that it could be explained simply here.

8

I have taken a look at the code for \rowcolors and adapted it to allow groups greater one. The new command \groupedRowColors takes four mandatory and one optional argument:

  • The first mandatory argument is the group size, the number of consecutive lines to have the same color.
  • The second mandatory argument is the start line, all lines above will not be colored. This is useful to exclude a header.
  • The third and fourth mandatory arguments are the colors to be used.

If you do not like where the grouping starts or would like to start with the other color you can use the optional argument to shift the colors. Please note that integer division in \numexpr rounds the result so the required shift may be different from what one might expect. (See this question.)

\documentclass{article}

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

\makeatletter
\newcommand{\groupedRowColors}[5][0]{% [#1: offset], #2: group size, #3: start line, #4: color 1, #5: color 2
    % copied from xcolor.sty
    \global\rownum=\z@
    \global\@rowcolorstrue
    \@ifxempty{#4}%
        {\def\@oddrowcolor{\@norowcolor}}%
        {\def\@oddrowcolor{\gdef\CT@row@color{\CT@color{#4}}}}%
    \@ifxempty{#5}%
        {\def\@evenrowcolor{\@norowcolor}}%
        {\def\@evenrowcolor{\gdef\CT@row@color{\CT@color{#5}}}}%
    % simplified (no check for \if@rowcmd)
    \def\@rowcolors{%
        \if@rowcolors
            \noalign{%
                \relax
                \ifnum\rownum<#3
                    \@norowcolor
                % I have changed this check:
                \else \ifodd \numexpr (\rownum-#1)/#2\relax
                    \@oddrowcolor
                \else
                    \@evenrowcolor
                \fi \fi
            }%
        \fi
    }%
    \CT@everycr{\@rowc@lors\the\everycr}%
    \ignorespaces
}
\makeatother


\begin{document}
\groupedRowColors{3}{2}{green!10}{blue!10}
\begin{tabular}{cc}
    \toprule
        Column~1 & Column~2 \\
    \midrule
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
    \bottomrule
\end{tabular}
\end{document}

enter image description here


EDIT: example with longtable

\documentclass{article}
\usepackage[a6paper, landscape]{geometry}

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

\makeatletter
\newcommand{\groupedRowColors}[5][0]{% [#1: offset], #2: group size, #3: start line, #4: color 1, #5: color 2
    % copied from xcolor.sty
    \global\rownum=\z@
    \global\@rowcolorstrue
    \@ifxempty{#4}%
        {\def\@oddrowcolor{\@norowcolor}}%
        {\def\@oddrowcolor{\gdef\CT@row@color{\CT@color{#4}}}}%
    \@ifxempty{#5}%
        {\def\@evenrowcolor{\@norowcolor}}%
        {\def\@evenrowcolor{\gdef\CT@row@color{\CT@color{#5}}}}%
    % simplified (no check for \if@rowcmd)
    \def\@rowcolors{%
        \if@rowcolors
            \noalign{%
                \relax
                \ifnum\rownum<#3
                    \@norowcolor
                % I have changed this check:
                \else \ifodd \numexpr (\rownum-#1)/#2\relax
                    \@oddrowcolor
                \else
                    \@evenrowcolor
                \fi \fi
            }%
        \fi
    }%
    \CT@everycr{\@rowc@lors\the\everycr}%
    \ignorespaces
}
\makeatother


\begin{document}
\groupedRowColors{3}{0}{green!10}{blue!10}
\begin{longtable}{ c c }
    \hiderowcolors
    \toprule
        Column~1 & Column~2 \\
    \midrule
\endfirsthead
        Column~1 & Column~2 \\
    \midrule
\endhead
    \midrule
        \multicolumn{2}{r@{}}{\footnotesize(to be continued on next page)}
\endfoot
    \bottomrule
\endlastfoot
    \showrowcolors
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
        (\the\rownum,0) & (\the\rownum,1) \\
\end{longtable}
\end{document}

(The definition of \groupedRowColors is unchanged.)

enter image description here

  • It took a little bit of fudging with the start line and shift arguments to get the look that I want, but otherwise this is almost exactly right. The only thing I needed to change to get the exact look I was after is the expression in the condition, which I changed to read as: '((\rownum-#3)/#2)-#1' instead of '(\rownum-#1)/#2' – Mark Oct 13 '17 at 12:35
  • Hmmm... I see that this doesn't work when I have a longtable with rows that are supposed to be at the head of each page. Ideally, a solution should also start the row count from 0 at the beginning of each new page. – Mark Oct 14 '17 at 21:05
  • @Mark I don't know a possibility to reset the row count at a page break. \global\rownum=0 between \endfirsthead and \endhead does not work. – jakun Oct 15 '17 at 7:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.