%Paper: 
%From: mblock@nwu.edu
%Date: Fri, 13 Oct 95 17:30:55 PDT

% I'm using LATEX, and NOT PlainTex.
% This requires the files "table.tex","epsfig.sty" and "epsf.tex"
%  which have also been enclosed.
%  Title is BLOISSI3.TEX, the preprint (12 pt) of the paper sent to Blois VI
%  June, 1995, Elastic and Diffractive Scattering, Blois, France.
%
\input table
\documentstyle[12pt,fleqn,epsfig]{article} % Sets up style of document.
    % The above line uses "12pt" to set up a document in 12 pt font in the
    % style 'article' (see LaTeX manual) and
    % "fleqn" to set up left-flush equations indented about 1 tab stop.
%
      % A preamble that sets up a different page size:
      % set 1" body margins, but leaves space for page numbering at bottom.
    \setlength{\headheight}{0in} % This doc has no header
    \setlength{\headsep}{0in}    % and no header separation.
    \setlength{\topskip}{12pt}   % No unusual spacing for first line.
    \setlength{\topmargin}{0in} % Set: topmargin of 1"-0" = 1";
    \setlength{\oddsidemargin}{0in}  % side margin: 1"-0" = 1";
    \setlength{\evensidemargin}{0in} % ditto (Note: neg. #'s OK in TeX!).
    \setlength{\textwidth}{6.5in} % Text width= 8.5"- 2 * 1".
    \setlength{\textheight}{9.0in} % Text height= 11"- 2 * 1".
    \setlength{\footskip}{36pt} % Page number goes 1.5 lines below text end.
    \setlength{\footheight}{0.5in} % Page number in footer, 0.5" high
%
\def\stot{\sigma_{\rm tot}}
\def\ptm{p_{T\min}^{\phantom9}}
\def\eg{{\it e.g.}}
\def\ie{{\it i.e.}}
\def\etal{{\it et al.}}
\def\skipline{\vspace{8pt}}
    \def\pbar{\mbox{$\bar {\rm p}$}}
    \def\pp{\mbox{\rm pp}}
    \def\pbarp{\pbar{\mbox{\rm p}}}
\newcounter{list}
%
% New command to LABEL the item, for all lists--but NOT numList.
\newcommand{\Label}[1]{\newcounter{#1}\setcounter{#1}{\value{list}}}
%
% New environments:
% 1)
% Define new environment to make ALPHABETICAL (CAPS) list, left and right
% indented, called "AlphList".
%
\newcommand{\refAlph}[1]{(\Alph{#1})}
%
\newenvironment{AlphList}%
{\begin{list}% Has two arguments.
%First argument makes label.
{(\Alph{list})}% Label command. Makes label of form (A), etc.
%
%Second argument is for formatting.
{\usecounter{list}
\setlength{\rightmargin}{\leftmargin}}
}%
% Commands used for formatting.  Tells
% program that counter to be used is "list", and to set right
% indentation equal to left.
%
{\end{list}}% End of "AlphList" definition.
%
%
%
% 2)New environment to make alphabetical(lower case) list, left and right
% indented, called "alphList".
%
\newcommand{\refalph}[1]{(\alph{#1})}
%
\newenvironment{alphList}%
{\begin{list}% Has two arguments.
%First argument makes label.
{(\alph{list})}% Label command. Makes label of form (A), etc.
%
%Second argument is for formatting.
{\usecounter{list}
\setlength{\rightmargin}{\leftmargin}}
}%
% Commands used for formatting.  Tells
% program that counter to be used is "list", and to set right
% indentation equal to left.
%
{\end{list}}% End of "alphList" definition.
%
% Define new environment to make uppercase Romanlist, left and right
% indented, called "RomList".
%
\newcommand{\refRom}[1]{(\Roman{#1})} % reference command to give (ii)
%
\newenvironment{RomList}%
{\begin{list}% Has two arguments.
%First argument makes label.
{(\Roman{list})}% Label command. Makes label of form (A), etc.
%
%Second argument is for formatting.
{\usecounter{list}
\setlength{\rightmargin}{\leftmargin}}
}%
% Commands used for formatting.  Tells
% program that counter to be used is "list", and to set right
% indentation equal to left.
%
{\end{list}}% End of "RomList" definition.
%
% Define new environment to make lowercase romanlist, left and right
% indented, called "romList".
\newcommand{\refrom}[1]{(\roman{#1})} % reference command to give (ii)
\newenvironment{romList}%
{\begin{list}% Has two arguments.
%First argument makes label.
{(\roman{list})}% Label command. Makes label of form (A), etc.
%
%Second argument is for formatting.
{\usecounter{list}
\setlength{\rightmargin}{\leftmargin}}
}%
% Commands used for formatting.  Tells
% program that counter to be used is "list", and to set right
% indentation equal to left.
%
{\end{list}}% End of "romList" definition.
%
% Define new environment to make numerical lsit, left and right
% indented, called "numList".
\newenvironment{numList}%
{\begin{list}% Has two arguments.
%First argument makes label.
{\arabic{list}.}% Label command. Makes label of form   22.   , etc.
%
%Second argument is for formatting.
{\usecounter{list}
\setlength{\rightmargin}{\leftmargin}}
}%
% Commands used for formatting.  Tells
% program that counter to be used is "list", and to set right
% indentation equal to left.
%
{\end{list}}% End of "numList" definition.
%
% End definitions
%******************************************************************
%
%
%
% Commands for new TABLE
\def\C{\JustCenter} % Makes centered headings.
\def\LC#1{\C \Lower{#1}} %Makes lowered (half-way)&centered heading.
\def\PseudoVrule{\hfil \vrule \hskip2pt \vrule \hfil} % To make double
          % vertical line, use \|*, which invokes \PseudoVrule definition.
%
%    End of preamble
% LaTex's command to start a document.
%
% Set page style to:
                    % (1) Have Northwestern HEP logo on top.
                    % (2) have NO page number printed;
                    % (3 have abstract on same page;
                    % (4) have footnotes done with *, dagger, etc.
\begin{document}    % Beginning of document environment.
%
%
\begin{titlepage} % This environment allows me to set up an "empty"
          % page. I must fill it with \title, \abstract and \date.
     % Make the NU logo here.
     % We make a box of the perfect size for the current report number.
%
     % We must ENTER Report Number and DATE below.
\newcommand\reportnumber{490} % ENTER current report number.
\newcommand\mydate{September, 1995} %Set date up in logo.
%
%
\newlength{\nulogo} % define a new length "nulogo".
     % Use  "\settowidth" to get correct width of box, called "nulogo".
\settowidth{\nulogo}{\small\sf{N.U.H.E.P. Report No. \reportnumber}}
\title{
\vspace{-.8in} % Puts everything toward top of page
\hfill\fbox{{\parbox{\nulogo}{\small\sf{Northwestern University: \\
N.U.H.E.P. Report No. \reportnumber\\
          \mydate}}}}
          \vspace{.5in} \\
          %\vspace{1in} \\
          % The "\fbox" puts a BOX around text and the
          % "\small\sf" sets it in small, sans serif type,
          % the "\parbox{nulogo}{} makes a paragraph box, of correct width,
          % the "\fbox makes a box around the "parbox", and finally,
          % the "\hfill" pushes it to right.
          % Finally, the "\vspace{1in}" sets the NEXT line down by one inch.
% We now continue to put in MAIN title.
{The High Energy Behavior of the Forward Scattering Parameters---An Amplitude
Analysis Update
 }
\vspace{.2in}\\
%
}
%
\author{
M.~M.~Block
\thanks{Work partially supported by Department of Energy contract
DA-AC02-76-Er02289 Task B.}\vspace{-5pt}   \\
{\small\em Department of Physics and Astronomy,} \vspace{-5pt} \\ %Make
                    %smaller separation between lines.
{\small\em Northwestern University, Evanston, IL 60208}\\
\vspace{-5pt}\\
           % The negative \vspace decreases the space between last line.
%
B.~Margolis
\thanks{Deceased.
}\vspace{-5pt} \\
{\small\em  Physics Department,}\vspace{-5pt}  \\
{\small\em McGill University, Montreal, Canada H3A 2T8}\\
\vspace{-5pt}\\
           % The negative \vspace decreasesthe space between last line.
%
A.~R.~White
\thanks{Work supported by
Department of Energy contract
W-31-109-ENG-38.}\vspace{-5pt} \\
{\small\em High Energy Physics Division,} \vspace{-5pt} \\
{\small\em Argonne National Laboratory, Argonne, Il 60439}  \\
\vspace{.2in}\\
           % The negative \vspace decreasesthe space between last line.
%
{\small \sf Paper presented by Martin M. Block}\\[-4pt]
{\small \sf at the}\\[-4pt]
{\small \sf VIth Blois Workshop, Chateau de Blois, France, June, 1995}\\[-4pt]
%
}    %    End of title section.
     % Commands to print title.
\date{} % This stops printing of date.
\maketitle
\vfill
\vspace{.2in}
     %    End of title section.
     % Command to print title.
\date{} % This stops printing of date.
%
%
%\vspace{-.3in}
           % The negative \vspace decreasesthe space between last line.

     % This method, of locally redefining "\thepage", i.e., the value of the
     % page counter, as "blank", avoids
          % numbering a page.
\renewcommand\thepage{\ }
%
     % Start title input here.
\begin{abstract} % Start of abstract section.
Utilizing the most recent experimental data, we reanalyze high energy \pbar p
and pp data, using the asymptotic amplitude
analysis, under the
assumption that we have reached `asymptopia'. This analysis gives strong
evidence for a $\log \,(s/s_0)$ dependence at {\em current} energies
and {\em not} $\log^2 (s/s_0)$, and also
demonstrates that odderons are {\em not} necessary to explain the
experimental data.

\end{abstract}  % End of abstract environment.
\end{titlepage} % End of titlepage environment.
%
% Start MAIN body of text here.
     % Turn on page numbering, in arabic numerals.
\pagenumbering{arabic}
\renewcommand{\thepage}{-- \arabic{page}\ --}  % Put dashes on either
          % side of the page number.
\renewcommand{\thesection}{\Roman{section}}  %% makes titles like Revtex



%    Text starts here.
\section{Dedication}
This work is dedicated to the memory of Bernard Margolis, Rutherford Professor
of Physics at McGill University, Montreal, Canada, who died shortly after this
paper was presented in June, 1995.  He was a magnificent physicist and a more
magnificent friend. He will be sorely missed!
\section{Asymptotic Amplitude Analysis}
%
In spite of the fact that there are excellent arguments
\cite{others}
that the
energy region in which present experiments are conducted---even at the
Tevatron Collider---is too low to be
considered asymptotic, we will consider here the consequences of assuming
the {\em opposite}. This allows us to test specific hypotheses
using a well-defined phenomenological
analysis .
We caution the reader that we
{\em don't believe} we are in `asymptopia' and thus {\em don't believe} the
analysis is applicable as a true asymptotic analysis. We {\em do believe}
that present day energies are too low to make  a truly asymptotic analysis.
Nonetheless, we feel that such an analysis is valuable as a guideline to
what is and is not happening at present energies.

We apply a ``standard'' asymptotic analytic amplitude
analysis
pro\-ce\-dure\cite{others} to the now-available data
on $\stot$, the total cross section and $\rho$, the ratio of the real
to the imaginary portion of the forward scattering amplitude, in the energy
region $\sqrt s$ = 5 to 1800
GeV, including the new CDF cross sections. The data are parameterized in terms
of even and odd analytic
amplitudes. Consistent with all asymptotic theorems, this allows use of
even amplitudes varying as fast as $\log^{2}(s/s_0)$ and odd
amplitudes (the `Odderon' family) that do {\em not} vanish as
$s\rightarrow\infty$.

We show here only the large $s$ limit of the even and odd
amplitudes that are used\cite{others}. We make five fits to the data:
\begin{romList}
\item Fit 1: $\log^{2}(s/s_0)$ energy dependence for the cross section, with
no  Odderon amplitude,
\item Fit 2: $\log^{2}(s/s_0)$ energy dependence for the cross section, with
an Odderon amplitude whose cross sectional dependence is $\log s$, the most
rapid behavior allowed by asymptotic theorems,
\item Fit 3: $\log^{2}(s/s_0)$ energy dependence for the cross section, with
an Odderon amplitude whose cross sectional dependence is constant,
\item Fit 4: $\log \,(s/s_0)$ energy dependence for the cross section, with
no  Odderon amplitude,
\item Fit 5: $\log \,(s/s_0)$ energy dependence for the cross section, with
an Odderon amplitude whose cross sectional dependence  is constant, the most
rapid behavior allowed by asymptotic theorems for this choice of even
amplitude.
\end{romList}

In all cases, an odd amplitude which vanishes with increasing energy is
also employed, as well as an even amplitude that mimics Regge behavior.
%
\subsection{log$\,{}^{2}(s)$ Energy Behavior}
We introduce $f_+$ and $f_-$, the even and odd (under crossing) analytic
amplitudes
at $t=0$, and define the $\bar {\rm p}$p and pp forward scattering
amplitudes by
$f_{\bar{\rm p}{\rm p}}= f_{+} + f_{-}\,\,\,\,{\rm and}\,\,\,\,
f_{\rm pp}=f_+ - f_-,$
giving total cross sections $\stot$ and
the $\rho $-values
\begin{eqnarray}
\sigma_{\bar{\rm p}{\rm p}}=\frac{4\pi}{p}
                    \,{\rm Im}\,f_{\bar{\rm p}{\rm p}}
,\,\,\,\,
\sigma_{{\rm pp}}=\frac{4\pi}{p}\,{\rm Im}\,f_{\rm pp},\,\,\,\,
\rho_{\bar{\rm p}{\rm p}}=
\frac{ {\rm Re}\,f_{\bar{\rm p}{\rm p}} }
{ {\rm Im}\,f_{ \bar{\rm p}{\rm p} } }
,\,\,\,\, {\rm and}\,\,\,\,
\rho_{{\rm pp}}=
\frac{ {\rm Re}\,f_{{\rm pp}} }
{ {\rm Im}\,f_{{\rm pp}} }.
\end{eqnarray}
We parameterize the `conventional' even and odd amplitudes $f_+$ and $f_-$
by :
\begin{eqnarray}
     \frac{4\pi}{p}f_+ &=& i \left ( A+
     \beta \left [\log \left (\frac{s}{s_0}\right ) - i \frac{\pi}{2}
     \right ]^2 + c\,s^{\mu -1}e^{i\pi(1-\mu )/2}\right ) \label{eq:even2} \\
     \frac{4\pi}{p}f_- &=& -Ds^{\alpha -1} e^{i\pi (1-\alpha )/2}.
\label{eq:odd}
\end{eqnarray}

The parameter $\alpha $ in Eq~(\ref{eq:odd}) turns out to be about 0.5,
and thus
this odd amplitude vanishes as $s\rightarrow\infty$.

Asymptotic theorems by Eden and Kinoshita\cite{others} prove
that the {\em difference} of cross sections can not grow
faster than $\log^{\gamma /2}(s)$, when the cross section grows as
$\log^{\gamma }(s)$. Thus, odd amplitudes which do {\em not}
vanish as
$s\rightarrow\infty$ for this case are :

     $\frac{4\pi}{p}f_-^{(0)}= -\,\epsilon ^{(0)},\,\,\,\,
     \frac{4\pi}{p}f_-^{(1)} =-\left [
                      \log \left ( \frac {s}{s_0} \right ) -i \frac{\pi}{2}
                       \right ] \epsilon ^{(1)},\,\,\,\, {\rm and},\,\,\,\,
     \frac{4\pi}{p}f_-^{(2)} = -\left [
                      \log \left ( \frac {s}{s_0} \right ) -i \frac{\pi}{2}
                      \right ]^{2} \epsilon ^{(2)}.$

The complete odd amplitude is formed by adding any one (or none)
of the $f^{(i)}_-$  to the conventional odd amplitude $f_-$
of Eq~(\ref{eq:odd}).  We then fit the experimental $\rho $ and
$\stot $ data, for
both pp and $\bar{\rm p}$p, for energies between 5 and 1800 GeV, to obtain
the real constants $A,\beta ,s_0,c,\mu ,D,\alpha ,\epsilon ^{(i)}$.  The data
used below 500 GeV are listed in \cite{others}, and the high energy
points are from UA1, UA4, E710
and CDF\cite{others}.
We emphasize that what we really fit for the UA4 and CDF cross sections is
the measured
experimental quantity $\stot\times (1+\rho^2)$, which is appropriate for
experiments that measure a `luminosity-free' cross section, whereas for UA1
and the 1020 GeV point of E710,
we fit the experimental quantity $\stot\times \sqrt {1+\rho^2}$,
which was
their experimentally measured quantity (they measured a
`luminosity-dependent' cross section).

\subsection{Fitted Results for log$\,{}^{2}(s)$ Behavior}
\begin{romList}
\item Fit 1---This fit uses no Odderons in the odd amplitude and uses the
even amplitude of Eq~(\ref{eq:even2}).
The $\chi^2$/d.f. ($\chi^2$/degree of freedom)
for the fit
was 1.94, a rather large number.  The fitted constants are shown in
Table \ref{ta:amp},
Fit 1---the computed
curves are shown in Fig.~\ref{sfit1} (for $\stot$) and Fig.~\ref{rfit1} (for
$\rho$).
%
%
\noindent The most obvious features of the fit are
\begin{alphList}
 \item the predicted value
of the total cross section is much
too high
to fit the experimental values (E710 and CDF) at 1800 GeV,
\item it predicts much too high a $\rho $-value at 546 GeV.
\end{alphList}

We conclude that a simple $\log^2(s)$ fit does not fit the data.

\item Fit 2---
We fit the data with an additional degree of
freedom, by adding Odderon 2  to $f_-$ of
Eq~(\ref{eq:odd}), along with the even
amplitude of Eq~(\ref{eq:even2}).  The parameters are summarized as Fit 2,
in Table \ref{ta:amp}. Again, we
conclude that this combination doesn't fit the data, since the high energy
cross section predicted at 1800 GeV is much too high.
Although the
$\rho$-value predicted at 540 GeV is slightly lower, the $\rho$ values
predicted are still too high.
\item Fit 3---The odd
amplitude added to the conventional $f_-$ of Eq~(\ref{eq:odd}) was
Odderon 1.  The parameters are given as Fit 3 in
Table \ref{ta:amp}.  Again, the fit suffers
from the
same defect as the Odderon 2 fit, giving much too high a total cross section
at 1800 GeV, as well as predicting a UA4/2
$\rho$-value which was much too high.

The addition of Odderon 0 can have no effect on
the cross section. Since it turns out to have a negligible effect on $\rho$,
we will not
consider it further.
\end{romList}
We conclude that an even amplitude varying as
$\log^2(s/s_0)$ {\em does not fit} the cross section data. We see that
the experimental cross section does not rise as rapidly as $\log^2(s/s_0)$,
in the present-day energy region. The addition
of an Odderon term does not change this conclusion.%\newpage
%
\begin{figure}[htb]
\centerline{\psfig{figure=sblfit1.eps,width=4.25in}}% NB, the width is TRUE
				% width, 4.25 inches
\caption{\protect{\footnotesize {The total cross section  $\sigma_{tot}$, in
mb, for
$\bar {\rm{p}}$p and
pp scattering {\it vs.} the energy, $\protect\sqrt s$, in GeV, for Fit 1,
described
in Table I.  The fit was made with a $\log^2(s)$ energy variation, and no
Odderon.  The crosses are for the $\bar {\rm{p}}$p experimental data and
the circles
indicate pp data. The dot-dashed curves are for $\bar {\rm{p}}$p, and the
solid curves for pp. The pp cosmic-ray lower limit\protect\cite{others} is
appended to
the curve, but is {\em not} used in the fit.}}}\protect\label{sfit1}
\end{figure}
%
\begin{figure}[hbt]
\centerline{\psfig{figure=rblfit1.eps,width=4.25in}}% NB, the width is TRUE
				% width, 4.25 inches
\caption{\protect{\footnotesize {The $\rho$-value for $\bar {\rm{p}}$p and
pp scattering {\it vs.} the energy, $\protect\sqrt s$, in GeV, for Fit 1,
described
in Table I.  The fit was made with a $\log^2(s)$ energy variation, and no
Odderon. The crosses are for the $\bar {\rm{p}}$p experimental data and
the circles
indicate pp data. The dot-dashed curves are for $\bar {\rm{p}}$p, and the
solid curves for pp.}}}\protect\label{rfit1}
\end{figure}
%\newpage
\begin{figure}[htb]
\centerline{\psfig{figure=sblfit4.eps,width=4.25in}}% NB, the width is TRUE
					% width, 4.25 inches
\caption{\protect{\footnotesize {The total cross section  $\sigma_{tot}$, in
mb, for
$\bar {\rm{p}}$p and
pp scattering {\it vs.} the energy, $\protect\sqrt s$, in GeV, for Fit 4,
described
in Table I.  The fit was made with a $\log(s)$ energy variation, and no
Odderon.  The crosses are for the $\bar {\rm{p}}$p experimental data and
the circles
indicate pp data. The dot-dashed curves are for $\bar {\rm{p}}$p, and the
solid curves for pp. The pp cosmic-ray lower limit\protect\cite{others} is
appended to
the curve, but is {\em not} used in the fit.}}}\protect\label{sfit4}
\end{figure}
%
\begin{figure}[hbt]
\centerline{\psfig{figure=rblfit4.eps,width=4.25in}}% NB, the width is TRUE
						% width, 4.25 inches
\caption{\protect{\footnotesize {The $\rho$-value for $\bar {\rm{p}}$p and
pp scattering {\it vs.} the energy, $\protect\sqrt s$, in GeV, for Fit 4,
described
in Table I.  The fit was made with a $\log(s)$ energy variation, and no
Odderon. The crosses are for the $\bar {\rm{p}}$p experimental data and
the circles
indicate pp data. The dot-dashed curves are for $\bar {\rm{p}}$p, and the
solid curves for pp.}}}\protect\label{rfit4}
\end{figure}
%\vspace{.4in}
%\noindent
\begin{table}[h,t]                   % Use "table" environment, but also
                                 % use  "tabular" environment below.
%
\def\arraystretch{1.5}            % Make the space between rows in the Table,
                                  % 1.5 x bigger than the default spacing.
\begin{tabular}[b]{|l||l|l|l||l|l|}
      % Start main Table here.
     \cline{2-6}
      \multicolumn{1}{c|}{}
      &\multicolumn{3}{c||}{$\stot \sim \log^2(s/s_0)$}
      &\multicolumn{2}{c|}{$\stot \sim \log(s/s_0)$}\\
      \hline
      Parameters&Fit 1&Fit 2&Fit 3&Fit 4&Fit 5 \\ \hline
     $A$ (mb)&$40.3\pm .20$&$40.2\pm$ .24&$41.6\pm$ .04&$-26.0\pm 12.7$
     &$-22.5\pm 11.7$\\
     $\beta$ (mb)&$.47\pm .02$&$.48\pm .02$&$.57\pm .01$&$9.6\pm .9$
     &$9.4\pm .8$ \\
     $s_0$ (${\rm (GeV)}^2$)&$200\pm 20$&$207\pm 25$&$346\pm 11$&$500$
     &$500$ \\
     $D$ (mb${\rm (GeV)}^{2(1-\alpha)}$)&$-40.9\pm 1.9$&$-38.8\pm 2.1$
     &$-36.8\pm 1.6$&$-43.2\pm 2.1$&$-43.3\pm2.0$ \\
     $\alpha$&$.46\pm .02$&$.47\pm .02$&$.49\pm .02$&$.45\pm .02$
     &$.45\pm .02$ \\
     $c$ (mb${\rm (GeV)}^{2(1-\mu)})$&$30.9\pm 4.1$&$26.6\pm 4.3$
     &$5.9\pm 2.6$&$159\pm 17$&$154\pm 16$ \\
     $\mu$&$.46$&$.49$&$.49$&$.86\pm .01$&$.86\pm .01$ \\
     $\epsilon^{(2)}$ (mb)&&$-.024 \pm.011$&&& \\
     $\epsilon^{(1)}$ (mb)&&&$.035 \pm.040$&&$-.016\pm .043$ \\
     \hline
     $\chi^2/$d.f.&1.94&1.83&2.58&1.22&1.22 \\
     d.f.&82&81&81&82&81\\
     \hline
\end{tabular}
     %\vspace{1in} \\
     \caption{\protect\small Results of fits to total cross sections and
     $\rho $-values, including Odderons. Fit 1, Fit 2 and Fit 3 correspond
     to an asymptotic
     cross section variation of $\log ^2(s/s_0)$, with no Odderon,
     Odderon~2 and
     Odderon~1, respectively, whereas Fit 4 and Fit 5 correspond
     to an energy dependence of $\log (s/s_0)$, with no Odderon and Odderon~1,
     respectively.\label{ta:amp}}
%     \\
\end{table}
%\def\arraystretch{1}  %Restore the default row spacing in the Table.
\subsection{log$\,(s)$ Energy Behavior}
Since the experimental cross section in the energy region 5-1800 GeV did
not vary as fast as $\log ^2(s/s_0)$, we now consider an asymptotic variation
that goes as $\log \,(s/s_0)$.  We substitute for the even
amplitude in
Eq~(\ref{eq:even2}) a new amplitude $f_+$ varying as $\log \,(s/s_0)$,
$
     \frac{4\pi}{p}f_+ = i \left (A+
     \beta\left [\log \left (\frac{s}{s_0}\right ) - i \frac{\pi}{2}
     \right ] + c\,s^{\mu -1}e^{i\pi(1-\mu )/2} \right ).
$
We use the conventional odd amplitude of Eq~(\ref{eq:odd}), along with no
Odderon or Odderon 1, in Fits 4 and 5, respectively. We make the
important observation that since
the energy variation of the cross section is now only $\log (s)$,
Odderon 2 is {\em not} allowed by the asymptotic theorems.

\subsection{Fitted Results for log$\,(s)$ Behavior}
\begin{romList}
\item
Fit 4---The data are fitted with a log$\,(s/s_0)$ cross section
energy behavior,
with no Odderon. The results are detailed in Table \ref{ta:amp}, and plotted
in Fig.~\ref{sfit4} and
Fig.~\ref{rfit4}. The fit is quite satisfactory, giving a $\chi^2$/d.f.
of 1.22, fitting reasonably well to all cross section data over the
entire range of energy.  Most importantly, it now fits the UA4/2 $\rho$-value
at 546 GeV,
as well as the E710 $\rho$-value at 1800 GeV.%\newpage

%


\item Fit 5---
The data are fitted with a log$\,(s)$ cross section energy behavior,
along with Odderon 1. The results are given in Table
2. This fit (as is Fit 4) is
quite satisfactory, giving a $\chi^2$/d.f. of 1.24. Indeed, it is almost
indistinguishable from fit 4.
\end{romList}
We find that the experimental cross sections and $\rho$-values in the
energy domain 5--1800 GeV can be reproduced using a
$\log (s/s_0)$ energy variation. Further, the introduction of an Odderon
amplitude is not needed to explain the experimental data. Also, using the new
CDF cross
sections does not change these conclusions.


%
\begin{thebibliography}{99} % Begin bibliography environment.
% Start references here.
    % \vspace{.2in}
	\bibitem{others}For a complete bibliography, see M.~M. Block {\em et al.},
p. 373, Proceedings,
XXIII
International Symposium on Multiparticle Dynamics, Aspen, CO, 1994, World
Scientific, M.~M.~Block and A.~White, Editors.
\end{thebibliography}
\end{document}




\font\eightrm=cmr8
\font\sevenrm=cmr7
\font\sixrm=cmr6
\font\fiverm=cmr5
\font\eighti=cmmi8
\font\sixi=cmmi6
\font\fivei=cmmi6
\font\eightsy=cmsy8
\font\sixsy=cmsy6
\font\fivesy=cmsy5
\font\tenex=cmex10
\font\eightit=cmti8
\font\eightsl=cmsl8
\font\eighttt=cmtt8
\font\eightbf=cmbx8
\font\sixbf=cmbx6
\font\fivebf=cmbx5


\def\eightpoint{\def\rm{\fam0\eightrm}% switch to 8-point type
  \textfont0=\eightrm \scriptfont0=\sixrm \scriptscriptfont0=\fiverm
  \textfont1=\eighti \scriptfont1=\sixi \scriptscriptfont0=\fivei
  \textfont2=\eightsy \scriptfont2=\sixsy \scriptscriptfont2=\fivesy
  \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
  \textfont\itfam=\eightit  \def\it{\fam\itfam\eightit}%
  \textfont\slfam=\eightsl  \def\sl{\fam\slfam\eightsl}%
  \textfont\ttfam=\eighttt  \def\tt{\fam\ttfam\eighttt}%
  \textfont\bffam=\eightbf  \scriptfont\bffam=\sixbf
   \scriptscriptfont\bffam=\fivebf  \def\bf{\fam\bffam\eightbf}%
  \normalbaselineskip=9pt
  \setbox\strutbox=\hbox{\vrule height7pt depth2pt width0pt}%
  \let\sc=\sixrm  \normalbaselines\rm}


%   EPSF.TEX macro file:
%   Written by Tomas Rokicki of Radical Eye Software, 29 Mar 1989.
%   Revised by Don Knuth, 3 Jan 1990.
%   Revised by Tomas Rokicki to accept bounding boxes with no
%      space after the colon, 18 Jul 1990.
%
%   TeX macros to include an Encapsulated PostScript graphic.
%   Works by finding the bounding box comment,
%   calculating the correct scale values, and inserting a vbox
%   of the appropriate size at the current position in the TeX document.
%
%   To use with the center environment of LaTeX, preface the \epsffile
%   call with a \leavevmode.  (LaTeX should probably supply this itself
%   for the center environment.)
%
%   To use, simply say
%   \input epsf           % somewhere early on in your TeX file
%   \epsfbox{filename.ps} % where you want to insert a vbox for a figure
%
%   Alternatively, you can type
%
%   \epsfbox[0 0 30 50]{filename.ps} % to supply your own BB
%
%   which will not read in the file, and will instead use the bounding
%   box you specify.
%
%   The effect will be to typeset the figure as a TeX box, at the
%   point of your \epsfbox command. By default, the graphic will have its
%   `natural' width (namely the width of its bounding box, as described
%   in filename.ps). The TeX box will have depth zero.
%
%   You can enlarge or reduce the figure by saying
%     \epsfxsize=<dimen> \epsfbox{filename.ps}
%   (or
%     \epsfysize=<dimen> \epsfbox{filename.ps})
%   instead. Then the width of the TeX box will be \epsfxsize and its
%   height will be scaled proportionately (or the height will be
%   \epsfysize and its width will be scaled proportiontally).  The
%   width (and height) is restored to zero after each use.
%
%   A more general facility for sizing is available by defining the
%   \epsfsize macro.    Normally you can redefine this macro
%   to do almost anything.  The first parameter is the natural x size of
%   the PostScript graphic, the second parameter is the natural y size
%   of the PostScript graphic.  It must return the xsize to use, or 0 if
%   natural scaling is to be used.  Common uses include:
%
%      \epsfxsize  % just leave the old value alone
%      0pt         % use the natural sizes
%      #1          % use the natural sizes
%      \hsize      % scale to full width
%      0.5#1       % scale to 50% of natural size
%      \ifnum#1>\hsize\hsize\else#1\fi  % smaller of natural, hsize
%
%   If you want TeX to report the size of the figure (as a message
%   on your terminal when it processes each figure), say `\epsfverbosetrue'.
%
\newread\epsffilein    % file to \read
\newif\ifepsffileok    % continue looking for the bounding box?
\newif\ifepsfbbfound   % success?
\newif\ifepsfverbose   % report what you're making?
\newdimen\epsfxsize    % horizontal size after scaling
\newdimen\epsfysize    % vertical size after scaling
\newdimen\epsftsize    % horizontal size before scaling
\newdimen\epsfrsize    % vertical size before scaling
\newdimen\epsftmp      % register for arithmetic manipulation
\newdimen\pspoints     % conversion factor
%
\pspoints=1bp          % Adobe points are `big'
\epsfxsize=0pt         % Default value, means `use natural size'
\epsfysize=0pt         % ditto
%
\def\epsfbox#1{\global\def\epsfllx{72}\global\def\epsflly{72}%
   \global\def\epsfurx{540}\global\def\epsfury{720}%
   \def\lbracket{[}\def\testit{#1}\ifx\testit\lbracket
   \let\next=\epsfgetlitbb\else\let\next=\epsfnormal\fi\next{#1}}%
%
\def\epsfgetlitbb#1#2 #3 #4 #5]#6{\epsfgrab #2 #3 #4 #5 .\\%
   \epsfsetgraph{#6}}%
%
\def\epsfnormal#1{\epsfgetbb{#1}\epsfsetgraph{#1}}%
%
\def\epsfgetbb#1{%
%
%   The first thing we need to do is to open the
%   PostScript file, if possible.
%
\openin\epsffilein=#1
\ifeof\epsffilein\errmessage{I couldn't open #1, will ignore it}\else
%
%   Okay, we got it. Now we'll scan lines until we find one that doesn't
%   start with %. We're looking for the bounding box comment.
%
   {\epsffileoktrue \chardef\other=12
    \def\do##1{\catcode`##1=\other}\dospecials \catcode`\ =10
    \loop
       \read\epsffilein to \epsffileline
       \ifeof\epsffilein\epsffileokfalse\else
%
%   We check to see if the first character is a % sign;
%   if not, we stop reading (unless the line was entirely blank);
%   if so, we look further and stop only if the line begins with
%   `%%BoundingBox:'.
%
          \expandafter\epsfaux\epsffileline:. \\%
       \fi
   \ifepsffileok\repeat
   \ifepsfbbfound\else
    \ifepsfverbose\message{No bounding box comment in #1; using defaults}\fi\fi
   }\closein\epsffilein\fi}%
%
%   Now we have to calculate the scale and offset values to use.
%   First we compute the natural sizes.
%
\def\epsfclipstring{}% do we clip or not?  If so,
\def\epsfclipon{\def\epsfclipstring{ clip}}%
\def\epsfclipoff{\def\epsfclipstring{}}%
%
\def\epsfsetgraph#1{%
   \epsfrsize=\epsfury\pspoints
   \advance\epsfrsize by-\epsflly\pspoints
   \epsftsize=\epsfurx\pspoints
   \advance\epsftsize by-\epsfllx\pspoints
%
%   If `epsfxsize' is 0, we default to the natural size of the picture.
%   Otherwise we scale the graph to be \epsfxsize wide.
%
   \epsfxsize\epsfsize\epsftsize\epsfrsize
   \ifnum\epsfxsize=0 \ifnum\epsfysize=0
      \epsfxsize=\epsftsize \epsfysize=\epsfrsize
      \epsfrsize=0pt
%
%   We have a sticky problem here:  TeX doesn't do floating point arithmetic!
%   Our goal is to compute y = rx/t. The following loop does this reasonably
%   fast, with an error of at most about 16 sp (about 1/4000 pt).
% 
     \else\epsftmp=\epsftsize \divide\epsftmp\epsfrsize
       \epsfxsize=\epsfysize \multiply\epsfxsize\epsftmp
       \multiply\epsftmp\epsfrsize \advance\epsftsize-\epsftmp
       \epsftmp=\epsfysize
       \loop \advance\epsftsize\epsftsize \divide\epsftmp 2
       \ifnum\epsftmp>0
          \ifnum\epsftsize<\epsfrsize\else
             \advance\epsftsize-\epsfrsize \advance\epsfxsize\epsftmp \fi
       \repeat
       \epsfrsize=0pt
     \fi
   \else \ifnum\epsfysize=0
     \epsftmp=\epsfrsize \divide\epsftmp\epsftsize
     \epsfysize=\epsfxsize \multiply\epsfysize\epsftmp   
     \multiply\epsftmp\epsftsize \advance\epsfrsize-\epsftmp
     \epsftmp=\epsfxsize
     \loop \advance\epsfrsize\epsfrsize \divide\epsftmp 2
     \ifnum\epsftmp>0
        \ifnum\epsfrsize<\epsftsize\else
           \advance\epsfrsize-\epsftsize \advance\epsfysize\epsftmp \fi
     \repeat
     \epsfrsize=0pt
    \else
     \epsfrsize=\epsfysize
    \fi
   \fi
%
%  Finally, we make the vbox and stick in a \special that dvips can parse.
%
   \ifepsfverbose\message{#1: width=\the\epsfxsize, height=\the\epsfysize}\fi
   \epsftmp=10\epsfxsize \divide\epsftmp\pspoints
   \vbox to\epsfysize{\vfil\hbox to\epsfxsize{%
      \ifnum\epsfrsize=0\relax
        \special{PSfile=#1 llx=\epsfllx\space lly=\epsflly\space
            urx=\epsfurx\space ury=\epsfury\space rwi=\number\epsftmp
            \epsfclipstring}%
      \else
        \epsfrsize=10\epsfysize \divide\epsfrsize\pspoints
        \special{PSfile=#1 llx=\epsfllx\space lly=\epsflly\space
            urx=\epsfurx\space ury=\epsfury\space rwi=\number\epsftmp\space
            rhi=\number\epsfrsize \epsfclipstring}%
      \fi
      \hfil}}%
\global\epsfxsize=0pt\global\epsfysize=0pt}%
%
%   We still need to define the tricky \epsfaux macro. This requires
%   a couple of magic constants for comparison purposes.
%
{\catcode`\%=12 \global\let\epsfpercent=%\global\def\epsfbblit{%BoundingBox}}%
%
%   So we're ready to check for `%BoundingBox:' and to grab the
%   values if they are found.
%
\long\def\epsfaux#1#2:#3\\{\ifx#1\epsfpercent
   \def\testit{#2}\ifx\testit\epsfbblit
      \epsfgrab #3 . . . \\%
      \epsffileokfalse
      \global\epsfbbfoundtrue
   \fi\else\ifx#1\par\else\epsffileokfalse\fi\fi}%
%
%   Here we grab the values and stuff them in the appropriate definitions.
%
\def\epsfempty{}%
\def\epsfgrab #1 #2 #3 #4 #5\\{%
\global\def\epsfllx{#1}\ifx\epsfllx\epsfempty
      \epsfgrab #2 #3 #4 #5 .\\\else
   \global\def\epsflly{#2}%
   \global\def\epsfurx{#3}\global\def\epsfury{#4}\fi}%
%
%   We default the epsfsize macro.
%
\def\epsfsize#1#2{\epsfxsize}
%
%   Finally, another definition for compatibility with older macros.
%
\let\epsffile=\epsfbox

\font\ninerm=cmr9
\font\sevenrm=cmr7
\font\sixrm=cmr6
\font\fiverm=cmr5
\font\ninei=cmmi9
\font\sixi=cmmi6
\font\fivei=cmmi6
\font\ninesy=cmsy9
\font\sixsy=cmsy6
\font\fivesy=cmsy5
\font\tenex=cmex10
\font\nineit=cmti9
\font\ninesl=cmsl9
\font\ninett=cmtt9
\font\ninebf=cmbx9
\font\sixbf=cmbx6
\font\fivebf=cmbx5


\def\ninepoint{\def\rm{\fam0\ninerm}% switch to 9-point type
  \textfont0=\ninerm \scriptfont0=\sixrm \scriptscriptfont0=\fiverm
  \textfont1=\ninei \scriptfont1=\sixi \scriptscriptfont0=\fivei
  \textfont2=\ninesy \scriptfont2=\sixsy \scriptscriptfont2=\fivesy
  \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
  \textfont\itfam=\nineit  \def\it{\fam\itfam\nineit}%
  \textfont\slfam=\ninesl  \def\sl{\fam\slfam\ninesl}%
  \textfont\ttfam=\ninett  \def\tt{\fam\ttfam\ninett}%
  \textfont\bffam=\ninebf  \scriptfont\bffam=\sixbf
   \scriptscriptfont\bffam=\fivebf  \def\bf{\fam\bffam\ninebf}%
  \normalbaselineskip=11pt
  \setbox\strutbox=\hbox{\vrule height8pt depth3pt width0pt}%
  \let\sc=\sevenrm  \normalbaselines\rm}


% TABLE 1.0 
% Copyright Michael J. Wichura August 1988

%% The following three lines were inserted by C.E.K. of Personal TeX on 9-6-89
\input nine
\input eight
\font\csc=cmcsc10

 
 
% The TABLE macros are divided into sections, roughly according to
% function:
 
% Section Name        Function
% a       Allocation  Allocates storage registers for parameters.  
% f       Format      Reads format section; builds preamble for \halign;
%                      processes \ReFormat command.
% g       Get Value   Converts "spec"'s (as in spec_{LT}) to 
%                      corresponding "values"'s (as in value_{LT}).
% h       Hacks       Utility macros; error messages; miscellaneous commands.
% k       Keys        Definition and scanning of format keys.
% n       Numeric     Macros for TABLE's numeric format.
% s       Struts      Macros for struts.
% t       Tables      Sets up \halign for table; end-of-row processing;
%                      alternate vertical rules; spanning; horizontal
%                      lines; stretching and shrinking; repositioning 
%                      commands.
 
% The name of each internal macro begins with the prefix "\!t", the 
% "!" having category code 11, followed by the letter of the section 
% in which the macro is defined. For example, a macro beginning "\!th" 
% is defined in Section h (Hacks). There a few exceptions:
% the general purpose macros "\!ttemp", "\!ttempa", "\!ttempb", and
% "\!tnext" are repeatedly defined on the spot as the need arises.
 
% External macros (and active characters) are defined in the following 
% sections:
%    Macro                    Section
%    "                        t
%    \-                       t
%    \=                       t
%    \ActivateBarAndQuote     h 
%    \AugmentedTableStrut     s 
%    \BackSpace               h
%    \BeginFormat             f
%    \BeginTable              t
%    \BeginTableParBox        a
%    \Center                  t
%    \ColumnWidthFactor       a 
%    \ColumnWidthUnit         a
%    \DQuote                  h 
%    \EndFormat               k  (\EndFormat is actually a key)
%    \EndTable                t
%    \EndTableParBox          a
%    \Enlarge                 s
%    \enlarge                 s
%    \EveryTable              a 
%    \EveryTableParBox        a
%    \Expand                  t
%    \InterColumnSpaceFactor  a 
%    \InterColumnSpaceUnit    a
%    \JustCenter              t
%    \JustLeft                t
%    \JustRight               t
%    \KernFactor              a 
%    \KernUnit                a 
%    \Left                    t
%    \LeftTabskip             a
%    \LineThicknessFactor     a 
%    \LineThicknessUnit       a 
%    \LongLines               t
%    \Lower                   h
%    \MakeStrut               s
%    \NewFormatKey            k
%    \NormalCWU               a
%    \NormalICSU              a
%    \NormalKU                a
%    \NormalLTU               a
%    \NormalSU                a
%    \NormalTableUnits        a
%    \OpenUp                  s
%    \PseudoVrule             t
%    \Raise                   h
%    \ReadFormatKeys          k
%    \ReFormat                f
%    \Right                   t
%    \RightTabskip            a
%    \SetTableToWidth         t
%    \Smash                   h
%    \StandardTableStrut      s
%    \StrutDepthFactor        a 
%    \StrutHeightFactor       a 
%    \StrutUnit               a 
%    \TaBlE                   h
%    \TracingFormats          a
%    \TracingKeys             a
%    \Use                     t
%    \use                     t
%    \VBar                    h 
%    \Vspace                  h
%    \VspaceFactor            a 
%    \WidenTableBy            t
%    \\                       t 
%    \_                       t
%    \|                       t
%    |                        t
%    ~                        t
% 
\catcode `\!=11
\catcode `\@=11

% Don't try to read the TABLE macros until after you've read the
% TABLE manual. The internal documentation of the macros is
% sketchy; you need the manual to understand what's going on.
% You should also review the material on \halign s in the TeXbook,
% since TABLE uses an \halign to perform its alignments.
 
% In studying the TABLE macros, you should start by skimming the
% macros in the "miscellaneous hacks", "error messages", and "loops"
% subsections of Section h, as well as the "\GetValue" macro in
% Section g; these macros are called many times by the other macros.
% To continue with a "bottom-up" approach, read next Sections k, 
% f, and t. (Top-downers should reverse the order.) The other 
% Sections can be looked at as the need arises.
 


% *********************************************************************
% SECTION A: ALLOCATION
% *********************************************************************

\let\!tacr=\\ % Save meaning of \\ (Needed if TABLE is used with LaTeX

% *********************************************************************
% TABLE PARAMETERS: Units
% *********************************************************************

\newdimen\LineThicknessUnit 
\newdimen\StrutUnit            
\newskip \InterColumnSpaceUnit  
\newdimen\ColumnWidthUnit     
\newdimen\KernUnit

\let\!taLTU=\LineThicknessUnit % Used in preamble
\let\!taCWU=\ColumnWidthUnit   % Used in preamble
\let\!taKU =\KernUnit          % Used in preamble

\newtoks\NormalTLTU
\newtoks\NormalTSU
\newtoks\NormalTICSU
\newtoks\NormalTCWU
\newtoks\NormalTKU

% NOTE: The user should modify the following DEFAULTS to suit his/her
% taste, and output device:
%\def\PixelsPerInch{300}
\NormalTLTU={1in \divide \LineThicknessUnit by 300 }
\NormalTSU ={\normalbaselineskip
  \divide \StrutUnit by 11 }  % 11 = 8+3 = NormalT Height+Depth Factors
\NormalTICSU={.5em plus 1fil minus .25em}  % .5em = width of a digit
\NormalTCWU ={.5em}
\NormalTKU  ={.5em}

\def\NormalTableUnits{%
  \LineThicknessUnit   =\the\NormalTLTU
  \StrutUnit           =\the\NormalTSU
  \InterColumnSpaceUnit=\the\NormalTICSU
  \ColumnWidthUnit     =\the\NormalTCWU
  \KernUnit            =\the\NormalTKU}
 
\NormalTableUnits

% The user should issue \NormalTableUnits when setting a table 
% in a different point size, since the Table...Units themselves 
% are static while the Normal...Units vary with the point size.


% *********************************************************************
% TABLE PARAMETERS: Factors
% *********************************************************************

\newcount\LineThicknessFactor    
\newcount\StrutHeightFactor      
\newcount\StrutDepthFactor       
\newcount\InterColumnSpaceFactor 
\newcount\ColumnWidthFactor      
\newcount\KernFactor
\newcount\VspaceFactor

% DEFAULTS:
\LineThicknessFactor    =2
\StrutHeightFactor      =8
\StrutDepthFactor       =3
\InterColumnSpaceFactor =3
\ColumnWidthFactor      =10
\KernFactor             =1
\VspaceFactor           =2


% *********************************************************************
% DIAGNOSTIC PARAMETERS
% *********************************************************************

\newcount\TracingKeys % >=1 reports new keys, >=2 reports key usage
\newcount\TracingFormats  % >=1 reports templates for columns
                          % >=2 reports \halign preamble


% *********************************************************************
% PARBLOCK PARAMETERS
% *********************************************************************

\def\BeginTableParBox#1{%
  \vtop\bgroup 
    \hsize=#1
    \normalbaselines 
    \let~=\!ttTie
    \let\-=\!ttDH
    \the\EveryTableParBox} 
  
\def\EndTableParBox{%
    \MakeStrut{0pt}{\StrutDepthFactor\StrutUnit}
  \egroup} % finishes the \vtop begun by \BeginTableParbox

\newtoks\EveryTableParBox
\EveryTableParBox={%
  \parindent=0pt
  \raggedright
  \rightskip=0pt plus 4em %   Provide more stretch
  \relax} 


% *********************************************************************
% EVERY TABLE TOKENS
% *********************************************************************

\newtoks\EveryTable
\newtoks\!taTableSpread


% *********************************************************************
% Extreme left- and right- tabskips
% *********************************************************************

\newskip\LeftTabskip
\newskip\RightTabskip


% *********************************************************************
% INTERNAL VARIABLES
% *********************************************************************

\newcount\!taCountA
\newcount\!taColumnNumber
\newcount\!taRecursionLevel % (Initially 0)

\newdimen\!taDimenA  % used by \Enlarge
\newdimen\!taDimenB  % used by \Enlarge
\newdimen\!taDimenC  % used by numeric.tex
\newdimen\!taMinimumColumnWidth

\newtoks\!taToksA

\newtoks\!taPreamble
\newtoks\!taDataColumnTemplate
\newtoks\!taRuleColumnTemplate
\newtoks\!taOldRuleColumnTemplate
\newtoks\!taLeftGlue
\newtoks\!taRightGlue

\newskip\!taLastRegularTabskip

\newif\if!taDigit
\newif\if!taBeginFormat
\newif\if!taOnceOnlyTabskip



% *********************************************************************
% SECTION H: HACKS
% *********************************************************************

% ****************************************************************
% TABLE LOGO
% ****************************************************************
\def\TaBlE{%
  T\kern-.27em\lower.5ex\hbox{A}\kern-.18em B\kern-.1em
    \lower.5ex\hbox{L}\kern-.075em E}


% ****************************************************************
% ACTIVE CHARACTERS
% ****************************************************************

% ACTIVATE BAR AND QUOTE: Makes | and " active if they aren't
% already active (in which case the user will probably have given
% them special meanings); definitions are provided which effectively
% undoes the activeness outside a Table. 

{\catcode`\|=13 \catcode`\"=13
  \gdef\ActivateBarAndQuote{%
    \ifnum \catcode`\|=13
    \else
      \catcode`\|=13
      \def|{%
        \ifmmode
          \vert
        \else
          \char`\|
        \fi}%
    \fi
    \ifnum \catcode`\"=13
    \else
      \catcode`\"=13
      \def"{\char`\"}%
    \fi}}
 
% ****************************************************************
% Macros for | and " having category code 12.
% ****************************************************************
{\catcode `\|=12 \catcode `\"=12 
\gdef\VBar{|}
\gdef\DQuote{"}}


% ****************************************************************
% MISCELANEOUS HACKS
% ****************************************************************

% MESSAGE <Message>: Writes out <Message> to terminal and log file.
\def\!thMessage#1{\immediate\write16{#1}\ignorespaces}
 
% X: Abbreviation for expandafter
\let\!thx=\expandafter

% GOBBLE: Eats next token
\def\!thGobble#1{} 

% SPACE TOKEN
\def\\{\let\!thSpaceToken= }\\ 

% HEIGHT, DEPTH, AND WIDTH
\def\!thHeight{height}
\def\!thDepth{depth}
\def\!thWidth{width}

% TOKSEDEF <token register>=<replacement text>: Places <replacement
% text>, fully expanded a la \edef, in the specified <token register>.
\def\!thToksEdef#1=#2{%
  \edef\!ttemp{#2}%
  #1\!thx{\!ttemp}%
  \ignorespaces}


% ****************************************************************
% ERROR MESSAGES
% ****************************************************************

% STORE ERROR MSG <Control Sequence> <Message>
% Replacement text of <Control Sequence> is a macro with Message
% as its name.  E.g., after \StoreErrorMsg\Help{Type <CR>},
% \Help expands to "\Type <CR>"
\def\!thStoreErrorMsg#1#2{%
  \toks0 =\!thx{\csname #2\endcsname}%
  \edef#1{\the\toks0 }}

% READ ERROR MSG <Control sequence>
% Continuing the above example, \ReadErrorMsg\Help produces "Type <CR>"
\def\!thReadErrorMsg#1{%
  \!thx\!thx\!thx\!thGobble\!thx\string #1}

% ERROR <Error Message> <Error Help>
\def\!thError#1#2{%
  \begingroup
    \newlinechar=`\^^J%
    \edef\!ttemp{#2}%
    \errhelp=\!thx{\!ttemp}%
    \!thMessage{%
      ^^J\!thReadErrorMsg\!thErrorMsgA 
      ^^J\!thReadErrorMsg\!thErrorMsgB}%
    \errmessage{#1}%
  \endgroup}

% TEXT FOR ERROR MESSAGE
\!thStoreErrorMsg\!thErrorMsgA{%
  TABLE error; see manual for explanation.}
\!thStoreErrorMsg\!thErrorMsgB{%
  Type \space H <return> \space for immediate help.}

% GET REPLACEMENT <Prompt Message> <Replacement Value>
%  <Replacement Vale> must be a control sequence
\def\!thGetReplacement#1#2{%
   \begingroup
     \!thMessage{#1}
     \endlinechar=-1
     \global\read16 to#2%
   \endgroup}


% ****************************************************************
% LOOP MACRO 
% ****************************************************************

% LOOP ... REPEAT macro from TUGboat Vol 8 #2: 1987
% Syntax is like that of plain TeX's \loop ... \repeat macro
\def\!thLoop#1\repeat{%
  \def\!thIterate{%
    #1%
    \!thx \!thIterate
    \fi}%
  \!thIterate 
  \let\!thIterate\relax}


% ***************************************************************
% VERTICALLY-CENTERED SMASH
% ***************************************************************

% SMASH: Like TeX's \smash, only the argument
% is centered vertically before its height and depth are smashed to 0pt.
\def\Smash{%
  \relax
  \ifmmode
    \expandafter\mathpalette
    \expandafter\!thDoMathVCS
  \else
    \expandafter\!thDoVCS
  \fi}
                      
% DO VCS
\def\!thDoVCS#1{%
  \setbox\z@\hbox{#1}%
  \!thFinishVCS}
                      
% DO MATH VCS
\def\!thDoMathVCS#1#2{%
  \setbox\z@\hbox{$\m@th#1{#2}$}%
  \!thFinishVCS}
                      
% FINISH VCS
\def\!thFinishVCS{%
  \vbox to\z@{\vss\box\z@\vss}}
 

% ***************************************************************
% RAISE AND LOWER
% ***************************************************************

% Like TeX's \raise and \lower, except: (1) The first argument
% to these commands is a dimension expressed in TABLE's usual conventions;
% the default is (StrutHeightFactor+StrutDepthFactor)*StrutUnit/2
% (2) like \smash, these commands function in math mode as well 
% as horizontal mode; (3) again like \smash, the result is declared
% to have height and depth 0pt

% Examples  \Raise2{Stuff}:  "Stuff" is raised 2*StrutUnit
%           \Raise {Stuff}:  "Stuff" is raised a half-line
%           $\Lower(10pt){\alpha}$:  "$\alpha$" is lowered 10 points

% RAISE
\def\Raise{%
  \def\!thSign{+}%
  \!tgGetValue\!thSetDimen}

% LOWER
\def\Lower{%
  \def\!thSign{-}%
  \!tgGetValue\!thSetDimen}

% SET DIMEN
\def\!thSetDimen{%
  \ifnum \!tgCode=1
    \ifx \!tgValue\empty
      \!taDimenA \StrutHeightFactor\StrutUnit
      \advance \!taDimenA \StrutDepthFactor\StrutUnit
      \divide \!taDimenA 2
    \else
      \!taDimenA \!tgValue\StrutUnit
    \fi
  \else
    \!taDimenA \!tgValue
  \fi
  \!taDimenA=\!thSign\!taDimenA\relax
  %
  % BRANCH ON MODE
  \ifmmode
    \expandafter\mathpalette
    \expandafter\!thDoMathRaise
  \else
    \expandafter\!thDoSimpleRaise
  \fi}
                      
% DO SIMPLE RAISE
\def\!thDoSimpleRaise#1{%
  \setbox\z@\hbox{\raise \!taDimenA\hbox{#1}}%
  \!thFinishRaise} % From Plain TeX: \ht0=0pt \dp0=0pt \box0
                      
% DO MATH RAISE
\def\!thDoMathRaise#1#2{%
  \setbox\z@\hbox{\raise \!taDimenA\hbox{$\m@th#1{#2}$}}%
  \!thFinishRaise}

% FINISH RAISE. This is the same as Plain's \finsm@sh; some macro
% packages redefine \finsm@sh.
\def\!thFinishRaise{%
  \ht\z@\z@ 
  \dp\z@\z@
  \box\z@}
                      

% ***************************************************************
% BACK SPACE
% ***************************************************************
\def\BackSpace{%
  \!tgGetValue\!thKernBack}

\def\!thKernBack{%
  \kern -
  \ifnum \!tgCode=1 
    \ifx \!tgValue\empty 
      \the\KernFactor
    \else
      \!tgValue    % user-specified integer
    \fi
    \KernUnit
  \else 
    \!tgValue      % user-specified dimension
  \fi
  \ignorespaces}%


% ***************************************************************
% Vspace
% ***************************************************************
\def\Vspace{%
  \noalign
  \bgroup
  \!tgGetValue\!thVspace}

\def\!thVspace{%
  \vskip
    \ifnum \!tgCode=1 
      \ifx \!tgValue\empty 
        \the\VspaceFactor
      \else
        \!tgValue    % user-specified integer
      \fi
      \StrutUnit
    \else 
      \!tgValue      % user-specified skip
    \fi
  \egroup} % Ends the \noalign
  


% *********************************************************************
% SECTION F: FORMAT
% *********************************************************************

% As explained in Section 3.3 of the manual, TABLE alternates each
% of the user's "data" columns with a "rule" column; moreover, TABLE
% places a "dummy data" column at the left and right of a table.
% A table with  n  nominal data columns therefore actually has a
% total of
%       n        (nominal data columns)
%     +(n+1)     (rule columns)
%     + 2        (dummy data columns)
%     ____
%      2n+3 
% columns.
  
% FORMATs job is to create an \halign preamble for the alignment
% of these (2n+3) columns. The preamble consists of templates
% for the various columns, strung together with &'s and interlaced
% with \tabskip glue specifications.
  
% FORMAT constructs the template for a nomimal data column according
% to the user-specified format keys. As the keys are read from left
% to right, the template is built up "from the inside out" (as 
% illustrated in Section 3.1.9 of the manual), the inner-most part
% being the "#" sign. A "|" in the format terminates template
% building; the completed template is adjoined to preamble along 
% with the template for the following rule column.

% Minimum column widths, if specified, are implemented by creating
% an "artificial row" with data entries of the form 
%   \hskip <minimum column width>. 
% This row has zero height and depth and is completely invisible.


% BEGIN FORMAT
\def\BeginFormat{%
  \catcode`\|=12 % Inhibit expansion if | immediately follows a <number>
  \catcode`\"=12 %  read by \getvalue.
  \!taPreamble={}% 
  \!taColumnNumber=0
  \skip0 =\InterColumnSpaceUnit
  \multiply\skip0 \InterColumnSpaceFactor
  \divide\skip0 2
  \!taRuleColumnTemplate=\!thx{%
    \!thx\tabskip\the\skip0 }%
  \!taLastRegularTabskip=\skip0 
  \!taOnceOnlyTabskipfalse
  \!taBeginFormattrue % Used to intercept key "]"
  \def\!tfRowOfWidths{}%  Artificial Table Row with horizontal struts
                       %  to enforce specified minimum column widths
  \ReadFormatKeys}

% SET (MINIMUM COLUMN) WIDTH: Invoked by the key "w".
\def\!tfSetWidth{%
  \ifx \!tfRowOfWidths \empty  % true if no prior "w" keys
    \ifnum \!taColumnNumber>0  % true if "w" key is to right of first "|"
      \begingroup              % RowOfWidths={&\omit || n copies of
                               % &\omit&\omit}, where n = number of columns
         \!taCountA=1          % to the left of this one
         \aftergroup \edef \aftergroup \!tfRowOfWidths \aftergroup {%
           \aftergroup &\aftergroup \omit
           \!thLoop
             \ifnum \!taCountA<\!taColumnNumber
             \advance\!taCountA 1
             \aftergroup \!tfAOAO
           \repeat 
           \aftergroup }%
      \endgroup
    \fi
  \fi      
  \ifx [\!ttemp % \!tgGetValue sets \!ttemp = token after w
    \!thx\!tfSetWidthText
  \else
    \!thx\!tfSetWidthValue
  \fi}

% AOAO = (Apersand Omit Ampersand Omit)
\def\!tfAOAO{%
  &\omit&\omit}

% SET WIDTH TEXT
\def\!tfSetWidthText [#1]{% #1 = specified text 
  \def\!tfWidthText{#1}%
  \ReadFormatKeys}

% SET WIDTH VALUE
\def\!tfSetWidthValue{%
  \!taMinimumColumnWidth = 
    \ifnum \!tgCode=1 
      \ifx\!tgValue\empty % Use default multiplier if user didn't specify one
        \ColumnWidthFactor
      \else
        \!tgValue 
      \fi
      \ColumnWidthUnit
    \else
      \!tgValue 
    \fi
  \def\!tfWidthText{}%      Override possible prior `w[sample entry]'
  \ReadFormatKeys}


% SET TABSKIP: Invoked by the tabskip keys "t" and "o"
\def\!tfSetTabskip{%
  \ifnum \!tgCode=1
    \skip0 =\InterColumnSpaceUnit
    \multiply\skip0 
      \ifx \!tgValue\empty
        \InterColumnSpaceFactor         % Default integer
      \else
       \!tgValue                        % User-specified integer
      \fi
  \else
    \skip0 =\!tgValue                   % User-specified <skip>
  \fi
  \divide\skip0 by 2
  \ifnum\!taColumnNumber=0 
    \!thToksEdef\!taRuleColumnTemplate={%
      \the\!taRuleColumnTemplate 
      \tabskip \the\skip0 }
  \else
    \!thToksEdef\!taDataColumnTemplate={%
      \the\!taDataColumnTemplate 
      \tabskip \the\skip0 }
  \fi
  \if!taOnceOnlyTabskip
  %                               % Tabskip used at right of this col only
  \else
    \!taLastRegularTabskip=\skip0 % Remember this Tabskip, for possible
  \fi                             % restoration after a subsequent"OnceOnly"
  \ReadFormatKeys}


% SET VRULE: Invoked by the key "|"
\def\!tfSetVrule{%
  \!thToksEdef\!taRuleColumnTemplate={%
    \noexpand\hfil
    \noexpand\vrule
    \noexpand\!thWidth
    \ifnum \!tgCode=1
      \ifx \!tgValue\empty
        \the\LineThicknessFactor      % Default integer
      \else
        \!tgValue                     % User-specified integer
      \fi
      \!taLTU                         % \LineThicknessUnit
    \else
      \!tgValue                       % User-specified dimension
    \fi
    ####%
    \noexpand\hfil
    \the\!taRuleColumnTemplate}       % has \tabskips, when column number=0
  \!tfAdjoinPriorColumn}
 
% SET ALTERNATE VRULE: Invoked by the key "\|", in the form
%   \|{<template for (rule) column>}. The "{" and "}" are mandatory,
% and the <template for column> must contain a "#". The key system 
% CAN'T be used to set up this template.  The <template> can have the
% form  "\span\macro".
\def\!tfSetAlternateVrule{%
  \afterassignment\!tfSetAlternateA
  \toks0 =}                           % Put template into \toks0

\def\!tfSetAlternateA{%
  \!thToksEdef\!taRuleColumnTemplate={%
    \the\toks0 \the\!taRuleColumnTemplate} % RCT may have \tabskips
  \!tfAdjoinPriorColumn}

% ADJOIN PRIOR COLUMN
\def\!tfAdjoinPriorColumn{%
  \ifnum \!taColumnNumber=0
    \!taPreamble=\!taRuleColumnTemplate % New \tabskip may have been added
    \ifnum \TracingFormats>0             
      \!tfShowRuleTemplate
    \fi
  \else
    \ifx\!tfRowOfWidths\empty  % no "w" keys specified yet, not even this col
    \else
      \!tfUpdateRowOfWidths
    \fi
    % Adjoin positioning glues to left and right of template
    \!thToksEdef\!taDataColumnTemplate={%
      \the \!taLeftGlue
      \the \!taDataColumnTemplate
      \the \!taRightGlue}
    \ifnum \TracingFormats>0
      \!tfShowTemplates
    \fi
    % Adjoin data- and rule-column templates to preamble
    \!thToksEdef\!taPreamble={%
      \the\!taPreamble
      &
      \the\!taDataColumnTemplate
      &
      \the\!taRuleColumnTemplate}
  \fi
%
% START NEW COLUMN
  \advance \!taColumnNumber 1
  % Initialize data-column template, restoring last "regular" tabskip
  % after a "once only" tabskip
  \if!taOnceOnlyTabskip              
    \!thToksEdef\!taDataColumnTemplate={%
       ####\tabskip \the\!taLastRegularTabskip}
  \else
    \!taDataColumnTemplate{##}%
  \fi
  % Remaining initializations
  \!taRuleColumnTemplate{}% # is inserted by \SetVrule, or \SetAlternateVrule
  \!taLeftGlue{\hfil}%         % Default positioning is "center"
  \!taRightGlue{\hfil}%         
  \!taMinimumColumnWidth=0pt
  \def\!tfWidthText{}%
  \!taOnceOnlyTabskipfalse    % Set true by key "o"
  \ReadFormatKeys}

% UPDATE ROW OF WIDTHS
\def\!tfUpdateRowOfWidths{%
  % If user had a "w[<Text>]" key, set <Text> according to the 
  % template for this column, and find the width of the result
  \ifx \!tfWidthText\empty
  \else % set specified text according to current template & find width
    \!tfComputeMinColWidth
  \fi
  \edef\!tfRowOfWidths{%
    \!tfRowOfWidths
    &%
    \omit                                  % Data Column
    \ifdim \!taMinimumColumnWidth>0pt
      \hskip \the\!taMinimumColumnWidth
    \fi
    &
    \omit}}                                % Rule Column

% COMPUTE MINIMUM COLUMN WIDTH (from specified WidthText)
\def\!tfComputeMinColWidth{%
  \setbox0 =\vbox{%
    \ialign{% Plain's initialized \halign; \tabskip=0pt \everycr={}
       \span\the\!taDataColumnTemplate\cr
       \!tfWidthText\cr}}%
  \!taMinimumColumnWidth=\wd0 }

% SHOW (INITIAL) RULE TEMPLATE
\def\!tfShowRuleTemplate{%
  \!thMessage{}
  \!thMessage{TABLE FORMAT}
  \!thMessage{Column: Template}
  \!thMessage{%
    \space *c: ##\tabskip \the\LeftTabskip}
  \!taOldRuleColumnTemplate=\!taRuleColumnTemplate}

% SHOW TEMPLATES
\def\!tfShowTemplates{%
  \!thMessage{%
    \space \space r: \the\!taOldRuleColumnTemplate}
  \!taOldRuleColumnTemplate=\!taRuleColumnTemplate
  \!thMessage{%
    \ifnum \!taColumnNumber<10
      \space
    \fi
    \the\!taColumnNumber c: \the\!taDataColumnTemplate}
  \ifdim\!taMinimumColumnWidth>0pt
    \!thMessage{%
      \space \space w: \the\!taMinimumColumnWidth}
  \fi}
      

% FINISH UP: Invoked by the keys "." and \EndFormat
\def\!tfFinishFormat{%
  \ifnum \TracingFormats>0
    \!thMessage{%
      \space \space r: \the\!taOldRuleColumnTemplate
        \tabskip \the\RightTabskip}%
    \!thMessage{%
      \space *c: ##\tabskip 0pt}
  \fi
  \ifnum \!taColumnNumber<2
    \!thError{%
      \ifnum \!taColumnNumber=0
        No
      \else
        Only 1
      \fi
      "|"}%
      {\!thReadErrorMsg\!tfTooFewBarsA
       ^^J\!thReadErrorMsg\!tfTooFewBarsB
       ^^J\!thReadErrorMsg\!tkFixIt}%
  \fi
  \!thToksEdef\!taPreamble={%
    ####\tabskip\LeftTabskip 
    &
    \the\!taPreamble \tabskip\RightTabskip
    &
    ####\tabskip 0pt \cr}
  \ifnum \TracingFormats>1
    \!thMessage{Preamble=\the\!taPreamble}
  \fi
  \ifnum \TracingFormats>2
    \!thMessage{Row Of Widths="\!tfRowOfWidths"}
  \fi
  \!taBeginFormatfalse % Intercepts "|", tabskips, and "."
  \catcode`\|=13
  \catcode`\"=13
  \!ttDoHalign}

% ERROR MESSAGE FOR NOT ENOUGH "|"'s
\!thStoreErrorMsg\!tfTooFewBarsA{%
  There must be at least 2 "|"'s (and/or "\string \|"'s)}
\!thStoreErrorMsg\!tfTooFewBarsB{%
  between \string\BeginFormat\space and \string\EndFormat\space (or ".").}


% REFORMAT [<key letters>]{<text>}: Formats <text> according to
% <key letters>. Used to override the template for a column,
% or columns when used after \use.
\def\ReFormat[{%
  \omit
  \!taDataColumnTemplate{##}%
  \!taLeftGlue{}% 
  \!taRightGlue{}% 
  \catcode`\|=12  % Inhibit expansion if | immediately follows a <number>
  \catcode`\"=12  % read by \getvalue. Actually, '|' and '"' shouldn't
  \ReadFormatKeys}% appear in a \ReFormat cmd; this is here as a safeguard.

% END REFORMAT: Invoked by the key "]"
\def\!tfEndReFormat{%
  \ifnum \TracingFormats>0
    \!thMessage{ReF: 
       \the\!taLeftGlue
       \hbox{\the\!taDataColumnTemplate}%   White lie
       \the\!taRightGlue}
  \fi
  \catcode`\|=13
  \catcode`\"=13
  \!tfReFormat}

\def\!tfReFormat#1{%
  \the \!taLeftGlue
  \vbox{%
    \ialign{%
      \span\the\!taDataColumnTemplate\cr
       #1\cr}}%
  \the \!taRightGlue}



% *********************************************************************
% SECTION G: GET VALUE
% *********************************************************************

% GET_VALUE{<return macro>}<tokens> functions as follows:

% If <tokens> has the form <(stuff)>, then 
%    code=2   and   value=<stuff>

% Otherwise <tokens> has the form <DDDXYZ> where <DDD> denotes (a possibly
% empty) string of consecutive digits (0,1,2,...,9) terminated by the first 
% character <X> (possibly a blank) that is not a digit. In this case
%    code=1   and   value=<DDD>  (= <null>,  if <DDD> is non-empty).

% Examples:                         Code      Value
%  "\GetValue{\macro} 3"               1       null
%  "\GetValue{\macro}A "               1       null
%  "\GetValue{\macro}1 "               1          1
%  "\GetValue{\macro}25A"              1         25
%  "\GetValue{\macro}25012 "           1      25012
%  "\GetValue{\macro}(10pt)"           2       10pt
%  "\GetValue{\macro}(1in)"            2        1in
%  "\GetValue{\macro} (1in)"           1       null


% GET_VALUE{<macro to execute after value is found>} 
\def\!tgGetValue#1{%
  \def\!tgReturn{#1}%          Set return
  \futurelet\!ttemp\!tgCheckForParen}%  Now \!ttemp is the token 
                                    %  immediately after {}

% CHECK_PAREN: See if \!ttemp is a (
\def\!tgCheckForParen{%
  \ifx\!ttemp (%
    \!thx \!tgDoParen
  \else
    \!thx \!tgCheckForSpace
  \fi}

% DO_PAREN: Set code to 2, value to stuff inside ( )'s
\def\!tgDoParen(#1){%
  \def\!tgCode{2}%
  \def\!tgValue{#1}%     NOTE #1 MUST BE A LEGITIMATE VALUE
  \!tgReturn}

% CHECK_SPACE: See if \!ttemp is a <blank space>
\def\!tgCheckForSpace{%
  \def\!tgCode{1}%
  \def\!tgValue{}%           Initialize value to <null>
  \ifx\!ttemp\!thSpaceToken
    \!thx \!tgReturn        % <blank space> means no value was specified
  \else
    \!thx \!tgCheckForDigit         
  \fi}

% CHECK_DIGIT: \!ttemp is not a <blank space>; if its a digit (0,1,...,9)
% get the <number> starting with that digit.
\def\!tgCheckForDigit{%
  \!taDigitfalse
  \ifx 0\!ttemp
    \!taDigittrue
  \else
    \ifx 1\!ttemp
      \!taDigittrue
    \else
      \ifx 2\!ttemp
        \!taDigittrue
      \else
        \ifx 3\!ttemp
          \!taDigittrue
        \else
          \ifx 4\!ttemp
            \!taDigittrue
          \else
            \ifx 5\!ttemp
              \!taDigittrue
            \else
              \ifx 6\!ttemp
                \!taDigittrue
              \else
                \ifx 7\!ttemp
                  \!taDigittrue
                \else
                  \ifx 8\!ttemp
                    \!taDigittrue
                  \else
                    \ifx 9\!ttemp
                      \!taDigittrue
                    \fi
                  \fi
                \fi
              \fi
            \fi
          \fi
        \fi
      \fi
    \fi
  \fi
  \if!taDigit
    \!thx \!tgGetNumber
  \else
    \!thx \!tgReturn 
  \fi}

% GET_NUMBER
\def\!tgGetNumber{%
  \afterassignment\!tgGetNumberA
  \!taCountA=}
\def\!tgGetNumberA{%
  \edef\!tgValue{\the\!taCountA}%
  \!tgReturn}


% ********************************************************************
% MISCELANEOUS "RETURNS" FROM \getvalue
% ********************************************************************

% SET UP PAR BOX: Puts \BeginTableParBox{<user-specified \hsize>} 
% to the left of "#" and \EndTableParBox to the right of "#".
\def\!tgSetUpParBox{%
  \edef\!ttemp{%
    \noexpand \ReadFormatKeys
    b{\noexpand \BeginTableParBox{%
      \ifnum \!tgCode=1 
        \ifx \!tgValue\empty 
          \the\ColumnWidthFactor
        \else
          \!tgValue    % user-specified integer
        \fi
        \!taCWU        % \ColumnWidthUnit 
      \else 
        \!tgValue      % user-specified dimension
      \fi}}}%
  \!ttemp
  a{\EndTableParBox}}

% SET KERNS
\def\!tgInsertKern{%
  \edef\!ttemp{%
    \kern
    \ifnum \!tgCode=1 
      \ifx \!tgValue\empty 
        \the\KernFactor
      \else
        \!tgValue    % user-specified integer
      \fi
      \!taKU         % \KernUnit
    \else 
      \!tgValue      % user-specified dimension
    \fi}%
  \edef\!ttemp{%
    \noexpand\ReadFormatKeys
    \ifh@            % true if kern goes to left of "#"
      b{\!ttemp}
    \fi
    \ifv@            % true if kern goes to right of "#"
      a{\!ttemp}
    \fi}%
  \!ttemp}



% *********************************************************************
% SECTION K: KEYS
% *********************************************************************

% ****************************************************************
% DEFINING NEW KEYS
% ****************************************************************

% NEW FORMAT KEY <Key Letter>: Must be followed by 
%   <Parameter Text> <Replacement Text>
% Sets up a new key letter command by expanding (essentially) to
%   \expandafter \def \csname !tk<Key Letter>\endcsname
%     <Parameter Text>{<Replacement Text>}
% A warning message is issued if <Key Letter> is already in use.
\def\NewFormatKey#1{%
  \!thx\def\!thx\!ttempa\!thx{\string #1}%
  \!thx\def\!thx\!ttempb\!thx{\csname !tk<\!ttempa>\endcsname}%
  \ifnum \TracingKeys>0
    \!tkReportNewKey
  \fi
  \!thx\ifx \!ttempb \relax
    \!thx\!tkDefineKey
  \else 
    \!thx\!tkRejectKey
  \fi}

% REPORT NEW KEY
\def\!tkReportNewKey{%
  \!taToksA\!thx{\!ttempa}%  
  \!thMessage{NEW KEY: "\the\!taToksA"}}

% DEFINE KEY
\def\!tkDefineKey{%
  \!thx\def\!ttempb}%

% DUPLICATE KEY
\def\!tkRejectKey{%
    \!taToksA\!thx{\!ttempa}% 
    \!thError{Key letter "\the\!taToksA" already used}
      {\!thReadErrorMsg\!tkFixIt}
    \def\!tkGarbage}%

% ERROR MESSAGE FOR DUPLICATE KEY
\!thStoreErrorMsg\!tkFixIt{%
  You'd better type \space 'E' \space and fix your file.}


% ****************************************************************
% READING FORMAT KEYS
% ****************************************************************

% READ FORMAT KEYS
\def\ReadFormatKeys#1{%
  \!thx\def\!thx\!ttempa\!thx{\string #1}%
  \!thx\def\!thx\!ttempb\!thx{\csname !tk<\!ttempa>\endcsname}%
  \ifnum \TracingKeys>1
    \!tkReportKey
  \fi
  \!thx\ifx \!ttempb\relax 
    \!thx\!tkReplaceKey
  \else
    \!thx\!ttempb
  \fi}

% REPORT KEY
\def\!tkReportKey{%
  \!taToksA\!thx{\!ttempa}% 
  \!thMessage{KEY: "\the\!taToksA"}}

% REPLACE KEY
\def\!tkReplaceKey{%
  \!taToksA\!thx{\!ttempa}%
  \!thError {Undefined format key "\the\!taToksA"}
    {\!thReadErrorMsg\!tkUndefined ^^J\!thReadErrorMsg\!tkBadKey}
  \!tkReplaceKeyA}

\def\!tkReplaceKeyA{%
  \!thGetReplacement{\!thReadErrorMsg\!tkReplace}\!tkReplacement
  \!thx\ReadFormatKeys\!tkReplacement}

% ERROR MESSAGES FOR KEY RELACEMENT
\!thStoreErrorMsg\!tkUndefined{%
  The format key in " "'s on the next to top line is undefined.}
\!thStoreErrorMsg\!tkBadKey{%
  Type \space E \space to quit now, or
  \space<CR> \space and respond to next prompt.}
\!thStoreErrorMsg\!tkReplace{%
  Type \space<replacement key><CR> \space,
   or simply \space<CR> \space to skip offending key:}


% ****************************************************************
% PRIMITIVE KEYS
% ****************************************************************

% Key "b":  b{TOKENS} adds TOKENS to the left of (before) the template
\NewFormatKey b#1{%
  \!thx\!tkJoin\!thx{\the\!taDataColumnTemplate}{#1}%
  \ReadFormatKeys}

\def\!tkJoin#1#2{%
  \!taDataColumnTemplate{#2#1}}%

% Key "a":  a{TOKENS} adds TOKENS to the right of (after) the template
\NewFormatKey a#1{%
  \!taDataColumnTemplate\!thx{\the\!taDataColumnTemplate #1}%
  \ReadFormatKeys}

% Key "\{": Enclose template in braces.
\NewFormatKey \{{%
  \!taDataColumnTemplate=\!thx{\!thx{\the\!taDataColumnTemplate}}%
  \ReadFormatKeys}

% Key "*":  "*{N}{KEY LETTERS}" is equivalent to specifying  
% <KEY LETTERS>  N  times.
% KEY LETTERS may contain further * specifications
\NewFormatKey *#1#2{%
  \!taCountA=#1\relax
  \!taToksA={}%
  \!thLoop 
    \ifnum \!taCountA > 0
    \!taToksA\!thx{\the\!taToksA #2}%
    \advance\!taCountA -1
  \repeat 
  \!thx\ReadFormatKeys\the\!taToksA}


% ****************************************************************
% POSITIONING KEYS
% ****************************************************************

% Key "\LeftGlue": Specifies the glue (usually \hfil, or nothing) to be
% added to extreme left of the template to position a column
\NewFormatKey \LeftGlue#1{%
  \!taLeftGlue{#1}%
  \ReadFormatKeys}

% Key "\RightGlue": Specifies the glue (usually \hfil, or nothing) to be
% added to the extreme right of the template to position a column
\NewFormatKey \RightGlue#1{%
  \!taRightGlue{#1}%
  \ReadFormatKeys}

% Key "c": Centered column.
\NewFormatKey c{%
  \ReadFormatKeys 
  \LeftGlue\hfil
  \RightGlue\hfil}

% Key "l": Left-adjusted column.
\NewFormatKey l{%
  \ReadFormatKeys 
  \LeftGlue{}   % In case more than one positioning key is specified.
  \RightGlue\hfil}

% Key "r": Right-adjusted column.
\NewFormatKey r{%
  \ReadFormatKeys 
  \LeftGlue\hfil
  \RightGlue{}}

% Key "k": Adds kerns to left and right of "#"
% This key and the two below use Plain TeX's \if@h as if it were \if@left,
% and \if@v as if it were \if@right. Table making goes on in a group,
% so even in the unlikely circumstance that a \phantom is currently under
% construction, there's no problem.
\NewFormatKey k{%
  \h@true
  \v@true
  \!tgGetValue{\!tgInsertKern}}

% Key "i": Adds a kern to the left of "#"
\NewFormatKey i{%
  \h@true
  \v@false
  \!tgGetValue{\!tgInsertKern}}
  
% Key "j": Adds a kern to the right of "#"
\NewFormatKey j{%
  \h@false
  \v@true
  \!tgGetValue{\!tgInsertKern}}
  

% ****************************************************************
% NUMERIC ITEM KEYS
% ****************************************************************

% Key "n": numeric item , non-math mode. 
\NewFormatKey n{%
  \def\!tnStyle{}%
   \futurelet\!tnext\!tnTestForBracket}

% Key "N": numeric item, math mode.
\NewFormatKey N{%
  \def\!tnStyle{$}%
   \futurelet\!tnext\!tnTestForBracket}


% ****************************************************************
% ATTRIBUTE KEYS
% ****************************************************************

% Key "m": Math mode.
\NewFormatKey m{%
  \ReadFormatKeys b$ a$}

% Key "M": Displaymath mode.
\NewFormatKey M{%
  \ReadFormatKeys \{ b{$\displaystyle} a$}

% Key "\m": Template ${}#\hfil$
\NewFormatKey \m{%
  \ReadFormatKeys l b{{}} m}

% Key "\M": Template $\displaystyle{{}#\hfil}$
\NewFormatKey \M{%
  \ReadFormatKeys l b{{}} M}

% Key "f":  Set font  (E.g., f\it sets up italic font (assuming \it
% has its usual meaning)
\NewFormatKey f#1{%
  \ReadFormatKeys b{#1}}

% Key "B": abbreviation for f\bf
\NewFormatKey B{%
  \ReadFormatKeys f\bf}

% Key "I": abbreviation for f\it
\NewFormatKey I{%
  \ReadFormatKeys f\it}

% Key "S": abbreviation for f\sl
\NewFormatKey S{%
  \ReadFormatKeys f\sl}

% Key "R": abbreviation for f\rm
\NewFormatKey R{%
  \ReadFormatKeys f\rm}

% Key "T": abbreviation for f\tt
\NewFormatKey T{%
  \ReadFormatKeys f\tt}

% Key "p": ParBox
\NewFormatKey p{%
  \!tgGetValue{\!tgSetUpParBox}}


% ****************************************************************
% MINIMUM COLUMN WIDTH KEY
% ****************************************************************

% Key "w": minimum column width
\NewFormatKey w{%
  \!tkTestForBeginFormat w{\!tgGetValue{\!tfSetWidth}}}


% ****************************************************************
% TABSKIP KEYS
% ****************************************************************

% Key "s": Set tabskip for the inter-column space to the right
% of the current column, and all subsequent spaces, until overriden
% by a new "s" or "o" key.
\NewFormatKey s{%
  \!taOnceOnlyTabskipfalse    % in case same column has a prior "o" key
  \!tkTestForBeginFormat t{\!tgGetValue{\!tfSetTabskip}}}

% Key "o": Apply the \tabskip stated for this column ONLY to the
% inter-column space just to the right of this column; restore the
% the previous \tabskip for subsequent columns. 
\NewFormatKey o{%
  \!taOnceOnlyTabskiptrue
  \!tkTestForBeginFormat o{\!tgGetValue{\!tfSetTabskip}}}


% ****************************************************************
% RULE KEYS
% ****************************************************************

% Key "|": Standard rule column designator
\NewFormatKey |{%
  \!tkTestForBeginFormat |{\!tgGetValue{\!tfSetVrule}}}

% Key "\|": Non-standard rule column designator
\NewFormatKey \|{%
  \!tkTestForBeginFormat \|{\!tfSetAlternateVrule}}


% ****************************************************************
% END-OF-FORMAT KEYS
% ****************************************************************

% Key ".":  PERIOD -- end of \BeginFormat section.
\NewFormatKey .{%
  \!tkTestForBeginFormat.{\!tfFinishFormat}} 

% Key "\EndFormat": Equivalent to "."
\NewFormatKey \EndFormat{%
  \!tkTestForBeginFormat\EndFormat{\!tfFinishFormat}} 

% Key "]": End of \ReFormat section
\NewFormatKey ]{%
  \!tkTestForReFormat ] \!tfEndReFormat}


% ****************************************************************
% VALIDITY CHECKS
% ****************************************************************

% TEST FOR BEGIN FORMAT{<Key>}{Intended Action}: This test is run
% on keys that can only be used by \BeginFormat ---  "s",  "o",
% "|",  "\|",  "w",  ".",  and  "\EndFormat".
\def\!tkTestForBeginFormat#1#2{% 
  \if!taBeginFormat  
    \def\!ttemp{#2}%
    \!thx \!ttemp    
  \else
    \toks0={#1}%  
    \toks2=\!thx{\string\ReFormat}%
    \!thx \!tkImproperUse
  \fi}   

% TEST FOR RE FORMAT{<Key>}{Intended Action}: This test is run
% on the key "]", which can only be used by \ReFormat.
\def\!tkTestForReFormat#1#2{% 
  \if!taBeginFormat  
    \toks0={#1}%  
    \toks2=\!thx{\string\BeginFormat}%
    \!thx \!tkImproperUse
  \else
    \def\!ttemp{#2}%
    \!thx \!ttemp    
  \fi}   

% IMPROPER USE OF KEY
\def\!tkImproperUse{% 
  \!thError{\!thReadErrorMsg\!tkBadUseA "\the\toks0 "}%
    {\!thReadErrorMsg\!tkBadUseB \the\toks2 \space command.
    ^^J\!thReadErrorMsg\!tkBadKey}%
  \!tkReplaceKeyA}
 
% ERROR MESSAGES FOR IMPROPER USE OF KEY 
\!thStoreErrorMsg\!tkBadUseA{Improper use of key }  
\!thStoreErrorMsg\!tkBadUseB{% 
  The key mentioned above can't be used in a }



% *********************************************************************
% SECTION n: NUMERIC
% *********************************************************************

% NOTE: THE SPACE BETWEEN A NUMERIC ENTRY AND THE FOLLOWING '|', '"', 
%   OR '\|' IS MANDATORY.
% EMPTY NUMERIC ENTRIES ARE NOT ALLOWED: USE '{}' OR '\omit' INSTEAD.

% TEST FOR BRACKET: Invoked by the keys "n" and "N".
\def\!tnTestForBracket{%
  \ifx [\!tnext
    \!thx\!tnGetArgument
  \else
    \!thx\!tnGetCode
  \fi}

% GET CODE: E.g. "4", or "4.0", "0.4", or "10.2"
\def\!tnGetCode#1 {%  NOTE THE BLANK
  \!tnConvertCode #1..!}

% CONVERT CODE: E.g. converts above to [0000], [0000.], [.0000],
% [0000000000.00]
\def\!tnConvertCode #1.#2.#3!{%
  \begingroup
    \aftergroup\edef \aftergroup\!ttemp \aftergroup{%
      \aftergroup[% 
      \!taCountA #1
      \!thLoop
        \ifnum \!taCountA>0
        \advance\!taCountA -1
        \aftergroup0
      \repeat
      \def\!ttemp{#3}%
      \ifx\!ttemp \empty
      \else
        \aftergroup.
        \!taCountA #2
        \!thLoop 
          \ifnum \!taCountA>0
          \advance\!taCountA -1
          \aftergroup0
        \repeat
      \fi 
      \aftergroup]\aftergroup}%
    \endgroup\relax
    \!thx\!tnGetArgument\!ttemp}
  
% GET ARGUMENT: [<sample left field> <optional .<sample right field>>
\def\!tnGetArgument[#1]{%
  \!tnMakeNumericTemplate\!tnStyle#1..!}

% MAKE NUMERIC TEMPLATE
\def\!tnMakeNumericTemplate#1#2.#3.#4!{%  #1=<empty> or $
  \def\!ttemp{#4}%
  \ifx\!ttemp\empty
    \!taDimenC=0pt
  \else
    \setbox0=\hbox{\m@th #1.#3#1}%
    \!taDimenC=\wd0
  \fi
  \setbox0 =\hbox{\m@th #1#2#1}%
  \!thToksEdef\!taDataColumnTemplate={%
    \noexpand\!tnSetNumericItem
    {\the\wd0 }%
    {\the\!taDimenC}%
    {#1}%
    \the\!taDataColumnTemplate}  % Might have tabskip glue in here
  \ReadFormatKeys}

% SET NUMERIC ITEM
\def\!tnSetNumericItem #1#2#3#4 {%             NOTE THE BLANK
  \!tnSetNumericItemA {#1}{#2}{#3}#4..!}

\def\!tnSetNumericItemA #1#2#3#4.#5.#6!{%
  \def\!ttemp{#6}%
  \hbox to #1{\hss \m@th #3#4#3}%
  \hbox to #2{%
    \ifx\!ttemp\empty
    \else
       \m@th #3.#5#3%
    \fi
    \hss}}



% *********************************************************************
% SECTION S: STRUTS
% *********************************************************************

% The following are in ALLOCATIONS
  %\newdimen\StrutUnit (normal value \normalbaselineskip / 11)
  %\newcount\StrutHeightFactor (normal value 8)
  %\newcount\StrutDepthFactor  (normal value 3)

% MAKE STRUT OF SPECIFIED HEIGHT AND DIMENSION
% \MakeStrut <height><depth>; height and depth are <dimen>'s
\def\MakeStrut#1#2{%
  \vrule width0pt height #1 depth #2}

% STANDARD VERTICAL STRUT
% Makes a strut of height=StrutHeightFactor*StrutUnit
%                  depth =StrutDepthFactor *StrutUnit
\def\StandardTableStrut{%
  \MakeStrut{\StrutHeightFactor\StrutUnit}
    {\StrutDepthFactor\StrutUnit}}


% STANDARD VERTICAL STRUT, WITH EXTRA HEIGHT/DEPTH
% \AugmentedTableStrut<multiple for extra height><multiple for extra depth>
%   makes a strut of height=(StrutHeightFactor+#1)*StrutUnit
%                    depth =(StrutDepthFactor+#2)*StrutUnit
\def\AugmentedTableStrut#1#2{%
  \dimen@=\StrutHeightFactor\StrutUnit
  \advance\dimen@ #1\StrutUnit
  \dimen@ii=\StrutDepthFactor\StrutUnit
  \advance\dimen@ii #2\StrutUnit
  \MakeStrut{\dimen@}{\dimen@ii}}


% ENLARGE<extra height><extra depth><original>
% Enlarges "original" by extra height and extra depth.
% Extra height and extra depth are <dimen>'s.
% Works for various math styles, and takes into account
%   \spacefactor in horizontal mode
\def\Enlarge#1#2{%  3rd argument is picked up later
  % #1=extra height
  % #2=extra depth
  \!taDimenA=#1\relax
  \!taDimenB=#2\relax
  \let\!TsSpaceFactor=\empty
  \ifmmode
    \!thx \mathpalette
    \!thx \!TsEnlargeMath
  \else
    \!thx \!TsEnlargeOther
  \fi}

\def\!TsEnlargeOther#1{%
  \ifhmode
    \setbox\z@=\hbox{#1%
      \xdef\!TsSpaceFactor{\spacefactor=\the\spacefactor}}%
  \else
    \setbox\z@=\hbox{#1}%
  \fi
  \!TsFinishEnlarge}
    
\def\!TsEnlargeMath#1#2{%
  \setbox\z@=\hbox{$\m@th#1{#2}$}%
  \!TsFinishEnlarge}

\def\!TsFinishEnlarge{%
  \dimen@=\ht\z@
  \advance \dimen@ \!taDimenA
  \ht\z@=\dimen@
  \dimen@=\dp\z@
  \advance \dimen@ \!taDimenB
  \dp\z@=\dimen@
  \box\z@ \!TsSpaceFactor{}}


% ENLARGE BY MULTIPLES OF StrutUnit
% \enlarge<multiple for extra height><multiple for extra depth><original>
% Enlarges by (multiple for extra heigth)*StrutUnit
%   and       (multiple for extra depth) *StrutUnit
\def\enlarge#1#2{%  3rd argument is picked up later
  \Enlarge{#1\StrutUnit}{#2\StrutUnit}}


% OPENUP#1#2: increases strut height and depth factors by #1 and #2.
\def\OpenUp#1#2{%
  \advance \StrutHeightFactor #1\relax
  \advance \StrutDepthFactor #2\relax}



% *********************************************************************
% SECTION T: TABLES
% *********************************************************************

% Table-making is initiated by \BeginTable. After processing that
% command, TeX absorbs the instructions in the prologue to the table
% until it gets to \BeginFormat. \BeginFormat sets up the preamble
% for the \halign that will be used to create the table. \EndFormat
% initiates the \halign-ment, which is terminated by \EndTable.


% *********************************************************************
% BEGIN TABLE, (DO HALIGN), END TABLE
% *********************************************************************
% BEGIN TABLE
\def\BeginTable{%
  \futurelet\!tnext\!ttBeginTable}

\def\!ttBeginTable{%
  \ifx [\!tnext
    \def\!tnext{\!ttBeginTableA}%
  \else 
    \def\!tnext{\!ttBeginTableA[c]}%
  \fi
  \!tnext}

\def\!ttBeginTableA[#1]{%
  \if #1u%                  % "unboxed" table
    \ifmmode                 
      \def\!ttEndTable{%    % user had better be in display math mode
        \relax}%            %   and have only one table at the outer level
    \else                   % user had better be in vertical mode
      \bgroup
      \def\!ttEndTable{%
        \egroup}%
    \fi
  \else
    \hbox\bgroup $
    \def\!ttEndTable{%
      \egroup %   for the \vtop, \vbox, or \vcenter, yet to come
      $%          for math mode
      \egroup}%   for the \hbox
    \if #1t%
      \vtop
    \else
      \if #1b%
        \vbox
      \else
        \vcenter % math mode was essential for this
      \fi
    \fi
    \bgroup      % for the \vtop, \vbox, or \vcenter
  \fi
  \advance\!taRecursionLevel 1 % RecursionLevel governs initialization
  \let\!ttRightGlue=\relax  % This may be changed by \JustCenter, etc
  \everycr={}
  \ifnum \!taRecursionLevel=1
    \!ttInitializeTable
  \fi}

% INITIALIZE TABLE
\bgroup
  \catcode`\|=13
  \catcode`\"=13
  \catcode`\~=13
  \gdef\!ttInitializeTable{%
    \let\!ttTie=~ %                         Meanings of ~ and \- are
    \let\!ttDH=\- %                           restored by \BeginTableParBox
    \catcode`\|=\active
    \catcode`\"=\active
    \catcode`\~=\active
    \def |{\unskip\!ttRightGlue&&}%         Use rule-column template
    \def\|{\unskip\!ttRightGlue&\omit\!ttAlternateVrule}% 
    %                                       Override rule-column template
    \def"{\unskip\!ttRightGlue&\omit&}%     Omit rule-column template
    \def~{\kern .5em}%                      ~ now has the width of a digit
    \def\\{\!ttEndOfRow}%
    \def\-{\!ttShortHrule}%
    \def\={\!ttLongHrule}%
    \def\_{\!ttFullHrule}%
    \def\Left##1{##1\hfill\null}%           \null prevents \unskip from
    \def\Center##1{\hfill ##1\hfill\null}%    killing the \hfill
    \def\Right##1{\hfill##1}%
    \def\use{\!ttuse}%
    \def\Use{\!ttUse}%
    \the\EveryTable}
\egroup

\let\!ttRightGlue=\relax  % This may be changed, in a group, by 
                          %   \JustCenter, etc

% DO HALIGN: Invoked by END FORMAT (or the key ".")
\def\!ttDoHalign{%
  \baselineskip=0pt \lineskiplimit=0pt \lineskip=0pt %
  \tabskip=0pt
  \halign \the\!taTableSpread \bgroup
   \span\the\!taPreamble
   \ifx \!tfRowOfWidths \empty
   \else 
     \!tfRowOfWidths \cr % 
   \fi}

% END TABLE
\def\EndTable{%
  \egroup % finishes the \halign
  \!ttEndTable}%    closes off the table envirnoment set up by \BeginTable


% *********************************************************************
% END OF ROW PROCESSING
% *********************************************************************

% END OF ROW: When followed by
%   0, inserts no strut
%   +, inserts an AugmentedTableStrut (with <x-height> and <x-depth> 
%      as arguments
%   anything else, inserts a StandardTableStrut,
% and finished off the row with a \cr. 
\def\!ttEndOfRow{%
  \futurelet\!tnext\!ttTestForBlank}

% TEST FOR BLANK
\def\!ttTestForBlank{%
%  \!thMessage{At Test For Blank: \meaning\!tnext}
  \ifx \!tnext\!thSpaceToken  % the "usual" case
    \!thx\!ttDoStandard
  \else
    \!thx\!ttTestForZero
  \fi}
  
% TEST FOR ZERO
\def\!ttTestForZero{%
  \ifx 0\!tnext
    \!thx \!ttDoZero
  \else
    \!thx \!ttTestForPlus
  \fi}

% TEST FOR PLUS
\def\!ttTestForPlus{%
  \ifx +\!tnext
    \!thx \!ttDoPlus
  \else
    \!thx \!ttDoStandard
  \fi}

% DO ZERO: No strut
\def\!ttDoZero#1{% #1 eats the 0
  \cr} 

% DO PLUS: Insert "Extra" strut; #2=extra height, #3=extra depth, both
% as integers (units of \StrutUnit)
\def\!ttDoPlus#1#2#3{% #1 eats the +
  \AugmentedTableStrut{#2}{#3}%
  \cr} 

% DO STANDARD: Insert standard table strut
\def\!ttDoStandard{% 
  \StandardTableStrut
  \cr}


% *********************************************************************
% ALTERNATE VRULES
% *********************************************************************

% A '\|' can appear in a rule-column in place of a '|', '"', or '&'.
 
% If '\|' is immediately followed by a blank, a string of digits, or
% (...) [... had better be a <dimen>], a \vrule is placed in the
% rule column; the thickness of the \vrule follows TABLE's usual
% conventions. Be sure to put a blank after a string of digits.

% If '\|' is immediately followed by a '*', a user-specified default
% "pseudo"-rule is placed in the rule column. This P.R. is specified
% by the parameterless macro \PseudoVrule. For example, 
% to place a "double rule" into a rule column, you could make the definition
%   \def\PseudoVrule{\hfil\vrule \hskip1pt \vrule\hfil}

% If none of the above cases applies, a non-space token follows '\|':
% that token is placed in the rule-column. To put a '*' in a
% rule-column, enter '\|{*}'. '\|\PseudoVrule' has the same effect
% as '\|*'. 

% ALTERNATE VRULE
\def\!ttAlternateVrule{%
  \!tgGetValue{\!ttAVTestForCode}}  % AV == Alternate Vrule

% TEST FOR CODE (2)
\def\!ttAVTestForCode{%
  \ifnum \!tgCode=2              % (...) follows "\|"
    \!thx\!ttInsertVrule         % \InsertVrule ends with "&"
  \else
    \!thx\!ttAVTestForEmpty
  \fi}

% TEST FOR EMPTY (VALUE)
\def\!ttAVTestForEmpty{%
  \ifx \!tgValue\empty           % non-digit after "\|"
    \!thx\!ttAVTestForBlank
  \else
    \!thx\!ttInsertVrule         % integer after "\|"
  \fi}

% TEST FOR BLANK
\def\!ttAVTestForBlank{%
  \ifx \!ttemp\!thSpaceToken     % blank after "\|"
    \!thx\!ttInsertVrule
  \else
    \!thx\!ttAVTestForStar 
  \fi}

% TEST FOR STAR
\def\!ttAVTestForStar{%
  \ifx *\!ttemp                  % "*" after "\|"
    \!thx\!ttInsertDefaultPR     % PR == pseudo-rule
  \else
    \!thx\!ttGetPseudoVrule       % "Anything else" after "\|"
  \fi}

% INSERT VRULE
\def\!ttInsertVrule{%
  \hfil 
  \vrule \!thWidth
    \ifnum \!tgCode=1
      \ifx \!tgValue\empty 
        \LineThicknessFactor
      \else
        \!tgValue
      \fi
      \LineThicknessUnit
    \else
      \!tgValue
    \fi
  \hfil
  &}

% INSERT DEFAULT PSEUDO-RULE
\def\!ttInsertDefaultPR*{%
  \PseudoVrule    % User-specified default pseudo-rule
  &}

% GET PSEUDO-RULE
\def\!ttGetPseudoVrule#1{%
  \toks0={#1}%
  #1&}

% DEFAULT PSEUDO-RULE
\def\PseudoVrule{}


% *********************************************************************
% USE: Version of \multispan for rule-&-column tables
% *********************************************************************

% USE 
% \use <number> spans the next <number> data columns. 
\def\!ttuse#1{%
  \ifnum #1>\@ne 
    \omit 
    \mscount=#1 %        \mscount is in Plain
    \advance\mscount by \m@ne
    \advance\mscount by \mscount
    \!thLoop 
      \ifnum\mscount>\@ne 
      \sp@n %            from Plain (\span\omit \advance\mscount\m@ne)
    \repeat 
    \span 
  \fi}

\def\!ttUse#1[{%
  \!ttuse{#1}%
  \ReFormat[}


% *********************************************************************
% HRULES
% *********************************************************************

% FULL HORIZONTAL RULE: Draws a rule across the table, 
% using \noalign{\hrule}
\def\!ttFullHrule{%
  \noalign
  \bgroup
  \!tgGetValue{\!ttFullHruleA}}

\def\!ttFullHruleA{%
  \!ttGetHalfRuleThickness % Sets \dimen0 to half of specified thickness
  \hrule \!thHeight \dimen0 \!thDepth \dimen0
  \penalty0 % so can break an ``unboxed'' table after a horizontal rule.
  \egroup} % ends the \noalign

% SHORT HORIZONTAL RULE: Draws a rule across 1 (or more) columns,
% using \leaders; this rule doesn't extend across the neighboring
% tabskip glues to join up with adjacent rule columns. By contrast
% the LONG HORIZONTAL RULE below does just that.
\def\!ttShortHrule{%
  \omit
  \!tgGetValue{\!ttShortHruleA}}

\def\!ttShortHruleA{%
  \!ttGetHalfRuleThickness % Sets \dimen0 to half of specified thickness
  \leaders \hrule \!thHeight \dimen0 \!thDepth \dimen0 \hfill
  \null    % prevents an \unskip from annihilating the \leaders
  \ignorespaces} 

% LONG HORIZONTAL RULE: This rule requires special coding. 
% It must be preceded and followed by '&', instead of the usual
% '|' or '"'. However, '\_' can follow '\use' in the usual manner.
% And in fact, to insert long-rules in two or more contiguous columns,
% '\use' MUST be used with an argument = total number of columns involved.
\def\!ttLongHrule{%
  \omit\span\omit\span \!ttShortHrule}

% GET RULE THICKNESS
\def\!ttGetHalfRuleThickness{%
  \dimen0 =
    \ifnum \!tgCode=1
      \ifx \!tgValue\empty
        \LineThicknessFactor
      \else
        \!tgValue    % user-specified integer
      \fi
      \LineThicknessUnit
    \else
      \!tgValue      % user-specified dimension
    \fi
  \divide\dimen0 2 }


% *********************************************************************
% STRETCHING AND SHRINKING A TABLE
% *********************************************************************

% SET TABLE TO WIDTH <dimen>
\def\SetTableToWidth#1{%
  \!taTableSpread={to #1}}

% WIDEN TABLE BY <dimen>
\def\WidenTableBy#1{%
  \ifdim #1=0pt
    \!taTableSpread={}%
  \else
    \!taTableSpread={spread #1}%
  \fi}

\def\Expand{%
  \SetTableToWidth{\hsize}}%

\def\LongLines{%
  \LeftTabskip =0pt plus 1fill
  \RightTabskip=\LeftTabskip
  \Expand}


% *********************************************************************
% REPOSITIONING COMMANDS (\JUSTLEFT, etc.)
% *********************************************************************

\def\JustLeft{%
  \omit \let\!ttRightGlue=\hfill}
\def\JustCenter{%
  \omit \hfill\null \let\!ttRightGlue=\hfill}
\def\JustRight{%
  \omit \hfill\null}


% *********************************************************************
% Restore meaning of \\, and reset category codes
% *********************************************************************
\let\\=\!tacr
\catcode`\!=12
\catcode`\@=12



