3
\documentclass{article}
\usepackage{lipsum}
\usepackage{cals}
\usepackage[latin]{babel}
\showboxbreadth=100
\showboxdepth=100

\makeatletter
\let\oldDispatch=\cals@row@dispatch
\newbox\rowBefore
\newbox\rowAfter
\newbox\decorationCopy
\newdimen\splitHeight

    \def\cals@row@dispatch{%
    \cals@ifbreak\iftrue % detect that a break is required
  \splitHeight=\pagegoal \advance\splitHeight -\pagetotal
  \ifdim \splitHeight>50pt % break inrow only if at least 100pt left
    \advance\splitHeight -5pt % avoid pagebreak due to overflows
    %
    % Split the current row on two: before and after the break
    %
    \setbox\rowBefore=\hbox{}
    \setbox\rowAfter=\hbox{}
    \def\next{%
      \setbox0=\lastbox
      \ifvoid0
        \def\next{\global\setbox\rowBefore=\box\rowBefore
                  \global\setbox\rowAfter=\box\rowAfter }%
      \else
        \setbox2=\vsplit0 to\splitHeight
        \setbox\rowBefore=\hbox{\box2 \unhbox\rowBefore}%
        \setbox\rowAfter=\hbox{\box0 \unhbox\rowAfter}%
      \fi
      \next}
    \setbox0=\hbox{\unhbox\cals@current@row \next}
    %
    % Decoration backup, typeset the first row,
    % restore context, typeset the second at the end of macro
    %
    \setbox\decorationCopy=\copy\cals@current@cs
    \setbox\cals@current@row=\box\rowBefore
    \ht\cals@current@cs=\ht\cals@current@row
    \oldDispatch
    \cals@issue@break
    \cals@thead@tokens
    \setbox\cals@current@row=\box\rowAfter
    \cals@reheight@cells\cals@current@row
    \setbox\cals@current@cs=\box\decorationCopy
    \ht\cals@current@cs=\ht\cals@current@row
    \let\cals@current@context=b
  \fi
\fi
\oldDispatch}

\begin{document}
\begin{calstable}
\colwidths{{150pt}{150pt}{150pt}}

\def\cals@framecs@width{.4pt}
\def\cals@framers@width{.4pt}

\thead{\brow \bfseries \cell{header1}\cell{header2}\cell{header3}
  \mdseries \erow}
\brow \cell{\lipsum[ 1]}\cell{\lipsum[ 2]}\cell{\lipsum[ 3]} \erow
\brow \cell{\lipsum[ 4]}\cell{\lipsum[ 5]}\cell{\lipsum[ 6]} \erow
\brow \cell{\lipsum[ 7]}\cell{\lipsum[ 8]}\cell{\lipsum[ 9]} \erow
\brow \cell{\lipsum[10]}\cell{\lipsum[11]}\cell{\lipsum[12]} \erow
\brow \cell{\lipsum[13]}\cell{\lipsum[14]}\cell{\lipsum[15]} \erow
\brow \cell{\lipsum[16]}\cell{\lipsum[17]}\cell{\lipsum[18]} \erow
\end{calstable}
\end{document}
Zeno Shuai
  • 395
  • 1
  • 7
  • Maybe this answer could help here. At least it does find the last line of a page (and so does the lineno package, which does not put a line number on an empty line). –  Dec 21 '18 at 05:49
  • Just out of curiosity: Why are you using the cals package? Wouldn't it be easier to shorten the text height parameter by some small amount (say, 5 points) and to add an \hrule (not \hline) directive at the bottom of the (now shortened) text block? – Mico Dec 21 '18 at 05:53
  • cals is the only package i found can breaking table in the row. – Zeno Shuai Dec 21 '18 at 07:31

1 Answers1

1

I think you can play with the following fragment:

\setbox\rowBefore=\hbox{\box2 \unhbox\rowBefore}%

It creates the last box on the page, so you can add something to it. On the first look, the following works:

\setbox\rowBefore=\hbox{\box2 \unhbox\rowBefore
  \hbox to 0pt{\hss\vbox{\hrule width\wd\cals@current@cs}}}%

By the way, cals does not support inside-row table breaks. It is just a hack exists what makes breaking possible with a bit of luck.

olpa
  • 1,116