% Save file as: LONGTABLE.STY          Source: FILESERV@SHSU.BITNET  
% Master File: longtable.tex
% Document Type: LaTeX
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%                  longtable.sty
%                  %%%%%%%%%%%%%
%
%  New version of the tabular environment that allows multi-page tables.
%         \begin{longtable} ... \end{longtable}
%
%                   David Carlisle
%                   carlisle@uk.ac.man.cs
%                   17/6/91 (Version 2)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% Longtable takes the same mandatory argument as tabular (eg. {cc|rr}).
% It starts a new page, so the optional positional argument ([t],[c] or [b]) is
% not relevant. Instead the optional argument specifies left, right or centred
% adjustment ([l], [r] or [c]). The default is usually [c].

% See the file longtable.tex for more information and examples.

% These macros work by adding a dummy row to the end of a \halign (so
% that I know that the last line contains all the columns). This line is
% removed from each \halign as it is completed, and the widths of the boxes
% inside used to produce the dummy row for the next chunk. The main macro is
% \LT@get@widths. This determines the widths of each column of the chunk just
% completed. It bears a remarkable similarity to the \endvrulealign macro of
% appendix D of the TeXBook!
%
% The rest of the code is just window dressing to give the whole thing a more
% LaTeX-like feel.

% Version 1 20/12/90
%
% Version 1 did not work with the Mittelbach and Schoepf
% New Font Selection Scheme.  See the comment in \LT@nofcols.

% Improvements in Version 2 17/6/91
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%  *  Works with the New Font Selection Scheme.
%  *  Works with Mittelbach's array.sty.
%  *  Improved the \caption command.
%        Now accepts multi-line captions, like article.sty's table enviromnent.
%        Also has a \caption* form which does not print the table counter.
%  *  Added the \endfoot command, so that row(s), (or just an \hline) may be
%        added to the bottom of each page of the table.
%  *  Lots more comments in the code!

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% USER SETABLE PARAMETERS
\newskip\LTleft%          Glue to the left of the table (usually \fill).
\newskip\LTright%         Glue to the right of the table (usually \fill).
\newcount\LTchunksize%    Chunk size (The number of rows taken per \halign).
\newdimen\LTcapwidth%     Width of the \parbox containing the caption.

% DEFAULTS
% Centre longtables
\LTleft=\fill
\LTright=\fill

% 20 rows considered at a time
\LTchunksize=20

% 4in captions
\LTcapwidth=4in

% INTERNAL PARAMETERS
\newbox\LT@head%          Box for the table head (maybe not the first page).
\newbox\LT@firsthead%     Box for the head of the first page of the table.
\newbox\LT@foot%          Box for the foot of the table.
\newdimen\LT@head@ht%     Height of the head (= max of \ht of the head boxes).
\newcount\LT@cols%        Counter for number of columns.
\newcount\LT@rows%        Counter for rows up to chunksize.
\newdimen\LT@sep%         Separation between \hline's (usually 0pt).
\newif\ifLT@save@row%     Switch for using the saved row (usually FALSE).
\newif\ifLT@firstchunk%   True inside the first chunk.


% Do not use the stored column widths.
\LT@save@rowtrue

\let\setlongtables\LT@save@rowfalse

