TransWikia.com

rows of alternating colors in longtable: filling whitespace depending on the row number

TeX - LaTeX Asked on December 8, 2021

I’m using the longtable package along with booktabs-style rules and alternating row colors. The MWE

documentclass{article}
usepackage[a6paper]{geometry}

usepackage[T1]{fontenc}
usepackage[utf8]{inputenc}
usepackage{lmodern}

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

usepackage{calc}

begin{document}

begin{ThreePartTable}
    rowcolors{2}{white}{gray}
    begin{longtable}{p{.333textwidth-2tabcolsep}p{.333textwidth-2tabcolsep}p{.333textwidth-2tabcolsep}}
        caption{Lorem Ipsum.}\
        toprule
            Lorem & Ipsum & Dolor\
            midrule
        endfirsthead
            Lorem & Ipsum & Dolor\
            midrule
        endhead
            hline 
            multicolumn{3}{r}{(emph{continued on next page})} \
        endfoot
            bottomrule
        endlastfoot
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foonewline foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
        end{longtable}
    end{ThreePartTable}
end{document}

will give:

enter image description here

There is some whitespace between midrule and the first row as well as bottomrule and the last row on page 3. I learnt from this answer that one can fill those gaps using belowrulesepcolor and aboverulesepcolor:

documentclass{article}
usepackage[a6paper]{geometry}

usepackage[T1]{fontenc}
usepackage[utf8]{inputenc}
usepackage{lmodern}

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

usepackage{calc}

newcommand*{belowrulesepcolor}[1]{%
  noalign{%
    kern-belowrulesep
    begingroup
      color{#1}%
      hrule heightbelowrulesep
    endgroup
  }%
}
newcommand*{aboverulesepcolor}[1]{%
  noalign{%
    begingroup
      color{#1}%
      hrule heightaboverulesep
    endgroup
    kern-aboverulesep
  }%
}

begin{document}

begin{ThreePartTable}
    rowcolors{2}{white}{gray}
    begin{longtable}{p{.333textwidth-2tabcolsep}p{.333textwidth-2tabcolsep}p{.333textwidth-2tabcolsep}}
        caption{Lorem Ipsum.}\
        toprule
            Lorem & Ipsum & Dolor\
            midrule
        endfirsthead
            Lorem & Ipsum & Dolor\
            %aboverulesepcolor{gray}
            midrule
            belowrulesepcolor{gray}
        endhead
            hline 
            multicolumn{3}{r}{(emph{continued on next page})} \
        endfoot
            aboverulesepcolor{gray}
            bottomrule
        endlastfoot
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foonewline foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
            foo & bar & foo\
        end{longtable}
    end{ThreePartTable}
end{document}

Which will give:

enter image description here

However, the first row on page 2 will also be preceded by a gray bar, although the first row is white. Is there any chance to make this more robust, i.e. by using some if-else-statement using the current row number? Thanks.

2 Answers

An altetnative solution with the new LaTeX3 package tabularray:

documentclass{article}

usepackage[a6paper]{geometry}
usepackage{xcolor}
usepackage{tabularray}
UseTblrLibrary{booktabs}

begin{document}

begin{longtblr}[
  caption = {Lorem Ipsum},
  note{a} = {First note.},
  note{b} = {Second note.},
]{
  colspec={XXX},
  row{odd} = {gray8},
  row{1} = {white},
  rowhead = 1,
  rowsep = 1pt,
}
toprule
    Lorem & Ipsum & Dolor\
midrule
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foonewline foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
    foo & bar & foo\
bottomrule
end{longtblr}

end{document}

enter image description here

Answered by L.J.R. on December 8, 2021

How about this solution? It seems like the longtable package executes code in a funny way, which means some workarounds are needed to get it right. If you are OK with it, I think this should be enough.

enter image description here

documentclass{article}
usepackage{booktabs}
usepackage[a6paper]{geometry}
usepackage{expl3}
usepackage{array}
usepackage{xcolor, colortbl}
usepackage{longtable}

begin{document}


% define some colors
definecolor{colora}{HTML}{00bfff}
definecolor{colorb}{HTML}{ffffff}
definecolor{colorc}{HTML}{00ff7f}
definecolor{colord}{HTML}{ffffff}


ExplSyntaxOn

% set up the list of colors to be used
clist_new:N l_colors_clist
clist_set:Nn l_colors_clist {colora, colorb, colorc, colord}

int_new:N l_color_ind_int

% the function that computes color index
cs_new:Npn __compute_color_index:n #1 {
    int_set:Nn l_tmpb_int { clist_count:N l_colors_clist }
    int_set:Nn l_tmpa_int { int_div_truncate:nn {#1} {l_tmpb_int} }
    int_gset:Nn l_color_ind_int { #1 - l_tmpa_int * l_tmpb_int + 1}
}


int_new:N l_list_ind_int
bool_new:N l_is_header_bool

cs_new:Npn resetlistindex {
    int_gset:Nn l_list_ind_int {0}
    bool_gset_false:N l_is_header_bool
    __compute_color_index:n {l_list_ind_int}
}

cs_new:Npn calloneachrow {
    bool_if:NTF l_is_header_bool {
        bool_gset_false:N l_is_header_bool
    } {
        % increment row counter
        int_gincr:N l_list_ind_int
        __compute_color_index:n {l_list_ind_int}
    }
}

% this function sets correct cell color
cs_new:Npn calloneachcell {
    bool_if:NTF l_is_header_bool {}
    {
        % get color name
        tl_set:Nx l_tmpa_tl { clist_item:Nn l_colors_clist {l_color_ind_int} }
        % use this color
        exp_args:No cellcolor {l_tmpa_tl}
    }
}

% suppress color in header
cs_new:Npn callonheader {
    bool_gset_true:N l_is_header_bool
}


ExplSyntaxOff


% unfortunately, using rowcolor directly doesn't seem to work
% therefore, I use the following workaround:

% declare a new column type, which calls calloneachcell every time
newcolumntype{C}{>{calloneachcell}c}

% set list index to 0
resetlistindex
begin{longtable}{CCC<{calloneachrow}}
caption{Caption}\
toprule
callonheader %suppress background color for headers
% here, I need to explicitly execute cellcolor{white}
% because the code of column type C will be executed
% before callonheader, which means the first cell will
% have background color. I simply just override it with
% white color.
cellcolor{white} Lorem & Ipsum & Dolor\
midrule
endfirsthead
callonheader %suppress background color for headers
cellcolor{white} Lorem & Ipsum & Dolor\
midrule
endhead
hline 
multicolumn{3}{r}{(emph{continued on next page})} \
endfoot

bottomrule
endlastfoot
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
% need to use a parbox to wrap around newline
parbox{3ex}{foonewline} & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
foo & bar & foo\
end{longtable}


end{document}

Answered by Alan Xiang on December 8, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP