%         This work is protected as an unpublished work under
%         U.S. copyright laws.
%         Copyright 1987, by Washington State University.
%         All rights reserved.
%
%               Last updated on 7/1/89
%
%     MULTIPLE COLUMN FORMATS FLEXIBLE MODE, two and three column
%
\catcode`*=11\catcode`@=11
\global\output{\flex*ut{\unvbox255}} %     FLEXCOL normal output routine
\gdef\flex*ut#1{% FLEXIBLE OUTPUT, flex*ut
    \boxmaxdepth=\maxdepth
    \shipout\vbox{
    \offinterlineskip                % butt boxes together
    \if*title                        % Do nothing if this is a title page
    \else\makeheadline\fi            % makeheadline redefined in TEXT1
    \vbox to\*txth{                  % page height equals single column text height
    \ifvoid\topins                   % no top insert present
    \else\unvbox\topins\fi           % place top insert before main text
    #1                               % insert the main information
    \vfil                            % PREVENTS UNDERFULL BOX WHEN ONLY A FEW POINTS OFF
    \ifvoid\footins                  % no foot insert present
    \else\vskip\skip\footins         % skip to footnote position
    \footnoterule                    % print footnote rule
       \unvbox\footins\fi            % place foot insert after main text and rule
    \makefootline} % end vbox to *txth
    } % end vbox with running heads, if any
    \if*title\notitlepage\fi         % reset vsize for a normal page
    \if\*pcount>0\*blkpg\fi          % call for empty page macro, TEXT1
    \*ncfalse
    \advancepageno}                  % End flex*ut, flexible output macro
%
\gdef\*adjp#1{% ADJUST PAGE MACRO, height of inserts lost during output call, this macro
   \global\advance#1 by-\topskip     % restores these values to the output routines
    \ifvoid\topins                   % compensate for topskip
    \else                            % if no insert present do nothing else
       \global\advance#1 by-\ht\topins % routine restores those values
       \global\advance#1 by-\dp\topins % to the new output routines.
       \global\advance#1 by-\skip\topins
       \global\advance#1 by\dp\strutbox % fine tune split
    \fi
    \ifvoid\footins                  % do nothing if no footinsert present
    \else                            % else compensate for skips when footins present
       \global\advance#1 by-\ht\footins %
       \global\advance#1 by-\dp\footins %
       \global\advance#1 by-\skip\footins %
       \global\advance#1 by\dp\strutbox % fine tune split
    \fi}% END *adjp, adjust page macro
%
%         \*balctest is called whenever leaving 2 or 3 column formatting
%
\gdef\*balctest{% TEST REMAINING TEXT DEPTH text for more than one page of remaining text
    \setbox0=\vbox{\unvbox255}       % height box255 always=vsize
    \dimen9=\ht0                     % find height of material in box255
    \advance\dimen9 by\topskip       % account for top of page topskip
    \if*dbl \advance\dimen9 by\splittopskip % second column splittopskip
    \else\advance\dimen9 by2\splittopskip % second and third columns
    \fi % end accounting for topskips for splitting routines
    \setbox255=\vbox{\unvbox0}
    \ifdim\dimen9>\vsize             % too much material for one page
       \if*dbl\expandafter\global\output={\*balc}\*twcout %
       \else\expandafter\global\output={\*balc}\*thcout %
       \fi                           % use normal output before using balance columns routine
    \else                            % less than one full page of text remaining
       \*balc                        % use balance columns routine
    \fi}% END, *balctest, test for output routine to balance columns
%
\gdef\*flextwc{\par% BEGIN FLEX METHOD OF TWO COLUMNS
    \goodbreak
    \if*dbl\e*flextwc\fi             % end any active two column format
    \if*tpl\e*flexthc\else           % if previous material in threecolumns call
    \vskip\the\*mskb\fi              % end threecolumns, else skipbefore.
%
    \def\*balc{% BALANCECOLUMNS, TWO COLUMNS---beginning
       \*badj                        % check for binding adjust
       \splittopskip=\topskip        % splittopskip equals topskip
       \setbox0=\vbox{\unvbox255}    % release unbalanced page material
       \dimen0=\ht0                  % prepare to find equal height dimension
       \divide\dimen0 by2            % split dimension for two columns
       \advance\dimen0 by-\baselineskip % back up one line
       \ifdim\dimen0<\baselineskip   % check split depth
          \dimen0=\topskip           % account for the topskip
          \advance\dimen0 by\baselineskip % account for one line
       \fi
       {\vbadness=10000              % prevents underfull box message during loop
            \loop \global\setbox3=\copy0 % routine.
            \global\setbox1=\vsplit3 to\dimen0 %
            \ifdim\ht3>\dimen0       % if column longer...
            \global\advance\dimen0 by1pt %
            \repeat}                 % end balancing loop
       \setbox0=\vbox to\dimen0{\unvbox1} %
       \setbox2=\vbox to\dimen0{\dimen2=\dp3 %
          \unvbox3 \kern-\dimen2 \vfill} %
       \ifvoid2 \setbox2=\vbox to\dimen0{\null\vfill}\fi %
       \*pgsofar                     % format text accummulated so far
       \global\output={\*dbl-error}  % error message if balance fails
       \dimen@=\*txth                % return vsize to single page size
       \*adjp\dimen@                 % adjust vsize for any remaining inserts
       \global\vsize=\dimen@         % adjusted vsize
       }% END, *balc, balancecolumns macro, twocolumns
%
    \def\*pgsofar{% PAGESOFAR, format for two columns
        \unvbox\*ppage               % boxes two column material
        \D=\the\*twcgut \D=.5\D      % half gutter skip on either side of rule
        \wd0=\hsize \wd2=\hsize      % set text box width securely
        \hbox to\*txtw{\box0\hskip\D\vrule width\the\*clrw
               \hskip\D\box2\hfil}   % set boxes and rules
        }% END, *pgsofar, pagesofar output macro
%
   \def\*twcout{% TWO COLUMN OUTPUT, normal output routine
       \splittopskip=\topskip
       \splitmaxdepth=\maxdepth
       \*badj                        % check for binding adjust
       \dimen@=\vsize                % total text depth for two column out routine
       \divide\dimen@ by2            % set splitting dimension
       \*adjp\dimen@                 % adjust page size for inserts
       \setbox0=\vsplit255 to\dimen@ % split boxes to proper height
       \setbox2=\vsplit255 to\dimen@
       \flex*ut\*pgsofar             % output current page
       \unvbox255                    % release extra text material gathered
       \*bigch=2\*txth               % allow vsize changes from cpt*vsize
       \global\vsize=\*bigch         % reset vsize to two column format
       \penalty\outputpenalty}% END *twcout, two columns output routine
%
%     TWOCOLUMNS, NEW COLUMN ROUTINE
%     Harvey 12/06/85
%     This method will fail if a topinsert or footinsert is added to
%     the page after the new column call. The box and glue are set
%     at the newcolumn call accounting for inserts active then only
%
   \def\newcolumn{\par % NEWCOLUMN, Flexible method, two columns
       \D=.5\vsize                   % depth of one column
       \ifdim\pagetotal>\D           % determine which column is current
          \D=\pagegoal               % second column, depth > .5\vsize
          \advance\D by-\pagetotal
          \advance\D by-\topskip     % account for topskip of 1st column
          \advance\D by-\splittopskip % splittopskip of 2d column
          \advance\D by-\dp\strutbox % account for character depth
       \else                         % first column, depth equals half the vsize
          \advance\D by-\pagetotal   % subtract current page depth
          \advance\D by-\topskip     % subtract topskip form page depth
          \advance\D by-\dp\strutbox % account for character depth
       \fi
       \vbox to\D{\vfill}            % blank box to fill column
       \*nctrue
       \goodbreak}% END, newcolumn macro for two columns
    \let\nc=\newcolumn               % set two column definition of newcolumn
%
    \begingroup % BEGIN TWOCOLUMNS---set-up
    \global\*dbltrue                 % double columns active
    \brokenpenalty=0   % If these penalties are set to zero the text
    \clubpenalty=0     % will be formatted properly. If the are in force
    \widowpenalty=0    % uneven columns may result. The penalties will be
    \hyphenpenalty=0   % honored in either page or vsplit modes.
    \exhyphenpenalty=0
    \tolerance=6400                  % raise tolerance for short column material
    \hbadness=6400                   % warning message given at 6400
    \*bigch=2\*txth                  % initialize two column page height
    \dimen@=\*txth                   % set dimen@ to current page height
    \advance\dimen@ by-\pagetotal    % subtract current page depth
    \*adjp\dimen@                    % adjust page depth for inserts
    \vsize=2\dimen@                  % set vsize equal to twice the remaining depth
    \output={\global\setbox\*ppage=\vbox{\unvbox255}}\eject
    \output={\*twcout}               % output partial page and set output
    \hsize=\the\*twcw                % to twocolumnout, set new hsize for column
    \topskip=12pt plus4pt            % glue for vsplitting mechanism
    }% END, *flextwc, flexible two column---set-up
