The colortbl package^{∗}

David Carlisle

1999/03/24

Abstract This package implements a flexibable mechanism for giving colured ‘panels’ behind specified columns in a table. This package requires the array and color packages.

1 Introduction

This package is for colouring tables (i.e., giving coloured panels behind column entries). In that it has many similarities with Timothy Van Zandt’s colortab package. The internal implementation is quite different though, also colortab works with the table constructs of other formats besides L^{A}TEX. This package requires L^{A}TEX (and its color and array packages).

First, a standard tabular, for comparison.

  \begin{tabular}{|l|c|}
   one&two\\
   three&four
   \end{tabular}

one  two
three four

2 The \columncolor command

The examples below demonstrate various possibilities of the \columncolor command introduced by this package. The vertical rules specified by | are kept in all the examples, to make the column positioning clearer, although possibly you would not want coloured panels and vertical rules in practice.

The package supplies a \columncolor command, that should (only) be used in the argument of a > column specifier, to add a coloured panel behind the specified column. It can be used in the main ‘preamble’ argument of array or tabular, and also in \multicolumn specifiers.

The basic format is: \columncolor[⟨color model⟩]{⟨colour⟩} [⟨left overhang⟩][⟨right overhang⟩]

The first argument (or first two if the optional argument is used) are standard color package arguments, as used by \color.

∗This file has version number v0.1i, last revised 1999/03/24.

The last two arguments control how far the panel overlaps past the widest entry in the column. If the right overhang argument is omitted then it defaults to left overhang. If they are both omitted they default to \tabcolsep (in tabular) or

\arraycolsep (in array).

If the overhangs are both set to 0pt then the effect is:

|>{\columncolor[gray]{.8}[0pt]}l|
>{\color{white}%
\columncolor[gray]{.2}[0pt]}l|

one  two
three four

The default overhang of \tabcolsep produces:

|>{\columncolor[gray]{.8}}l|
>{\color{white}%
\columncolor[gray]{.2}}l|

one  two
three four

You might want something between these two extremes. A value of .5\tabcolsep produces the following effect

|>{\columncolor[gray]{.8}[.5\tabcolsep]}l|
>{\color{white}%
\columncolor[gray]{.2}[.5\tabcolsep]}l|

one  two
three four

This package should work with most other packages that are compatible with the array package syntax. In particular it works with longtable and dcolumn as the following example shows.

Before starting give a little space: \setlength\minrowclearance{2pt}

A long table example

First two columns  Third column
p-type  D-type (dcolumn)

P-column and another one

12·34
Total (wrong) 100·6

Some long text in the first column bbb

1·2

aaa and some long text in the second column

1·345

Total  (wrong)  100·6
aaa  bbb  1·345

Note that the coloured rules in all columns stretch to accomodate large entries in one column.

bbb 1·345

Continued…

2

A long table example (continued)

First two columns  Third column
p-type  D-type (dcolumn)
aaa bbb 100

