%
% This is hairy because output routines are hairy\dots
%
% We need several insert boxes.  Naming convention: the letter for the
% box size and two letter code for the location.  We use \cs{newbox}
% instead of \cs{newinsert} since we do not use associated \cs{count},
% \cs{dimen} and \cs{skip} registers.
%    \begin{macrocode}
\newbox\nfbox@S@ul
\newbox\nfbox@S@ur
\newbox\nfbox@S@ll
\newbox\nfbox@S@lr
\newbox\nfbox@S@UL
\newbox\nfbox@S@UR
\newbox\nfbox@S@LL
\newbox\nfbox@S@LR
\newbox\nfbox@T@ul
\newbox\nfbox@T@ur
\newbox\nfbox@T@UL
\newbox\nfbox@T@UR
\newbox\nfbox@W@ul
\newbox\nfbox@W@ll
\newbox\nfbox@W@UL
\newbox\nfbox@W@LL
\newbox\nfbox@B@ul
\newbox\nfbox@B@UL
%    \end{macrocode}
% 
% \begin{macro}{\@tempboxb}
%   Standard \LaTeX\ has \cs{@tempboxa}.  We need more\dots
%    \begin{macrocode}
\ifx\@tempboxb\@undefined
  \newbox\@tempboxb
\fi
%    \end{macrocode}
%   
% \end{macro}
%
%
% \begin{macro}{\standard@output}
%   The standard \LaTeX\ output routine is saved as
%   \cs{standard@output}.  We use it for one column pages---maybe one
%   even wants a standard float here?
%    \begin{macrocode}
\edef\standard@output{\the\output}
%    \end{macrocode}
%   
% \end{macro}
%
% \begin{macro}{\output}
%   Right now we use standard output on one column pages and the new
%   one with two columns
%    \begin{macrocode}
\output{\if@twocolumn\the\nf@output\else\standard@output\fi}
%    \end{macrocode}
%   
% \end{macro}
%
% \begin{macro}{\nf@output}
%   Here we define our own output routine.
%    \begin{macrocode}
\newtoks\nf@output
\nf@output {%
%    \end{macrocode}
%
% We define the current boxes 
% \cs{curr@nfbox...}.  Also, |uc| or |lc| mean Upper or Lower Current column
%    \begin{macrocode}
  \ifodd\c@page
    \global\let\curr@nfbox@S@ul\nfbox@S@UL
    \global\let\curr@nfbox@S@ur\nfbox@S@UR
    \global\let\curr@nfbox@S@ll\nfbox@S@LL
    \global\let\curr@nfbox@S@lr\nfbox@S@LR
    \global\let\curr@nfbox@T@ul\nfbox@T@UL
    \global\let\curr@nfbox@T@ur\nfbox@T@UR
    \global\let\curr@nfbox@W@ul\nfbox@W@UL
    \global\let\curr@nfbox@W@ll\nfbox@W@LL
    \global\let\curr@nfbox@B@ul\nfbox@B@UL
  \else
    \global\let\curr@nfbox@S@ul\nfbox@S@ul
    \global\let\curr@nfbox@S@ur\nfbox@S@ur
    \global\let\curr@nfbox@S@ll\nfbox@S@ll
    \global\let\curr@nfbox@S@lr\nfbox@S@lr
    \global\let\curr@nfbox@T@ul\nfbox@T@ul
    \global\let\curr@nfbox@T@ur\nfbox@T@ur
    \global\let\curr@nfbox@W@ul\nfbox@W@ul
    \global\let\curr@nfbox@W@ll\nfbox@W@ll
    \global\let\curr@nfbox@B@ul\nfbox@B@ul
  \fi
  \if@firstcolumn
    \global\let\curr@nfbox@S@uc\curr@nfbox@S@ul
    \global\let\curr@nfbox@S@lc\curr@nfbox@S@ll
    \global\let\curr@nfbox@T@uc\curr@nfbox@T@ul
  \else
    \global\let\curr@nfbox@S@uc\curr@nfbox@S@ur
    \global\let\curr@nfbox@S@lc\curr@nfbox@S@lr
    \global\let\curr@nfbox@T@uc\curr@nfbox@T@ur
  \fi
  \let \par \@@par
%    \end{macrocode}
%
% There are several possibilities when we start the output routine for
% a single column in a two-column layout.
% \begin{enumerate}
% \item Wide or big non-floats completely cover the page.  In this
% case we do not need to create columns, and directly go to the
% output.
% \item The column is occupied by tall or single nonfloats.  We make
% a column of nonfloats and send it further.
% \item There is room for text on the page, but its height
% (\cs{@colroom}) is different from the one known to the page builder
% (\cs{vsize}).  In this case we change \cs{vsize} and return.
% \item The room for text is exactly \cs{vsize}.  In this case we form
% a column and return.
% \end{enumerate}
%    \begin{macrocode}
  \global\@colht=\textheight
  \ifdim\ht\curr@nfbox@B@ul>0.5\baselineskip
    \global\advance\@colht by -\textheight
  \fi
  \ifdim\ht\curr@nfbox@W@ul>0.5\baselineskip
    \global\advance\@colht by -0.5\textheight
  \fi
  \ifdim\ht\curr@nfbox@W@ll>0.5\baselineskip
    \global\advance\@colht by -0.5\textheight
  \fi
  \ifdim\@colht < \baselineskip
    \nf@output@widepage
  \else
    \nf@makecol
  \fi
}
%    \end{macrocode}
%   
% \end{macro}
%
% \begin{macro}{\nf@output@widepage}
%   The macro \cs{nf@output@widepage} outputs a page completely filled
%   by wide pictures.
%    \begin{macrocode}
\def\nf@output@widepage{%
  \unvbox\@cclv
  \penalty\outputpenalty
  \if@firstcolumn\else
  \ClassError{faosyb}{Wide or big nonfloats defined too late.  Move
    them up}{I encountered Big or Wide floats when I already made the
    first column.  Please move them up}
  \fi
  \ifdim\ht\curr@nfbox@B@ul>0.5\baselineskip
     \setbox\@tempboxa\vsplit\curr@nfbox@B@ul to \textheight
     \setbox\@outputbox \vbox\bgroup
     \boxmaxdepth \@maxdepth
     \box\@tempboxa
     \vfill
     \egroup
  \else
     \setbox\@tempboxa\vsplit\curr@nfbox@W@ul to 0.5\textheight
     \setbox\@tempboxb\vsplit\curr@nfbox@W@ll to 0.5\textheight
     \setbox\@outputbox\vbox\bgroup
        \boxmaxdepth \@maxdepth
        \box\@tempboxa
        \nointerlineskip
        \box\@tempboxb
        \vfill
     \egroup
  \fi
  \global\vsize\textheight
  \global\@colht\textheight
  \@outputpage
  \@firstcolumntrue
}
%    \end{macrocode}
%   
% \end{macro}
%
%
% \begin{macro}{\nf@makecol}
%   This macro tries to make one column of text.  If successful, it
%   puts first column into temporary storage, and outputs the page
%   when or if the second column is ready.
%
%   When we start \cs{nf@makecol}, \cs{@colht} already reflects
%   possible wide nonfloats.  This to get \cs{@colroom}, we need to
%   take into account only the narrow ones
%    \begin{macrocode}
\def\nf@makecol{%
  \global\@colroom\@colht
  \ifdim\ht\curr@nfbox@T@uc>0.5\baselineskip
     \global\@colroom=0pt
  \fi
  \ifdim\ht\curr@nfbox@S@uc>0.5\baselineskip
     \global\advance\@colroom by -0.5\textheight
  \fi
  \ifdim\ht\curr@nfbox@S@lc>0.5\baselineskip
     \global\advance\@colroom by -0.5\textheight
  \fi
%    \end{macrocode}
%
%  Now there could be two cases.  If \cs{@colroom} is small, we fill
%  the column with the non-floats only.  Otherwise we have a ``mixed''
%  column with both text and nonfloats.
%    \begin{macrocode}
  \ifdim\@colroom<0.5\baselineskip
    \nf@makenfcol
  \else
    \nf@makemixedcol
  \fi}
%    \end{macrocode}
%   
% \end{macro}
%
%
% \begin{macro}{\nf@makenfcol}
%   This macro outputs a column with only non-floats.  If it is
%   called, we already know that the narrow non-floats would fill the
%   column, so we do not do any additional checks.
%    \begin{macrocode}
\def\nf@makenfcol{%
  \unvbox\@cclv
  \penalty\outputpenalty
  \ifdim\@colht>0.9\textheight  % one tall or two squares
    \ifdim\ht\curr@nfbox@T@uc>0.5\baselineskip
      \setbox\@outputbox\vbox\bgroup
      \boxmaxdepth \@maxdepth
      \vsplit \curr@nfbox@T@uc to \textheight
      \egroup
    \else
     \setbox\@outputbox\vbox\bgroup
      \boxmaxdepth \@maxdepth
      \vsplit\curr@nfbox@S@uc to 0.5\textheight
       \nointerlineskip
       \vsplit\curr@nfbox@S@lc to 0.5\textheight
     \egroup
    \fi
  \else  % one square
    \ifdim\ht\curr@nfbox@S@uc>0.49\textheight
      \setbox\@outputbox\vsplit \curr@nfbox@S@uc to 0.5\textheight
    \else
      \setbox\@outputbox\vsplit \curr@nfbox@S@lc to 0.5\textheight
    \fi
  \fi
  \nf@opcol
}
%    \end{macrocode}
%   
% \end{macro}
%
% \begin{macro}{\nf@makemixedcol}
%   This macro is used when we have a mix of text with nonfloats (or
%   possibly just text).  
%
%   We check whether the page builder has the right idea about
%   the text size;  if not, we return from the output routine
%    \begin{macrocode}
\def\nf@makemixedcol{%
  \ifdim\@colroom=\vsize
    \nf@makemixedcol@
  \else
    \global\vsize=\@colroom
    \unvbox\@cclv
    \penalty\outputpenalty
  \fi}