\def\longtable{%
  \let\LT@iftwocoulmn\if@twocolumn
  \onecolumn
% This is the least satisfactory part of longtable.sty. Using \@texttop and then
% messing arround with \vsize and the headline and footline. The proper way to
% do this is probably with a new insertion class, and some help from the output
% routine. However I do not think style files should mess with the output
% routine. The user can load up any number of styles giving new environments or
% commands, but the document can only have one output routine. (Changing the
% output routine mid-document must be worse than changing \vsize!)
% Use \@texttop for the table head.
  \def\@texttop{\ifvoid\LT@firsthead\copy\LT@head\else\box\LT@firsthead\fi}%
% Use \@textbotom for the table foot, and ragged bottom.
%  (The extra \vfill below is used to squash a \vfil put between the table
%   and the final foot by \newpage.)
  \def\@textbottom{\vskip-\lastskip\copy\LT@foot\vfill\vss}%
% Keep the headline and footline in place.
  \global\let\LT@oddfoot\@oddfoot \global\let\LT@evenfoot\@evenfoot
  \gdef\@oddfoot{%
    \gdef\@evenfoot{\lower\LT@head@ht\@@line{\LT@evenfoot}}%
    \gdef\@oddfoot{\lower\LT@head@ht\@@line{\LT@oddfoot}}\LT@oddfoot}%
  \gdef\@evenfoot{%
    \gdef\@evenfoot{\lower\LT@head@ht\@@line{\LT@evenfoot}}%
    \gdef\@oddfoot{\lower\LT@head@ht\@@line{\LT@oddfoot}}\LT@evenfoot}%
  \topskip\z@
% Check for an optional argument.
  \@ifnextchar[{\LT@array}{\LT@array[x]}}

\def\LT@array[#1]#2{\refstepcounter{table}%
% Get the saved row from LT@<i,ii,..> (from the .aux file).
  \xdef\LT@save@row{%
    \expandafter\noexpand\csname LT@\romannumeral\c@table\endcsname}%
% Set up the glue arround the table if an optional argument given.
  \if l#1\LTleft\z@ \LTright\fill
   \else\if r#1\LTleft\fill \LTright\z@
     \else\if c#1\LTleft\fill \LTright\fill \fi\fi\fi
% Set up these internal commands for longtable.
  \let\\\LT@tabularcr
  \let\hline\LT@hline \let\kill\LT@kill\let\caption\LT@caption
% Set up internal commands according to Lamport or Mittlebach.
  \ifx\d@llar\LT@undef\let\next\LT@LL\else\let\next\LT@FM\fi\next{#2}%
% A few more internal commands for longtable common to LL and FM.
  \let\@sharp##\let\protect\relax
  \lineskip\z@\baselineskip\z@
% Start the first chunk. Each chunk initially goes in box0
  \global\LT@rows\z@\LT@firstchunktrue
  \setbox\z@=\vbox\bgroup\LT@preamble}


% L.L. version
\def\LT@LL#1{%
  \setbox\@arstrutbox=\hbox{\vrule
     height\arraystretch \ht\strutbox
     depth\arraystretch \dp\strutbox
     width \z@}%
  \let\@acol\@tabacol \let\@classz\@tabclassz
  \let\@classiv\@tabclassiv
% Interpret the preamble argument.
  \@mkpream{#1}%
% Find out how many columns we have (store in \LT@cols).
  \global\LT@cols=\z@
% Following line DOES NOT work with M&S font selection, use & instead of \@sharp
%  \expandafter\LT@nofcols\@preamble\@sharp\end
  \expandafter\LT@nofcols\@preamble&\end
% Check to see whether the .aux file contained info for this table.
  \LT@test
  \edef\LT@preamble{\tabskip\LTleft\halign to \hsize\bgroup
    \tabskip\z@ \@arstrut \@preamble \tabskip\LTright \cr}%
  \let\@startpbox\@@startpbox\let\@endpbox\@@endpbox
  \let\par\relax
  \let\LT@LL@FM@cr\@tabularcr}
% End of L.L. scheme.


% F.M. version
\def\LT@FM#1{%
  \@tempdima\ht\strutbox
  \advance \@tempdima by\extrarowheight
  \setbox \@arstrutbox \hbox{\vrule
             \@height \arraystretch \@tempdima
             \@depth \arraystretch \dp \strutbox
             \@width \z@}%
  \col@sep\tabcolsep \gdef\d@llar{}%
   \begingroup
% Interpret the preamble argument.
    \@mkpream{#1}%
    \global\LT@cols=\z@
% Find out how many columns we have (store in \LT@cols).
    \expandafter\LT@nofcols\@preamble&\end%
% Check to see whether the .aux file contained info for this table.
    \LT@test
% We need to rename to \LT@preamble here as F.M's scheme uses
% \global, and we may need to nest \@mkpream, eg for \multicolumn
% or an array. We do not ned to worry about nested longtables though!
    \xdef\LT@preamble{\everycr{}\tabskip\LTleft\halign to \hsize\bgroup
      \tabskip\z@ \@arstrut \@preamble \tabskip\LTright \cr}%
  \endgroup
  \m@th\let\par\@empty
  \let\LT@LL@FM@cr\@arraycr}
% End of F.M. scheme


\def\endlongtable{%
% Essentially add a final \\
  \crcr\LT@save@row\cr\egroup\egroup
  \LT@takeone\LT@get@widths\writeLT@save@row
% If the last chunk has different widths than the first, warn the user.
  \ifx\LT@save@row\LT@@save@row\else
    \@warning{Column widths have changed in table \thetable}\fi
% Put things back how we found them.
  \advance\vsize\LT@head@ht \advance\textheight\LT@head@ht
  \LT@iftwocoulmn\LT@twocolumn\else\newpage\fi
  \global\let\@oddfoot\LT@oddfoot \global\let\@evenfoot\LT@evenfoot}

\def\LT@tabularcr{%
% Increment the counter, and do  tabular's \\ or finish the chunk.
  \global\advance\LT@rows\@ne \ifnum\LT@rows=\LTchunksize
  \let\next\LT@t@bularcr\else\let\next\LT@LL@FM@cr\fi
  \next}

\def\LT@t@bularcr{\@ifstar{\LT@xtabularcr}{\LT@xtabularcr}}

\def\LT@xtabularcr{\@ifnextchar[{\LT@argtabularcr}{\LT@ntabularcr}}

\def\LT@ntabularcr{%
% Add the dummy row, and finish the \halign.
  \cr\LT@save@row\cr\egroup\egroup
  \global\LT@rows\z@
% Take the last row off, dissect it, and then start the next chunk.
  \LT@takeone\LT@get@widths\setbox\z@=\vbox\bgroup\LT@preamble}

\def\LT@argtabularcr[#1]{\ifdim #1>\z@
   \unskip\@xargarraycr{#1}\else \@yargarraycr{#1}\fi
% Add the dummy row, and finish the \halign.
  \LT@save@row\cr\egroup\egroup
  \global\LT@rows\z@
% Take the last row off, dissect it, and then start the next chunk.
  \LT@takeone\LT@get@widths\setbox\z@=\vbox\bgroup\LT@preamble}

\def\LT@kill{\cr\LT@save@row\cr\egroup\egroup
  \global\LT@rows\z@
% Take the last two rows off, dissect one, and then start the next chunk.
  \LT@taketwo\LT@get@widths\setbox\z@=\vbox\bgroup\LT@preamble}

\def\endhead{\crcr\LT@save@row\cr\egroup\egroup
  \global\LT@rows\z@
% Save the curent chunk in \LT@head.
  \LT@get@head\LT@head
  \LT@get@widths
% Leave room on each page for the table heads.
  \ifdim\LT@head@ht<\ht\LT@firsthead
     \advance\LT@head@ht\ht\LT@firsthead
     \advance\vsize-\ht\LT@firsthead
     \advance\textheight-\ht\LT@firsthead
  \else
     \advance\LT@head@ht\ht\LT@head
     \advance\vsize-\ht\LT@head
     \advance\textheight-\ht\LT@head
  \fi
% Start the next chunk.
  \setbox\z@=\vbox\bgroup\LT@preamble}

\def\endfirsthead{\crcr\LT@save@row\cr\egroup\egroup
  \global\LT@rows\z@
% Save the curent chunk in \LT@head.
  \LT@get@head\LT@firsthead
  \LT@get@widths
% Start the next chunk.
  \setbox\z@=\vbox\bgroup\LT@preamble}

\def\endfoot{\crcr\LT@save@row\cr\egroup\egroup
  \global\LT@rows\z@
% Save the curent chunk in \LT@foot.
  \LT@get@head\LT@foot
  \LT@get@widths
  \advance\LT@head@ht\ht\LT@foot
% Leave room on each page for the table foot.
  \advance\vsize-\ht\LT@foot
  \advance\textheight-\ht\LT@foot
% Start the next chunk.
  \setbox\z@=\vbox\bgroup\LT@preamble}

% Count the number of columns.
% Note that the columns are counted by examining \(LT)@preamble, rather than
% simply getting \@mkpream to increment the counter as it builds the preamble
% so that this style works with many of the styles which add extra column
% specifiers to LaTeX's standard ones. For instance I have styles which add
% `d' (A column lined up on decimal points)%
% `C' `L' `R' (Like `c' `l' `r', except that they are in math mode, cf array)
% It also means that this part works for array.sty.

%\def\LT@nofcols#1\@sharp{\futurelet\next\@LT@nofcols}
% DOES NOT WORK WITH M&S font selection, use & instead of sharp.
%  (lfonts.new defines \@tabclassz so that \@sharp is inside a group.)

\def\LT@nofcols#1&{\futurelet\next\@LT@nofcols}

% NEW \@LT@nofcols as \LT@preamble has one less & than \@sharp.
\def\@LT@nofcols{\global\advance\LT@cols\@ne
  \ifx\next\end\let\next\@gobble
  \else\let\next\LT@nofcols\fi\next}

% Test whether the .aux file had a saved row for this table.
\def\LT@test{\expandafter\ifx\LT@save@row\relax\LT@blank@row\else
  \ifLT@save@row\LT@blank@row\fi\fi}

% Create a blank row if we are not using the info in the .aux file.
\def\LT@blank@row{{%
  \xdef\LT@save@row{\omit}%
  \loop
  \advance\LT@cols\m@ne
  \ifnum\LT@cols>\z@
  \xdef\LT@save@row{\LT@save@row&\omit\ }%
  \repeat}}

% Store the last row in \box1
\def\LT@takeone{\setbox\z@=\vbox{\unvbox\z@\global\setbox\@ne=\lastbox}}

% Throw away the last row, store the penultimate row in \box1
\def\LT@taketwo{\setbox\z@=\vbox{\unvbox\z@
  \global\setbox\@ne=\lastbox\unskip\global\setbox\@ne=\lastbox}}

% Store the current chunk in the box #1
\def\LT@get@head#1{%
  \setbox#1
    \vbox{\unvbox\z@\global\setbox\@ne=\lastbox}\setbox\z@=\vbox{}}

% See \endvrulealign macro of appendix D of the TeXBook.
\def\LT@get@widths{%
  \let\LT@save@row\end
% Open up the alignment.
  \unvbox\z@
  \penalty\z@
% Loop through the last row, discarding glue, and saving box widths.
  \setbox\z@=\hbox{\unhbox\@ne
    \loop
    \unskip
    \setbox\tw@=\lastbox
    \ifhbox\tw@
      \defLT@save@row
    \repeat}%
% Remember the widths if we are in the first chunk.
  \ifLT@firstchunk\let\LT@@save@row\LT@save@row\LT@firstchunkfalse\fi}

% Add a column to the dummy row.
\def\defLT@save@row{\ifx\LT@save@row\end
  \xdef\LT@save@row{\omit\kern\the\wd\tw@}\else
  \xdef\LT@save@row{\omit\kern\the\wd\tw@&\LT@save@row}\fi}

% Write the dummy row to the .aux file.
\def\writeLT@save@row{\immediate\write\@auxout
  {\gdef\string\LT@\romannumeral\c@table{\LT@save@row}}}

% \hline and \hline\hline both produce TWO lines.
% The only difference being the glue and penalties between them.
% This is so that a page break at a \hline produces a line on both
% pages. Also this \hline is more like a \cline[1-\LT@cols]. tabular's
% \hline would draw lines the full width of the page.
\def\LT@hline{\noalign{\ifnum0=`}\fi%
   \penalty\@M
   \futurelet\LT@next\LT@@hline}

\def\LT@sepa{\penalty-\@medpenalty\vskip\doublerulesep}
\def\LT@sepb{\penalty-\@lowpenalty\vskip-\arrayrulewidth}

\def\LT@@hline{\ifx\LT@next\hline
      \global\let\LT@next\@gobble
      \global\let\LT@sep\LT@sepa
  \else\global\let\LT@next\empty
       \global\let\LT@sep\LT@sepb\fi\ifnum0=`{\fi}%
  \multispan\LT@cols\unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr
  \noalign{\LT@sep}%
  \multispan\LT@cols\unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr
  \noalign{\penalty\@M}%
  \LT@next}

% The caption is \multicolumn{\LT@cols}{c}{a parbox with the table's caption}
\def\LT@caption{\noalign\bgroup
  \@ifnextchar[{\egroup\LT@c@ption}{\LT@capti@n}}

% Caption command (with [optional argument])
\def\LT@c@ption[#1]#2{%
  \LT@mkcaption{\bf Table \thetable: #2}%
  \def\@tempa{#1}\ifx\@tempa\empty\else
  {\let\\\space\addcontentsline{lot}{table}{\numberline{\thetable}{#1}}}\fi}

% Caption command (no [optional argument])
\def\LT@capti@n{\@ifstar{\egroup\LT@mkcaption}{\egroup\LT@@c@ption}}

% Caption command (no [optional argument] or *)
\def\LT@@c@ption#1{%
  \LT@mkcaption{\bf Table \thetable: #1}%
  {\let\\\space\addcontentsline{lot}{table}{\numberline{\thetable}{#1}}}}

% Put the caption in a box of width 0pt, so that it never has an effect on the
% column widths in the table. Inside that is a \parbox of width \LTcapwidth.
% It would be nice to replace \LTcapwidth by the width of the table, but how can
% I find that ? Adding up the widths in \LT@save@row will not work if there is
% any non-zero \tabskip (\extracolumnsep). I need to know the SET lengths of
% \LTleft and \LTright.
\def\LT@mkcaption#1{%
  \multicolumn{\LT@cols}{c}{\hbox to \z@{\hss\parbox[t]{\LTcapwidth}%
    {\let\\\@normalcr
    % article.sty's \@makecaption (without the 10pt skip at the top)
    \setbox\@tempboxa\hbox{#1}%
   \ifdim \wd\@tempboxa >\hsize #1
     \else \hbox to\hsize{\hfil\box\@tempboxa\hfil}\fi
            \endgraf\vskip\baselineskip}\hss}}}

% If you want the final lines of the table to be something different
% from the usual foot lines, you might like to try the (somewhat less
% than satisfactory) command \lastfoot.
% The idea is to put something like this at the end of the table:
%
%  pen  & ultimate & line \\
%  last & line     & here % as this is the last line, no \\
%  \lastfoot{\begin{center}
%	     Some par-mode material\\
%             that you want at the end.
%	     \end{center}
%           }
%  \end{longtable}
%
% Note that the output routine will stick this on the same page as the end of
% the table even if there is no room. Also if this affects more pages
% than you expect, try reducing the \LTchunksize.

\def\lastfoot#1{\global\setbox\LT@foot\vbox{\let\\\@normalcr#1}}


% Like \twocolumn but using \newpage instead of \clearpage.
% \twocolumn would put a blank page between two consecutive longtables.
\def\LT@twocolumn{\newpage \global\columnwidth\textwidth
   \global\advance\columnwidth -\columnsep \global\divide\columnwidth\tw@
   \global\hsize\columnwidth \global\linewidth\columnwidth
   \global\@twocolumntrue \global\@firstcolumntrue
   \@dblfloatplacement}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% In case you have an old version of LaTeX.
% Taken from latex.tex (after 14 Jan 89)

\def\@endpbox{\unskip\strut\par\egroup\hfil}
\let\@@endpbox\@endpbox
% 14 Jan 89: Def of \@endpbox changed from
%    \def\@endpbox{\par\vskip\dp\@arstrutbox\egroup\hfil}
% so vertical spacing works out right if the last line of a `p' entry
% has a descender.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
