2

I want to control table, created by longtable enwironment such way that it would have pagebreak before last two lines if the rest of the table would be longer than some height (it depends on height of text, that follows the table and should be fully on last page with at least two last columns of table). The last line and text after table is static block, I put it into lastfoot. But line before last should be always on the same page with last line.

Here is the shortest working example:

\documentclass[12pt]{letter}
\usepackage[english]{babel}
\usepackage{longtable}
\usepackage{array}

\makeatletter
\newtoks\f@st
\f@st={}
\def\pr@line#1{#1\global\f@st={}}
\def\RPOline#1#2{\pr@line{\the\f@st}\global\f@st={#1&#2\cr\hline}}
\newcolumntype{C}[1]{>{\centering}m{#1}}
\newsavebox\l@stb@x
\def\RPOb@g{
    \global\savebox{\l@stb@x}{\hbox to\textwidth{\vbox to 10cm{some text\vfill bottom}}}
    \begin{longtable}{|C{1cm}|C{5cm}|}
    \hline N& Name\cr\hline\endfirsthead
    \endhead\endfoot
    \multicolumn{2}{l}{\usebox{\l@stb@x}}\endlastfoot
}
\newtoks\old@utput
\newdimen\texth@
\old@utput=\expandafter{\the\output}
\def\ts@{\texth@=\textheight\advance\texth@ by -\ht\l@stb@x\advance\texth@ by -5mm\relax
    \setbox0=\vbox{\unvbox255}\ifdim\ht0<\texth@
    \setbox255=\vbox{\unvbox0\pr@line{\the\f@st}}\else
    \setbox255=\vbox{\unvbox0}\fi
    \the\old@utput
    \global\output=\expandafter{\the\old@utput}}
\def\PRO@nd{
    \global\output={\ts@}\cr\pagebreak
    \pr@line{\the\f@st}
    \end{longtable}
}
\newenvironment{RPOtable}{\RPOb@g}{\PRO@nd}
\makeatother
\newcount\tstcnt
\def\fillt#1{\ifnum\tstcnt>0\global\advance\tstcnt by -1\relax #1\fillt{#1}\fi}
\def\filltbl#1#2{\global\tstcnt=#1\relax\fillt{#2}}

\begin{document}
\begin{RPOtable}
    \filltbl{31}{\RPOline{a}{Sample line}}
    \RPOline{L}{Last line}
\end{RPOtable}
\end{document}

When I put \cr\pagebreak into \PRO@nd (like written above) I get no errors but have empty lines in table and the table always breaks on \pagebreak. If I omit \pagebreak, line marked as "Last line" stays on previous page, and there's still an empty table line after it.

Question

How can I make "unbreaking" of page with longtable? I can't do \vsplit bacause it is already a box. Also I always have error messages Misplased \noalign if I don't put \cr before of \pagebreak.

6
  • I can't follow your code (nor do I understand the description of the problem) and I know something about longtable's internals, please always post a complete small document that demonstrates the problem, not a series of processable fragments. May 6, 2014 at 21:32
  • \cr is not a latex command but as longtable only breaks between rows, you are only allowed to use \pagebreak immediately after \\ . May 6, 2014 at 21:34
  • You have \ifx\relax#1 but it appears that #1 is always \the so the test is always false. It is very hard to guess what this is indented to do. May 6, 2014 at 21:36
  • @DavidCarlisle, this longtable don't work with \\, but work with \cr (that's because of specific column types - for central alignment: I have errors misplaced noalign with \). As for \ifx I agree: this is my error, it do nothing.
    – Eddy_Em
    May 6, 2014 at 21:46
  • If \\ isn't working then there is an error in the document but it's impossible to comment on the code in the form presented here, sorry, you need to post a proper example document with a description of what the intended result is, otherwise I suspect not much can be done other than close the question as "unclear" May 6, 2014 at 21:49

1 Answer 1

3

As documented in the longtable documentation the way to keep the final rows together is to put them into the last foot, or to use \\*.

The code as posted is in the wrong place so producing spurious cells hence the extra vertical line segments, and is missing % at ends of lines so introducing white space. If I understand the problem there should be no need to switch output routines. Certainly switching output routine inside the table seems brave.

You need \arraybackslash after \centering to use \\ in this context (or use \tabularnewline never \cr except in internal code.

This version puts the last 4 rows in the last foot below there is a version that uses nopagebreak penalties (which as noted in comments probably need some further tweaks).

\documentclass[12pt]{letter}
\usepackage[english]{babel}
\usepackage{longtable}
\usepackage{array}

\raggedbottom
\newcolumntype{C}[1]{>{\centering\arraybackslash}m{#1}}
\setlength\extrarowheight{2pt}

\def\samplerow#1#2{%
\ifnum#1>0
#2\\\hline
\afterfi
\expandafter\samplerow\expandafter{\the\numexpr#1-1\relax}{#2}%
\fi}
\def\afterfi#1\fi{\fi#1}


\raggedbottom
\begin{document}


\makeatother
\begin{longtable}{@{}|C{1cm}|C{5cm}|@{}}
\hline
N&Name\\\hline\endhead
\samplerow{4}{a&sample line}
\noalign{\nobreak\smallskip\noindent\parbox\textwidth{Last line}}\endlastfoot
\samplerow{25}{a&Sample Line}
\end{longtable}
\end{document}

The following generates 31 lines plus a head and following paragraph, ensuring at least 4 rows are kept with the end of the table.

enter image description here

You could normally just use \nopagebreak but \hline allows page breaking at \hline so this substitutes a non page break version for the last few rows.

\documentclass[12pt]{letter}
\usepackage[english]{babel}
\usepackage{longtable}
\usepackage{array}

\raggedbottom
\newcolumntype{C}[1]{>{\centering\arraybackslash}m{#1}}
\setlength\extrarowheight{2pt}

\makeatletter
\def\samplerow#1#2{%
\ifnum#1>0
#2\\
\ifnum#1<5 
\nopagebreak
  \multispan\LT@cols
     \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr
\nopagebreak
\else
\hline
\fi
\afterfi
\expandafter\samplerow\expandafter{\the\numexpr#1-1\relax}{#2}%
\fi}
\def\afterfi#1\fi{\fi#1}
\makeatother

\raggedbottom
\begin{document}


\makeatother
\begin{longtable}{@{}|C{1cm}|C{5cm}|@{}}
\hline
N&Name\\\hline\endhead
\noalign{\nobreak\smallskip\noindent\parbox\textwidth{Last line}}\endlastfoot
\samplerow{31}{a&Sample Line}
\end{longtable}
\end{document}
9
  • Thank you for pointing to my errors. But your variant don't solves my problem. In real the table fills by external soft that makes latex file and run pdflatex, it can't do "right" table, it just fills all rows. So, I really need to do something with \output or modify longtable by my own needs.
    – Eddy_Em
    May 7, 2014 at 4:31
  • The main my problem is to store last table row in some token. It doesn't work :(
    – Eddy_Em
    May 7, 2014 at 5:25
  • @Eddy_Em If you ask unanswerable questions it's unlikely that you get answers that you want. You have given no indication of why you need to change the output routine (there can't be any need to change it within the table) nor given any indication of why you need ore the last row in a way different to the mechanism shown here. May 7, 2014 at 7:30
  • That's simple: document format require next to the last table line to be present on the same page with last (total sum) line and footer. In common case I want to have a strict control of table: the best way would be an ability to \vsplit its content into separate lines to leave N lines on current page and push remain lines to next.
    – Eddy_Em
    May 7, 2014 at 7:42
  • I think, I should make another question.
    – Eddy_Em
    May 7, 2014 at 7:47

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.