%
\gdef\e*flextwc{% TERMINATION MACRO FOR TWO COLUMNS FLEX METHOD
    \if*nc \vfill\eject\fi           % When we've done a \nc dump the page before balancing
    \output={\*balctest}\eject       % test for too much text for balancing
    \global\output={\flex*ut{\unvbox255}} % output page
    \global\*dblfalse                % change two column indicator to false
    \endgroup % END DOUBLE COLUMN FORMAT
    \global\vsize=\*txth             % reset page size to single column height
    \global\hsize=\*txtw             % reset page width to single column width
    \dimen@=\vsize                   % prepare to include current inserts
    \*adjp\dimen@                    % adjust for topskip and inserts
    \global\pagegoal=\dimen@         % adjust pagegoal for current inserts
    \penalty-500
    \vskip\the\*mska
    }% END e*flextwc, TWO COLUMNS termination routine
%
%
\gdef\*flexthc{\par% BEGIN FLEX METHOD OF THREE COLUMNS
    \goodbreak
    \if*tpl\e*flexthc\fi             % end any active triple columns
    \if*dbl\e*flextwc\else           % if previous material is in twocolumns, end
    \vskip\the\*mskb\fi              % twocolumns, else skipbefore
%
    \def\*balc{% BALANCECOLUMNS, THREECOLUMNS---beginning
       \*badj                        % check for binding adjust
       \splittopskip=\topskip        % split dimension for 3col
       \setbox0=\vbox{\unvbox255}
       \dimen0=\ht0                  % prepare to find equal height dimension
       \divide\dimen0 by3            % split dimension for each column
       \advance\dimen0 by-\baselineskip % back-up one baselineskip
       \ifdim\dimen0<\baselineskip   % check split depth
          \dimen0=\topskip           % account for the topskip
          \advance\dimen0 by\baselineskip % account for one line
       \fi
       {\vbadness=10000
            \loop \global\setbox5=\copy0 % begin vsplit loop for balancing
            \global\setbox3=\vsplit5 to\dimen0
            \global\setbox4=\vsplit5 to\dimen0
            \ifdim\ht5>\dimen0 \global\advance\dimen0 by1pt
            \repeat} % end balancing loop
       \setbox0=\vbox to\dimen0{\unvbox3} % first column
       \setbox1=\vbox to\dimen0{\unvbox4} % second column
       \ifvoid1 \setbox1=\vbox to\dimen0{\line{\hfil}\vfill}\fi
       \setbox2=\vbox to\dimen0{\dimen2=\dp5\unvbox5\kern-\dimen2 \vfill}
       \ifvoid2 \setbox2=\vbox to\dimen0{\line{\hfil}\vfill}\fi
       \*pgsofar
       \global\output={\*tpl-error}  % error message if loop fails
       \vsize=\*txth                 % reset page size to single column
       \dimen@=\vsize                % return vsize to single page vsize
       \*adjp\dimen@                 % adjust for topskip and inserts
       \global\vsize=\dimen@         % new vsize accounts for current inserts
       }% END, *balc, balance columns, threecolumns
%
    \def\*pgsofar{\unvbox\*ppage     % boxes three column material
        \D=\the\*thcgut \D=.5\D      % half gutter for each side of rule
        \wd0=\hsize \wd1=\hsize \wd2=\hsize % set text box width securely
        \hbox to\*txtw{\box0\hskip\D\vrule width\the\*clrw
            \hskip\D\box1\hskip\D\vrule width\the\*clrw
            \hskip\D\box2\hfil}      % set boxes and rules
            }% End *pgsofar, page-so-far macro
%
   \def\*thcout{% THREE COLUMNS OUT, normal output routine for threecolumns
       \splittopskip=\topskip
       \splitmaxdepth=\maxdepth
       \*badj                        % check for binding adjust
       \dimen@=\vsize                % total text depth for three column out routine
       \divide\dimen@ by3            % set splitting dimension
       \*adjp\dimen@                 % adjust for topskip and inserts
       \setbox0=\vsplit255 to\dimen@ % split boxes to proper height
       \setbox1=\vsplit255 to\dimen@ %
       \setbox2=\vsplit255 to\dimen@ %
       \flex*ut\*pgsofar             % send material to output routine
       \unvbox255                    % release any extra material gathered
       \*bigch=3\*txth               % allow vsize changes from cpt*vsize
       \global\vsize=\*bigch         % reset vsize for three column format
       \penalty\outputpenalty}% END *thcout,  normal output penalty set
%
%     THREECOLUMNS, NEW COLUMN ROUTINE
%     Harvey 12/19/85
%     This routine has no way to compensate for inserts following the
%     new column call and will produce an overfull vbox message while
%     output active. It may also produce and underfull vbox message
%     if there is no stretchable glue in the column.
   \def\newcolumn{\par               % new column, three columns
       \ifdim\pagetotal>.66666\vsize % you are in the third column
          \D=\pagegoal               % work from pagegoal for third column
          \advance\D by-\topskip     % account for topskip in 1st column
          \advance\D by-2\splittopskip % splittopskip in columns 2 and 3
          \advance\D by-\pagetotal   % subtract current pagetotal
          \advance\D by-\dp\strutbox % account for character depth
       \else\ifdim\pagetotal>.3\vsize % you are in the second column
          \D=.66666\vsize            % column goal is 2/3 vsize
          \advance\D by-\topskip     % account topskip in 1st column
          \advance\D by-\splittopskip % splittopskip in column 2
          \advance\D by-\pagetotal   % compensate for text
          \advance\D by-\dp\strutbox % account for character depth
            \else                    % you are in the first column
               \D=.33333\vsize       % goal is 1/3 vsize in first column
               \advance\D by-\topskip % account for splittopskip
               \advance\D by-\pagetotal % compensate for text
               \advance\D by-\dp\strutbox % account for character depth
          \fi\fi                     % end column determination and fil
    \vbox to\D{\vfill}
    \*nctrue
    \goodbreak}% END, newcolumn for three columns
%
    \let\nc=\newcolumn               % set new column definition to three columns
%
    \begingroup % BEGIN GROUP, THREE COLUMNS
    \global\*tpltrue                 % set three column indicator on
    \brokenpenalty=0     % These penalties should be zero in multicolumn
    \clubpenalty=0       % modes that use the vsplit method of paging,
    \widowpenalty=0      % the paging methods would honor the penalties.
    \hyphenpenalty=0     % is erratic columns.
    \exhyphenpenalty=0   %
    \tolerance=9600                  % raise tolerance for short columns
    \hbadness=9600                   % warnings issued at badness of 9600
    \*bigch=3\*txth                  % initialize three column height
    \dimen@=\*txth                   % set dimen@ to current page height
    \advance\dimen@ by-\pagetotal    % subtract current page depth
    \*adjp\dimen@                    % adjust page for topskip and inserts
    \vsize=3\dimen@                  % set vsize to 3 times remaining single column depth
    \output={\global\setbox\*ppage=\vbox{\unvbox255}}\eject
    \output={\*thcout}               % output partial page and set output
    \hsize=\the\*thcw                % to threecolumnout, set new hsize for column
    \topskip=12pt plus4pt            % glue for the vsplitting mechanism
    }% END *flexthc, three columns set-up
