6

Is it possible to specify where the preferred page breaks in a longtable are? I'm trying to create a longtable with three types of rows:

  1. rows which should never be followed by a page break
  2. rows which can be followed by a page break if necessary
  3. rows which mark the preferred page break locations

I know that \\* will get me rows of type 1, but I don't know how to accomplish the other two.

Also, while there will generally be a row of type 2 or 3 every two or three rows, I'd still like to avoid big blocks of white space at the bottom of the page by introducing some stretchable spaces after each row:

  1. 0pt plus 1pt
  2. 0pt plus 1pt
  3. 12pt plus 6pt

I know I can use \\[12pt] to introduce a fixed amount of distance after a particular row, but changing this up for a stretchable space raises errors.

I've been able to do something like this in a list environment before by redefining \item, \par, and \\, but now need the header and footer capabilities of longtable. Is it possible to define some variants on \\ or \tabularnewline inside the longtable environment which will accomplish both these goals?

MWE (doesn't actually do much, but it gives you something to play with):

\documentclass[12pt,a5paper]{article}

\usepackage{longtable}

\newcounter{bla}
\newcommand\bla{\stepcounter{bla}row\thebla}

\setlength{\baselineskip}{12pt plus 1pt}

\begin{document}

\begin{longtable}{c}
\bla \\* \bla type 2 \\ \bla \\* \bla \\* \bla type 3\\[12pt]
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\[12pt]
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\[12pt]
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\[12pt]
\bla \\* \bla \\* \bla type 2 \\ \bla \\* \bla type 3\\[12pt]
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\[12pt]
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\[12pt]
\bla \\* \bla type 2 \\ \bla \\* \bla type 2 \\ \bla \\* \bla type 3\\[12pt]
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\[12pt]
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\[12pt]
\end{longtable}

\end{document}
  • as there is no flexibility between the rows (and infinite stretchability at bottom of page) there is not really any penalty calculation so only really no break (\\*) or forced break (\\ \pagebreak) make sense. If you modified things to only have finite glue at the end then \\ \noalign\penalty 500 might start to make a difference, perhaps... You can use \\ \noalign{\vspace{10pt plus 10pt}} most likely – David Carlisle Dec 15 '16 at 22:54
8

Let' see.

  1. rows which should never be followed by a page break
  2. rows which can be followed by a page break if necessary
  3. rows which mark the preferred page break locations

Number 1 can be done with \\* as you have noticed. However, there is a bug that causes this not to work if it is followed by a \cline. There is a patch for this (see longtable multirow problem with cline and nopagebreak).

Number 2 is the normal row ending \\.

Number 3 can be done by adding \noalign{\penalty-5000} after the \\. The 5000 can be changed to get more or less preference for a page break. This will only work if there is enough stretchability in the page.

You can add stretchable space between rows with \noalign{\vskip 12pt plus 6pt}, but then the vertical lines will be broken.

  • unfortunately I defeat the finite stretch by adding \vss at the bottom, just posting a fix for that... – David Carlisle Dec 15 '16 at 23:05
  • @DavidCarlisle Are you also going to put this fix, and a fix for \cline in a release? – Piet van Oostrum Dec 16 '16 at 0:02
  • er possibly (cline is more of a fix, this is more of a feature request as tables with stretch space between rows is not something you would often want I suspect (certainly I've not seen it asked before) but there is a queue of such things and too many things that break if I try to chantge them all so I'm not sure what best plan is... see htmlpreview.github.io/?https://raw.githubusercontent.com/… – David Carlisle Dec 16 '16 at 0:06
  • There will be no lines in these tables, so the mentioned defects regarding lines are not a problem. Applying the rest I get the results I want. Since for my use case the fix of @DavidCarlisle for the \vss makes only a small difference, I'm going to pick this one as the answer (though David still gets an upvote). Thanks. – rpspringuel Dec 16 '16 at 1:26
  • @rpspringuel no objection to Piet getting a tick:-) but do you have a case where stretchable space added as in a \noalign here actually stretches? Nothing is impossible but my understanding of the code would imply that \noalign{\vskip 12pt plus 6pt} is the same as \noalign{\vskip 12pt } unless you remove the vss? – David Carlisle Dec 16 '16 at 7:42
2

enter image description here

In order to make finite amounts of stretech have any effect between rows you need to modify longtable not to add infinite stretch at the bottom of the page (like using \flushbottom instead of \raggedbottom the package doesn't have an interface for that but just deleting \vss where it appears produces

enter image description here

\documentclass[12pt,a5paper]{article}

\usepackage{longtable}

\newcounter{bla}
\newcommand\bla{\stepcounter{bla}row\thebla}

\setlength{\baselineskip}{12pt plus 1pt}

\makeatletter
\def\LT@output{%
  \ifnum\outputpenalty <-\@Mi
    \ifnum\outputpenalty > -\LT@end@pen
      \LT@err{floats and marginpars not allowed in a longtable}\@ehc
    \else
      \setbox\z@\vbox{\unvbox\@cclv}%
      \ifdim \ht\LT@lastfoot>\ht\LT@foot
        \dimen@\pagegoal
        \advance\dimen@-\ht\LT@lastfoot
        \ifdim\dimen@<\ht\z@
          \setbox\@cclv\vbox to \textheight{\unvbox\z@\copy\LT@foot}%
          \@makecol
          \@outputpage
          \setbox\z@\vbox{\box\LT@head}%
        \fi
      \fi
      \global\@colroom\@colht
      \global\vsize\@colht
      \vbox to \textheight
        {\unvbox\z@\box\ifvoid\LT@lastfoot\LT@foot\else\LT@lastfoot\fi}%
    \fi
  \else
    \setbox\@cclv\vbox to \textheight{\unvbox\@cclv\copy\LT@foot}%
    \@makecol
    \@outputpage
      \global\vsize\@colroom
    \copy\LT@head\nobreak
  \fi}

\begin{document}


\begin{longtable}{c}
\bla \\* \bla type 2 \\ \bla \\* \bla \\* \bla type 3\\\noalign{\vspace{10pt plus 1fill minus 2pt}}
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\\noalign{\vspace{10pt plus 5pt minus 2pt}}
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\\noalign{\vspace{10pt plus 5pt minus 2pt}}
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\\noalign{\vspace{10pt plus 5pt minus 2pt}}
\bla \\* \bla \\* \bla type 2 \\ \bla \\* \bla type 3\\\noalign{\vspace{10pt plus 5pt minus 2pt}}
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\\noalign{\vspace{10pt plus 5pt minus 2pt}}
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\\noalign{\vspace{10pt plus 5pt minus 2pt}}
\bla \\* \bla type 2 \\ \bla \\* \bla type 2 \\ \bla \\* \bla type 3\\\noalign{\vspace{10pt plus 5pt minus 2pt}}
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\\noalign{\vspace{10pt plus 5pt minus 2pt}}
\bla \\* \bla type 2 \\ \bla \\* \bla type 3\\\noalign{\vspace{10pt plus 5pt minus 2pt}}
\end{longtable}


\end{document}
  • I've been using this patch for a bit and just found an interesting "feature." It seems that the patch forces the last page of the longtable to fill the page, even when it really should only take up a small portion of the page and allow the document to continue on the same page. Is there anyway to avoid this behavior while still allowing some interline stretch within the table? – rpspringuel Dec 31 '16 at 20:00
  • what happens if you use \vfill after the table? – David Carlisle Dec 31 '16 at 20:27
  • Doesn't seem to make a difference, though I don't have a time to do other than cursory testing at the moment. – rpspringuel Dec 31 '16 at 21:33

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.