%    \end{macrocode}
%   
% \end{macro}
%
% \begin{macro}{\nf@makmixedcol@}
%   And now the real work of \cs{nf@makemixedcol@}
%    \begin{macrocode}
\def\nf@makemixedcol@{%
   \ifvoid\footins
     \setbox\@outputbox \box \@cclv
   \else
     \setbox\@outputbox \vbox {%
       \boxmaxdepth \@maxdepth
       \unvbox \@cclv
       \vskip \skip\footins
       \color@begingroup
         \normalcolor
         \footnoterule
         \unvbox \footins
       \color@endgroup
       }%
   \fi
   \ifdim\ht\curr@nfbox@S@uc>0.49\textheight
     \setbox\@tempboxa\vsplit\curr@nfbox@S@uc to 0.5\textheight
     \setbox\@outputbox \vbox 
       \bgroup
         \box\@tempboxa
         \nointerlineskip
         \box\@outputbox
       \egroup
   \fi
   \ifdim\ht\curr@nfbox@S@lc>0.49\textheight
     \setbox\@tempboxa\vsplit\curr@nfbox@S@lc to 0.5\textheight
     \setbox\@outputbox \vbox 
       \bgroup
         \box\@outputbox
         \nointerlineskip
         \box\@tempboxa
       \egroup
   \fi
   \nf@opcol}