%
\gdef\e*flexthc{% TERMINATION THREE COLUMNS FLEX METHOD
    \if*nc \vfill\eject\fi           % When we've done a \nc dump the page before balancing
    \output={\*balctest}\eject           % balance remaining three column material
    \global\output={\flex*ut{\unvbox255}} % shipout page
    \global\*tplfalse                % end three column indicator
    \endgroup % END GROUP THREE COLUMNS
    \global\vsize=\*txth             % reset vsize to single column height
    \global\hsize=\*txtw             % reset hsize to single column width
    \dimen@=\vsize                   % prepare to include current inserts
    \*adjp\dimen@                    % adjust for topskip and inserts
    \global\pagegoal=\dimen@         % reset pagegoal to include inserts
    \penalty-500
    \vskip\the\*mska}% END E*flexthc, three columns termination macro
%
%
\gdef\onecolumn{\if*dbl\e*flextwc\fi  % end double column formatting
                \if*tpl\e*flexthc\fi
                \global\output={\*mkpg}
               }%  end triple column formatting
\global\let\oc=\onecolumn
%
\gdef\*dbl-error{\errhelp=\balerrhelp
    \errmessage{ Double columns can't be balanced on page \the\pageno . %
                Please type h for help. }%
    \flex*ut{\unvbox255}}
\gdef\*tpl-error{\errhelp=\balerrhelp
    \errmessage{ Triple columns can't be balanced on page \the\pageno . %
                Please type h for help. }%
    \flex*ut{\unvbox255}}%
%
\catcode`*=12\catcode`@=3
 
 
