% \iffalse meta-comment
%
% Copyright (C) 2011 by Kevin W. Hamlen
% -------------------------------------
%
% This file may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3a 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.3a or later is part of all distributions of
% LaTeX version 2004/10/01 or later.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{trfrac.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{trfrac}
%<*package>
  [2011/5/20 v2.3 Tree Fraction Package]
%</package>
%
%<*driver>
\documentclass{ltxdoc}
\usepackage{amsmath}
\usepackage{hyperref}
\usepackage{trfrac}
\newcount\seclevel%
\newcommand{\getseclevel}{%
  \global\seclevel=3\relax%
  \ifnum\arabic{subsection}=0\global\seclevel=2\relax\fi%
}
{\catcode`/=0 \catcode`\\=11
  /gdef/DescMacro#1{%
    /getseclevel%
    /pdfbookmark[/the/seclevel]{\\#1}{macdef-#1}%
    /expandafter/DescribeMacro/expandafter{/csname #1/endcsname}%
    /hyperdef{macro}{#1}{}/kern0pt%
  }
}
\newcommand{\DescEnv}[1]{%
  \getseclevel%
  \pdfbookmark[\the\seclevel]{#1}{envdef-#1}%
  \DescribeEnv{#1}%
  \hyperdef{env}{#1}{}\kern0pt%
}
\newcommand{\mac}[1]{{\tt\hyperlink{macro.#1}{\char92 #1}}}
\newcommand{\env}[1]{{\tt\hyperlink{env.#1}{#1}}}
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
  \DocInput{trfrac.dtx}
\end{document}
%</driver>
% \fi
%
% \CheckSum{412}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
% \changes{v1.0}{2005/09/05}{Initial version}
% \changes{v2.0}{2006/05/01}{Renamed to TrFrac package}
%
% \DoNotIndex{\@depth,\@height,\@width}
% \DoNotIndex{\advance,\begingroup,\bgroup,\box,\def,\dp,\egroup,\else}
% \DoNotIndex{\endgroup,\fi,\fontdimen,\futurelet,\global}
% \DoNotIndex{\hb@xt@,\hbox,\hfil,\hss,\ht,\ifdim,\ifmmode,\ifnum,\ifx}
% \DoNotIndex{\kern,\let,\m@th,\newcommand,\newenvironment,\newif}
% \DoNotIndex{\null,\offinterlineskip,\p@,\PackageError,\penalty}
% \DoNotIndex{\protect,\raise,\relax,\setbox,\space,\strut}
% \DoNotIndex{\textfont,\thr@@,\tw@,\unhbox,\vbox,\vrule,\vtop,\wd,\z@}
%
% \GetFileInfo{trfrac.dtx}
%
% \title{The \textsf{trfrac} package\thanks{This document corresponds to
%    \textsf{trfrac}~\fileversion, dated~\filedate.}}
% \author{Kevin W.~Hamlen}
%
% \maketitle
%
% \begin{abstract}
% The |trfrac| package provides convenient mechanisms for typesetting
% derivation trees in \LaTeX.
% Derivation trees look like nested fractions; thus, the primary contribution
% of this software is a macro |\trfrac| that functions much like \LaTeX's
% |\frac| for fractions, but with a number of important differences that make
% it better suited to tree-like structures.
% \end{abstract}
%
% \section{Introduction}
%
% Typing rules and typing derivations in formal typing systems are usually
% written like fractions in which the numerator consists of one or more
% premise judgments or derivations, and the denominator consists of a
% single conclusion judgment.
% For example, the typing rule for application in the simply-typed lambda
% calculus is typically written
% \[ \trfrac[\small(\emph{app})]
%           {\Gamma \vdash e_1:\tau\rightarrow\tau' \qquad
%            \Gamma \vdash e_2:\tau}
%           {\Gamma \vdash e_1 e_2 : \tau'} \]
% where $\Gamma \vdash e_1:\tau\rightarrow\tau'$ and $\Gamma \vdash e_2:\tau$
% are the two premise judgments of the rule, and
% $\Gamma \vdash e_1 e_2 : \tau'$ is the conclusion judgment.
%
% Simple rules like the above are easy to typeset with \LaTeX's built-in
% |\frac| macro, or with fraction macros like |\dfrac| provided by the
% |amslatex| package; but when derivations consist of a tree of nested rules,
% |\frac| and |\dfrac| often prove inadequate because they yield spacing
% and alignment that is unsuited to derivation trees.
% For example, consider the derivation
% \[ \trfrac[\small(\emph{app})]
%           {\Gamma \vdash e_1:\tau\rightarrow\tau' \qquad
%            \trfrac[\small(\emph{app})]
%                   {\Gamma \vdash e_2:\tau''\rightarrow\tau \qquad
%                    \Gamma \vdash e_3:\tau''}
%                   {\Gamma \vdash e_2 e_3:\tau}}
%           {\Gamma \vdash e_1 (e_2 e_3):\tau'} \]
% which contains a nested subderivation of one of its premise judgments.
% This was easily typeset using the |\trfrac| macro provided by
% the |trfrac| package.
% The complete \LaTeX\ code is as follows:
% \begin{verbatim}
% \[ \trfrac[\small(\emph{app})]
%           {\Gamma \vdash e_1:\tau\rightarrow\tau' \qquad
%             \trfrac[\small(\emph{app})]
%                    {\Gamma \vdash e_2:\tau''\rightarrow\tau \qquad
%                     \Gamma \vdash e_3:\tau''}
%                    {\Gamma \vdash e_2 e_3:\tau}}
%           {\Gamma \vdash e_1 (e_2 e_3):\tau'} \]
% \end{verbatim}
% In contrast, if one writes analogous code using |\dfrac| instead of
% |\trfrac|, the result is
% \[ \dfrac{\Gamma \vdash e_1:\tau\rightarrow\tau' \qquad
%           \dfrac{\Gamma \vdash e_2:\tau''\rightarrow\tau \qquad
%                  \Gamma \vdash e_3:\tau''}
%                 {\Gamma \vdash e_2 e_3:\tau}\text{\small(\emph{app})}}
%          {\Gamma \vdash e_1 (e_2 e_3):\tau'}\text{\small(\emph{app})} \]
% which is unsuitable for two reasons:
% First, the leftmost premise is floating up above the fraction bar when
% it should be sitting on the bar.
% Second, the bottom fraction bar is longer than it should be; it has been
% unnecessarily extended rightward to span the entire ``numerator'' of the
% ``fraction''.
% This can become problematic when derivations are large and horizontal
% space is at a premium.
%
% In addition to providing |\trfrac| as an alternative to fraction macros,
% the |trfrac| package also provides two environments that can be helpful
% for squeezing numerous and/or lengthy premise judgments into a smaller
% amount of horizontal space.
% Derivations can sometimes contain long judgments that must be wrapped, or
% numerous premise judgments that must be placed above one another for lack
% of space.
% The |trfrac| package provides math environments |trgather| and |tralign|
% for stacking sets of judgments vertically within a derivation tree.
% The |trgather| environment horizontally centers each judgment in the stack,
% whereas the |tralign| environment aligns each judgment at a specified point.
% For example, the derivation
% \[ \trfrac[\small(\emph{case})]
%           {\begin{trgather}
%              \Gamma \vdash e:\tau_1+\tau_2 \\
%              \Gamma[x_1\mapsto\tau_1] \vdash e_1:\tau \qquad
%              \Gamma[x_2\mapsto\tau_2] \vdash e_2:\tau
%            \end{trgather}}
%           {\begin{tralign}
%              \Gamma \vdash \mathbf{case}~e~\mathbf{of}~
%                  &\mathit{in}_1(x_1)\Rightarrow e_1 \\
%              \mid\,&\mathit{in}_2(x_2)\Rightarrow e_2 : \tau
%            \end{tralign}} \]
% can be produced with
% \begin{verbatim}
% \[ \trfrac[\small(\emph{case})]
%           {\begin{trgather}
%              \Gamma \vdash e:\tau_1+\tau_2 \\
%              \Gamma[x_1\mapsto\tau_1] \vdash e_1:\tau \qquad
%              \Gamma[x_2\mapsto\tau_2] \vdash e_2:\tau
%            \end{trgather}}
%           {\begin{tralign}
%              \Gamma \vdash \mathbf{case}~e~\mathbf{of}~
%                  &\mathit{in}_1(x_1)\Rightarrow e_1 \\
%              \mid\,&\mathit{in}_2(x_2)\Rightarrow e_2 : \tau
%            \end{tralign}} \]
% \end{verbatim}
%
% The |split| and |aligned| environments provided by the |amsmath| package
% provide facilities for vertically stacking sub-equations in similar ways,
% but like |\dfrac|, these often prove inadequate for derivation trees
% because they vertically center the material they typeset, causing any
% adjacent material to float above the fraction bar.
%
% \section{Usage}
%
% To start using the macros and environments provided by the |trfrac| package,
% place the line
%
% \medskip{\narrower|\usepackage{trfrac}|}\medskip
%
% \noindent
% somewhere near the top of your \TeX\ file.
%
% \DescMacro{trfrac}
% Subsequently, within any math environment you can use
%
% \medskip{\narrower
%   |\trfrac[|\meta{name}|]{|\meta{premises}|}{|\meta{consequent}|}|
% }\medskip
%
% \noindent
% to typeset a derivation rule, where
% \meta{name} is optional material processed in horizontal text mode
% that is to sit to the right of the fraction bar,
% \meta{premises} is math material that is to sit above the fraction bar, and
% \meta{consequent} is math material that is to sit below the fraction bar.
% The \meta{consequent} and \meta{name} may not contain additional |\trfrac|
% macros, but the \meta{premises} may.
%
% The outermost |\trfrac| in a derivation is vertically centered on its
% fraction bar, but inner |\trfrac|'s in a derivation have baselines at
% the bottoms of their consequents.
% This makes it possible to typeset something like
% \[ {\cal D} =
%    \trfrac[\small(\emph{app})]
%           {\Gamma \vdash e_1:\tau\rightarrow\tau' \qquad
%            \trfrac[\small(\emph{app})]
%                   {\Gamma \vdash e_2:\tau''\rightarrow\tau \qquad
%                    \Gamma \vdash e_3:\tau''}
%                   {\Gamma \vdash e_2 e_3:\tau}}
%           {\Gamma \vdash e_1 (e_2 e_3):\tau'} \]
% in which the material ``${\cal D} =$'' should be vertically centered with
% respect to the bottom fraction bar, but the left premise should not be
% centered with respect to the right subderivation's fraction bar.
%
% \DescEnv{trgather}
% The environment
%
% \medskip{\narrower\parindent=0pt
%   |\begin{trgather}|\par
%   \hskip1em \meta{eqn$_1$} |\\[|\meta{len$_1$}|]|\par
%   \hskip1em \meta{eqn$_2$} |\\[|\meta{len$_2$}|]|\par
%   \hskip2em $\vdots$\par
%   \hskip1em \meta{eqn$_n$} |\\[|\meta{len$_n$}|]|\par
%   |\end{trgather}|\par
% }\medskip
%
% \noindent
% can be used in math mode to stack a set of equations, each of which is to
% be centered horizontally over one another.
% Here, \meta{eqn$_i$} is material processed in math mode and
% \meta{len$_i$} is an optional length that modifies the vertical spacing
% between the current equation and the next.
% The baseline of the resulting stack of equations is the baseline of
% the bottom equation in the stack.
%
% \DescEnv{tralign}
% The environment
%
% \medskip{\narrower\parindent=0pt
%   |\begin{tralign}|\par
%   \hskip1em \meta{left$_1$}|&|\meta{right$_1$} |\\[|\meta{len$_1$}|]|\par
%   \hskip1em \meta{left$_2$}|&|\meta{right$_2$} |\\[|\meta{len$_2$}|]|\par
%   \hskip2em $\vdots$\par
%   \hskip1em \meta{left$_n$}|&|\meta{right$_n$} |\\[|\meta{len$_n$}|]|\par
%   |\end{tralign}|\par
% }\medskip
%
% \noindent
% can be used in math mode to stack a set of equations, each of which is to
% be aligned horizontally by the position of the |&| in the equation.
% Here, \meta{left$_i$} and \meta{right$_i$} is the math material to be
% placed to the left and right, respectively, of the vertical center axis of
% the resulting stack of equations;
% and \meta{len$_i$} is an optional length that modifies the vertical
% spacing between the current equation and the next.
% The baseline of the resulting stack of equations is the baseline of
% the bottom equation in the stack.
%
% \DescMacro{trtopgap}
% \DescMacro{trbotgap}
% The space just above and just below each fraction bar can be adjusted by
% changing the values of lengths |\trtopgap| and |\trbotgap|.
% For example, to decrease the distance between fraction bars and numerators
% by 2 points and increase the distance between fraction bars and denominators
% by 1 point of space, you could write:
%
% \medskip{\narrower\parindent=0pt
%   |\trtopgap=-2pt|\par
%   |\trbotgap=1pt|\par
% }\medskip
%
% \StopEventually{\PrintIndex}
%
% \section{Implementation}
%
% The following is a verbatim listing of the |trfrac| package implementation
% with comments explaining how it works.
%
% \begin{macro}{\trtopgap}
% \begin{macro}{\trbotgap}
% Declare dimension registers that allow users to control the amount of
% space above and below fraction bars.
%    \begin{macrocode}
\newdimen\trtopgap\trtopgap\z@
\newdimen\trbotgap\trbotgap\z@
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\TRF@startp}
% \begin{macro}{\TRF@endp}
% When processing a numerator, the |\TRF@trfrac| code must be able to determine
% if (a)~the current derivation is the first thing being added to the current
% horizontal list, and if (b)~the current horizontal list ends in a derivation.
% To accomplish this, two sentinal penalties are added to horizontal lists:
% |\TRF@startp| is added at the beginning of a horizontal list comprising a
% numerator, and |\TRF@endp| is added just after every derivation.
% Then |\lastpenalty| can be used to inquire whether the current horizontal
% list ends in either penalty.
% (Since derivations encased within numerators cannot undergo line-breaking,
% these extra penalties will have no effect on \LaTeX's processing of the
% actual output.)
%    \begin{macrocode}
\newcommand\TRF@startp{31415926}
\newcommand\TRF@endp{27182818}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\ifTRF@first}
% In accordance with the above, the following conditional remembers if the
% current derivation is the first in the horizontal list comprising the
% numerator of a larger derivation.
%    \begin{macrocode}
\newif\ifTRF@first
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifTRF@outer}
% The outermost derivation behaves slightly differently than subderivations
% within a derivation tree.
% (Its baseline is its fraction bar instead of its denominator's baseline,
% and it should not include the spurious |\TRF@endp| penalty, since
% line-breaking might occur.)
% The following conditional therefore remembers whether we're at the
% outermost level.
%    \begin{macrocode}
\newif\ifTRF@outer\TRF@outertrue
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\ifTRF@derivok}
% Subderivations are not permitted to appear within denominators or within
% rule names.
% The |\ifTRF@derivok| conditional is set to |false| when processing such
% material.
%    \begin{macrocode}
\newif\ifTRF@derivok\TRF@derivoktrue
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\TRF@lhang}
% \begin{macro}{\TRF@rhang}
% After processing a horizontal list that might contain one or more
% derivations, |\TRF@lhang| holds the distance from the left edge of the
% resulting box to the leftmost item's denominator
% (or |0pt| if the leftmost list item is not a derivation),
% and |\TRF@rhang| holds the distance from the rightmost item's denominator
% to the right edge of the resulting box
% (or |0pt| if the rightmost list item is not a derivation).
%    \begin{macrocode}
\newdimen\TRF@lhang\TRF@lhang\z@
\newdimen\TRF@rhang\TRF@rhang\z@
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\TRF@lsave}
% We also need a place to save the value of |\TRF@lhang| so that we can
% (sometimes) restore it to its original value after it has been globally
% modified by nested |\trfrac| macros.
%    \begin{macrocode}
\newdimen\TRF@lsave
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\TRF@ni}
% \begin{macro}{\TRF@bi}
% \begin{macro}{\TRF@bw}
% The temporary registers declared below store the the numerator indentation,
% bar indentation, and bar width, respectively, when typesetting a
% derivation rule.
%    \begin{macrocode}
\newdimen\TRF@ni
\newdimen\TRF@bi
\newdimen\TRF@bw
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\TRF@numbox}
% \begin{macro}{\TRF@denombox}
% \begin{macro}{\TRF@eqbox}
% While constructing a derivation, the following three boxes hold the
% derivation's numerator, denominator, and rule name, respectively.
%    \begin{macrocode}
\newbox\TRF@numbox
\newbox\TRF@denombox
\newbox\TRF@eqbox
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\TRF@trfrac}
% The following macro typesets a single derivation rule in a derivation tree.
% Its arguments are
% (1)~the rule name (processed in horizontal mode),
% (2)~the numerator (processed in math mode), and
% (3)~the denominator (processed in math mode).
%    \begin{macrocode}
\newcommand\TRF@trfrac[3]{%
  \begingroup%
%    \end{macrocode}
% We start by saving the original value of |\TR@lhang| and deciding whether
% this is the first subderivation in a numerator of a larger derivation.
% These must come before anything else, and the results used later.
%    \begin{macrocode}
    \ifnum\lastpenalty=\TRF@startp\relax%
      \TRF@firsttrue%
    \else%
      \TRF@firstfalse%
    \fi%
    \TRF@lsave\TRF@lhang%
%    \end{macrocode}
% Typeset the equation number and put it in a box.
%    \begin{macrocode}
    \setbox\TRF@eqbox\hbox{\TRF@derivokfalse#1}%
    \ifdim\wd\TRF@eqbox>\z@%
      \setbox\TRF@eqbox\hbox{\kern\p@\unhbox\TRF@eqbox}%
    \fi%
%    \end{macrocode}
% Typeset the numerator and put it in a box.
% We begin the box with the |\TRF@startp| penalty so that if the first list
% item is a derivation, it will see that nothing has preceded it and will
% therefore set |\TRF@lhang|.
% We initialize it to zero so that if the first item is not a derivation,
% |\TRF@lhang| will remain zero.
% If the last thing in the numerator is a |\TRF@endp| penalty, then the list
% must have ended with a subderivation whose denominator is a distance
% |\TRF@rhang| from its right edge.
% Otherwise the rightmost item was not a subderivation, so we zero
% |\TRF@rhang|.
%    \begin{macrocode}
    \TRF@lhang\z@%
    \setbox\TRF@numbox\hbox{%
      \TRF@outerfalse%
      \m@th$\strut%
      \penalty\TRF@startp\relax%
      #2%
      \ifnum\lastpenalty=\TRF@endp\relax\else%
        \global\TRF@rhang\z@%
      \fi%
      $%
    }%
%    \end{macrocode}
% Finally, typeset the denominator in a box.
% Denominators may not contain subderivations, so this preserves the
% values of |\TRF@lhang| and |\TRF@rhang|.
%    \begin{macrocode}
    \setbox\TRF@denombox\hbox{%
      \TRF@derivokfalse%
      \m@th$\strut#3$%
    }%
%    \end{macrocode}
% Compute the
% bar width $\mathit{bw}=\max(n-l-r,d)$,
% denominator indentation $l'=\max((n-r+l)-d,0)/2$,
% numerator indentation $\mathit{ni}=\max(d-(n-r+l),0)/2$, and
% bar indentation $\mathit{bi}=\min(\mathit{ni}+l,\mathit{di})$,
% respectively, where $n$ is the numerator width, $d$ is the denominator
% width, $l$ is the old value of |\TRF@lhang|, and $r$ is |\TRF@rhang|.
%    \begin{macrocode}
    \dimen@\wd\TRF@numbox%
    \advance\dimen@-\TRF@rhang%
    \TRF@bw\dimen@%
    \advance\TRF@bw-\TRF@lhang%
    \ifdim\wd\TRF@denombox>\TRF@bw\TRF@bw\wd\TRF@denombox\fi%
    \advance\dimen@\TRF@lhang%
    \advance\dimen@-\wd\TRF@denombox%
    \TRF@ni\ifdim\dimen@>\z@\z@\else-.5\dimen@\fi%
    \TRF@bi\TRF@ni%
    \advance\TRF@bi\TRF@lhang%
    \TRF@lhang\ifdim\dimen@<\z@\z@\else.5\dimen@\fi%
    \ifdim\TRF@bi>\TRF@lhang\TRF@bi\TRF@lhang\fi%
%    \end{macrocode}
% Compute the new value of |\TRF@rhang| as
% $r'=\max(\mathit{ni}+n,\mathit{bi}+\mathit{bw}+e)-l'-d$,
% where $e$ is the width of the equation number.
% The final result is globally assigned so that its value will persist
% beyond the local scope in which numerators are typeset.
%    \begin{macrocode}
    \TRF@rhang\TRF@ni%
    \advance\TRF@rhang\wd\TRF@numbox%
    \dimen@\TRF@bi%
    \advance\dimen@\TRF@bw%
    \advance\dimen@\wd\TRF@eqbox%
    \ifdim\dimen@>\TRF@rhang\TRF@rhang\dimen@\fi%
    \advance\TRF@rhang-\TRF@lhang%
    \advance\TRF@rhang-\wd\TRF@denombox%
    \global\TRF@rhang\TRF@rhang%
%    \end{macrocode}
% Begin typesetting the final fraction as a math-inner node.
% The vbox that comprises the node has an hbox comprising the denominator on
% the bottom and an hbox comprising everything else on the top.
% This allows the denominator baseline to become the baseline of the entire
% fraction.
% If this is the outermost level, the final box is set with |\vtop| so that
% the numerator is the baseline, and then raised a bit so that the fraction
% bar becomes the baseline.
%    \begin{macrocode}
    \mathinner{%
      \ifTRF@outer%
        \raise\fontdimen22\textfont\tw@\vtop%
      \else%
        \vbox%
      \fi%
      {%
        \offinterlineskip%
        \hbox{%
          \vbox{%
%    \end{macrocode}
% Compute the distance between the numerator and the fraction bar.
% The formula for computing this number is given in step 15d of Appendix G
% of {\it The \TeX book} (p.~445).
%    \begin{macrocode}
            \dimen@\fontdimen8\textfont\tw@%
            \advance\dimen@-\fontdimen22\textfont\tw@%
            \advance\dimen@-.5\fontdimen8\textfont\thr@@%
            \advance\dimen@-\dp\TRF@numbox%
            \ifdim\dimen@<3\fontdimen8\textfont\thr@@%
              \dimen@3\fontdimen8\textfont\thr@@%
            \fi%
            \advance\dimen@\trtopgap%
%    \end{macrocode}
% Typeset the numerator part, horizontally centered over the fraction bar
% (but possibly overhanging the equation number).
%    \begin{macrocode}
            \hbox{\kern\TRF@ni\unhbox\TRF@numbox}%
            \kern\dimen@%
%    \end{macrocode}
% Typeset the fraction bar followed by the equation number.
% The height of the fraction bar is based on math font metric~8.
% The equation number is typeset at zero height so that it does not push
% the numerator or denominator away from the fraction bar.
%    \begin{macrocode}
            \hbox{%
              \kern\TRF@bi%
              \vrule\@width\TRF@bw%
                    \@height.5\fontdimen8\textfont\thr@@%
                    \@depth.5\fontdimen8\textfont\thr@@%
              \vbox{%
                \dimen@.5\ht\TRF@eqbox%
                \advance\dimen@.5\dp\TRF@eqbox%
                \kern-\dimen@%
                \box\TRF@eqbox%
                \kern-\dimen@%
              }%
            }%
          }%
        }%
%    \end{macrocode}
% Insert the vertical space that separates a fraction bar from its
% denominator.
% See step 15d of Appendix G of {\it The \TeX book} (p.~445) for a
% derivation of this distance.
%    \begin{macrocode}
        \dimen@\fontdimen11\textfont\tw@%
        \advance\dimen@\fontdimen22\textfont\tw@%
        \advance\dimen@-.5\fontdimen8\textfont\thr@@%
        \advance\dimen@-\ht\TRF@denombox%
        \ifdim\dimen@<3\fontdimen8\textfont\thr@@%
          \dimen@3\fontdimen8\textfont\thr@@%
        \fi%
        \advance\dimen@\trbotgap%
        \kern\dimen@%
%    \end{macrocode}
% Typeset the denominator horizontally centered below the fraction bar.
%    \begin{macrocode}
        \hbox{\kern\TRF@lhang\box\TRF@denombox}%
      }%
    }%
%    \end{macrocode}
% If this is a subderivation within another, add a |\TRF@endp| penalty to
% the current horizontal list so that if this is the last item in a numerator,
% the value we computed for |\TRF@rhang| will be used by the outer derivation
% to determine the amount by which its numerator may overhang the fraction
% bar to the right.
%    \begin{macrocode}
    \ifTRF@outer\else%
      \penalty\TRF@endp\relax%
    \fi%
%    \end{macrocode}
% If this is the leftmost subderivation in the numerator of another derivation,
% the value of |\TRF@lhang| must be made global so that it can be used by the
% outer derivation to compute the amount by which its numerator may overhang
% the fraction bar to the left.
% Otherwise |\TRF@lhang| must be restored to whatever value it had on entrance
% to this |\trfrac|.
% (It is not enough to just let it get restored to whatever it was before the
% current local scope, since some nested modifications to it might have been
% global.)
%    \begin{macrocode}
    \global\TRF@lhang\ifTRF@first\TRF@lhang\else\TRF@lsave\fi%
  \endgroup%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\trfrac}
% The following is the entrypoint to the derivation code.
% The |\trfrac| macro takes one optional argument which, if present, is the
% name of the rule (processed in horizontal mode),
% followed by two mandatory arguments---the rule's numerator and denominator.
% Derivations can only appear in math mode, and cannot appear within the
% denominator of another derivation or within its rule name.
%    \begin{macrocode}
\newcommand\trfrac[3][]{%
  \ifTRF@derivok%
    \ifmmode%
      \TRF@trfrac{#1}{#2}{#3}%
    \else%
      \TRF@mmerr%
    \fi%
  \else%
    \TRF@derr%
  \fi%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\TRF@mmerr}
% Produce an error if |\trfrac| is used outside of math mode.
%    \begin{macrocode}
\newcommand\TRF@mmerr{%
  \PackageError{trfrac}{\protect\trfrac\space%
     only allowed in math mode}%
    {I encountered a \protect\trfrac\space%
     macro without first encountering a begin-math token.}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\TRF@derr}
% Subderivations within denominators are not supported because that would
% require computing chiastic structures rather than tree structures.
%    \begin{macrocode}
\newcommand\TRF@derr{%
  \PackageError{trfrac}{\protect\trfrac\space%
     not allowed in the consequent of another \protect\trfrac}%
    {\protect\trfrac\space can only appear in the premise (numerator%
     ) of another \protect\trfrac, not in the consequent (denominator%
     ) of a \protect\trfrac.}%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\TRF@next}
% The |\TRF@next| token is here reserved so that it can be used in conjunction
% with |\futurelet| (when processing optional arguments).
%    \begin{macrocode}
\newcommand\TRF@next{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\TRF@sep}
% In a |trgather| or |tralign| environment, the |\\| macro is used to delimit
% lines.
% It is temporarily set equal to |\TRF@sep| (below), which is just like |\cr|
% in an |\halign| except that it takes an optional length argument that
% has the effect of inserting a vertical space between the lines.
%    \begin{macrocode}
\newcommand\TRF@sep{\futurelet\TRF@next\TRF@@sep}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\TRF@@sep}
% The following processes the optional argument to |\TRF@sep|.
%    \begin{macrocode}
\newcommand\TRF@@sep{%
  \ifx[\TRF@next%
    \let\TRF@next\TRF@separg%
  \else%
    \let\TRF@next\TRF@sepnoarg%
  \fi%
  \TRF@next%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\TRF@separg}
% The following is the code for a |\TRF@sep| that has been provided the
% optional argument.
%    \begin{macrocode}
\newcommand\TRF@separg{}
\def\TRF@separg[#1]{\cr\noalign{\kern#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\TRF@sepnoarg}
% The following is the code for a |\TRF@sep| that has not been provided the
% optional argument.
% You might think that it would have been simpler to use |\let| instead of
% |\newcommand| in the line below, or even to just use |\cr| within some of
% the code above instead of defining this new macro at all,
% but |\cr| is a strange beast; it can only be expanded onto the token
% stream when we're sure of everything that is to follow it.
%    \begin{macrocode}
\newcommand\TRF@sepnoarg{\cr}
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{trgather}
% A |trgather| environment is just like |amsmath|'s |gathered| environment
% except that its baseline is at the bottom instead of in the middle.
%    \begin{macrocode}
\newenvironment{trgather}{%
  \vbox\bgroup%
    \let\\\TRF@sep%
    \ialign\bgroup\hfil{\m@th$##$}\hfil\cr%
}{%
  \crcr\egroup\egroup%
}
%    \end{macrocode}
% \end{environment}
%
% \begin{environment}{tralign}
% A |tralign| environment is like |amsmath|'s |aligned| environment except that
% its baseline is at the bottom instead of in the middle, and it's restricted
% to two columns (for simplicity).
%    \begin{macrocode}
\newenvironment{tralign}{%
  \vbox\bgroup%
    \let\\\TRF@sep%
    \ialign\bgroup\hfil{\m@th$##\null$}&{\m@th$\null##$}\hfil\cr%
}{%
  \crcr\egroup\egroup%
}
%    \end{macrocode}
% \end{environment}
%
% \Finale
\endinput
