% \iffalse meta-comment
%
% Copyright 1989-2021 Johannes L. Braams.  All rights reserved.
%
% This file is part of the supertabular package.
% ---------------------------------------------
%
% It may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status "maintained".
%
% The Current Maintainer of this work is Johannes Braams.
%
% The list of all files belonging to the supertabular package is
% given in the file `MANIFEST.
%
% The list of derived (unpacked) files belonging to the distribution
% and covered by LPPL is defined by the unpacking scripts (with
% extension .ins) which are part of the distribution.
% \fi
%
% \CheckSum{1188}
% \iffalse
%% Sourcefile `supertabular.dtx'.
%%
%% Copyright (C) 1988 by Theo Jurriens 
%% Copyright (C) 1990-2024 by Johannes Braams texniek at texniek.nl
%%                            The Netherlands
%%                       all rights reserved.
%%
%%
%<*dtx>
\ProvidesFile{supertabular.dtx}
%</dtx>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{supertabular}
%<driver>\ProvidesFile{supertabular.drv}
%\ProvidesFile{supertabular.dtx}
              [2024/07/20 v4.2c the supertabular environment]
%
%<*driver>
\documentclass{ltxdoc}
\usepackage[debugshow,calculate]{supertabular}
\newcommand{\tbsp}{\rule{0pt}{18pt}}
\begin{document}
\providecommand{\Lenv}[1]{\textsf{#1}}
\providecommand{\pkg}[1]{\texttt{#1}}
\providecommand{\cls}[1]{\texttt{#1}}
\providecommand{\file}[1]{\texttt{#1}}
\DocInput{supertabular.dtx}
\end{document}
%</driver>
% \fi
%
%   \changes{v4.0a}{1996/11/28}{Cleanup of the code, now a \file{.dtx}
%      source file} 
%   \changes{v4.0c}{1997/02/20}{Replace \cs{tableformat} by
%      \cs{ST@tableformat} to prevent a clash with the \pkg{KOMA}
%      pacakage} 
%   \changes{v4.0f}{1997/04/10}{Repaired a few typos in the
%      documentation}
%   \changes{v4.1a}{1997/09/18}{Repaired a number of typos and added
%      contributed mpsupertabular environemnts} 
%   \changes{v4.1b}{1997/10/08}{Renamed \cs{@@tabularcr} to
%     \cs{org@tabularcr}}
%   \changes{v4.2a}{2020-06-27}{renamed \cs{ST@lineht} to \cs{ST@rowht}}
%   \changes{v4.2c}{2024/07/20}{A few documentation changes}
%
%  \GetFileInfo{supertabular.dtx}
%  \title{The \texttt{supertabular} environment\thanks{This file
%        has version number \fileversion, last
%        revised \filedate.}}
%  \author{Johannes Braams and Theo Jurriens}
%  \date{\filedate}
%  \maketitle
%
%  \section{Introduction}
%
%    The package \pkg{supertabular} offers a new environment, the
%    \Lenv{supertabular} environment. As the name indicates it is an
%    extension of the normal \Lenv{tabular} environment.
%
%    With the original \Lenv{tabular} environment a tabular must
%    always fit on \emph{one} page. If the tabular becomes too large
%    the text overwrites the page's bottom margin and you get an
%    \texttt{Overfull vbox} message. 
%
%    The \Lenv{supertabular} environment uses the \Lenv{tabular}
%    environment internally, but it evaluates the used space every
%    time it gets a |\\| command. If the tabular reaches the
%    textheight, it automatically inserts an optional tabletail, an
%    |\end{tabular}| command, starts a new page, a new
%    \Lenv{tabular} environment and inserts the optional tablehead on
%    the new page continuing the tabular.  
%
%  \section{User interface}
%
%    The package \pkg{supertabular} has three options, they control
%    the amount of information that is written to the \file{.log}
%    file. 
%    \begin{enumerate}
%    \item The option \textsf{errorshow} (the default) doens't write
%      any extra information. 
%    \item The option \textsf{pageshow} writes information about when
%      and why \pkg{supertabular} decides to break the tabular
%      environment in order to produce a new page. 
%    \item The option \textsf{debugshow} also adds information about
%      each row that is added to the tabular.
%    \item The option \textsf{estimate} (the default) has the package
%      use the old estimation-based algortihm to establish the height
%      of individual rows.
%    \item The option \textsf{calculate} has the package use the new
%      calculation-based algortihm to establish the height
%      of individual rows.
%    \end{enumerate}
%
%    Below is a description of the new commands and environments that
%    this package provides.
%
%  \DescribeMacro{\tablefirsthead}
%    The command |\tablefirsthead| takes one argument, it defines the
%    contents of the first occurence of the tabular head.\\ 
%    The use of this command is optional. Don't forget to close the
%    head by a |\\|.
%
%  \DescribeMacro{\tablehead}
%    The command |\tablehead| takes one argument, it defines the
%    contents of all subsequent ocurrences of the tabular head.\\ 
%    Don't forget to close the head by a |\\|
%
%  \DescribeMacro{\tabletail}
%    The command |\tabletail| takes one argument, it defines something
%    which should be inserted before each |\end{tabular}|, except
%    the last. 
%
%  \DescribeMacro{\tablelasttail}
%    The command |\tablelasttail| takes one argument, it defines
%    something which should be inserted before the last
%    |\end{tabular}|.\\
%    The use of this command is optional.
%
%  \DescribeMacro{\topcaption}
%  \DescribeMacro{\bottomcaption}
%  \DescribeMacro{\tablecaption}
%    These commands all take the same arguments as \LaTeX's standard
%    |\caption| command. They provide a caption for the super-table,
%    either at the top or at the bottom of the table. When
%    |\tablecaption| is used the caption will be placed at the
%    default location, which is at the top.
%
%  \DescribeEnv{supertabular}
%  \DescribeEnv{supertabular*}
%    The environments \Lenv{supertabular} and \Lenv{supertabular*}
%    can be used much like the standard \LaTeX\ environments
%    \Lenv{tabular} and \Lenv{tabular*}.
%
%  \DescribeEnv{mpsupertabular}
%  \DescribeEnv{mpsupertabular*}
%     The environments \Lenv{mpsupertabular} and
%    \Lenv{mpsupertabular*} work like the \Lenv{supertabular} and
%    \Lenv{supertabular*} environments but put each page into a
%    \Lenv{minipage} first. Thus it is possible to have footnotes
%    inside a \Lenv{mpsupertabular}. The footnotetext is printed at
%    the end of each page. 
% 
%  \DescribeMacro{\shrinkheight}
%    The allowed maximimum height of a part of the supertabular on a
%    page can be adjusted using the command |\shrinkheight|. It takes
%    one argument, the length with which to shrink (positive value) or
%    grow (negative value) the allowed height.
%
%  \section{Weak points}
%
%  \begin{itemize}
%  \item When the material of a normal entry (not a p-arg) becomes
%    larger than the estimated |\ST@rowht|, overfull |\vbox|es
%    will be produced. 
%  \item When the last p-arg on a page gets more than 4 lines
%    (probably even more than 3 lines) it will result in an  overfull
%    |\vbox|.  Also some combinations of |\baselinestretch|
%    |\arraystretch| and  a large font may lead to one row too much. 
%  \item if accidentally the last row of the tabular produces a
%    newpage, on the next page the tabletail will be written
%    immediately after the tablehead. Depending on the contents, this
%    may result in an error message regarding misplaced |\noalign|. 
%
%    A quick but not very elegant solution: shrink the allowed height
%    of the table with the command |\shrinkheight{...pt}| after the
%    first |\\| of the supertabular. 
%  \item The \Lenv{mpsupertabular} environment sometimes has problems 
%    with pagebreaks when footnotes appear in the lower part of the 
%    tabular. 
%  \end{itemize}
%
%  \section{Examples}
%
%  \DeleteShortVerb{\|}
%    Here is an example of a \Lenv{supertabular}. 
%    First,  here is (part of) the user input for the table below:
%\begin{verbatim}
%    \begin{center}
%    \tablefirsthead{%
%      \hline
%      \multicolumn{1}{|c}{\tbsp Number} &
%      \multicolumn{1}{c}{Number$^2$} &
%      Number$^4$ &
%      \multicolumn{1}{c|}{Number!} \\
%      \hline}
%    \tablehead{%
%      \hline
%      \multicolumn{4}{|l|}{\small\sl continued from previous page}\\
%      \hline
%      \multicolumn{1}{|c}{\tbsp Number} &
%      \multicolumn{1}{c}{Number$^2$} &
%      Number$^4$ &
%      \multicolumn{1}{c|}{Number!} \\
%      \hline}
%    \tabletail{%
%      \hline
%      \multicolumn{4}{|r|}{\small\sl continued on next page}\\
%      \hline}
%    \tablelasttail{\hline}
%    \bottomcaption{This table is split across pages}
%
%    \begin{supertabular}{|r@{\hspace{6.5mm}}|r@{\hspace{5.5mm}}|r|r|}
%    1   &     1  &        1  &           1    \\
%    2   &     4  &       16  &           2    \\
%    3   &     9  &       81  &           6    \\
%    4   &    16  &      256  &          24    \\[5mm]
%    ...
%    19  &   361  &   130321  &  1.21645100E+17\\
%    20  &   400  &   160000  &  2.43290200E+18\\
%    \end{supertabular}
%    \end{center}
%\end{verbatim}
%
%    Then the table should be split across the page boundary:    
%    \begin{center}
%    \tablefirsthead{%
%      \hline
%      \multicolumn{1}{|c}{\tbsp Number} &
%      \multicolumn{1}{c}{Number$^2$} &
%      Number$^4$ &
%      \multicolumn{1}{c|}{Number!} \\
%      \hline}
%    \tablehead{%
%      \hline
%      \multicolumn{4}{|l|}{\small\sl continued from previous page}\\
%      \hline
%      \multicolumn{1}{|c}{\tbsp Number} &
%      \multicolumn{1}{c}{Number$^2$} &
%      Number$^4$ &
%      \multicolumn{1}{c|}{Number!} \\
%      \hline}
%    \tabletail{%
%      \hline
%      \multicolumn{4}{|r|}{\small\sl continued on next page}\\
%      \hline}
%    \tablelasttail{\hline}
%    \bottomcaption{This table is split across pages}
%
%    \begin{supertabular}{|r@{\hspace{6.5mm}}|r@{\hspace{5.5mm}}|r|r|}
%    1\tbsp &  1  &        1  &           1    \\
%    2   &     4  &       16  &           2    \\
%    3   &     9  &       81  &           6    \\
%    4   &    16  &      256  &          24    \\[5mm]
%    5   &    25  &      625  &         120    \\
%    6   &    36  &     1296  &         720    \\
%    7   &    49  &     2401  &        5040    \\
%    8   &    64  &     4096  &       40320    \\
%    9   &    81  &     6561  &      362880    \\
%    10  &   100  &    10000  &     3628800    \\
%    11  &   121  &    14641  &    39916800    \\
%    12  &   144  &    20736  &   479001600    \\[.5cm]
%    \hline & & & \\
%    13  &   169  &    28561  &  6.22702080E+9 \\[1cm]
%    14  &   196  &    38416  &  8.71782912E+10\\
%    15  &   225  &    50625  &  1.30767437E+12\\
%    16  &   256  &    65536  &  2.09227899E+13\\
%    17  &   289  &    83521  &  3.55687428E+14\\[5mm]
%    18  &   324  &   104976  &  6.40237370E+15\\
%    19  &   361  &   130321  &  1.21645100E+17\\
%    20  &   400  &   160000  &  2.43290200E+18\\
%    \end{supertabular}
%    \end{center}
%
%    Here is another example whith a \texttt{p} column-definition. The
%    tablehead is the same as above. The tabletail is a double
%    \verb|\hline|; \verb|\arraystretch| is set to \texttt{1.5} and
%    the font size is \verb|\small|. 
%
%    \begin{center}
%    \tablefirsthead{%
%      \hline
%      \multicolumn{1}{|c}{\tbsp Number} &
%      \multicolumn{1}{c}{Number$^2$} &
%      Number$^4$ &
%      \multicolumn{1}{c|}{Number!} \\
%      \hline}
%    \tablelasttail{\hline\hline}
%    \topcaption{This table should also be split accross pages.}
%    \renewcommand{\arraystretch}{1.5}
%    \small
%    \begin{supertabular}{| r@{\hspace{6.5mm}}|%
%                           r@{\hspace{5.5mm}}| r p{5cm}|}
%    1  &  1  &  1  &  \tbsp here is a relative short entry \\
%    2  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    3  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    4  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    5  &  1  &  1  &  here is a relative short entry \\
%    6  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    7  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    8  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    9  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    10 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    11 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    12 &  1  &  1  &  here is a relative short entry \\
%    13 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    14 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    15 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    16 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    17 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    18 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    \end{supertabular}
%    \end{center}
%
%    Here is the same table again, but this time using the
%    \Lenv{supertabular*} environment and stretching the table to the
%    full width of the text. 
%
%    \begin{center}
%    \tablefirsthead{%
%      \hline
%      \multicolumn{1}{|c}{\tbsp Number} &
%      \multicolumn{1}{c}{Number$^2$} &
%      Number$^4$ &
%      \multicolumn{1}{c|}{Number!} \\
%      \hline}
%    \tablelasttail{\hline\hline}
%    \topcaption{This table should also be split accross pages.}
%    \renewcommand{\arraystretch}{1.5}
%    \small
%    \begin{supertabular*}{\textwidth}%
%                         {| r@{\extracolsep{6.5mm plus 1fil}}|%
%                            r@{\extracolsep{5.5mm plus 0.5fil}}|%
%                            r@{\extracolsep{0mm plus 0.1fil}}%
%                            p{5cm}|}
%    1  &  1  &  1  &  \tbsp here is a relative short entry \\
%    2  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    3  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    4  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    5  &  1  &  1  &  here is a relative short entry \\
%    6  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    7  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    8  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    9  &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    10 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    11 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    12 &  1  &  1  &  here is a relative short entry \\
%    13 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    14 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    15 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    16 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    17 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    18 &  1  &  1  &  and here is a long entry, where line breaks
%                      and line breaks and line breaks have to occur\\
%    \end{supertabular*}
%    \end{center}
%
%  \MakeShortVerb{\|}
%
%  \section{Known problems}
%
%    \begin{itemize}
%    \item When a float occurs on the same page as the start of a
%      supertabular you can expect unexpected results. 
%
%      When the float was defined on the same page you might end up
%      with the first part of the supertabular on a page by its own. 
%
%    \item You should not use the supertabular \emph{inside} a
%      floating-environment such as \texttt{table} as this will result
%      in \TeX\ trying to put the whole supertabular on \emph{one}
%      page. 
%
%    \item In some instances you might still end up with overfull
%      |\vbox| messages. 
%
%    \item Sometimes the last page of the supertabular contains just
%       an empty head an tail. 
%    \end{itemize}
%  \StopEventually{}
%
%  \section{The Implementation}
%    First we define a few options that control the level of tracing
%    output this package delivers. the option \textsf{errorshow} is the
%    default situation.
% \changes{v4.1f}{2019/01/16}{The value for \cs{C@tracingst} needs to
%    be 3 instead of 2} 
%    \begin{macrocode}
%<*package>
\newcount\c@tracingst
\DeclareOption{errorshow}{\c@tracingst\z@}
\DeclareOption{pageshow}{\c@tracingst\thr@@}
\DeclareOption{debugshow}{\c@tracingst5\relax}
%    \end{macrocode}
%    In version 4.1g a new way of determining the height of the
%    average row was introduced. Instead of using an estimation, based
%    on the value of |\baselineskip| a computation was introduced,
%    based on the size of the |\strutbox|. The effect of this new
%    method was that the parial tabulars fill the page better, so less
%    \texttt{underfull vbox} message would appear. Unfortunately this
%    had a negative effect on existing documents (that don;t come out
%    like they used to) and especially when a very small font
%    (|\tiny| or |\scriptsize| was chosen for the tabular and the
%    cells contain subscripts or superscripts. It turned out that the
%    heigth and depth of a formula like $5^5_5$ exceeds the size of
%    |\strutbox|. The result is that the rows have more height (and/or
%    depth) thatn what the algorithm computed. Hence, when more rows
%    are added to the partial tabular than fit on the page. Especially
%    on the first part thisis a probem as the partial tabular becomes
%    too high and doesn't fit in the avialbale space. \TeX\ then
%    decides to move it to the next page, resulting in two
%    consecutive pages that have a lot of white space on them.
% \changes{v4.2a}{2020-06-27}{Two new options to choose the
%    computation algorithhm}
%    \begin{macrocode}
\DeclareOption{calculate}{\def\ST@calculate@rowht{\ST@compute@rowht}}
\DeclareOption{estimate}{\def\ST@calculate@rowht{\ST@estimate@rowht}}
%\def\ST@calculate@rowht{\ST@estimate@rowht}
%    \end{macrocode}
%    The default for the options is to only show errors and use the
%    old estmation algorithm (so as not to break old documents).
%    \begin{macrocode}
\ExecuteOptions{errorshow,estimate}
\ProcessOptions
%    \end{macrocode}
%
% \begin{macro}{\topcaption}
% \begin{macro}{\bottomcaption}
%    The user-commands |\topcaption| and |\bottomcaption| set the
%    flag |@topcaption| to determine where to put the
%    tablecaption. The default is to put the caption on the top of
%    the table 
%    \begin{macrocode}
\newif\if@topcaption \@topcaptiontrue
\def\topcaption{\@topcaptiontrue\tablecaption}
\def\bottomcaption{\@topcaptionfalse\tablecaption}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tablecaption}
%    This command has to function exactly like |\caption| does, except
%    it has to store its argument (and the optional argument) for
%    later processing \emph{within} the supertabular environment. 
%
%    \begin{macrocode}
\long\def\tablecaption{%
  \refstepcounter{table}\@dblarg{\@xtablecaption}}
\long\def\@xtablecaption[#1]#2{%
  \long\gdef\@process@tablecaption{\ST@caption{table}[#1]{#2}}}
\global\let\@process@tablecaption\relax
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\ifST@star}
%    This switch is used in the internal macros to remember which
%    kind of environment was started.
%    \begin{macrocode}
\newif\ifST@star
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ifST@mp}
%    This switch is used in the internal macros to remember if the
%    tabular should be put into a minipage.
% \changes{v4.1a}{1997/09/18}{Added \cs{ifST@mp} switch}
%    \begin{macrocode}
\newif\ifST@mp
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@wd}
%    For the \Lenv{supertabular*} environment it is necessary to
%    store the intended width of the tabular.
%    \begin{macrocode}
\newdimen\ST@wd
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@rightskip}
% \changes{v4.1a}{1997/09/18}{Dimen register added}
%  \begin{macro}{\ST@leftskip}
% \changes{v4.1a}{1997/09/18}{Dimen register added}
%  \begin{macro}{\ST@parfillskip}
% \changes{v4.1a}{1997/09/18}{Dimen register added}
%    For the \Lenv{mpsupertabular} environments we need special
%    versions of |\leftskip|, |\rightskip| and |\parfillskip|.
%    \begin{macrocode}
\newskip\ST@rightskip
\newskip\ST@leftskip 
\newskip\ST@parfillskip
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\ST@captionroom}
% \changes{v4.1g}{2020/02/02}{New macro}
%    When a supertabular is preceded by a caption that fact might not
%    yet be visible in the amount of space occupoed on the page
%    sofar. Therefore we include the possibility to reduce the height
%    of the first part of the supertabular. In order to this we need a
%    macro that indicates a caption has been put in front of the
%    table. We do this to reduce the risk that the first part of the
%    table is too high after all and is pushed onto the next page due
%    to an overfull |\vbox| condition.
%    \begin{macrocode}
\def\ST@captionroom{\z@}
%    \end{macrocode}
%  \end{macro}
%
%  
%  \begin{macro}{\ST@caption}
%    This is a redefinition of LaTeX's |\@caption|, |\@makecaption| is
%    called within a group so as not to return to |\normalsize|
%    globally. Also a fix is made for the `feature' of the
%    |\@makecaption| of the document class \cls{article} and friends
%    that a caption \textbf{always} gets a |\vskip 10pt| at the top
%    and \textbf{none} at the bottom. If a user wants to precede his
%    table with a caption this results in a collision. 
%
% \changes{v4.1g}{2020/02/02}{Record the fact that a caption has
%    preceeded the table by setting \cs{ST@captionroom}}
%    \begin{macrocode}
\long\def\ST@caption#1[#2]#3{\par%
  \addcontentsline{\csname ext@#1\endcsname}{#1}%
                  {\protect\numberline{%
                      \csname the#1\endcsname}{\ignorespaces #2}}
  \begingroup
    \@parboxrestore
    \normalsize
    \if@topcaption \vskip -10\p@ \fi
    \@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\par
    \if@topcaption \vskip 10\p@ \gdef\ST@captionroom{20\p@}\fi
  \endgroup}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\tablehead}
% \changes{v4.0a}{1996/11/28}{Locally reset \cs{}\cs{} to \cs{cr}}
%  \begin{macro}{\tablefirsthead}
%    |\tablehead| activates the new tabular |\cr| commands.
% \changes{v4.0i}{1997/09/18}{Don't reset \cs{}\cs{} to \cs{cr}, but
%    to \cs{@tabularcr}} 
% \changes{v4.1b}{1997/10/08}{Not \cs{@tabularcr} but
%    \cs{org@tabularcr}}
% \changes{v4.2b}{2021-02-14}{When the argument is empty the internal
%    macro \cs{@tablehead} needs to be empty as well.} 
%    \begin{macrocode}
\newcommand\tablehead[1]{%
  \def\@ST@arg{#1}%
  \ifx\@ST@arg\@empty\gdef\@tablehead{}\else
    \gdef\@tablehead{%
    \noalign{%
        \global\let\@savcr=\\
        \global\let\\=\org@tabularcr}%
      #1%
      \noalign{\global\let\\=\@savcr}}%
  \fi}
\tablehead{}
%    \end{macrocode}
%    It's possible to specify a different tablehead for the first
%    `part' of the table. That only needs to be used once so it
%    `undefines' itself at the end. That way we make sure that it
%    doesn't accidentally get used for a second supertabular in the
%    document.
% \changes{v4.1f}{2019/01/12}{\cs{\@table@first@head} needs the same
%    definition as \cs{\@tablehead} (found by FMi)}
% \changes{v4.2b}{2021-02-14}{When the argument is empty the internal
%    macro \cs{@table@first@head} needs to be empty as well.} 
%    \begin{macrocode}
\newcommand\tablefirsthead[1]{%
  \def\@ST@arg{#1}%
  \ifx\@ST@arg\@empty\gdef\@table@first@head{}\else
    \gdef\@table@first@head{%
      \noalign{%
        \global\let\@savcr=\\
        \global\let\\=\org@tabularcr}%
      #1%
      \noalign{%
        \global\let\\=\@savcr
        \global\let\@table@first@head\undefined
      }}%
  \fi}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\tabletail}
%  \begin{macro}{\tablelasttail}
%    If the user uses an extra amount of tabular-data (like
%    |\multicolumn|) in |\tabletail| \TeX\ starts looping because of
%    the definition of |\ST@cr|. So make |\\| act just like a
%    |\@tabularcr| inside this tail to prevent the loop.  Save and
%    restore the value of |\\|.
%
% \changes{v4.0i}{1997/09/18}{Don't reset \cs{}\cs{} to \cs{cr}, but
%    to \cs{@tabularcr}} 
% \changes{v4.1b}{1997/10/08}{Not \cs{@tabularcr} but
%    \cs{org@tabularcr}}
% \changes{v4.2b}{2021-02-14}{When the argument is empty the internal
%    macro \cs{@tabletail} needs to be empty as well.} 
%    \begin{macrocode}
\newcommand\tabletail[1]{%
  \def\@ST@arg{#1}%
  \ifx\@ST@arg\@empty\gdef\@tabletail{}\else
    \gdef\@tabletail{%
      \noalign{%
        \global\let\@savcr=\\
        \global\let\\=\org@tabularcr}%
      #1%
      \noalign{\global\let\\=\@savcr}}%
  \fi}
\tabletail{}
%    \end{macrocode}
%    It's possible to specify a different tabletail for the last
%    `part' of the table. That only needs to be used once so it
%    `undefines' itself at the end. That way we make sure that it
%    doesn't accidentally get used for a second supertabular in the
%    document.
% \changes{v4.1f}{2019/01/12}{\cs{\@table@last@tail} needs the same
%    definition as \cs{\@tabletail}}
% \changes{v4.2b}{2021-02-14}{When the argument is empty the internal
%    macro \cs{@tabletail} needs to be empty as well.} 
%    \begin{macrocode}
\newcommand\tablelasttail[1]{%
  \def\@ST@arg{#1}%
  \ifx\@ST@arg\@empty\gdef\@table@last@tail{}\else
    \gdef\@table@last@tail{%
      \noalign{%
        \global\let\@savcr=\\
        \global\let\\=\org@tabularcr}%
      #1%
      \noalign{%
        \global\let\\=\@savcr
        \global\let\@table@last@tail\undefined
      }}%
  \fi}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\sttraceon}
% \changes{v3.7b}{1994/05/16}{Added macro}
%  \begin{macro}{\sttraceoff}
% \changes{v3.7b}{1994/05/16}{Added macro}
%    There now is a possiblity to follow the decisions supertabular
%    makes about breaking the tabular. This has to be enabled when
%    converting this file with \texttt{docstrip} to a \texttt{.sty}
%    file. 
%    \begin{macrocode}
\newcommand\sttraceon{\c@tracingst5\relax}
\newcommand\sttraceoff{\c@tracingst\z@}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\ST@trace}
%    A macro that gets the trace message as its argument
%    \begin{macrocode}
\newcommand\ST@trace[2]{%
  \ifnum\c@tracingst>#1\relax
    \GenericWarning
      {(supertabular)\@spaces\@spaces}
      {Package supertabular: #2}%
  \fi
  }
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@trace@cr}
%    A variant of |\ST@trace| that can be called from within |\\| as
%    that command is looking for an optional argument and will end up
%    scanning the next line.
%  \begin{macro}{\ST@save@lineno}
% \changes{v4.1f}{2019/01/18}{Added a macro to save the current input
%    linenumber}
%    But because this variant is called from within |\\| we need to
%    save the current input linenumber before \TeX\ starts scanning
%    for the optional argument. If we don't, the reported linenumber
%    depends on whether or not the optional argument is present...
%    \begin{macrocode}
\newcommand\ST@save@lineno{%
  \expandafter\gdef\expandafter\ST@LineNo\expandafter{%
    \the\inputlineno}}
%    \end{macrocode}
%    Within |\ST@trace@cr| we can than locally modify |\on@line| to
%    use this saved line number.
%    \begin{macrocode}
\newcommand\ST@trace@cr[2]{%
  \ifnum\c@tracingst>#1\relax
  \begingroup
  \edef\on@line{ on input line \ST@LineNo}%
    \GenericWarning
      {(supertabular)\@spaces\@spaces}
      {Package supertabular: #2}%
  \endgroup
  \fi
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%  \begin{macro}{\ST@pageleft}
% \changes{v3.7b}{1994/05/16}{Renamed from \cs{maxsize}}
% \changes{v4.0a}{1996/11/28}{Renamed from \cs{page@left}}
%    This register holds the estimate of the amount of space left over
%    on the current page. This is used in the decision when to start a
%    new page.
%    \begin{macrocode}
\newdimen\ST@pageleft
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\shrinkheight}
% \changes{v4.0a}{1996/11/28}{New command}
% \changes{v4.0h}{1997/05/20}{This command should use \cs{advance} but
%    didn't...} 
%    A command to diminish the value of |\ST@pageleft| if necessary.
%    \begin{macrocode}
\newcommand*\shrinkheight[1]{%
  \noalign{\global\advance\ST@pageleft-#1\relax}}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\setSTheight}
% \changes{v4.0h}{1997/05/10}{New command}
%    A command to set the value of |\ST@pageleft| if necessary.
%    \begin{macrocode}
\newcommand*\setSTheight[1]{%
  \noalign{\global\ST@pageleft=#1\relax}}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@headht}
%  \begin{macro}{\ST@tailht}
%    The register |ST@headht| will hold the height of the first head
%    of a \Lenv{supertabular} environment; the register |\ST@tailht|
%    will hold the height of table tail (if any)
%    \begin{macrocode}
\newdimen\ST@headht
\newdimen\ST@tailht
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\ST@pagesofar}
%    The register |\ST@pagesofar| is used to store the estimate of the
%    amount of page already filled up.
%    \begin{macrocode}
\newdimen\ST@pagesofar
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@pboxht}
%    The measured (total) height  of a parbox-argument
%    \begin{macrocode}
\newdimen\ST@pboxht
%    \end{macrocode}
%  \end{macro}
%
% \changes{v4.0b}{1997/02/04}{Removed the use of \cs{ST@pboxcorr},
%    correction seems to be no longer necessary}
%
%  \begin{macro}{\ST@rowht}
%  \begin{macro}{\ST@stretchht}
% \changes{v4.0g}{1997/04/12}{Dimension register added}
%  \begin{macro}{\ST@prevht}
% \changes{v4.0g}{1997/04/12}{Dimension register added}
%    The estimated height of a normal row is stored in
%    |\ST@rowht|. The dimension register |\ST@stretchht| was used to
%    store the difference between the `normal' row height and the
%    row height when |\arraystretch| has a non-standard value. This
%    was used in the case where p-box entries are added to the
%    tabular. The dimension register |\ST@prevht| is used to store the
%    height of the previous row, to use it as an estimate for the
%    height of the next row. This is needed for a better estimate of
%    when to break the tabular. 
%    \begin{macrocode}
\newdimen\ST@rowht
\newdimen\ST@prevht
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\ST@toadd}
%    When a tabular row is ended with |\\[...]| we need to temporarily
%    store the optional argument in |\ST@toadd|.
%    \begin{macrocode}
\newdimen\ST@toadd
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@dimen}
%    A private scratch dimension register.
%    \begin{macrocode}
\newdimen\ST@dimen
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@pbox}
%    A box register to temporarily store the contents of a parbox.
%    \begin{macrocode}
\newbox\ST@pbox
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@tabularcr}
%  \begin{macro}{\ST@xtabularcr}
%  \begin{macro}{\ST@argtabularcr}
%    These are redefinitions of |\@tabularcr| and |\@xtabularcr|. This
%    is needed to include |\ST@cr| in the definition of
%    |\@xtabularcr|. 
%
%    All redefined macros have names that are similar to the original
%    names, except with a leading 'ST'.
%    \begin{macrocode}
% \changes{v4.1f}{2019/01/18}{Save the input linenumber before \TeX\
%    scans for an optional argument}
\def\ST@tabularcr{%
  {\ifnum0=`}\fi
  \ST@save@lineno
  \@ifstar{\ST@xtabularcr}{\ST@xtabularcr}}
\def\ST@xtabularcr{%
  \@ifnextchar[%]
    {\ST@argtabularcr}%
    {\ifnum0=`{\fi}\cr\ST@cr}}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%    \begin{macrocode}
\def\ST@argtabularcr[#1]{%
  \ifnum0=`{\fi}%
  \ifdim #1>\z@
    \unskip\ST@xargarraycr{#1}
  \else 
    \ST@yargarraycr{#1}%
  \fi}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@xargarraycr}
%  \begin{macro}{\ST@yargarraycr}
%    In this case we need to copy the value of the optional argument
%    of |\\| in our private register |\ST@toadd|.
%    \begin{macrocode}
\def\ST@xargarraycr#1{%
  \@tempdima #1\advance\@tempdima \dp \@arstrutbox
  \vrule \@height\z@ \@depth\@tempdima \@width\z@ \cr
  \noalign{\global\ST@toadd=#1}\ST@cr}
%    \end{macrocode}
%  \end{macro}
%
%    Here we need to insert |\ST@cr|
%    \begin{macrocode}
\def\ST@yargarraycr#1{%
  \cr\noalign{\vskip #1\global\ST@toadd=#1}\ST@cr}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@startpbox}
%    The macros that deal with parbox columns need to be redefined,
%    because we need to know the size of the parbox.
% \changes{v4.0b}{1997/02/04}{Removed use of \cs{ST@pboxcorr}}
%    \begin{macrocode}
\def\ST@startpbox#1{%
%    \end{macrocode}
%    To achieve our goal we need to save the text in box.
%    \begin{macrocode}
  \setbox\ST@pbox\vtop\bgroup\hsize#1\@arrayparboxrestore}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@astartpbox}
%    Our version of |\@astartpbox|.
% \changes{v4.0b}{1997/02/04}{Removed use of \cs{ST@pboxcorr}}
%    \begin{macrocode}
\def\ST@astartpbox#1{%
  \bgroup\hsize#1%
  \setbox\ST@pbox\vtop\bgroup\hsize#1\@arrayparboxrestore}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\ST@endpbox}
%  \begin{macro}{\ST@aendpbox}
% \changes{v4.0a}{1996/11/30}{Made definitions up to date with
%    \file{latex.ltx} (1996/06/01)} 
%    Our version of |\@endpbox| and |\@aendpbox|.
%    \begin{macrocode}
\def\ST@endpbox{%
  \@finalstrut\@arstrutbox\par\egroup
  \ST@dimen=\ht\ST@pbox
  \advance\ST@dimen by \dp\ST@pbox
  \ifnum\ST@pboxht<\ST@dimen
    \global\ST@pboxht=\ST@dimen
  \fi
  \ST@dimen=\z@
  \box\ST@pbox\hfil}
%    \end{macrocode}
%    
%    \begin{macrocode}
\def\ST@aendpbox{%
  \@finalstrut\@arstrutbox\par\egroup
  \ST@dimen=\ht\ST@pbox
  \advance\ST@dimen by \dp\ST@pbox
  \ifnum\ST@pboxht<\ST@dimen
    \global\ST@pboxht=\ST@dimen
  \fi
  \ST@dimen=\z@
  \unvbox\ST@pbox\egroup\hfil}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
% 
% \begin{macro}{\ST@compute@rowht}
% \changes{v4.1g}{2020/02/02}{New macro \cs{ST@compute@rowht} to
%    replace \cs{ST@estimate@rowht}} 
% \changes{v4.2a}{2020-06-27}{Make sure that \cs{ST@rowht} is large
%    enough to take subscripts and superscripts into account}
%    The height of a row in an array environemnt can be computed as:
%    \begin{itemize}
%      \item the height of the strutbox |\ht\strutbox| (plus
%        |\extrarowheight| when the \pkg{array} package is loaded),
%      \item multiplied by arraystretch,
%      \item plus the depth of the strutbox (|\dp\strutbox|) mulitplied
%        by |\arraystretch|.
%    \end{itemize}
%    \begin{macrocode}
\def\ST@compute@rowht{%
%    \end{macrocode}
%    Temporarily store a formula with superscript and subscript in a
%    box in order to be able to measure its height and depth.
%    \begin{macrocode}
  \setbox\@tempboxa=\vbox{\@arrayparboxrestore $5^5_5$}
%    \end{macrocode}
%    Use the largest height of either |\@tempboxa| or |\strutbox|.
%    \begin{macrocode}
  \ifnum\ht\@tempboxa>\ht\strutbox
    \ST@rowht=\ht\@tempboxa
  \else
    \ST@rowht=\ht\strutbox
  \fi
%    \end{macrocode}
%    If the \textsf{array} pacakge is used we need to add the
%    value of |\extrarowheight|.
%    \begin{macrocode}
  \ifx\extrarowheight\undefined\else
    \advance \ST@rowht by \extrarowheight
  \fi
%    \end{macrocode}
%    Also use the largest depth of either |\@tempboxa| or |\strutbox|.
%    \begin{macrocode}
  \ifnum\dp\@tempboxa>\dp\strutbox
    \advance\ST@rowht \dp\@tempboxa
  \else
    \advance\ST@rowht \dp\strutbox
  \fi
%    \end{macrocode}
%    And finally multiply by |\arraystretch|.
%    \begin{macrocode}
  \ST@rowht = \arraystretch\ST@rowht
%    \end{macrocode}
%    \begin{macrocode}
  \ST@trace\tw@{Normal Row height: \the\ST@rowht}%
  }
%    \end{macrocode}
% \end{macro}
%    
% \begin{macro}{\ST@estimate@rowht}
%    Estimates the height of normal line taking |\arraystretch| into
%    account. Also computes the difference between a normal line and a
%    `stretched' one.
% \changes{v4.0b}{1997/02/04}{Removed use of \cs{ST@pboxcorr}}
% \changes{v4.0g}{1997/04/12}{Added the computation of
%    \cs{ST@stretchht}}
% \changes{v4.2a}{2020-06-27}{removed the computation of
%    \cs{ST@stretchht} as it is no longer used} 
% \begin{macrocode}
\def\ST@estimate@rowht{%
  \ST@rowht=\arraystretch \baslineskp
  \global\advance\ST@rowht by 1\p@
  \ST@trace\tw@{Average Row height: \the\ST@rowht}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@calfirstpageht}
% \changes{v3.7a}{1993/04/05}{Renamed from \cmd\calpage}
%    Estimates the space left on the current page and decides whether
%    the tabular can be started on this page or on a new page.
%    \begin{macrocode}
\def\@calfirstpageht{%
  \ST@trace\tw@{Calculating height of tabular on first page}%
%    \end{macrocode}
%    The \TeX\ register |\pagetotal| contains the height of the page
%    sofar, the \LaTeX\ register |\@colroom| contains the height of
%    the column.
%    \begin{macrocode}
  \global\ST@pagesofar\pagetotal
  \global\ST@pageleft\@colroom
  \ST@trace\tw@{Height of text = \the\pagetotal; \MessageBreak
                Height of page = \the\ST@pageleft}%
%    \end{macrocode}
%    When we are in twocolumn mode \TeX\ may still be collecting
%    material for the first column although there seems to be no space
%    left. In this case we have to check against two times |\ST@pageleft|.
%    \begin{macrocode}
  \if@twocolumn
    \ST@trace\tw@{two column mode}%
    \if@firstcolumn
     \ST@trace\tw@{First column}%
      \ifnum\ST@pagesofar > \ST@pageleft 
        \global\ST@pageleft=2\ST@pageleft
        \ifnum\ST@pagesofar > \ST@pageleft
          \newpage\@calnextpageht
          \ST@trace\tw@{starting new page}%
        \else
%    \end{macrocode}
%    In this case we're in the second column, so we have to compensate
%    for the material in the first column.
%    \begin{macrocode}
          \ST@trace\tw@{Second column}%
          \global\advance\ST@pageleft -\ST@pagesofar
          \global\advance\ST@pageleft -\@colroom
        \fi
%    \end{macrocode}
%    When |\ST@pagesofar| is smaller than |\ST@pageleft| \TeX\ is
%    still collecting material for the first column, so we can start a
%    new tabular environment like we do on a single column page.
% \changes{v4.0i}{1997/09/17}{Added initialisation for the case where
%    the first column isn't full yet} 
%    \begin{macrocode}
      \else
        \global\advance\ST@pageleft by -\ST@pagesofar
        \global\ST@pagesofar\z@
      \fi
    \else
%    \end{macrocode}
%    When we end up here, \TeX\ has already decided it had enough
%    material for the first column and is building the second column.
% \changes{v4.1a}{1997/09/27}{Added initialisation for 2nd column of
%    twocolumn mode} 
%    \begin{macrocode}
      \ST@trace\tw@{Second column}
      \ifnum\ST@pagesofar > \ST@pageleft
        \ST@trace\tw@{starting new page}%
        \newpage\@calnextpageht
      \else
        \global\advance\ST@pageleft by -\ST@pagesofar
        \global\ST@pagesofar\z@
      \fi
    \fi
  \else
%    \end{macrocode}
%    In one column mode there is a simple decision.
%    \begin{macrocode}
    \ST@trace\tw@{one column mode}%
    \ifnum\ST@pagesofar > \ST@pageleft
      \ST@trace\tw@{starting new page}%
      \newpage\@calnextpageht
%    \end{macrocode}
%    When we are not starting a new page subtract the size of the
%    material already on it from the available space.
%    \begin{macrocode}
    \else
      \global\advance\ST@pageleft by -\ST@pagesofar
      \global\ST@pagesofar\z@
    \fi
  \fi
%    \end{macrocode}
%    When a caption preceeds the first part of the tabular we need to
%    reduce the available height on the page by |\ST@captionroom|.
% \changes{v4.1g}{2020/02/02}{Reduce the available height left on the
%    page when a caption preceeded the table} 
%    \begin{macrocode}
  \if@topcaption\advance\ST@pageleft-\ST@captionroom\fi
  \ST@trace\tw@{Available height: \the\ST@pageleft}%
%    \end{macrocode}
%    Now we need to know the height of the head of the table. In order
%    to measure this we typeset it in a normal \Lenv{tabular}
%    environment.
%    \begin{macrocode}
  \ifx\@@tablehead\@empty
    \ST@headht=\z@
  \else
    \setbox\@tempboxa=\vbox{\@arrayparboxrestore
      \ST@restore
      \expandafter\tabular\expandafter{\ST@tableformat}%
      \@@tablehead\endtabular}%
    \ST@headht=\ht\@tempboxa\advance\ST@headht\dp\@tempboxa
  \fi
  \ST@trace\tw@{Height of head: \the\ST@headht}%
%    \end{macrocode}
%    To decide when to start a new page, we need to know the vertical
%    size of the tail of the table.
%    \begin{macrocode}
  \ifx\@tabletail\@empty
    \ST@tailht=\z@
  \else
    \setbox\@tempboxa=\vbox{\@arrayparboxrestore
      \ST@restore
      \expandafter\tabular\expandafter{\ST@tableformat}
        \@tabletail\endtabular}
    \ST@tailht=\ht\@tempboxa\advance\ST@tailht\dp\@tempboxa
  \fi
%    \end{macrocode}
%    We add the average height of a row to this because when we
%    decide to continue the tabular we need to have enough space left
%    for one row \emph{and} the tail.
%    \begin{macrocode}
  \advance\ST@tailht by \ST@rowht
  \ST@trace\tw@{Height of tail: \the\ST@tailht}%
  \ST@trace\tw@{Maximum height of tabular: \the\ST@pageleft}%
  \@tempdima\ST@headht
%    \end{macrocode}
% \changes{v4.0b}{1997/02/04}{Base the decision whether to start on a
%    new page on the total of headheight, tailht and rowht}
%    Now we decide whether we can continue on the current page or
%    whether we need to start on a new page. We assume that the
%    minimum height of a tabular is the height of the head, the tail
%    and one row of data. If that doesn't fit a new page is started.
%    \begin{macrocode}
  \advance\@tempdima\ST@rowht
  \advance\@tempdima\ST@tailht
  \ST@trace\tw@{Minimum height of tabular: \the\@tempdima}%
  \ifnum\@tempdima>\ST@pageleft
    \ST@trace\tw@{starting new page}%
    \newpage\@calnextpageht
  \fi
%    \end{macrocode}
%    Take the height of the table into account,sosubstract it from the
%    available height. We need to do it like this because the |\\|
%    inside the definition of |\@@tablehead| have their normal
%    definition.
% \changes{v4.1g}{2020/02/02}{Subtract the height of the tablehead
%    from the available space}
%    \begin{macrocode}
  \advance\ST@pageleft-\ST@headht
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@calnextpageht}
% \changes{v3.7a}{1993/04/05}{Macro added}
% \changes{v4.0b}{1997/02/04}{Removed use of \cs{ST@pboxcorr}}
%    This calculates the maximum height of the tabular on all
%    subsequent pages of the supertabular environment.
%    \begin{macrocode}
\def\@calnextpageht{%
  \ST@trace\tw@{Calculating height of tabular on next page}%
  \global\ST@pageleft\@colroom
  \global\ST@pagesofar=\z@
  \ST@trace\tw@{Maximum height of tabular: \the\ST@pageleft}%
%    \end{macrocode}
%    Take the height of the head into account by subtracting it from
%    the avalable space.
% \changes{v4.1g}{2020/02/02}{Subtract \cs{ST@headht} from
%    \cs{ST@pageleft}} 
%    \begin{macrocode}
  \advance\ST@pageleft-\ST@headht
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\x@supertabular}
%    The body of the beginning of both environments is stored in a
%    single macro as the code is shared.
%    \begin{macrocode}
\def\x@supertabular{%
%    \end{macrocode}
%    First save the original definition of |\tabular| and then make it
%    point to |\inner@tabular|. This is done to enable supertabular
%    cells to contain a \Lenv{tabular} environment without getting
%    unexpected results when the \Lenv{supertabular} would be split
%    accross this inner \Lenv{tabular} environment.
% \changes{v4.0d}{1997/03/06}{Save definition of \cs{tabular} and
%    \cs{tabular*}} 
%    \begin{macrocode}
  \let\org@tabular\tabular
  \let\tabular\inner@tabular
%    \end{macrocode}
%    The same needs to be done for the \Lenv{tabular*}
%    environment. The coding is slightly more verbose.
%    \begin{macrocode}
  \expandafter\let
    \csname org@tabular*\expandafter\endcsname
    \csname tabular*\endcsname
  \expandafter\let\csname tabular*\expandafter\endcsname
    \csname inner@tabular*\endcsname
%    \end{macrocode}
%    If the caption should come at the top we insert it here.
%    \begin{macrocode}
  \if@topcaption \@process@tablecaption \fi
%    \end{macrocode}
%    Save the original definition of |\\|.
%    \begin{macrocode}
  \global\let\@oldcr=\\
%    \end{macrocode}
%    Save the current value of |\baselineskip|, as we need it in the
%    calculation of the average height of a row. 
%    \begin{macrocode}
  \def\baslineskp{\baselineskip}%
%    \end{macrocode}
%    We have to check whether \texttt{array.sty} was loaded, because
%    some of the internal macros have different names.
%    \begin{macrocode}
  \ifx\undefined\@classix
%    \end{macrocode}
%    Save old |\@tabularcr| and insert the definition of
%    |\ST@tabularcr|. 
% \changes{v4.1c}{1997/11/07}{For standard \LaTeX\ we need to change
%    \cs{@@startpbox}, \emph{not} \cs{@startpbox}}
%    \begin{macrocode}
    \let\org@tabularcr\@tabularcr
    \let\@tabularcr\ST@tabularcr
%    \end{macrocode}
%    Activate the new parbox algorithm.
%    \begin{macrocode}
    \let\org@startpbox=\@startpbox
    \let\org@endpbox=\@endpbox
    \let\@@startpbox=\ST@startpbox
    \let\@@endpbox=\ST@endpbox
  \else
%    \end{macrocode}
%    When \texttt{array.sty} was loaded things are a bit different.
%    \begin{macrocode}
    \let\org@tabularcr\@arraycr
    \let\@arraycr\ST@tabularcr
    \let\org@startpbox=\@startpbox
    \let\org@endpbox=\@endpbox
    \let\@startpbox=\ST@astartpbox
    \let\@endpbox=\ST@aendpbox
  \fi
%    \end{macrocode}
%
%    Check if the head of the table should be different for the first
%    and subsequent pages.
%    \begin{macrocode}
  \ifx\@table@first@head\undefined
    \let\@@tablehead=\@tablehead
  \else
    \let\@@tablehead=\@table@first@head
  \fi
%    \end{macrocode}
%    The first part of a supertabular may be moved on to the next page
%    if it doesn't fit on the current page after all. Subsequent parts
%    can not be moved; therefor we will have to switch the definition
%    of |\ST@skippage| around.
% \changes{v4.0e}{1997/04/09}{Make sure that only the first part of a
%    supertabular can be moved to the next page.} 
%    \begin{macrocode}
  \let\ST@skippage\ST@skipfirstpart
%    \end{macrocode}
%    Now we can estimate the average row height and the height of the
%    first page of the \Lenv{supertabular}.
% \changes{v4.0i}{1997/09/18}{Added \cs{noindent}}
% \changes{v4.1g}{2020/02/02}{Now call \cs{ST@calculate@rowht}}
%    \begin{macrocode}
  \ST@calculate@rowht
  \@calfirstpageht
  \noindent
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\supertabular}
%    We start by looking for an optional argument, which will be duly
%    ignored as it seems to make no sense to try to align a multipage
%    table in the middle...
%    \begin{macrocode}
\def\supertabular{%
  \@ifnextchar[{\@supertabular}%]
               {\@supertabular[]}}
%    \end{macrocode}
%    We can now save the preamble of the tabular in a macro.
%    \begin{macrocode}
\def\@supertabular[#1]#2{%
  \def\ST@tableformat{#2}%
  \ST@trace\tw@{Starting a new supertabular}%
%    \end{macrocode}
%    Then remember that this is not a \textsf{supertabular*}
%    environment.
%    \begin{macrocode}
  \global\ST@starfalse
%    \end{macrocode}
%    Don't use minipages.
% \changes{v4.1a}{1997/09/18}{Added setting of \cs{ST@mp}}
%    \begin{macrocode}
  \global\ST@mpfalse
%    \end{macrocode}
% 
%    Most of the following code is shared between the
%    \Lenv{supertabular} and \Lenv{supertabular*} environments. So to
%    avoid duplication it is stored in a macro.  
%    \begin{macrocode}
  \x@supertabular
%    \end{macrocode}
%    Finally start a normal \textsf{tabular} environment.
% \changes{v4.0d}{1997/03/06}{Use \cs{org@tabular} instead of
%    \cs{tabular}} 
%    \begin{macrocode}
  \expandafter\org@tabular\expandafter{\ST@tableformat}%
  \@@tablehead}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\supertabular*}
%    We start by looking for the optional argument of the tabular
%    environment. 
%    \begin{macrocode}
\@namedef{supertabular*}#1{%
  \@ifnextchar[{\@nameuse{@supertabular*}{#1}}%
               {\@nameuse{@supertabular*}{#1}[]}%]
  }
%    \end{macrocode}
%    We start by saving the intended width and the preamble of the
%    \textsf{tabular*}.
%    \begin{macrocode}
\@namedef{@supertabular*}#1[#2]#3{%
  \ST@trace\tw@{Starting a new supertabular*}%
  \def\ST@tableformat{#3}%
  \ST@wd=#1\relax
  \global\ST@startrue
  \global\ST@mpfalse
%    \end{macrocode}
%    Now we can call the common code for both environments.
%    \begin{macrocode}
  \x@supertabular
%    \end{macrocode}
%    And we can start a normal \textsf{tabular*} environment.
% \changes{v4.0f}{1997/04/11}{Use \cs{org@tabular*} instead of
%    \cs{tabular*}}
%    \begin{macrocode}
  \expandafter\csname org@tabular*\expandafter\endcsname
  \expandafter{\expandafter\ST@wd\expandafter}%
  \expandafter{\ST@tableformat}%
  \@@tablehead}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mpsupertabular}
% \changes{v4.1a}{1997/09/18}{Added \cs{mpsupertabular}}
%
%    This version of the supertabular environment puts each tabular 
%    into a minipage, thus making footnotes possible.
%    We start by looking for an optional argument, which will be duly
%    ignored as it seems to make no sense to try to align a multipage
%    table in the middle\dots
%    \begin{macrocode}
\def\mpsupertabular{%
  \@ifnextchar[{\@mpsupertabular}%]
               {\@mpsupertabular[]}}
%    \end{macrocode}
%    We can now save the preamble of the tabular in a macro.
%    \begin{macrocode}
\def\@mpsupertabular[#1]#2{%
  \def\ST@tableformat{#2}%
  \ST@trace\tw@{Starting a new mpsupertabular}%
%    \end{macrocode}
%    Then remember that this is not a \textsf{mpsupertabular*}
%    environment.
%    \begin{macrocode}
  \global\ST@starfalse
%    \end{macrocode}
%
%    And remember to close the minipage later.
%    \begin{macrocode}
  \global\ST@mptrue
%    \end{macrocode}
%
%    Since we are about to start a minipage of |\columnwidth| the 
%    horizontal alignment will no longer work. We have to remember the 
%    values and restore them inside the minipage.
%    \begin{macrocode}
  \ST@rightskip \rightskip
  \ST@leftskip \leftskip
  \ST@parfillskip \parfillskip
%    \end{macrocode}
%
%    Most of the following code is shared between the
%    \Lenv{mpsupertabular} and \Lenv{mpsupertabular*} environments. So
%    to avoid duplication it is stored in a macro.
%    \begin{macrocode}
  \x@supertabular
%    \end{macrocode}
%    Finally start a normal \textsf{tabular} environment.
% \changes{v4.1a}{1997/09/18}{Open minipage and adjust skips}
%    \begin{macrocode}
  \minipage{\columnwidth}%
  \parfillskip\ST@parfillskip
  \rightskip \ST@rightskip 
  \leftskip \ST@leftskip 
  \noindent\expandafter\org@tabular\expandafter{\ST@tableformat}%
  \@@tablehead}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mpsupertabular*}
% \changes{v4.1a}{1997/09/18}{Added \cs{mpsupertabular*}}
%
%    We start by looking for the optional argument of the tabular
%    environment. 
%    \begin{macrocode}
\@namedef{mpsupertabular*}#1{%
  \@ifnextchar[{\@nameuse{@mpsupertabular*}{#1}}%
               {\@nameuse{@mpsupertabular*}{#1}[]}%]
  }
%    \end{macrocode}
%    Now we can save the intended width and the preamble of the
%    \textsf{tabular*}.
%    \begin{macrocode}
\@namedef{@mpsupertabular*}#1[#2]#3{%
  \ST@trace\tw@{Starting a new mpsupertabular*}%
  \def\ST@tableformat{#3}%
  \ST@wd=#1\relax
  \global\ST@startrue
  \global\ST@mptrue
  \ST@rightskip \rightskip
  \ST@leftskip \leftskip
  \ST@parfillskip \parfillskip
%    \end{macrocode}
% 
%    Then we can call the common code for both environments.
%    \begin{macrocode}
  \x@supertabular
%    And we can start a normal \textsf{tabular*} environment.
%    \begin{macrocode}
  \minipage{\columnwidth}%
  \parfillskip\ST@parfillskip
  \rightskip \ST@rightskip 
  \leftskip \ST@leftskip 
  \noindent\expandafter\csname org@tabular*\expandafter\endcsname
  \expandafter{\expandafter\ST@wd\expandafter}%
  \expandafter{\ST@tableformat}%
  \@@tablehead}%
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endsupertabular}
% \begin{macro}{\endsupertabular*}
%    This closes the environments \Lenv{supertabular} and
%    \Lenv{supertabular*}. 
%    \begin{macrocode}
\def\endsupertabular{%
  \ifx\@table@last@tail\undefined
    \@tabletail
  \else
    \@table@last@tail
  \fi
  \csname endtabular\ifST@star*\fi\endcsname
%    \end{macrocode}
%    Restore the original definition of |\@tabularcr|
%    \begin{macrocode}
  \ST@restore
%    \end{macrocode}
%    Check if we have to insert a caption and restore to default
%    behaviour of putting captions at the top.
%    \begin{macrocode}
  \if@topcaption
  \else
    \@process@tablecaption
    \@topcaptiontrue
  \fi
%    \end{macrocode}
%
%    Restore the meaning of |\\| to the one it had before the start
%    of this environment. Also re-initialize some control-sequences
%
% \changes{v4.0h}{1997/05/20}{Added missing \cs{global} commands}
% \changes{v4.1d}{1999/08/07}{No longer make \cs{@table@first@head}
%    and \cs{@table@last@tail} undefined}
%    \begin{macrocode}
  \global\let\\\@oldcr
  \global\let\@process@tablecaption\relax
  \ST@trace\tw@{Ended a supertabular\ifST@star*\fi}%
  }
%    \end{macrocode}
%
%    The definition of the ending of the \Lenv{supertabular*}
%    environment is simple:
%    \begin{macrocode}
\expandafter\let\csname endsupertabular*\endcsname\endsupertabular
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\endmpsupertabular}
% \begin{macro}{\endmpsupertabular*}
%    This closes the environments \Lenv{mpsupertabular} and
%    \Lenv{mpsupertabular*}.
%    \begin{macrocode}
\def\endmpsupertabular{%
  \ifx\@table@last@tail\undefined
    \@tabletail
  \else
    \@table@last@tail
  \fi
  \csname endtabular\ifST@star*\fi\endcsname
  \endminipage
%    \end{macrocode}
%    Restore the original definition of |\@tabularcr|
%    \begin{macrocode}
  \ST@restore
%    \end{macrocode}
%    Check if we have to insert a caption and restore to default
%    behaviour of putting captions at the top.
%    \begin{macrocode}
  \if@topcaption
  \else
    \@process@tablecaption
    \@topcaptiontrue
  \fi
%    \end{macrocode}
%
%    Restore the meaning of |\\| to the one it had before the start
%    of this environment. Also re-initialize some control-sequences
% \changes{v4.1d}{1999/08/07}{No longer make \cs{@table@first@head}
%    and \cs{@table@last@tail} undefined}
%    \begin{macrocode}
  \global\let\\\@oldcr
  \global\let\@process@tablecaption\relax
  \ST@trace\tw@{Ended a mpsupertabular\ifST@star*\fi}%
  }
%    \end{macrocode}
%
%    The definition of the ending of the \Lenv{supertabular*}
%    environment is simple:
%    \begin{macrocode}
\expandafter\let\csname endmpsupertabular*\endcsname\endmpsupertabular
%    \end{macrocode}
% \end{macro}
% \end{macro}
%  \begin{macro}{\ST@restore}
%    This macro restores the original definitions of the macros that
%    handle parbox entries and the macros that handle the end of the
%    row. 
%    \begin{macrocode}
\def\ST@restore{%
  \ifx\undefined\@classix
    \let\@tabularcr\org@tabularcr
  \else
    \let\@arraycr\org@tabularcr
  \fi
  \let\@startpbox\org@startpbox
  \let\@endpbox\org@endpbox
  }
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\inner@tabular}
%  \begin{macro}{\inner@tabular*}
%    In order to facilitate complete \Lenv{tabular} environments to be
%    in a cell of a \Lenv{supertabular} environment we need to adapt
%    the definition of the orginal environments somewhat. For the
%    inner \Lenv{tabular} a number of definitions need to be
%    restored. 
% \changes{v4.0i}{1997/09/18}{Added \cs{noindent}}
%    \begin{macrocode}
\def\inner@tabular{%
  \ST@restore
  \let\\\@oldcr
  \noindent
  \org@tabular}
\@namedef{inner@tabular*}{%
  \ST@restore
  \let\\\@oldcr
  \noindent
  \csname org@tabular*\endcsname}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\ST@cr}
%    This macro is called by each |\\| inside the tabular environment.
%    It updates the estimate of the amount of space left on the
%    current page and starts a new page if necessary.
%    \begin{macrocode}
\def\ST@cr{%
  \noalign{%
    \ifnum\ST@pboxht<\ST@rowht
%    \end{macrocode}
%    If there is a non-empty row, but an empty parbox, then
%    |\ST@pboxht| might be non-zero, but too small, thereby breaking
%    the algorithm. Therefor we estimate the height of the row to be
%    |\ST@rowht| in this case.
%    \begin{macrocode}
      \global\advance\ST@pageleft -\ST@rowht
%    \end{macrocode}
%    And we store that fact in |\ST@prevht|.
% \changes{v4.0g}{1997/04/12}{store the height of the previous row in
%    \cs{ST@prevht}} 
%    \begin{macrocode}
      \global\ST@prevht\ST@rowht
    \else
%    \end{macrocode}
%    When the parbox was not empty we take into account its height
%    (plus a bit extra).
% \changes{v4.0g}{1997/04/12}{Also take \cs{ST@stretchht} into
%    account and store the height of the parbox in \cs{ST@prevht}}
% \changes{v4.1f}{2019/03/01}{Use \cs{ST@trace@cr} instead of
%    \cs{ST@trace}} 
% \changes{v4.1g}{2020/02/02}{\cs{ST@stretchht} is no longer needed}
%    \begin{macrocode}
     \ST@trace@cr\thr@@{Added par box with height \the\ST@pboxht}%
      \global\advance\ST@pageleft -\ST@pboxht
      \global\advance\ST@pageleft -0.1\ST@pboxht
      \global\ST@prevht\ST@pboxht
      \global\ST@pboxht\z@
    \fi
%    \end{macrocode}
%    |\ST@toadd| is the value of the optional argument of |\\|.
%    \begin{macrocode}
    \global\advance\ST@pageleft -\ST@toadd
    \global\ST@toadd=\z@
    \ST@trace@cr\thr@@{Space left for tabular: \the\ST@pageleft}%
  }
%    \end{macrocode}
%    This line is necessary because the tablehead has to be inserted
%    *after* the following |\if\else\fi|-clause. For this purpose
%    |\ST@next| is used by |\ST@newpage|. But we need to make sure
%    that |\ST@next| is not undefined when |\ST@newpage| is \emph{not}
%    called. In the middle of tableprocessing it shoud be an *empty*
%    macro (*not* |\relax|).%  (15.2.91)
% \changes{v4.1e}{2001/08/21}{Moved the default definition of
%    \cs{ST@next} out of the \cs{if} clause} 
%    \begin{macrocode}
  \noalign{\global\let\ST@next\@empty}%
%    \end{macrocode}
%    When the |\ST@pageleft| has become negative, the last row was so
%    high that the supertabular doesn't fit on the current page after
%    all. In this case we will skip the current page and start at the
%    top of the next one; otherwise \TeX\ will move this part of the
%    table to a new page anyway, probably with a message about an
%    overfull |\vbox|.
%    \begin{macrocode}
  \ifnum\ST@pageleft<\z@
    \ST@skippage
  \else
%    \end{macrocode}
%    When there is not enough space left on the current page, we start
%    a new page. To compute the amount of space needed we use the
%    height of the previous row (|\ST@prevht|) as an estimation of
%    the height of the next row. If we are processing a
%    \Lenv{mpsupertabular} we need to take the height of the footnotes
%    into account as well. 
% \changes{v4.0g}{1997/04/12}{Leave room for both \cs{ST@tailht}
%    \emph{and} \cs{ST@prevht}} 
% \changes{v4.1a}{1997/09/19}{Take care of space needed for 
%    footnotes and footnoterule} 
%    \begin{macrocode}
    \noalign{\global\@tempdima\ST@tailht
      \global\advance\@tempdima\ST@prevht
    \ifST@mp
      \ifvoid\@mpfootins\else
        \global\advance\@tempdima\ht\@mpfootins
        \global\advance\@tempdima 3pt
      \fi
    \fi}
    \ifnum\ST@pageleft<\@tempdima
      \ST@newpage
    \fi
  \fi
  \ST@next}
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\ST@skipfirstpart}
% \changes{v4.0d}{1997/03/06}{Added new macro.}
% \changes{v4.0e}{1997/04/09}{Renamed from \cs{ST@skippage}}
%    This macro skips the current page and moves the entire
%    supertabular that has been built up sofar to the next page.
%    \begin{macrocode}
\def\ST@skipfirstpart{%
  \noalign{%
    \ST@trace\tw@{Tabular too high, moving to next page}%
%    \end{macrocode}
%    In order for this to work properly we need to adapt the value of
%    |\ST@pageleft|. When this macro is called it has a negative
%    value. We should add the height of the next page to that
%    (|\@colroom|). From the result the `normal' height of the
%    supertabular should be substracted (|\@colroom| -
%    |\pagetotal|). This could be coded as follows:
%\begin{verbatim}
%      \ST@dimen\@colroom
%      \advance\ST@dimen-\pagetotal
%      \global\advance\ST@pageleft\@colroom
%      \global\advance\ST@pageleft-\ST@dimen
%\end{verbatim}
%    When you examine the code you will note that |\@colroom| is added
%    \emph{and} subtracted. Therefor the code above can be simplified
%    to:
%    \begin{macrocode}
    \global\advance\ST@pageleft\pagetotal
%    \end{macrocode}
%    Then we can set |\ST@pagesofar| to $0$...
%    \begin{macrocode}
    \global\ST@pagesofar\z@
%    \end{macrocode}
%    ... and start the new page, but in this special case we need to
%    trigger the output routine directly by issuing a |\penalty|
%    rather than calling |\newpage| as that macro effectively issues a
%    |\vskip-\maxdepth| which makes the first two rows of the tabular
%    overlap. 
% \changes{v4.2b}{2021-02-14}{Issue a \cs{penalty} instead of
%    \cs{newpage} to trigger the output routine.} 
%    \begin{macrocode}
    \penalty -\@M
%    \end{macrocode}
%
%    Finally we make sure that this macro can only be executed once
%    for each supertabular by changing the definition of
%    |\ST@skippage|. 
% \changes{v4.0e}{1997/04/09}{Make sure that only the first part of a
%    supertabular can be moved to the next page.} 
%    \begin{macrocode}
    \global\let\ST@skippage\ST@newpage
    }}
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\ST@newpage}
% \changes{v3.7b}{1994/05/16}{Added macro, split off from
%    \cmd\ST@cr}
%    This macro performs the actions necessary to start a new page.
%    \begin{macrocode}
\def\ST@newpage{%
  \noalign{\ST@trace\tw@{Starting new page, writing tail}}%
%    \end{macrocode}
%    Output |\tabletail|, close the tabular environment, close a
%    \Lenv{mnipage} if necessary, output all material and start a
%    fresh new page. 
% \changes{v4.1a}{1997/09/19}{Close minipage if we are in 
%    \Lenv{mpsupertabular}}
%    \begin{macrocode}
  \@tabletail
  \ifST@star
    \csname endtabular*\endcsname
  \else
    \endtabular
  \fi
  \ifST@mp
    \endminipage
  \fi
%    \end{macrocode}
%
%    Then we make sure that the macro |\ST@skippage| can no longer be
%    executed for this supertabular by changing the definition of it.
% \changes{v4.0d}{1997/03/06}{Use \cs{org@tabular} instead of
%    \cs{tabular}} 
% \changes{v4.0e}{1997/04/09}{Make sure that only the first part of a
%    supertabular can be moved to the next page.} 
% \changes{v4.0f}{1997/04/11}{Use \cs{org@tabular*} instead of
%    \cs{tabular*}}
% \changes{v4.0i}{1997/09/18}{Added \cs{noindent}}
% \changes{v4.1a}{1997/09/19}{Open new minipage if we are in 
%    \Lenv{mpsupertabular}}
%    \begin{macrocode}
  \global\let\ST@skippage\ST@newpage
  \newpage\@calnextpageht
  \let\ST@next\@tablehead
  \ST@trace\tw@{writing head}%
  \ifST@mp
    \noindent\minipage{\columnwidth}%
    \parfillskip\ST@parfillskip
    \rightskip \ST@rightskip 
    \leftskip \ST@leftskip 
  \fi
  \noindent
  \ifST@star
    \expandafter\csname org@tabular*\expandafter\endcsname
    \expandafter{\expandafter\ST@wd\expandafter}%
    \expandafter{\ST@tableformat}%
  \else
    \expandafter\org@tabular\expandafter{\ST@tableformat}%
  \fi}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \Finale
\endinput