%    \end{macrocode}
%   
% \end{macro}
%
%
% \begin{macro}{\nf@opcol}
% \changes{v1.3}{2013/12/16}{Typo corrected}
%   This is like the standard \LaTeX\ \cs{@outputdblcol}, but with the
%   treatment of wide nonfloats.
%    \begin{macrocode}
\def\nf@opcol{%
  \if@firstcolumn
    \global\@firstcolumnfalse
    \global\setbox\@leftcolumn\box\@outputbox
  \else
    \global\@firstcolumntrue
    \ifdim\ht\curr@nfbox@W@ul>0.5\baselineskip
      \setbox\@tempboxa\vsplit \curr@nfbox@W@ul to 0.5\textheight
    \else
      \setbox\@tempboxb\box\@tempboxa
    \fi
    \setbox\@outputbox \vbox\bgroup
      \box\@tempboxa
      \nointerlineskip
      \hb@xt@\textwidth {%
        \hb@xt@\columnwidth {%
          \box\@leftcolumn \hss}%
        \hfil
        {\normalcolor\vrule \@width\columnseprule}%
        \hfil
        \hb@xt@\columnwidth {%
          \box\@outputbox \hss}%
      }%
    \egroup
    \ifdim\ht\curr@nfbox@W@ll>0.5\baselineskip
      \setbox\@tempboxa\vsplit \curr@nfbox@W@ll to 0.5\textheight
      \setbox\@outputbox\vbox\bgroup
        \box\@outputbox
        \nointerlineskip
        \box\@tempboxa
      \egroup
    \fi
    \@outputpage
    \global\vsize\textheight
    \global\@colht\textheight
    \global\@colroom\textheight
   \fi}
%    \end{macrocode}
%   
% \end{macro}
%
% \begin{macro}{\standard@clearpage}
%   The usual \cs{clearpage} flushes the floats.  We keep it in
%   \cs{standard@clearpage}
%    \begin{macrocode}
\let\standard@clearpage\clearpage
%    \end{macrocode}
%   
% \end{macro}
% 
% \begin{macro}{\clearpage}
%   Now we can define \cs{clearpage} to take care of the mode:
%    \begin{macrocode}
\def\clearpage{%
  \if@twocolumn
    \nf@clearpage
  \else
    \standard@clearpage
\fi}
%    \end{macrocode}
%   
% \end{macro}
%
% \begin{macro}{\nf@totalheight}
%   The total height of all non-floats
%    \begin{macrocode}
\def\nf@totalheight{\dimexpr(%
  \ht\nfbox@S@UL+
  \ht\nfbox@S@UR+
  \ht\nfbox@S@LL+
  \ht\nfbox@S@LR+
  \ht\nfbox@T@UL+
  \ht\nfbox@T@UR+
  \ht\nfbox@W@UL+
  \ht\nfbox@W@LL+
  \ht\nfbox@B@UL+
  \ht\nfbox@S@ul+
  \ht\nfbox@S@ur+
  \ht\nfbox@S@ll+
  \ht\nfbox@S@lr+
  \ht\nfbox@T@ul+
  \ht\nfbox@T@ur+
  \ht\nfbox@W@ul+
  \ht\nfbox@W@ll+
  \ht\nfbox@B@ul)}
%    \end{macrocode}
%   
% \end{macro}
%
%
% \begin{macro}{\nf@clearpage}
%   We keep ejecting pages until get rid of nf stuff
%    \begin{macrocode}
 \def\nf@clearpage{%
  \write\m@ne{}%
  \if@firstcolumn
    \ifdim\dimexpr(\pagetotal+\nf@totalheight)>\baselineskip
    \leavevmode
     \null\vfill\newpage
     \null\vfill\newpage
    \fi
  \else
    \leavevmode
   \null\vfill\newpage
  \fi
  \ifdim\nf@totalheight>\baselineskip
  \nf@clearpage\fi
}
%    \end{macrocode}
%   
% \end{macro}
%
% \begin{macro}{\clearspread}
%   This is like \cs{cleardoublepage}, but with the logic inverted:
%    \begin{macrocode}
\def\clearspread{\clearpage\ifodd\c@page
    \hbox{}\newpage\if@twocolumn\hbox{}\newpage\fi\fi\@firstcolumntrue}
%    \end{macrocode}
%   
% \end{macro}
%
% We need to clear everything at the end
%    \begin{macrocode}
\AtEndDocument{\if@twocolumn
  \ifdim\nf@totalheight>\baselineskip
  \null\vfill\clearpage\fi
\fi}
%    \end{macrocode}
% 
%
