# Longtable does not break correctly when used with \specialrule instead of \hline

I'm writing an application that generate latex code, therefore the solution must be the most generic possible to ensure that it will generate clean pdf all the time. I would like to let my users specify the thickness of the tables (both horizontal and vertical lines) and the best solution I've found so far is to use "\specialrule" from the booktabs package.

Here is a MWE :

\documentclass{article}

\usepackage{longtable}
\usepackage{tabularx}
\usepackage{booktabs}
\newcommand\VRule[1][\arrayrulewidth]{\vrule width #1}

\begin{document}

Some text goes here

and here

and here

and here

and here

\begin{longtable}{!{\VRule[3pt]}c!{\VRule[3pt]}c!{\VRule[3pt]}c!{\VRule[3pt]}c!{\VRule[3pt]}c!{\VRule[3pt]}}
\specialrule{3pt}{0pt}{0pt}
This & is & the & nice & header \\  \specialrule{3pt}{0pt}{0pt} \endhead
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}
Portable & 1 & 676 & 21.00 & 676.00 \\  \specialrule{3pt}{0pt}{0pt}

\end{longtable}

\end{document}


My problem is that the break does not work correctly depending on the height of content before the table and the thickness of the lines. In this case, the last horizontal line of the longtable on the first page is moved on the second page.

-

## 2 Answers

\hline in longtable really needs to know a lot about how longtables are put together, in particular how the left and right margin works, and what to do at a page break. It's basically more like \cline, or rather two \clines one on top of the other to allow duplication at a break.

So basically rules from other packages are not likely to work unless they explicitly cater for longtable.

If you just need varying \arrayrulewidth you should be able to use \setlength{\arrayrulewidth}{3pt} and then a normal \hline.

booktabs does have some support for it but I note its documentation says explicitly.

A somewhat technical note: within a longtable, \hline and \hline\hline both produce a double rule (to allow for page breaks occurring at that point). But the booktabs rules do not. longtable's automatic doubling of \hline is questionable, even according to the documentation within that package. But doubled booktabs rules make almost no sense at all.

So it seems to imply that the behaviour at the page break is by design.

-
This works perfectly and my latex is simpler now, thank you. – Thibault Dory Jan 27 '12 at 8:09

The trick is (a) to define a foot with an additional line, or (b) to use \hline and change the linewidth with \setlength{\arrayrulewidth} (which changes the vertical lines in longtable, too).

Additionally I think the package tabu would be very useful for you. See the example:

\documentclass{article}

\usepackage{kantlipsum}% just for some blindtext

\usepackage{longtable}
\usepackage{tabu}
\newtabulinestyle{tb=1pt,out=1pt,ins=0.3pt}
% "tb" for "top & bottom",
% "out" for "(vertical left & right) outside",
% "ins" for "(vertical) inside"

% for global changes, could be changed locally inside a group:
\setlength{\arrayrulewidth}{0.3pt} % for "normal" lines ("\hline")
\tabulinestyle{0.3pt} % for "\tabucline" provided by "tabu" and "|" (!!!)
% note that I set both to the same width,
% these 2 also, for safety:
\setlength{\tabulinesep}{0pt}
\setlength{\extrarowsep}{0pt}

\begin{document}

\kant[1-2]

\begin{longtabu} to \linewidth [c]{|[out]X[-2c]|[ins]X[-1c]|[ins]X[-1c]|[ins]X[-1c]|[ins]X[-1c]|[out]}
% Define the first head
\tabucline[tb]{-}
\multicolumn{5}{|[out]c|[out]}{\large This is the nice header} \\
\tabucline[0.6pt]{-} %§%
\endfirsthead
% Define the head of continued page(s)
\multicolumn{5}{l}{\scriptsize\itshape continued from last page} \\
\tabucline[0.6pt]{-}
\multicolumn{5}{|[out]c|[out]}{\large This is the nice header} \\
\tabucline{-} % need to be actually the difference between tabucline above
% marked with %§%, and the "normal" tabuclines below
\endhead
% Define the normal foot
\tabucline[0.6pt]{-}
\multicolumn{5}{r}{\scriptsize\itshape continued on next page} \\
\endfoot
% Define the very last foot
\tabucline[tb]{-}
\endlastfoot
% table body
\everyrow{\tabucline{-}}% will be inserted after, emm, every row -- saves us a lot of work
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
Portable & 1 & 676 & 21.00 & 676.00 \\
\end{longtabu}

\end{document}


You have several opportunities for assigning a linewidth to \tabucline:

• by setting the \tabulinestyle
• by defining a new tabu linestyle
• individually as option (there are much more complex possibilities).

The vertical lines can be changed exactly that way, so setting \tabulinestyle applies also to them!

A caveat is, that the line, that is missed on the foot and goes to the next page, will be added to line, that belongs to the top head of continued pages.

OTOH you mentioned booktabs:

Never, ever use vertical rules.

The vertical space between the content and a horizontal line is controled by \tabulinesep and \extrarowheight. The differene acoording to the tabu manual:

\tabulinesep sets the minimal vertical space allowed between the cell content and the cell border. ...
\extrarowsep is an extra vertical space which is added to each row, unconditionally. ... As a result, the rows can share the same height/depth but the spacing is not dynamic.

It is also possible to change only the space above the content or below of it.

-
Thank you for the tip but this seems a little too complicated. The code is quite long compared to the longtable solution. – Thibault Dory Jan 27 '12 at 8:16
@ThibaultDory: Do what you want, but I don’t think so. But, yes, it’s particulary a different appoach. – Speravir Jan 27 '12 at 18:25