aaa Depending on your driver you may get unsightly gaps or lines where the ‘screens’ used to produce different shapes interact badly. You may want to cause adjacent panels of the same colour by specifying a larger overhang or by adding some negative space (in

                       a \noalign

between rows.

12·4

aaa  bbb  45·3

The End

This example shows rather poor taste but is quite colourful! Inspect the source file, colortbl.dtx, to see the full code for the example, but it uses the following column types.

\newcolumntype{A}{%
   >{\color{white}\columncolor{red}[.5\tabcolsep]%
      \raggedright}%
   p{2cm}}
\newcolumntype{B}{%
   >{\columncolor{blue}[.5\tabcolsep]%
     \color{yellow}\raggedright}
   p{3cm}}
\newcolumntype{C}{%
    >{\columncolor{yellow}[.5\tabcolsep]}%
      D{.}{\cdot}{3.3}}
\newcolumntype{E}{%
   >{\large\bfseries
     \columncolor{cyan}[.5\tabcolsep]}c}
\newcolumntype{F}{%
    >{\color{white}
      \columncolor{magenta}[.5\tabcolsep]}c}
\newcolumntype{G}{%
    >{\columncolor[gray]{0.8}[.5\tabcolsep][\tabcolsep]}l}

 \newcolumntype{H}{>{\columncolor[gray]{0.8}}l}
 \newcolumntype{I}{%
     >{\columncolor[gray]{0.8}[\tabcolsep][.5\tabcolsep]}%
                    D{.}{\cdot}{3.3}}

3 Using the ‘overhang’ arguments for tabular*

The above is all very well for tabular, but what about tabular*?

Here the problem is rather harder. Although TEX’s \leader mechanism which is used by this package to insert the ‘stretchy’ coloured panels is rather like glue, the \tabskip glue that is inserted between columns of tabular* (and longtable for that matter) has to be ‘real glue’ and not ‘leaders’.

Within limits the overhang options may be used here. Consider the first table example above. If we use tabular* set to 3 cm with a preamble setting of

      \begin{tabular*}{3cm}{%
      @{\extracolsep{\fill}}
      >{\columncolor[gray]{.8}[0pt][20mm]}l
      >{\columncolor[gray]{.8}[5mm][0pt]}l
      @{}}

one  two
three  four

Changing the specified width to 4 cm works, but don’t push your luck to 5 cm…

one  two
three  four

one  two
three  four

4 The \rowcolor command

As demonstrated above, one may change the colour of specified rows of a table by the use of \multicolumn commands in each entry of the row. However if your table is to be marked principally by rows, you may find this rather inconvenient. For this reason a new mechanism, \rowcolor, has been introduced^{1}.

\rowcolor takes the same argument forms as \columncolor. It must be used at the start of a row. If the optional overhang arguments are not used the overhangs will default to the overhangs specified in any \columncolor comands for that column, or \tabcolsep (\arraycolsep in array).

If a table entry is in the scope of a \columncolor specified in the table preamble, and also a \rowcolor at the start of the current row, the colour specified by \rowcolor will take effect. A \multicolumn command may contain >{\rowcolor… which will override the default colours for both the current row and column.

1At some cost to the internal complexity of this package

  \begin{tabular}{|l|c|}
   \rowcolor[gray]{.9}
   one&two\\
   \rowcolor[gray]{.5}
   three&four
   \end{tabular}

one  two
three four

5 Colouring rules.

So you want coloured rules as well?

One could do vertical rules without any special commands, just use something like !{\color{green}\vline} where you’d normally use |. The space between || will normally be left white. If you want to colour that as well, either increase the overhang of the previous column (to \tabcolsep + \arrayrulewidth + \doublerulesep) Or remove the inter rule glue, and replace by a coloured rule of the required thickness. So

!{\color{green}\vline}
@{\color{yellow}\vrule width \doublerulesep}
!{\color{green}\vline}

Should give the same spacing as || but more colour.

However colouring \hline and \cline is a bit more tricky, so extra commands are provided (which then apply to vertical rules as well).

6 \arrayrulecolor

\arrayrulecolor takes the same arguments as \color, and is a global declaration which affects all following horizontal and vertical rules in tables. It may be given outside any table, or at the start of a row, or in a > specification in a table preamble. You should note however that if given mid-table it only affects rules that are specified after this point, any vertical rules specified in the preamble will keep their original colours.

7 \doublerulesepcolor

Having coloured your rules, you’ll probably want something other than white to

go in the gaps made by || or \hline\hline. \doublerulesepcolor works just

the same way as \arrayrulecolor. The main thing to note that if this command is used, then longtable will not ‘discard’ the space between \hline\hline at a page break. (TEX has a built-in ability to discard space, but the coloured ‘space’ which is used once \doublerulesep is in effect is really a third rule of a different colour to the two outer rules, and rules are rather harder to discard.)

\setlength\arrayrulewidth{2pt}\arrayrulecolor{blue}
\setlength\doublerulesep{2pt}\doublerulesepcolor{yellow}
\begin{tabular}{||l||c||}
\hline\hline
one&two\\
three&four\\
\hline\hline
\end{tabular}

one  two
three four

8 More fun with \hhline

The above commands work with \hhline from the hhline package, however if hhline is loaded in addition to this package, a new possibility is added. You may use >{… } to add declarations that apply to the following - or = column

rule. In particular you may give \arrayrulecolor and \doublerulesepcolor

declarations in this argument.

Most manuals of style warn against over use of rules in tables. I hate to think what they would make of the following rainbow example:

Richard of York gave battle in vain

1  2  3  4  5  6  7

\newcommand\rainbowline[1]{%
\hhline{%
>{\arrayrulecolor   {red}\doublerulesepcolor[rgb]{.3,.3,1}}%
|#1:=%
>{\arrayrulecolor{orange}\doublerulesepcolor[rgb]{.4,.4,1}}%
=%
>{\arrayrulecolor{yellow}\doublerulesepcolor[rgb]{.5,.5,1}}%
=%
>{\arrayrulecolor {green}\doublerulesepcolor[rgb]{.6,.6,1}}%
=%
>{\arrayrulecolor  {blue}\doublerulesepcolor[rgb]{.7,.7,1}}%
=%
>{\arrayrulecolor{indigo}\doublerulesepcolor[rgb]{.8,.8,1}}%
=%
>{\arrayrulecolor{violet}\doublerulesepcolor[rgb]{.9,.9,1}}%
=:#1|%
}}
\arrayrulecolor{red}
\doublerulesepcolor[rgb]{.3,.3,1}%
\begin{tabular}{||*7{>{\columncolor[gray]{.9}}c}||}
\rainbowline{t}%

 \arrayrulecolor{violet}\doublerulesepcolor[rgb]{.9,.9,1}
 Richard&of&York&gave&battle&in&
 \multicolumn{1}{>{\columncolor[gray]{.9}}c||}{vain}\\
 \rainbowline{}%
 1&2&3&4&5&6&
 \multicolumn{1}{>{\columncolor[gray]{.9}}c||}{7}\\
 \rainbowline{b}%
 \end{tabular}

9 Less fun with \cline

Lines produced by \cline are coloured if you use \arrayrulecolor but you may not notice as they are covered up by any colour pannels in the following row. This is a ‘feature’ of \cline. If using this package you would probably better using the - rule type in a \hhline argument, rather than \cline.

10 The \minrowclearance command

As this package has to box and measure every entry to figure out how wide to make the rules, I thought I may as well add the following feature. ‘Large’ entries in tables may touch a preceding \hline or the top of a colour panel defined by this style. It is best to increase \extrarowsep or \arraystretch sufficiently to ensure this doesn’t happen, as that will keep the line spacing in the table regular. Sometimes however, you just want to L^{A}TEX to insert a bit of extra space above a large entry. You can set the length \minrowclearance to a small value. (The height of a capital letter plus this value should not be greater than the normal height of table rows, else a very uneven table spacing will result.)

Donald Arseneau’s tabls packages provides a similar \tablinesep. I was going to give this the same name for compatibility with tabls, but that is implemented quite differently and probably has different behaviour. So I’ll keep a new name for now.

11 The Code

1 ⟨∗package⟩

Nasty hacky way used by all the graphics packages to include debugging code.

 2 \edef\@tempa{%
 3 \noexpand\AtEndOfPackage{%
 4  \catcode`\noexpand\^^A\the\catcode`\^^A\relax}}
 5 \@tempa
 6 \catcode`\^^A=\catcode`\%
 7 \DeclareOption{debugshow}{\catcode`\^^A=9 }

All the other options are handled by the color package.

 8 \DeclareOption*{\PassOptionsToPackage\CurrentOption{color}}
 9 \ProcessOptions

I need these so load them now. Actually Mark Wooding’s mdwtab package could probably work instead of array, but currently I assume array package internals so…

10 \RequirePackage{array,color}

\@classz \@classz is the main function in the array package handling of primitive column types: It inserts the code for each of the column specifiers, ‘clrpmb’. The other classes deal with the other preamble tokens such as ‘@ ’or ‘>’.

11 \def\@classz{\@classx
12 \@tempcnta \count@
13 \prepnext@tok

At this point the colour specification for the background panel will be in the code for the ‘>’ specification of this column. This is saved in \toks\@temptokena but array will insert it too late (well it would work for c, but not for p) so fish the colour stuff out of that token register by hand, and then insert it around the entry.

Of course this is a terrible hack. What is really needed is a new column type that inserts stuff in the right place (rather like ! but without the spacing that that does). The \newcolumntype command of array only adds ‘second class’ column types. The re-implementations of \newcolumntype in my blkarray or Mark Wooding’s mdwtab allow new ‘first class’ column types to be declared, but stick with array for now. This means we have to lift the stuff out of the register before the register gets emptied in the wrong place.

14 \expandafter\CT@extract\the\toks\@tempcnta\columncolor!\@nil

Save the entry into a box (using a double group for colour safety as usual).

15 \@addtopreamble{%
16  \setbox\z@\hbox\bgroup\bgroup
17  \ifcase \@chnum

c code: This used to use twice as much glue as l and r (1fil on each side). Now modify it to use 1fill total. Also increase the order from 1fil to 1fill to dissuade people from putting stretch glue in table entries.

18  \hskip\stretch{.5}\kern\z@
19  \d@llarbegin
20  \insert@column
21  \d@llarend\hskip\stretch{.5}\or

l and r as before, but using fill glue.

22  \d@llarbegin \insert@column \d@llarend \hfill \or
23  \hfill\kern\z@ \d@llarbegin \insert@column \d@llarend \or

m, p and b as before.

24 $\vcenter
25 \@startpbox{\@nextchar}\insert@column \@endpbox $\or
26 \vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or
27 \vbox \@startpbox{\@nextchar}\insert@column \@endpbox
28 \fi

Close the box register assignment.

29 \egroup\egroup

The main new stuff.

30 \begingroup

Initalise colour command and overhands.

31 \CT@setup

Run any code resulting from \columncolor commands.

32 \CT@column@color

Run code from \rowcolor (so this takes precedence over \columncolor).

33 \CT@row@color

This is \relax unless one of the two previous commands has requested a colour, in which case it will be \CT@@do@color which will insert \leaders of appropriate colour.

34 \CT@do@color
35 \endgroup

Nothing to do with colour this bit, since we are boxing and measuring the entry anyway may as well check the height, so that large entries don’t bump into horizontal rules (or the top of the colour panels).

36  \@tempdima\ht\z@
37  \advance\@tempdima\minrowclearance
38  \vrule\@height\@tempdima\@width\z@

It would be safer to leave this boxed, but unboxing allows some flexibilty. However the total glue stretch should either be finite or fil (which will be ignored). There may be fill glue (which will not be ignored) but it should total 0fill. If this box contributes fill glue, then the leaders will not reach the full width of the entry. In the case of \multicolumn entries it is actually possible for this box to contribute shrink glue, in which case the coloured panel for that entry will be too wide. Tough luck.

39  \unhbox\z@}%
40 \prepnext@tok}

\CT@setup Initialise the overhang lengths and the colour command.

41 \def\CT@setup{%
42 \@tempdimb\col@sep
43 \@tempdimc\col@sep
44 \def\CT@color{%
45  \global\let\CT@do@color\CT@@do@color
46  \color}}

\CT@@do@color The main point of the package: Add the colour panels.

Add a leader of the specified colour, with natural width the width of the entry plus the specified overhangs and 1fill stretch. Surround by negative kerns so total natural width is not affected by overhang.

47 \def\CT@@do@color{%
48 \global\let\CT@do@color\relax
49  \@tempdima\wd\z@

50  \advance\@tempdima\@tempdimb
51  \advance\@tempdima\@tempdimc
52  \kern-\@tempdimb
53  \leaders\vrule

For quick debugging with xdvi (which can’t do colours). Limit the size of the rule, so I can see the text as well.

54 ^^A                     \@height\p@\@depth\p@
55  \hskip\@tempdima\@plus  1fill
56  \kern-\@tempdimc

Now glue to exactly compensate for the leaders.

57  \hskip-\wd\z@ \@plus -1fill }

\CT@extract Now the code to extract the \columncolor commands.

58 \def\CT@extract#1\columncolor#2#3\@nil{%
59 \if!#2%

! is a fake token inserted at the end.

60  \let\CT@column@color\@empty
61 \else

If there was an optional argument

62  \if[#2%
63  \CT@extractb{#1}#3\@nil
64  \else

No optional argument

65  \def\CT@column@color{%
66  \CT@color{#2}}%
67  \CT@extractd{#1}#3\@nil
68  \fi
69 \fi}

\CT@extractb Define \CT@column@color to add the right colour, and save the overhang lengths. Finally reconstitute the saved ‘>’ tokens, without the colour specification. First grab the colour spec, with optional arg.

70 \def\CT@extractb#1#2]#3{%
71 \def\CT@column@color{%
72  \CT@color[#2]{#3}}%
73 \CT@extractd{#1}}%

\CT@extractd Now look for left-overhang (default to \col@sep).

74 \def\CT@extractd#1{\@testopt{\CT@extracte{#1}}\col@sep}

\CT@extracte Same for right-overhang (default to left-overhang).

75 \def\CT@extracte#1[#2]{\@testopt{\CT@extractf{#1}[#2]}{#2}}

\CT@extractf Add the overhang info to \CT@do@color, for excuting later.

76 \def\CT@extractf#1[#2][#3]#4\columncolor#5\@nil{%
77 \@tempdimb#2\relax
78 \@tempdimc#3\relax
79 \edef\CT@column@color{%
80  \CT@column@color
81  \@tempdimb\the\@tempdimb\@tempdimc\the\@tempdimc\relax}%
82 \toks\@tempcnta{#1#4}}%

\CT@everycr Steal \everypar to initialise row colours

83 \let\CT@everycr\everycr
84 \newtoks\everycr
85 \CT@everycr{\noalign{\global\let\CT@row@color\relax}\the\everycr}
\CT@start
86 \def\CT@start{%
87 \let\CT@arc@save\CT@arc@
88 \let\CT@drsc@save\CT@drsc@
89 \let\CT@row@color@save\CT@row@color}
\CT@end
90 \def\CT@end{%
91 \global\let\CT@arc@\CT@arc@save
92 \global\let\CT@drsc@\CT@drsc@save
93 \global\let\CT@row@color\CT@row@color@save}
\shortstack  \shortstack
94 \gdef\@ishortstack#1{%
95 \CT@start\ialign{\mb@l {##}\unskip\mb@r\cr #1\crcr}\CT@end\egroup}

\@tabarray array and tabular (delayed for delarray)

96 \AtBeginDocument{%
97 \expandafter\def\expandafter\@tabarray\expandafter{%
98  \expandafter\CT@start\@tabarray}}
\endarray
99 \def\endarray{\crcr \egroup \egroup \gdef\@preamble{}\CT@end}
\multicolumn  \multicolumn
100 \def\multicolumn#1#2#3{%
101 \multispan{#1}\begingroup
102 \def\@addamp{\if@firstamp \@firstampfalse \else
103  \@preamerr 5\fi}%
104 \@mkpream{#2}\@addtopreamble\@empty
105 \endgroup
106 \def\@sharp{#3}%
107 \let\CT@row@color\relax
108 \let\CT@column@color\relax

109 \let\CT@do@color\relax
110 \@arstrut \@preamble
111 \null
112 \ignorespaces}

\@classvi Coloured rules and rule separations.

113 \def\@classvi{\ifcase \@lastchclass
114  \@acol \or
115  \ifx\CT@drsc@\relax
116  \@addtopreamble{\hskip\doublerulesep}%
117  \else
118  \@addtopreamble{{\CT@drsc@\vrule\@width\doublerulesep}}%
119  \fi\or
120  \@acol \or
121  \@classvii
122  \fi}
\doublerulesepcolor
123 \def\doublerulesepcolor#1#{\CT@drs{#1}}
\CT@drs
124 \def\CT@drs#1#2{%
125 \ifdim\baselineskip=\z@\noalign\fi
126 {\gdef\CT@drsc@{\color#1{#2}}}}
\CT@drsc@
127 \let\CT@drsc@\relax
\arrayrulecolor
128 \def\arrayrulecolor#1#{\CT@arc{#1}}
\CT@arc
129 \def\CT@arc#1#2{%
130 \ifdim\baselineskip=\z@\noalign\fi
131 {\gdef\CT@arc@{\color#1{#2}}}}
\CT@arc@
132 \let\CT@arc@\relax

hline

\@arrayrule
133 \def\@arrayrule{\@addtopreamble {{\CT@arc@\vline}}}
\hline
134 \def\hline{%
135 \noalign{\ifnum0=`}\fi
136  \let\hskip\vskip
137  \let\vrule\hrule

138  \let\@width\@height
139 {\CT@arc@\vline}%
140 \futurelet
141 \reserved@a\@xhline}
\@xhline
142 \def\@xhline{\ifx\reserved@a\hline
143  {\ifx\CT@drsc@\relax
144  \vskip
145  \else
146  \CT@drsc@\hrule\@height
147  \fi
148  \doublerulesep}%
149  \fi
150  \ifnum0=`{\fi}}

\cline \cline doesn’t really work, as it comes behind the coloured panels, but at least make it the right colour (the bits you can see, anyway).

151 \def\@cline#1-#2\@nil{%
152 \omit
153 \@multicnt#1%
154 \advance\@multispan\m@ne
155 \ifnum\@multicnt=\@ne\@firstofone{&\omit}\fi
156 \@multicnt#2%
157 \advance\@multicnt-#1%
158 \advance\@multispan\@ne
159 {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}%
160 \cr
161 \noalign{\vskip-\arrayrulewidth}}

\minrowclearance The row height fudge length.

162 \newlength\minrowclearance
163 \minrowclearance=0pt

\@mkpream While expanding the preamble array passes tokens through an \edef. It doesn’t use \protection as it thinks it has full control at that point. As the redefinition above adds \color, I need to add that to the list of commands made safe.

164 \expandafter\def\expandafter\@mkpream\expandafter#\expandafter1%
165 \expandafter{%
166  \expandafter\let\expandafter\CT@setup\expandafter\relax
167  \expandafter\let\expandafter\CT@color\expandafter\relax
168  \expandafter\let\expandafter\CT@do@color\expandafter\relax
169  \expandafter\let\expandafter\color\expandafter\relax
170  \expandafter\let\expandafter\CT@column@color\expandafter\relax
171  \expandafter\let\expandafter\CT@row@color\expandafter\relax
172  \@mkpream{#1}}

\CT@do@color For similar reasons, need to make this non-expandable

173 \let\CT@do@color\relax

\rowcolor
174 \def\rowcolor{%
175 \noalign{\ifnum0=`}\fi
176 \global\let\CT@do@color\CT@@do@color
177 \@ifnextchar[\CT@rowa\CT@rowb}
\CT@rowa
178 \def\CT@rowa[#1]#2{%
179 \gdef\CT@row@color{\CT@color[#1]{#2}}%
180 \CT@rowc}
\CT@rowb
181 \def\CT@rowb#1{%
182 \gdef\CT@row@color{\CT@color{#1}}%
183 \CT@rowc}
\CT@rowc
184 \def\CT@rowc{%
185 \@ifnextchar[\CT@rowd{\ifnum`{=0\fi}}}
\CT@rowd
186 \def\CT@rowd[#1]{\@testopt{\CT@rowe[#1]}{#1}}
\CT@rowe
187 \def\CT@rowe[#1][#2]{%
188 \@tempdimb#1%
189 \@tempdimc#2%
190 \xdef\CT@row@color{%
191  \expandafter\noexpand\CT@row@color
192  \@tempdimb\the\@tempdimb
193  \@tempdimc\the\@tempdimc
194  \relax}%
195 \ifnum0=`{\fi}}

\DC@endright dcolumn support. the D column sometimes internally converts a c column to an r one by squashing the supplied glue. This is bad news for this package, so redefine it to add negative glue to one side and positive to the other to keep the total added zero.

196 \AtBeginDocument{%
197 \def\@tempa{$\hfil\egroup\box\z@\box\tw@}%
198 \ifx\@tempa\DC@endright

New version of dcolumn, only want to fudge it in the D{.}{.}{3} case, not the new D{.}{.}{3.3} possibility. \hfill has already been inserted, so need to remove 1fill’s worth of stretch.

199  \def\DC@endright{%
200  $\hfil\egroup
201  \ifx\DC@rl\bgroup
202  \hskip\stretch{-.5}\box\z@\box\tw@\hskip\stretch{-.5}%

203  \else
204  \box\z@\box\tw@
205  \fi}%
206 \else
207  \def\@tempa{$\hfil\egroup\hfill\box\z@\box\tw@}%
208  \ifx\@tempa\DC@endright

Old dcolumn code.

209  \def\DC@endright{%
210  $\hfil\egroup%
211  \hskip\stretch{.5}\box\z@\box\tw@\hskip\stretch{-.5}}%
212  \fi
213 \fi}

hhline support (almost the whole package, repeated, sigh).

214 \AtBeginDocument{%
215 \ifx\hhline\@undefined\else
216 \def\HH@box#1#2{\vbox{{%
217 {\CT@drsc@\dimen@\tw@\arrayrulewidth
218 \advance\dimen@\doublerulesep
219 \hrule \@height\dimen@
220 \vskip-\dimen@}%
221 \CT@arc@
222 \hrule \@height \arrayrulewidth \@width #1
223 \vskip\doublerulesep
224 \hrule \@height \arrayrulewidth \@width #2}}}
225 \def\HH@loop{%
226 \ifx\@tempb`\def\next##1{\the\toks@\cr}\else\let\next\HH@let
227 \ifx\@tempb|\if@tempswa
228  \ifx\CT@drsc@\relax
229  \HH@add{\hskip\doublerulesep}%
230  \else
231  \HH@add{{\CT@drsc@\vrule\@width\doublerulesep}}%
232  \fi
233  \fi\@tempswatrue
234  \HH@add{{\CT@arc@\vline}}\else
235 \ifx\@tempb:\if@tempswa
236  \ifx\CT@drsc@\relax
237  \HH@add{\hskip\doublerulesep}%
238  \else
239  \HH@add{{\CT@drsc@\vrule\@width\doublerulesep}}%
240  \fi
241  \fi\@tempswatrue
242  \HH@add{\@tempc\HH@box\arrayrulewidth\arrayrulewidth\@tempc}\else
243 \ifx\@tempb##\if@tempswa\HH@add{\hskip\doublerulesep}\fi\@tempswatrue
244  \HH@add{{\CT@arc@\vline\copy\@ne\@tempc\vline}}\else
245 \ifx\@tempb~\@tempswafalse
246  \if@firstamp\@firstampfalse\else\HH@add{&\omit}\fi
247  \ifx\CT@drsc@\relax
248  \HH@add{\hfil}\else

249  \HH@add{{%
250 \CT@drsc@\leaders\hrule\@height\doublerulesep\hfil}}%
251  \fi
252  \else
253 \ifx\@tempb-\@tempswafalse
254  \if@firstamp\@firstampfalse\else\HH@add{&\omit}\fi
255  \HH@add{{%
256  \CT@arc@\leaders\hrule\@height\arrayrulewidth\hfil}}%
257  \else
258 \ifx\@tempb=\@tempswafalse
259  \if@firstamp\@firstampfalse\else\HH@add{&\omit}\fi
260  \HH@add
261  {\rlap{\copy\@ne}\leaders\copy\@ne\hfil\llap{\copy\@ne}}\else

Stop the backspacing for t and b, it messes up the underlying colour.

262 \ifx\@tempb t\HH@add{\HH@box\doublerulesep\z@}\@tempswafalse\else
263 \ifx\@tempb b\HH@add{\HH@box\z@\doublerulesep}\@tempswafalse\else
264 \ifx\@tempb>\def\next##1##2{%
265  \HH@add{%
266  {\baselineskip\p@\relax
267  ##2%
268  \global\setbox\@ne\HH@box\doublerulesep\doublerulesep}}%
269  \HH@let!}\else
270 \PackageWarning{hhline}%
271  {\meaning\@tempb\space ignored in \noexpand\hhline argument%
272  \MessageBreak}%
273 \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
274 \next}
275 \fi}

longtable support.

276 \AtBeginDocument{
277 \ifx\longtable\@undefined\else
278  \def\LT@@hline{%
279  \ifx\LT@next\hline
280  \global\let\LT@next\@gobble
281  \ifx\CT@drsc@\relax
282  \gdef\CT@LT@sep{%
283  \noalign{\penalty-\@medpenalty\vskip\doublerulesep}}%
284  \else
285  \gdef\CT@LT@sep{%
286  \multispan\LT@cols{%
287  \CT@drsc@\leaders\hrule\@height\doublerulesep\hfill}\cr}%
288  \fi
289  \else
290  \global\let\LT@next\empty
291  \gdef\CT@LT@sep{%
292  \noalign{\penalty-\@lowpenalty\vskip-\arrayrulewidth}}%
293  \fi
294  \ifnum0=`{\fi}%

295  \multispan\LT@cols
296  {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr
297  \CT@LT@sep
298  \multispan\LT@cols
299  {\CT@arc@\leaders\hrule\@height\arrayrulewidth\hfill}\cr
300  \noalign{\penalty\@M}%
301  \LT@next}
302  \fi}

303 ⟨/package⟩