0

When the remaining rows of a longtable fit exactly onto the current page, longtable will instead create a widow by printing a footer on the current page and moving the last row onto the next page (with repeated header and footer).

This can be prevented by printing the last row as part of the last footer, but I am wondering why this is happening in the first place, and whether this could perhaps be fixed in the longtable package. (Conceptually, I would expect the algorithm to only start a new page after it has determined that the remaining contents do not fit onto the current page.)

\documentclass{article}

\usepackage{booktabs}
\usepackage{longtable}

\begin{document}

\begin{longtable}{l}
\caption{Caption}\\
\toprule
Column heading\\
\midrule
\endfirsthead
\caption[]{Caption} \\
\toprule
Column heading\\
\midrule
\endhead
\midrule
Continued on next page\\
\midrule
\endfoot
\bottomrule
\endlastfoot
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
\end{longtable}


\end{document}
9
  • Depending on the exact properties of the actual longtable -- I will assume that you have more important things to do than typesetting tables with rows and rows consisting of the single letter "x" :-) -- you may decide to either forbid a linebreak in the penultimate row by changing \` to \*` or to provide a strategically placed \enlargethispage{1\baselineskip} instruction.
    – Mico
    Commented Aug 31, 2023 at 16:21
  • @Mico Changing \\ to \\* doesn't solve the problem, it only results in the penultimate row also being moved to the next page. I don't see how you can 'strategically place' \enlargethispage{1\baselineskip} such that it affects the right page, if your longtable runs across many pages (i.e. the general case).
    – oulenz
    Commented Aug 31, 2023 at 16:28
  • I thought the objective was to avoid creating a typographic widow. My first suggestion does just that, by forcing the final part of the longtable to contain at least two rows, in addition to whatever is produced by \endhead, instead of just one row.
    – Mico
    Commented Aug 31, 2023 at 16:51
  • The objective is to print the last row together with the other rows, given that there is enough space to do so.
    – oulenz
    Commented Aug 31, 2023 at 17:12
  • "Conceptually, I would expect the algorithm to only start a new page after it has determined that the remaining contents do not fit onto the current page.)" well it does, more a less, but your lastfoot is a lot smaller than your foot and at the point of deciding to break it doesn't know it's at the end. Commented Aug 31, 2023 at 21:59

2 Answers 2

2

longtable really can't look ahead, the whole point of it is to defer page breaking to the asynchronous output routine as for normal page breaking, so it doesn't have control over when page breaking decisions happen, the output routine jumps in when it jumps. It is measuring the space required using the vertical size of the footbox, it never checks that lastfoot is smaller, it could check that but I'm not sure what it could do.

That's the thing about tex: it is designed for the memory of a machine in 1979, it doesn't have the document in memory and might have written the last page to the pdf before \end{longtable} has even been read from the file system. longtable can't look ahead and it can't go back and change decisions (but it could typeset 1000 row tables in 1990 on a machine with less than 1Mb of memory....)

As shown in other answers newer packages make different assumptions and grab the whole table first. That gives more flexibility but is a complete redesign, not a feature that can simply be added

1

If you willing to use longtblr of tabularray package instead of longtable, then in your particular case table can be fit in one page even with one more row in table body:

enter image description here

(red lines show page layout)

Beside this the table code is (far) more concise and simpler:

\documentclass{article}
%--------------- show page layout. don't use in a real document!
\usepackage{showframe}
\renewcommand\ShowFrameLinethickness{0.15pt}
\renewcommand*\ShowFrameColor{\color{red}}
%
\usepackage{lipsum}                             % for dummy text
\usepackage[latin, english]{babel}
%---------------------------------------------------------------%
\usepackage{tabularray}
\UseTblrLibrary{booktabs}


\begin{document}

\begin{longtblr}[
caption = {Caption}
                ]{colspec={X[c]},
                  rowsep=0pt,
                  row{1}={font=\bfseries},
                 rowhead=1}
    \toprule
Column heading\\
    \midrule
%
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
x\\
%
one more table row\\
    \bottomrule
    \end{longtblr}
\end{document}

In the case that table is longer (has more rows or rows with multi lines text), it will split over page and automatic insert (continued) to caption on the next page and ˙continued on next page` at table bottom on the first page

2
  • Thank you, that's definitely useful to know! But unless longtable has generally been superseded by longtblr and/or tabularray, it's more of an alternative workaround than a direct answer to my question.
    – oulenz
    Commented Aug 31, 2023 at 16:33
  • @oulenz, what you after require more or less to rewrite the longtable algorithm for table break to which as you like, should test if table has one row to much that can be fit in one page. In some cases it may help to use \raggedbottom option but then you have new problems. For example see tex.stackexchange.com/questions/65355/…. So, to my opinion, reliable option is only to do some workaround as is suggested in my answer.
    – Zarko
    Commented Aug 31, 2023 at 17:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .