[comp.text.tex] an environment for large tables

duchier@cs.yale.edu (Denys Duchier) (07/29/90)

Here is another contribution to the old problem of splitting very
large tables across pages.  I define a `Tabular' environment which is
essentially identical to LaTeX's `tabular' environment, except it
doesn't take an optional argument and horizontal positioning is
controlled by \Tabularleftskip and \Tabularrightskip (default is
centered).

--Denys

%  Tabular.sty
%  Denys Duchier, Yale University, July 1990
%
%  This file defines a \Tabular environment which is essentially
%  similar to the \tabular environment but is able to handle very
%  large tables which have to be split across pages.
%
%  The major distinction is that \Tabular doesn't take an optional
%  argument.  It behaves much like \begin{tabular*}{\linewidth} with
%  \Tabularleftskip and \Tabularrightskip used as the stretchable glue
%  on either side.  Also, instead of contributing the table as a large
%  box, it performs a \unvbox so that individual rows are contributed
%  instead and page breaks can occur between them.
%
%              \begin{Tabular}{...} ... \end{Tabular}
%
%  has essentially the same effect as:
%
%  \begin{center}\begin{tabular}{...} ... \end{tabular}\end{center}
%
%  but may be split across pages.
%
%      {\Tabularleftskip  = 0pt
%       \Tabularrightskip = 0pt
%       \begin{Tabular}{@{}l@{\extracolsep{\fill}}cr@{}}
%           ...
%       \end{Tabular}}
%
%  will produce a 3 column table with the left column flushed left,
%  the right column flushed right, and equal spacing between the
%  columns.

\newskip\Tabularleftskip  \Tabularleftskip\@flushglue
\newskip\Tabularrightskip \Tabularrightskip\@flushglue

\newbox\Tabularbox

%  let's count the number of columns so that we know how many columns
%  hlines must span.

\newcount\Tabularcount
\newcount\Tabularcolumns
\def\@Tabclassz{\global\advance\Tabularcount\@ne\@tabclassz}
\let\@latexclassiii\@classiii
\def\@Tabclassiii{\global\advance\Tabularcount\@ne\@latexclassiii}

%  allow page breaks between rows

\def\@Tabularcr{{\ifnum0=`}\fi\@ifstar{\@xTabularcr}{\@xTabularcr}}
\def\@xTabularcr{\@ifnextchar[{\@argTabularcr}{\ifnum0=`{\fi}\cr
  \noalign{\pagebreak[1]}}}

\def\@argTabularcr[#1]{\ifnum0=`{\fi}\ifdim #1>\z@ 
   \unskip\@xargarraycr{#1}\else \@yargarraycr{#1}\fi
 \noalign{\pagebreak[1]}}

%  \hline is redefined to output 2 lines one on top of the other, with
%  a slightly more encouraging \pagebreak than between normal rows.
%  Thus, if a page break must occur, there will a line at the bottom,
%  and it will be repeated at the top of the next page too.  This is
%  visually much more appealing.

\let\@latexhline\hline
\let\@latextabarray\@tabarray
\def\@tabarray{\let\hline\@latexhline\@latextabarray}
\def\Tabularhline{\multispan{\Tabularcolumns}{\unskip\leaders\hrule
    height\arrayrulewidth\hfill}\cr
  \noalign{\vskip-\arrayrulewidth\pagebreak[2]}%
  \multispan{\Tabularcolumns}{\unskip\leaders\hrule
    height\arrayrulewidth\hfill}\cr}

\def\Tabular#1{\trivlist\item[]\noindent
  \setbox\Tabularbox\vbox\bgroup
    \let\@acol\@tabacol
    \let\@classz\@Tabclassz
    \let\@classiii\@Tabclassiii
    \let\@classiv\@tabclassiv
    \let\\\@Tabularcr
    \setbox\@arstrutbox=\hbox{\vrule
        height\arraystretch \ht\strutbox
        depth\arraystretch  \dp\strutbox
        width\z@}%
    \global\Tabularcount\z@
    \@mkpream{#1}%
    \Tabularcolumns\Tabularcount
    \let\hline\Tabularhline
    \let\@classiii\@latexclassiii
    \tabskip\Tabularleftskip
    \edef\@preamble{\halign to\linewidth\bgroup
      \tabskip\z@ \@arstrut \@preamble
      \tabskip\Tabularrightskip \cr}%
    \let\@starpbox\@@startpbox
    \let\@endpbox\@@endpbox
    \let\@sharp##\let\protect\relax
    \lineskip\z@\baselineskip\z@
    \@preamble}

\def\endTabular{\crcr\egroup\egroup\unvbox\Tabularbox\endtrivlist}