%\iffalse
% flowfram.dtx generated using makedtx version 0.94b (c) Nicola Talbot
% Command line args:
%   -src "flowfram.sty\Z=>flowfram.sty"
%   -doc "docstub.tex"
%   -author "Nicola Talbot"
%   -dir "source"
%   flowfram
% Created on 2007/8/21 13:54
%\fi
%\iffalse
%<*package>
%% \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         \~}
%</package>
%\fi
% \iffalse
% Doc-Source file to use with LaTeX2e
% Copyright (C) 2007 Nicola Talbot, all rights reserved.
% \fi
% \iffalse
%<*driver>
\documentclass{ltxdoc}

\CheckSum{8345}
\PageIndex

\usepackage{url}
\usepackage[colorlinks,hyperindex=false,
pdfauthor={Nicola L C Talbot},
pdftitle={Documented Source Code for flowfram.sty}]{hyperref}
\usepackage[style=altlist,toc,nonumberlist]{glossaries}

\newglossary[slg]{secondary}{sgi}{sgo}{Glossary}
\renewcommand{\acronymtype}{secondary}

\MakeShortVerb"
\DeleteShortVerb|

\newcommand{\sty}[1]{\textsf{#1}}
\newcommand{\env}[1]{\textsf{#1}}

\renewcommand{\usage}[1]{\textit{\hyperpage{#1}}}
\renewcommand{\main}[1]{\hyperpage{#1}}
\newcommand{\see}[2]{\emph{see} #1}
\makeatletter
\def\index@prologue{\section*{Index}
\addcontentsline{toc}{section}{Index}}
\makeatother


\newglossaryentry{typeblock}{name=typeblock,description={The 
area of the page where the main body of the text goes.
The width and height of this area are given by \cs{textwidth}
and \cs{textheight}},type=secondary}

\newglossaryentry{flow}{name=flow frame,description={The frames in 
a document such that the contents of the \env{document}
environment flow from one frame to the next in the order 
that they were defined. There must be at least one flow frame on
every page},type=secondary}

\newglossaryentry{static}{name=static frame,description={Frames
in which text is fixed in place. The contents are fixed until
explicitly changed},type=secondary}

\newglossaryentry{dynamic}{name=dynamic frame,description={Frames
in which text is fixed in place, but the contents are re-typeset
after each page},type=secondary}

\newglossaryentry{frame}{name=frame,description={A rectangular
area of the page in which text can be placed (not to be
confused with a frame making command). There are three types:
flow, static and dynamic},type=secondary}

\newglossaryentry{fcmd}{name=frame making command,description={A
\LaTeX\ command which places some kind of border around its
argument. For example: \cs{fbox}},type=secondary}

\newglossaryentry{pglist}{name=page list,description={A list of
pages. This can either be a single keyword: \texttt{all},
\texttt{odd}, \texttt{even} or \texttt{none}, or it can
be a comma-separated list of individual page numbers or
page ranges. For example: \texttt{\textless3,5,7-11,\textgreater15}
indicates pages 1,2,5,7,8,9,10,11 and all pages after page 15.
Note that these numbers refer to the actual value of the
page counter, not the absolute physical page number},
type=secondary}

\newglossaryentry{pgrange}{name=page range,description={Page
ranges can be closed, e.g.\ \texttt{5-10}, or open, e.g.
\texttt{\textless7} or \texttt{\textgreater9}},
type=secondary}

\newglossaryentry{bbox}{name=bounding box,plural=bounding boxes,
description={The smallest
possible rectangle that completely encompasses the object},
type=secondary}

\newacronym[name={identification number (IDN)},
description={A unique
number assigned to each frame, which you can use to identify
the frame when modifying its appearance. Example: if you
have defined 3 flow frames, 2 static frames and 1 dynamic
frame, the flow frames will have IDNs 1, 2 and 3, the static
frames will have IDNs 1 and 2, and the dynamic frame will
have IDN 1}]{idn}{IDN}{identification number}

\newacronym[name={identification label (IDL)},
description={A unique
label which can be assigned to a frame, enabling you to
refer to the frame by label instead of by its 
IDN}]{idl}{IDL}{identification label}

\makeglossaries

\begin{document}
\DocInput{flowfram.dtx}
\end{document}
%</driver>
%\fi
%\title{Documented Source Code for flowfram.sty v1.10}
%\author{Nicola L. C. Talbot}
%\date{20th Aug 2007}
%\maketitle
%
%This is the documented source code for the flowfram package.
%For a user manual, see \url{ffuserguide.pdf}.
%
%\tableofcontents
%
%\printglossary[type=secondary]
%
%\StopEventually{\PrintIndex}
%
%
%\section{The Code}
%\iffalse
%    \begin{macrocode}
%<*flowfram.sty>
%    \end{macrocode}
%\fi
% \subsection{Package Initialisation}
% Declare package, and identify it as a \LaTeXe\ package.
%    \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{flowfram}[2007/08/21 v1.10]
%    \end{macrocode}
% Load packages needed by this package
%    \begin{macrocode}
\RequirePackage{ifthen}
\RequirePackage{keyval}
\RequirePackage{graphics}
\RequirePackage{afterpage}
\@ifundefined{@ldc@l@r}{\RequirePackage{color}}{}
%    \end{macrocode}
% The colour of the \gls{bbox} borders when the draft 
% option is specified is given by the commands:
%    \begin{macrocode}
\newcommand{\setffdraftcolor}{\color[gray]{0.8}}
\newcommand{\setffdrafttypeblockcolor}{\color[gray]{0.9}}
%    \end{macrocode}
%\begin{macro}{\fflabelsep}
% In draft mode, each \gls{bbox} (apart from the one indicating
% the \gls{typeblock}), has a label positioned to the right of the
% box, at a distance of "\fflabelsep" from the right hand
% border.\DescribeMacro{\fflabelsep}
%    \begin{macrocode}
\newlength\fflabelsep
\fflabelsep=1pt
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\fflabelfont}
% The appearance of the label is set by the declaration:
%    \begin{macrocode}
\newcommand*{\fflabelfont}{\small\sffamily}
%    \end{macrocode}
%\end{macro}
% The command "\@ffdraft" is used to switch to draft mode.
% Allow user the option to show particular types of bounding
% boxes.
%    \begin{macrocode}
\newif\ifshowtypeblock
\newif\ifshowmargins
\newif\ifshowframebbox
%    \end{macrocode}
%\begin{macro}{\@ffdraft}
% Set all draft settings.
%    \begin{macrocode}
\newcommand*{\@ffdraft}{%
\showtypeblocktrue
\showmarginstrue
\showframebboxtrue
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ffnodraft}
% Unset all draft settings.
%    \begin{macrocode}
\newcommand*{\@ffnodraft}{%
\showtypeblockfalse
\showmarginsfalse
\showframebboxfalse
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@fr@meifdraft}
% Draw \gls{bbox}.
%    \begin{macrocode}
\newcommand*{\@fr@meifdraft}[3][\setffdraftcolor]{%
\def\ff@backcol{{none}}%
\@ifundefined{color}{\frame{#2}}{#1\frame{#2}}%
\ifthenelse{\equal{#3}{}}{}{%
\makebox[0pt][l]{\hskip\fflabelsep\fflabelfont{[#3]}}}}%
%    \end{macrocode}
%\end{macro}
% Colour setting commands, do nothing by default:
%    \begin{macrocode}
\newcommand*{\@s@tffcol}{}
\newcommand*{\@s@tfftextcol}{}
%    \end{macrocode}
%\begin{macro}{\@ffbackground}
% Deal with \gls{frame} background colour. Note that the background colour only
% extends to the limit of the \gls{frame}['s] \gls{bbox}. If you want the background
% colour to be flush with the \glspl{frame} border, you will have to create your own
% customised border.
%    \begin{macrocode}
\newcommand*{\@ffbackground}[1]{#1}
%    \end{macrocode}
%\end{macro}
% Now declare the options.  If draft, switch to draft definitions.
%    \begin{macrocode}
\DeclareOption{draft}{\@ffdraft}
%    \end{macrocode}
% If not draft, reset commands so that no \glspl{bbox}
% are drawn.
%    \begin{macrocode}
\DeclareOption{final}{\@ffnodraft}
%    \end{macrocode}
%\begin{macro}{\if@ttb@rotate}
% Allow provision to prevent rotation in the thumbtabs.
% If no rotation, thumbtab text will be stacked vertically.
% This will also affect whether or not to rotate \glspl{frame}.
%    \begin{macrocode}
\newif\if@ttb@rotate
\@ttb@rotatetrue
\DeclareOption{rotate}{\@ttb@rotatetrue}
\DeclareOption{norotate}{\@ttb@rotatefalse}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\rotateframe}
% Define command that will only rotate box if rotate option
% set.
%    \begin{macrocode}
\newcommand{\rotateframe}[2]{\if@ttb@rotate
\rotatebox{#1}{#2}%
\else
#2\relax
\fi}
%    \end{macrocode}
%\end{macro}
% Should the thumbtabs include number, title, both or
% neither?
%    \begin{macrocode}
\newif\if@ttb@num
\newif\if@ttb@title
\@ttb@numfalse
\@ttb@titletrue
\DeclareOption{ttbtitle}{\@ttb@titletrue}
\DeclareOption{ttbnotitle}{\@ttb@titlefalse}
\DeclareOption{ttbnum}{\@ttb@numtrue}
\DeclareOption{ttbnonum}{\@ttb@numfalse}
%    \end{macrocode}
% If color option specified, set up the default colours
% for the borders and text for all \gls{frame} types. Note that
% the colour name has to be grouped within the definition
% of "\flowframecol" and "\flowframetextcol". This
% was done so that you could do, for example, 
% "\renewcommand{\flowframecol}{[rgb]{1,1,0}}" so that
% you can specify the colour model as well.
% The commands "\@s@tffcol" and "\@s@tfftextcol"
% switch to the border and text colour, respectively. They
% both assume that "\ff@col" has been set to the 
% relevant colour before use.
%    \begin{macrocode}
\DeclareOption{color}{%
\def\flowframecol{{black}}\def\flowframetextcol{{black}}
\renewcommand*\@s@tffcol{\ifthenelse{\equal{\ff@col}{}}{}{%
\expandafter\color\ff@col}}
\renewcommand*\@s@tfftextcol{\ifthenelse{\equal{\ff@txtcol}{}}{}{%
\expandafter\color\ff@txtcol}}
\renewcommand*{\@ffbackground}[1]{%
\ifthenelse{\equal{\ff@backcol}{{none}}}{%
#1}{{\fboxsep=0pt\expandafter\colorbox\ff@backcol{#1}}}}
}
%    \end{macrocode}
% If nocolor is specified, ensure that the colour changing
% commands do nothing.
%    \begin{macrocode}
\DeclareOption{nocolor}{%
\def\flowframetextcol{}%
\def\flowframecol{}%
\renewcommand{\@s@tffcol}{}\renewcommand{\@s@tfftextcol}{}
\renewcommand{\@ffbackground}[1]{#1}
}
%    \end{macrocode}
% Check to see if the document class has the draft option
% set. The easiest way to do this is to check the length
% of "\overfullrule" (the marker that indicates overfull
% hboxes).
%    \begin{macrocode} 
\ifdim\overfullrule=0pt
\ExecuteOptions{final}
\else
\ExecuteOptions{draft}
\fi
%    \end{macrocode}
% If the "\normalcolor" command is something other than 
% "\relax", then implement
% the color option as the default, otherwise implement the
% nocolor option as the default.
%    \begin{macrocode}
\ifx\normalcolor\relax
\ExecuteOptions{nocolor}
\else
\ExecuteOptions{color}
\fi
%    \end{macrocode}
% Now the defaults have all been set, the package options
% specified by the user can be processed:
%    \begin{macrocode}
\ProcessOptions
%    \end{macrocode}
% If color option has been specified, but no color
% package has been loaded yet, load color.sty
%    \begin{macrocode}
\ifx\normalcolor\relax
\ifthenelse{\equal{\flowframetextcol}{}}{}{%
\RequirePackage{color}}
\fi
%    \end{macrocode}
% User may want a non standard style for the first page of 
% each chapter, so modify chapter commands to take this into 
% account.\DescribeMacro{\chapterfirstpagestyle}
%    \begin{macrocode}
\@ifundefined{chapter}{}{%
\newcommand*{\chapterfirstpagestyle}{plain}
\let\@ff@OLD@chapter\@chapter
\let\@ff@OLD@schapter\@schapter
\renewcommand{\@chapter}{%
\thispagestyle{\chapterfirstpagestyle}\@ff@OLD@chapter}
\renewcommand{\@schapter}{%
\thispagestyle{\chapterfirstpagestyle}\@ff@OLD@schapter}
}
%    \end{macrocode}
% Now get on with the package.  First we need to set up 
% a count register to store the number of \glspl{flow}, and
% one to store the id number of the current \gls{flow}:
%    \begin{macrocode}
\newcounter{maxflow}
\newcounter{thisframe}
\c@maxflow=0\relax
\c@thisframe=0\relax
%    \end{macrocode}
% Define a counter to store the total number of \glspl{static}:
%    \begin{macrocode}
\newcounter{maxstatic}
\c@maxstatic=0\relax
%    \end{macrocode}
% Define a counter to store the total number of \glspl{dynamic}:
%    \begin{macrocode}
\newcounter{maxdynamic}
\c@maxdynamic=0\relax
%    \end{macrocode}
% Define some temporary variables
%    \begin{macrocode}
\newcount\@colN
\newcount\@ff@tmpN
\newcount\ff@id
\newlength\@ff@offset
\newlength\@ff@tmp@x
\newlength\@ff@tmp@x@even
\newlength\@ff@tmp@y
%    \end{macrocode}
%\begin{macro}{\sdfparindent}
% Define a length to govern paragraph indentation within 
% static and dynamic frames.
% This is 0pt by default. 
%    \begin{macrocode}
\newlength\sdfparindent
%    \end{macrocode}
%\end{macro}
%
% \subsection{Flow Frames}
%\begin{macro}{\flowframesep}
% Set up default lengths. The gap between the text and the
% border is given by:
%    \begin{macrocode}
\newlength\flowframesep
\flowframesep=\fboxsep
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\flowframerule}
% The width of the frame is given by:
%    \begin{macrocode}
\newlength\flowframerule
\flowframerule=\fboxrule
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\flowframeshowlayout}
% Define command to show page layout.  This finishes the current
% page, temporarily sets draft mode, and prints an empty page.
% Only the \glspl{frame} for that page will be shown.
%\DescribeMacro{\flowframeshowlayout}
%    \begin{macrocode}
\newcommand*{\flowframeshowlayout}{%
\finishthispage
{\@ffdraft\mbox{}\finishthispage\clearpage}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\framebreak}
% If the \glspl{flow} are not all of the same width, the change
% in "\hsize" will not come into effect until the end
% of the paragraph. Provide a command to simulate a paragraph
% break, without making it look as though there is a paragraph.
% Provides an optional argument that is passed to 
% "\pagebreak".  Make sure it is grouped to localise
% the change in "\parfillskip" and "\parskip".
%    \begin{macrocode}
\newif\ifusedframebreak
\newcommand{\framebreak}[1][4]{%
\usedframebreaktrue
{\parfillskip=0pt\pagebreak[#1]\parskip=0pt\par\noindent}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\finishthispage}
% The commands "\newpage" and
% "\pagebreak" can be used to move on to the next
% \gls{flow}, but to finish the entire page, use 
% "\finishthispage".
%    \begin{macrocode}
\newcommand{\finishthispage}{%
\@colN=\c@thisframe
\newpage
\whiledo{\@colN<\c@maxflow}{\advance\@colN by 1\relax
\@ff@chckifthispg{\c@page}{\@colN}%
\if@notthiscol\else
\mbox{}\newpage%
\fi
}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\cleardoublepage}
% Modify the definition of "\cleardoublepage". This may
% or may not be defined so use "\def".
%    \begin{macrocode}
\def\cleardoublepage{\finishthispage
\if@twoside
\ifodd\c@page
\else
\hbox{}\finishthispage
\fi
\fi}
%    \end{macrocode}
%\end{macro}
% Disable "@twocolumn" flag, as it makes no sense.
%    \begin{macrocode}
\@twocolumnfalse
%    \end{macrocode}
% Disable "@mparswitch" flag, as each \gls{flow} has
% its own predefined margin setting.
%    \begin{macrocode}
\@mparswitchfalse
%    \end{macrocode}
%\begin{macro}{\globalreversemargin}
% The margins get switched during the output routine, so
% need the effect to be global.
%    \begin{macrocode}
\newcommand{\globalreversemargin}{%
\global\@mparbottom\z@\global\@reversemargintrue}
\newcommand{\globalnormalmargin}{%
\global\@mparbottom\z@\global\@reversemarginfalse}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@getmarginpos}
% Determine whether the margin should be on the right
% or left. This depends on the setting, which can either
% be "right" or "left" (self explanatory) or "inner" (on the 
% spine side, so left for odd pages and right for even
% pages) or "outer" (on the outside of the page, so right
% for odd pages and left for even pages.) When "\@getmarginpos"
% is finished, the setting is stored in "\ff@margin".
%    \begin{macrocode}
\newcommand{\@getmarginpos}[1]{%
\ifthenelse{\equal{#1}{inner}}{%
\if@twoside
\ifodd\c@page\def\ff@margin{left}\else\def\ff@margin{right}\fi
\else
\def\ff@margin{left}%
\fi
}{%
\ifthenelse{\equal{#1}{outer}}{%
\if@twoside
\ifodd\c@page\def\ff@margin{right}\else\def\ff@margin{left}\fi
\else
\def\ff@margin{right}%
\fi
}{%
\def\ff@margin{#1}}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\setmargin}
% Set the margin for current \gls{flow}.
%    \begin{macrocode}
\newcommand{\setmargin}{%
\@getmarginpos{%
\csname @ff@margin@\romannumeral\c@thisframe\endcsname}%
\ifthenelse{\equal{\ff@margin}{left}}%
{\globalreversemargin}{\globalnormalmargin}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\newflowframe}
% Create a new \gls{flow}. Syntax:\newline
% \cs{newflowframe}\oarg{pages}\marg{width}\marg{height}\marg{x}\marg{y}\oarg{label}
%
% First increment "\c@maxflow", and define boolean
% to indicate whether or not the \gls{flow} has a border,
% Then check to see whether or not the starred version is
% begin used. All the settings must be global: the
% output routine will create a new \gls{flow}, if there are no
% more defined, and since changes made in the output routine
% are localised, the new \gls{frame} will be lost unless it is 
% globally defined. Flow frames should only be set up in the
% preamble, but if there are not enough \glspl{frame} to fit all
% the document text, the output routine will create a new \gls{flow}.
% So, define "\newflowframe" so that it calls 
% "\@n@wflowframe"
%    \begin{macrocode}
\newcommand{\newflowframe}{\@n@wflowframe}
%    \end{macrocode}
%\end{macro}
% Set the external command for use only in the preamble, an
% make the output routine use the internal command
%    \begin{macrocode}
\@onlypreamble{\newflowframe}
%    \end{macrocode}
%\begin{macro}{\@n@wflowframe}
%    \begin{macrocode}
\newcommand{\@n@wflowframe}{%
\global\advance\c@maxflow by 1\relax
\expandafter\global\expandafter
\newif\csname ifcolumnframe\romannumeral\c@maxflow\endcsname
\@ifstar\@snewflowframe\@newflowframe
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@snewflowframe}
% Starred version sets boolean flag to indicate a border
%    \begin{macrocode}
\newcommand{\@snewflowframe}{%
\expandafter\global\expandafter
\let\csname ifcolumnframe\romannumeral\c@maxflow\endcsname\iftrue
\@@newflowframe}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@newflowframe}
% The unstarred version unsets boolean flag to indicate
% no border.
%    \begin{macrocode}
\newcommand{\@newflowframe}{%
\expandafter\global\expandafter
\let\csname ifcolumnframe\romannumeral\c@maxflow\endcsname\iffalse
\@@newflowframe}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@newflowframe}
% Now get on with initialising the \gls{flow}. By default, it
% will apply the \gls{flow} to all pages, the optional argument
% can override this.
%    \begin{macrocode}
\newcommand{\@@newflowframe}[5][all]{%
\expandafter\global\expandafter
\newbox\csname column\romannumeral\c@maxflow\endcsname
\expandafter\global\expandafter
\newlength\csname colwidth\romannumeral\c@maxflow\endcsname
\expandafter\global\expandafter
\newlength\csname colheight\romannumeral\c@maxflow\endcsname
\expandafter\global\expandafter
\newlength\csname col@\romannumeral\c@maxflow @posx\endcsname
\expandafter\global\expandafter
\newlength\csname col@\romannumeral\c@maxflow @posy\endcsname
\expandafter\global\expandafter
\setlength\csname colwidth\romannumeral\c@maxflow\endcsname{#2}
\expandafter\global\expandafter
\setlength\csname colheight\romannumeral\c@maxflow\endcsname{#3}
\expandafter\global\expandafter
\setlength\csname col@\romannumeral\c@maxflow @posx\endcsname{#4}
\expandafter\global\expandafter
\setlength\csname col@\romannumeral\c@maxflow @posy\endcsname{#5}
\expandafter\global\expandafter
\newlength\csname col@\romannumeral\c@maxflow @evenx\endcsname
\expandafter\global\expandafter
\newlength\csname col@\romannumeral\c@maxflow @eveny\endcsname
\expandafter\global\expandafter
\setlength\csname col@\romannumeral\c@maxflow @evenx\endcsname{#4}
\expandafter\global\expandafter
\setlength\csname col@\romannumeral\c@maxflow @eveny\endcsname{#5}
\expandafter
\gdef\csname @ff@frametype@\romannumeral\c@maxflow\endcsname{fbox}%
\expandafter
\gdef\csname @ff@col@\romannumeral\c@maxflow\endcsname{\flowframecol}
\expandafter
\gdef\csname @ff@txtcol@\romannumeral\c@maxflow\endcsname{%
\flowframetextcol}
\expandafter
\gdef\csname @ff@backcol@\romannumeral\c@maxflow\endcsname{{none}}
\expandafter
\gdef\csname @ff@pages@\romannumeral\c@maxflow\endcsname{#1}
\expandafter
\gdef\csname @ff@offset@\romannumeral\c@maxflow\endcsname{compute}
\expandafter
\gdef\csname @ff@angle@\romannumeral\c@maxflow\endcsname{0}%
\expandafter
\gdef\csname @ff@margin@\romannumeral\c@maxflow\endcsname{right}
\ifnum\c@thisframe=0\relax
\ifthenelse{\equal{#1}{all}\TE@or\equal{#1}{odd}}{%
\c@thisframe=\c@maxflow
\global\setlength{\hsize}{#2}%
\global\usedframebreaktrue
}{\ifthenelse{\equal{#1}{even}\TE@or\equal{#1}{none}}{}{%
\def\ff@pages{#1}%
\@for\@ff@pp:=\ff@pages\do{%
\def\@ff@numstart{0}\def\@ff@numend{0}%
\@ff@getrange{\@ff@pp}%
\ifnum\@ff@numstart=0\def\@ff@numstart{1}\fi
\ifnum\@ff@numstart=1\relax
\c@thisframe=\c@maxflow
\global\setlength{\hsize}{#2}%
\global\usedframebreaktrue
\fi
}}}%
\fi
\@ifnextchar[{\@s@tflowframeid{\c@maxflow}}{%
\@s@tflowframeid{\c@maxflow}[\number\c@maxflow]}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@s@tflowframeid}
% If square brackets occur after "\newflowframe", take
% the contents to be the label, otherwise the label will be
% the \gls{flow} number.
%    \begin{macrocode}
\def\@s@tflowframeid#1[#2]{%
\edef\ff@label{#2}%
\@ff@checkuniqueidl{#1}{\ff@label}%
\expandafter
\xdef\csname @col@id@\romannumeral#1\endcsname{\ff@label}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@checkuniqueidl}
% Check \gls{idl} "#2" for \gls{flow} "#1" is unique
%    \begin{macrocode}
\newcommand*{\@ff@checkuniqueidl}[2]{%
{\@colN=0\relax
\whiledo{\@colN<\c@maxflow}{%
\advance\@colN by 1\relax
\ifnum\@colN=#1\relax
\else
\ifthenelse{\equal{#2}{%
\csname @col@id@\romannumeral\@colN\endcsname}}{%
\PackageError{flowfram}{Flow frame IDL '#2' already defined}{%
You can't assign this label, as it is already defined
for flow frame \number\@colN}}{}%
\fi
}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@flowframeid}
% Work out the \gls{flow} \gls{idn} from the label. This
% iterates through the \glspl{flow}, so if you have a lot of
% them it is quicker to identifiy them by their \gls{idn}
% rather than their \gls{idl}.
% The \gls{idn} stored in "\ff@id".
%    \begin{macrocode}
\newcommand*{\@flowframeid}[1]{\@colN=0\relax
\ff@id=0\relax
\whiledo{\@colN<\c@maxflow}{\advance\@colN by 1\relax
\ifthenelse{%
\equal{#1}{\csname @col@id@\romannumeral\@colN\endcsname}}{%
\ff@id=\@colN\relax
% break out of loop
\@colN=\c@maxflow}{}}%
\ifnum\ff@id=0\relax
\PackageError{flowfram}{Can't find flow frame id '#1'}{}\fi}
%    \end{macrocode}
%\end{macro}
% Set up the keys for use with "\setflowframe", 
% "\setstaticframe" and "\setdynamicframe".
%
% Frame width is stored in "\ff@width".
%    \begin{macrocode}
\define@key{flowframe}{width}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'width' key}{}}{}%
\def\ff@width{#1}}
%    \end{macrocode}
% Frame height is stored in "\ff@height".
%    \begin{macrocode}
\define@key{flowframe}{height}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'height' key}{}}{}%
\def\ff@height{#1}}
%    \end{macrocode}
% Frame $x$ co-ordinate (odd and even pages) is stored
% in "\ff@x".
%    \begin{macrocode}
\define@key{flowframe}{x}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'x' key}{}}{}%
\def\ff@x{#1}}
%    \end{macrocode}
% Frame $y$ co-ordinate (odd and even pages) is stored
% in "\ff@y".
%    \begin{macrocode}
\define@key{flowframe}{y}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'y' key}{}}{}%
\def\ff@y{#1}}
%    \end{macrocode}
% Frame $x$ co-ordinate (even pages only) is stored
% in "\ff@evenx".
%    \begin{macrocode}
\define@key{flowframe}{evenx}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'evenx' key}{}}{}%
\def\ff@evenx{#1}}
%    \end{macrocode}
% Frame $y$ co-ordinate (even pages only) is stored in
% "\ff@eveny".
%    \begin{macrocode}
\define@key{flowframe}{eveny}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'eveny' key}{}}{}%
\def\ff@eveny{#1}}
%    \end{macrocode}
% Frame $x$ co-ordinate (odd pages only if twoside implemented)
% is stored in "\ff@oddx".
%    \begin{macrocode}
\define@key{flowframe}{oddx}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'oddx' key}{}}{}%
\def\ff@oddx{#1}}
%    \end{macrocode}
% Frame $y$ co-ordinate (odd pages only if twoside implemented)
% is stored in "\ff@oddy".
%    \begin{macrocode}
\define@key{flowframe}{oddy}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'oddy' key}{}}{}%
\def\ff@oddy{#1}}
%    \end{macrocode}
% New \gls{idl} for \gls{frame} is stored in "\ff@label".
%    \begin{macrocode}
\define@key{flowframe}{label}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'label' key}{}}{}%
\def\ff@label{#1}}
%    \end{macrocode}
% Frame border. If "none", define "\ff@frame" as "false", 
% otherwise define "\ff@frame" as "true". If "plain", define
% "\ff@frametype" as "fbox", otherwise define it to be
% the specified type, which should be the name of a
% \gls{fcmd} without the preceding backslash.
%    \begin{macrocode}
\define@key{flowframe}{border}[plain]{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'border' key - use
'none' for no border}{}}{}%
\ifthenelse{\equal{#1}{none}}{%
\def\ff@frame{false}}{\def\ff@frame{true}%
\ifthenelse{\equal{#1}{plain}}{\def\ff@frametype{fbox}}{%
\def\ff@frametype{#1}}}}
%    \end{macrocode}
% Frame's border colour. (This may not work for non-standard
% \glspl{fcmd}.)
%    \begin{macrocode}
\define@key{flowframe}{bordercolor}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'bordercolor' key}{}}{}%
\def\ff@col{#1}}
%    \end{macrocode}
% Frame's text colour.
%    \begin{macrocode}
\define@key{flowframe}{textcolor}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'textcolor' key}{}}{}%
\def\ff@txtcol{#1}}
%    \end{macrocode}
% The background colour of the \gls{frame}. Note this only covers
% the region of the \gls{bbox}, not any extra space between
% the \gls{bbox} and the border. If you want the background
% colour to go right up to the border, you will need to 
% define your own customised border.
%    \begin{macrocode}
\define@key{flowframe}{backcolor}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'backcolor' key}{}}{}%
\def\ff@backcol{#1}}
%    \end{macrocode}
% \Gls{pglist} for which the \gls{frame} should appear.
%    \begin{macrocode}
\define@key{flowframe}{pages}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'pages' key}{}}{}%
\def\ff@pages{#1}}
%    \end{macrocode}
% The border takes up extra space, which needs to be
% adjusted. This can be done for standard border types,
% but non-standard borders may require some help.
%    \begin{macrocode}
\define@key{flowframe}{offset}{\def\ff@offset{#1}%
\ifthenelse{\equal{#1}{}}{\PackageError{flowframe}{%
Invalid value for key 'offset'}{%
'offset' can either be 'compute' (to compute it according
to certain pre-defined rules) or a length}}{}}
%    \end{macrocode}
% Angle to rotate \gls{flow}:
%    \begin{macrocode}
\define@key{flowframe}{angle}{\def\ff@angle{#1}%
}
%    \end{macrocode}
% This key is only for \glspl{flow}:
%    \begin{macrocode}
\define@key{flowframe}{margin}{%
\ifthenelse{\equal{#1}{left} \or \equal{#1}{right} 
\or \equal{#1}{inner} \or \equal{#1}{outer}}{%
\def\ff@margin{#1}}{\PackageError{flowfram}{invalid value of 
'margin' key}{Key 'margin' can only take the values 
'left' or 'right'}}}
%    \end{macrocode}
% This key is only for \glspl{static}:
%    \begin{macrocode}
\define@key{flowframe}{clear}[true]{%
\ifthenelse{\equal{#1}{true}\or\equal{#1}{false}}{%
\def\ff@clear{#1}}{\PackageError{flowfram}{Key 'clear' is 
boolean}{You can only specify the values 'true' or 'false'}}}
%    \end{macrocode}
% This key is only for \glspl{dynamic}:
%    \begin{macrocode}
\define@key{flowframe}{style}{\ifthenelse{\equal{#1}{}}{%
\PackageError{flowfram}{Missing value for 'style' key}{}}{}%
\ifthenelse{\equal{#1}{none}}{\def\ff@style{relax}}{\def\ff@style{#1}}}
%    \end{macrocode}
% This key is only for \glspl{static} and \glspl{dynamic}.
%    \begin{macrocode}
\define@key{flowframe}{shape}{\def\ff@shape{#1}%
}
%    \end{macrocode}
% This key is only for \glspl{static} and \glspl{dynamic}.
%    \begin{macrocode}
\define@key{flowframe}{valign}{\ifthenelse{\equal{#1}{c} \or
\equal{#1}{t} \or \equal{#1}{b}}{\def\ff@valign{#1}}{%
\PackageError{flowfram}{Invalid value for 'valign' key}{You
may only specify 'c', 't' or 'b'}}}
%    \end{macrocode}
%\begin{macro}{\setallflowframes}
% Provide a command to change the settings for all flow
% frames. This just iterates through all the \glspl{flow},
% and sets each one in turn.
%    \begin{macrocode}
\newcommand*{\setallflowframes}[1]{%
\@colN=0\whiledo{\@colN<\c@maxflow}{\advance\@colN by 1\relax
\@@setflowframe{\@colN}{#1}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\setflowframe}
% Define "\setflowframe" command. Check to see
% whether or not the starred version is being used.
%    \begin{macrocode}
\newcommand*{\setflowframe}{\@ifstar\@ssetflowframe\@setflowframe}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ssetflowframe}
% This is the starred version. It finds the \gls{idn} for
% each label in the comma-separated list (first argument), 
% and applies the setting for that numbered \gls{flow}.
%    \begin{macrocode}
\newcommand{\@ssetflowframe}[2]{%
\@for\@ff@id:=#1\do{%
\@flowframeid{\@ff@id}%
\@@setflowframe{\ff@id}{#2}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@setflowframe}
% This is the unstarred version. It iterates through
% each \gls{idn} in the comma-separated list passed
% as the first argument, but it also checks for number
% ranges, and sets the values for that \gls{flow}. Ensures
% that number ranges do not lie out of bounds.
%    \begin{macrocode}
\newcommand*{\@setflowframe}[2]{%
\ifthenelse{\equal{#1}{all}}{%
\setallflowframes{#2}}{%
\ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{%
\ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}%
\whiledo{\@colN<\c@maxflow\TE@or\@colN=\c@maxflow}{%
\@@setflowframe{\@colN}{#2}%
\advance\@colN by 2\relax}%
}{%
\@for\@ff@id:=#1\do{%
\def\@ff@numstart{0}\def\@ff@numend{10000}%
\@ff@getrange{\@ff@id}%
\ifnum\@ff@numstart=0\relax
  \def\@ff@numstart{1}%
\fi
\ifnum\@ff@numend>\c@maxflow
  \def\@ff@numend{\c@maxflow}%
\fi
\@colN=\@ff@numstart
\whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{%
\@@setflowframe{\@colN}{#2}%
\advance\@colN by 1\relax
}}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@setflowframe}
% This is the command that actually sets the values for
% the \gls{flow} whose \gls{idn} is specified by the first
% parameter.
%    \begin{macrocode}
\newcommand*{\@@setflowframe}[2]{%
\def\ff@frame{}\def\ff@width{}\def\ff@height{}\def\ff@margin{}%
\def\ff@x{}\def\ff@y{}\def\ff@frametype{}\def\ff@col{}%
\def\ff@valign{}\def\ff@style{}%
\def\ff@txtcol{}\def\ff@clear{}\def\ff@offset{}\def\ff@pages{}%
\def\ff@label{}\def\ff@backcol{}\def\ff@evenx{}\def\ff@eveny{}%
\def\ff@oddx{}\def\ff@oddy{}\def\ff@angle{}\def\ff@shape{\empty}%
\setkeys{flowframe}{#2}%
\ifthenelse{\equal{\ff@frame}{}}{}{%
\setboolean{columnframe\romannumeral#1}{\ff@frame}}%
\ifthenelse{\equal{\ff@width}{}}{}{%
\expandafter\setlength\csname colwidth\romannumeral#1\endcsname
{\ff@width}}%
\ifthenelse{\equal{\ff@height}{}}{}{%
\expandafter\setlength\csname colheight\romannumeral#1\endcsname
{\ff@height}}%
\ifthenelse{\equal{\ff@x}{}}{}{%
\expandafter\setlength\csname col@\romannumeral#1@posx\endcsname
{\ff@x}%
\expandafter\setlength\csname col@\romannumeral#1@evenx\endcsname
{\ff@x}}
\ifthenelse{\equal{\ff@y}{}}{}{%
\expandafter\setlength\csname col@\romannumeral#1@posy\endcsname
{\ff@y}%
\expandafter\setlength\csname col@\romannumeral#1@eveny\endcsname
{\ff@y}}
\ifthenelse{\equal{\ff@evenx}{}}{}{%
\expandafter\setlength\csname col@\romannumeral#1@evenx\endcsname
{\ff@evenx}}
\ifthenelse{\equal{\ff@eveny}{}}{}{%
\expandafter\setlength\csname col@\romannumeral#1@eveny\endcsname
{\ff@eveny}}
\ifthenelse{\equal{\ff@oddx}{}}{}{%
\expandafter\setlength\csname col@\romannumeral#1@posx\endcsname
{\ff@oddx}}
\ifthenelse{\equal{\ff@oddy}{}}{}{%
\expandafter\setlength\csname col@\romannumeral#1@posy\endcsname
{\ff@oddy}}
\ifthenelse{\equal{\ff@label}{}}{}{%
\@s@tflowframeid{#1}[\ff@label]}
\ifthenelse{\equal{\ff@frametype}{}}{}{%
\expandafter\edef\csname @ff@frametype@\romannumeral#1\endcsname
{\ff@frametype}}
\ifthenelse{\equal{\ff@col}{}}{}{%
\expandafter\@setframecol\ff@col\end{#1}{col}{ff}}
\ifthenelse{\equal{\ff@txtcol}{}}{}{%
\expandafter\@setframecol\ff@txtcol\end{#1}{txtcol}{ff}}%
\ifthenelse{\equal{\ff@backcol}{}}{}{%
\expandafter\@setframecol\ff@backcol\end{#1}{backcol}{ff}}%
\ifthenelse{\equal{\ff@margin}{}}{}{%
\expandafter\xdef\csname @ff@margin@\romannumeral#1\endcsname
{\ff@margin}}%
\ifthenelse{\equal{\ff@pages}{}}{}{%
\expandafter\xdef\csname @ff@pages@\romannumeral#1\endcsname
{\ff@pages}}%
\ifthenelse{\equal{\ff@offset}{}}{}{%
\expandafter\xdef\csname @ff@offset@\romannumeral#1\endcsname
{\ff@offset}}%
\ifthenelse{\equal{\ff@angle}{}}{}{%
\expandafter\xdef\csname @ff@angle@\romannumeral#1\endcsname
{\ff@angle}}%
\ifthenelse{\equal{\ff@clear}{}}{}{%
\PackageError{flowfram}%
{Key 'clear' not available for flow frames}{}}%
\ifthenelse{\equal{\ff@style}{}}{}{%
\PackageError{flowfram}%
{Key 'style' not available for flow frames}{}}%
\if\ff@shape\empty
\else
\PackageError{flowfram}%
{Key 'shape' not available for flow frames}{}%
\fi
\ifthenelse{\equal{\ff@valign}{}}{}{%
\PackageError{flowfram}%
{Key 'valign' not available for flow frames}{}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\ffswapoddeven}
% Swap odd and even offsets for a given \gls{flow}. Do the main stuff for 
% a given \gls{flow} \gls{idn}.
%    \begin{macrocode}
\newcommand*{\@@flowframeswapcoords}[1]{%
\setlength{\@ff@tmp@x}%
{\csname col@\romannumeral#1@evenx\endcsname}
\expandafter\setlength\csname col@\romannumeral#1@evenx\endcsname
{\csname col@\romannumeral#1@posx\endcsname}%
\expandafter\setlength\csname col@\romannumeral#1@posx\endcsname
{\@ff@tmp@x}%
\setlength{\@ff@tmp@y}%
{\csname col@\romannumeral#1@eveny\endcsname}
\expandafter\setlength\csname col@\romannumeral#1@eveny\endcsname
{\csname col@\romannumeral#1@posy\endcsname}%
\expandafter\setlength\csname col@\romannumeral#1@posy\endcsname
{\@ff@tmp@y}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\ffswapoddeven}
% Allow user to specify \gls{flow} either by \gls{idn} or \gls{idl}:
%    \begin{macrocode}
\newcommand*{\ffswapoddeven}{%
\@ifstar\@sflowframeswapcoords\@flowframeswapcoords}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sflowframeswapcoords}
% Starred form
%    \begin{macrocode}
\newcommand*{\@sflowframeswapcoords}[1]{%
\@for\@ff@id:=#1\do{%
\@flowframeid{\@ff@id}%
\@@flowframeswapcoords{\ff@id}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@flowframeswapcoords}
% Unstarred form:
%    \begin{macrocode}
\newcommand*{\@flowframeswapcoords}[1]{%
\ifthenelse{\equal{#1}{all}}{%
\ff@id=0\relax
\whiledo{\ff@id<\c@maxflow}{\advance\ff@id by 1\relax
\@@flowframeswapcoords{\ff@id}}%
}{%
\ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{%
\ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}%
\whiledo{\@colN<\c@maxflow\TE@or\@colN=\c@maxflow}{%
\@@flowframeswapcoords{\@colN}%
\advance\@colN by 2\relax}%
}{%
\@for\@ff@id:=#1\do{%
\def\@ff@numstart{0}\def\@ff@numend{10000}%
\@ff@getrange{\@ff@id}%
\ifnum\@ff@numstart=0\relax
  \def\@ff@numstart{1}%
\fi
\ifnum\@ff@numend>\c@maxflow
  \def\@ff@numend{\c@maxflow}%
\fi
\@colN=\@ff@numstart
\whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{%
\@@flowframeswapcoords{\@colN}%
\advance\@colN by 1\relax
}}}}}
%    \end{macrocode}
%\end{macro}
%
% Allow user to get the dimensions of \gls{flow} (useful for
% \glspl{flow} created using "\Ncolumns" etc.) Only the \gls{idn} can
% be used for these commands.
%\begin{macro}{\flowframex}
%    \begin{macrocode}
\newcommand*{\flowframex}[1]{%
\csname col@\romannumeral#1@posx\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\flowframey}
%    \begin{macrocode}
\newcommand*{\flowframey}[1]{%
\csname col@\romannumeral#1@posy\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\flowframeevenx}
%    \begin{macrocode}
\newcommand*{\flowframeevenx}[1]{%
\csname col@\romannumeral#1@evenx\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\flowframeeveny}
%    \begin{macrocode}
\newcommand*{\flowframeeveny}[1]{%
\csname col@\romannumeral#1@eveny\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\flowframewidth}
%    \begin{macrocode}
\newcommand{\flowframewidth}[1]{%
\csname colwidth\romannumeral#1\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\flowframeheight}
%    \begin{macrocode}
\newcommand*{\flowframeheight}[1]{%
\csname colheight\romannumeral#1\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@setframecol}
% Set the colour of the frame, this is a little tricky 
% because the model may need to be specified in square
% brackets. First check to see if a colour model has been
% specified
%    \begin{macrocode}
\def\@setframecol{\@ifnextchar[\@@setframecol\@@setfr@mecol}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@setframecol}
% A colour model has been specified.
%    \begin{macrocode}
\def\@@setframecol[#1]#2\end#3#4#5{%
\expandafter\edef\csname @#5@#4@\romannumeral#3\endcsname{%
[#1]{#2}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@setfr@mecol}
% A colour model has not been specified.
%    \begin{macrocode}
\def\@@setfr@mecol#1\end#2#3#4{%
\expandafter\edef\csname @#4@#3@\romannumeral#2\endcsname{{#1}}}
%    \end{macrocode}
%\end{macro}
%
% \subsection{Static Frames}
%\begin{macro}{\newstaticframe}
% Now deal with setting up the \glspl{static}.  This is
% similar to the \glspl{flow}, except it has an 
% associated \LaTeX\ savebox rather than a \TeX\ box.
% Syntax:\newline
% \cs{newstaticframe}\oarg{pages}\marg{width}\marg{height}\marg{x}\marg{y}\oarg{label}\par
% As with "\newflowframe", the final optional argument is 
% dealt with at the end.
%    \begin{macrocode}
\newcommand*{\newstaticframe}{\@n@wstaticframe}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@n@wstaticframe}
%    \begin{macrocode}
\newcommand*{\@n@wstaticframe}{%
\global\advance\c@maxstatic by 1\relax
\newboolean{staticframe\romannumeral\c@maxstatic}%
\@ifstar\@snewstaticframe\@newstaticframe
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@snewstaticframe}
% Starred version (has a border):
%    \begin{macrocode}
\newcommand{\@snewstaticframe}{%
\setboolean{staticframe\romannumeral\c@maxstatic}{true}%
\@@newstaticframe}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@newstaticframe}
% Unstarred version (no border):
%    \begin{macrocode}
\newcommand{\@newstaticframe}{%
\setboolean{staticframe\romannumeral\c@maxstatic}{false}%
\@@newstaticframe}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@newstaticframe}
% Now set up the \gls{static}:
%    \begin{macrocode}
\newcommand*{\@@newstaticframe}[5][all]{%
\expandafter
\newbox\csname @staticframe@\romannumeral\c@maxstatic\endcsname
\expandafter
\newlength\csname @sf@\romannumeral\c@maxstatic @posx\endcsname
\expandafter
\newlength\csname @sf@\romannumeral\c@maxstatic @posy\endcsname
\expandafter\setlength
\csname @sf@\romannumeral\c@maxstatic @posx\endcsname{#4}%
\expandafter\setlength
\csname @sf@\romannumeral\c@maxstatic @posy\endcsname{#5}%
\expandafter\newlength
\csname @sf@\romannumeral\c@maxstatic @evenx\endcsname
\expandafter\newlength
\csname @sf@\romannumeral\c@maxstatic @eveny\endcsname
\expandafter\setlength
\csname @sf@\romannumeral\c@maxstatic @evenx\endcsname{#4}%
\expandafter\setlength
\csname @sf@\romannumeral\c@maxstatic @eveny\endcsname{#5}%
{\@ff@tmp@x=#2\relax
\@ff@tmp@y=#3\relax
\expandafter
\xdef\csname @sf@dim@\romannumeral\c@maxstatic\endcsname{%
[c][\the\@ff@tmp@y][c]{\the\@ff@tmp@x}}}%
\expandafter
\def\csname @sf@col@\romannumeral\c@maxstatic\endcsname{%
\flowframecol}%
\expandafter
\def\csname @sf@txtcol@\romannumeral\c@maxstatic\endcsname{%
\flowframetextcol}%
\expandafter
\def\csname @sf@backcol@\romannumeral\c@maxstatic\endcsname{%
{none}}%
\expandafter
\xdef\csname @sf@pages@\romannumeral\c@maxstatic\endcsname{#1}%
\expandafter
\gdef\csname @sf@offset@\romannumeral\c@maxstatic\endcsname{%
compute}%
\expandafter
\gdef\csname @sf@angle@\romannumeral\c@maxstatic\endcsname{0}%
\expandafter
\gdef\csname @sf@shape@\romannumeral\c@maxstatic\endcsname{\relax}%
\expandafter
\def\csname @sf@frametype@\romannumeral\c@maxstatic\endcsname{%
fbox}%
\newboolean{@sf@clear@\romannumeral\c@maxstatic}%
\setboolean{@sf@clear@\romannumeral\c@maxstatic}{false}
\@ifnextchar[{\@s@tstaticframeid{\c@maxstatic}}%
{\@s@tstaticframeid{\c@maxstatic}[\number\c@maxstatic]}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@s@tstaticframeid}
% Set the label for the \gls{static}:
%    \begin{macrocode}
\def\@s@tstaticframeid#1[#2]{%
\edef\ff@label{#2}%
\@sf@checkuniqueidl{#1}{\ff@label}%
\expandafter
\xdef\csname @sf@id@\romannumeral#1\endcsname{\ff@label}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sf@checkuniqueidl}
% Check \gls{idl} "#2" for \gls{static} "#1" is unique
%    \begin{macrocode}
\newcommand*{\@sf@checkuniqueidl}[2]{%
\@colN=0\relax
\whiledo{\@colN<\c@maxstatic}{%
\advance\@colN by 1\relax
\ifnum\@colN=#1\relax
\else
\ifthenelse{%
\equal{#2}{\csname @sf@id@\romannumeral\@colN\endcsname}}{%
\PackageError{flowfram}{Static frame IDL '#2' already defined}{%
You can't assign this label, as it is already defined
for static frame \number\@colN}}{}%
\fi
}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@staticframeid}
% Work out the \gls{idn} of the \gls{static} with the
% given label.  This iterates through each \gls{static},
% so if there are a lot of \glspl{static}, it may take a while.
% The \gls{idn} stored in "\ff@id".
%    \begin{macrocode}
\newcommand*{\@staticframeid}[1]{\@colN=0\relax
\ff@id=0\relax
\whiledo{\@colN<\c@maxstatic}{\advance\@colN by 1\relax
\ifthenelse{%
\equal{#1}{\csname @sf@id@\romannumeral\@colN\endcsname}}{%
\ff@id=\@colN\relax
% break out of loop
\@colN=\c@maxstatic}{}}%
\ifnum\ff@id=0\PackageError{flowfram}{Can't find static frame 
id '#1'}{}\fi}
%    \end{macrocode}
%\end{macro}
%
% Make it easier to get the x and y values for static
% frames. (Width and height stored differently.)
%\begin{macro}{\staticframex}
%    \begin{macrocode}
\newcommand*{\staticframex}[1]{%
\csname @sf@\romannumeral#1@posx\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\staticframey}
%    \begin{macrocode}
\newcommand*{\staticframey}[1]{%
\csname @sf@\romannumeral#1@posy\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\staticframeevenx}
%    \begin{macrocode}
\newcommand*{\staticframeevenx}[1]{%
\csname @sf@\romannumeral#1@evenx\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\staticframeeveny}
%    \begin{macrocode}
\newcommand*{\staticframeeveny}[1]{%
\csname @sf@\romannumeral#1@eveny\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\setallstaticframes}
% Modify the settings for all the \glspl{static}:
%    \begin{macrocode}
\newcommand*{\setallstaticframes}[1]{%
\@colN=0\whiledo{\@colN<\c@maxstatic}{\advance\@colN by 1\relax
\@@setstaticframe{\@colN}{#1}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\setstaticframe}
% Modify the settings for the specified \glspl{static}:
%    \begin{macrocode}
\newcommand*{\setstaticframe}{%
\@ifstar\@ssetstaticframe\@setstaticframe}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ssetstaticframe}
% Starred version: Iterate through the comma-separated
% list of labels.
%    \begin{macrocode}
\newcommand*{\@ssetstaticframe}[2]{%
\@for\@ff@id:=#1\do{%
\@staticframeid{\@ff@id}%
\@@setstaticframe{\ff@id}{#2}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@setstaticframe}
% Unstarred version. Iterate through the comma-separated
% list of \glspl{idn}, and check for number ranges.
% Ensures that number ranges do not lie out of bounds.
%    \begin{macrocode}
\newcommand*{\@setstaticframe}[2]{%
\ifthenelse{\equal{#1}{all}}{%
\setallstaticframes{#2}}{%
\ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{%
\ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}%
\whiledo{\@colN<\c@maxstatic\TE@or\@colN=\c@maxstatic}{%
\@@setstaticframe{\@colN}{#2}%
\advance\@colN by 2\relax}%
}{%
\@for\@ff@id:=#1\do{%
\def\@ff@numstart{0}\def\@ff@numend{10000}%
\@ff@getrange{\@ff@id}%
\ifnum\@ff@numstart=0\relax
  \def\@ff@numstart{1}%
\fi
\ifnum\@ff@numend>\c@maxstatic
  \def\@ff@numend{\c@maxstatic}%
\fi
\@colN=\@ff@numstart
\whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{%
\@@setstaticframe{\@colN}{#2}%
\advance\@colN by 1\relax
}}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@setstaticframe}
% Modify the settings for the \gls{static} whose \gls{idn}\
% is given by the first argument.
%    \begin{macrocode}
\newcommand*{\@@setstaticframe}[2]{%
\expandafter\expandafter\expandafter
\@ff@getstaticpos\csname @sf@dim@\romannumeral#1\endcsname
\def\ff@frame{}\edef\ff@width{\the\@ff@tmp@x}\def\ff@angle{}%
\edef\ff@height{\the\@ff@tmp@y}\def\ff@style{}\def\ff@frametype{}%
\def\ff@x{}\def\ff@y{}\def\ff@col{}\def\ff@txtcol{}%
\def\ff@backcol{}\def\ff@shape{0}%
\def\ff@clear{}\def\ff@margin{}\def\ff@offset{}\def\ff@pages{}%
\def\ff@label{}\def\ff@evenx{}\def\ff@eveny{}%
\def\ff@oddx{}\def\ff@oddy{}%
\setkeys{flowframe}{#2}%
\ifthenelse{\equal{\ff@frame}{}}{}{%
\setboolean{staticframe\romannumeral#1}{\ff@frame}}%
\ifthenelse{\equal{\ff@x}{}}{}{%
\expandafter\global
\expandafter\setlength\csname @sf@\romannumeral#1@posx\endcsname
{\ff@x}%
\expandafter\global
\expandafter\setlength\csname @sf@\romannumeral#1@evenx\endcsname
{\ff@x}}%
\ifthenelse{\equal{\ff@y}{}}{}{%
\expandafter\global
\expandafter\setlength\csname @sf@\romannumeral#1@posy\endcsname
{\ff@y}%
\expandafter\global
\expandafter\setlength\csname @sf@\romannumeral#1@eveny\endcsname
{\ff@y}}%
\ifthenelse{\equal{\ff@evenx}{}}{}{%
\expandafter\global
\expandafter\setlength\csname @sf@\romannumeral#1@evenx\endcsname
{\ff@evenx}}%
\ifthenelse{\equal{\ff@eveny}{}}{}{%
\expandafter\global
\expandafter\setlength\csname @sf@\romannumeral#1@eveny\endcsname
{\ff@eveny}}%
\ifthenelse{\equal{\ff@oddx}{}}{}{%
\expandafter\global
\expandafter\setlength\csname @sf@\romannumeral#1@posx\endcsname
{\ff@oddx}}%
\ifthenelse{\equal{\ff@oddy}{}}{}{%
\expandafter\global
\expandafter\setlength\csname @sf@\romannumeral#1@posy\endcsname
{\ff@oddy}}%
\expandafter
\xdef\csname @sf@dim@\romannumeral#1\endcsname{%
[c][\ff@height][\ff@valign]{\ff@width}}%
\ifthenelse{\equal{\ff@frametype}{}}{}{%
\expandafter
\xdef\csname @sf@frametype@\romannumeral#1\endcsname{%
\ff@frametype}}%
\ifthenelse{\equal{\ff@label}{}}{}{%
\@s@tstaticframeid{#1}[\ff@label]}
\ifthenelse{\equal{\ff@col}{}}{}{%
\expandafter\@setframecol\ff@col\end{#1}{col}{sf}}%
\ifthenelse{\equal{\ff@txtcol}{}}{}{%
\expandafter\@setframecol\ff@txtcol\end{#1}{txtcol}{sf}}%
\ifthenelse{\equal{\ff@backcol}{}}{}{%
\expandafter\@setframecol\ff@backcol\end{#1}{backcol}{sf}}%
\ifthenelse{\equal{\ff@offset}{}}{}{%
\expandafter
\xdef\csname @sf@offset@\romannumeral#1\endcsname{\ff@offset}}%
\ifthenelse{\equal{\ff@angle}{}}{}{%
\expandafter
\xdef\csname @sf@angle@\romannumeral#1\endcsname{\ff@angle}}%
\if0\ff@shape
\else
\expandafter\global\expandafter
\let\csname @sf@shape@\romannumeral#1\endcsname\ff@shape
\fi
\ifthenelse{\equal{\ff@pages}{}}{}{%
\expandafter
\xdef\csname @sf@pages@\romannumeral#1\endcsname{\ff@pages}}%
\ifthenelse{\equal{\ff@clear}{}}{}{%
\setboolean{@sf@clear@\romannumeral#1}{\ff@clear}}%
\ifthenelse{\equal{\ff@margin}{}}{}{%
\PackageError{flowfram}{Key 'margin' not available for 
static frames}{Static frames don't have marginal notes}}%
\ifthenelse{\equal{\ff@style}{}}{}{%
\PackageError{flowfram}{Key 'style' not available for 
static frames}{}}%
}
%    \end{macrocode}
%\end{macro}
%
%\begin{macro}{\simpar}
% Simulate paragraph break inside "\shapepar"
%    \begin{macrocode}
 %\newcommand*{\simpar}{\hfil\vadjust{\vskip\parskip}\break\indent}
\newcommand*{\simpar}{\hfill\\\indent\mbox{}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\ffpshpar}
% Provide means to allow parshape to be carried over a paragraph 
% break.
%    \begin{macrocode}
\let\FLForgpar\par
\newcommand{\ffpshpar}{\edef\flf@next{\hangafter=\the\hangafter
\hangindent=\the\hangindent}\FLForgpar\flf@next
\edef\flf@next{\prevgraf=\the\prevgraf}\@ff@parshape\indent\mbox{}\flf@next}
%    \end{macrocode}
%\end{macro}
%
% Provide a means to have section headings within "\parshape".
%\begin{macro}{\@ff@parshape}
%    \begin{macrocode}
\def\@ff@parshape{\parshape=0}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@sectionhead}
%    \begin{macrocode}
\newcommand*{\@ff@sectionhead}[1]{%
\def\ff@sechead{#1}%
\ffpshpar
\@ifstar{\@s@ff@heading}{\@dblarg\@ff@heading}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@s@ff@heading}
%    \begin{macrocode}
\def\@s@ff@heading#1{%
\@ifundefined{@ff@old\ff@sechead}{\PackageError{flowfram}{Unknown
heading command '\ff@sechead'}{}}{%
\begingroup
\edef\flf@next{\hangafter=\the\hangafter
\hangindent=\the\hangindent}\FLForgpar\flf@next
\let\par=\FLForgpar
\edef\flf@next{\prevgraf=\the\prevgraf}%
\csname @ff@old\ff@sechead\endcsname*{\@ff@parshape\flf@next 
#1}%
\xdef\flf@next{\@ff@parshape
\prevgraf=\the\prevgraf}%
\endgroup
}%
\mbox{}\flf@next\let\flf@next\undefined}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@heading}
%    \begin{macrocode}
\def\@ff@heading[#1]#2{%
\@ifundefined{@ff@old\ff@sechead}{\PackageError{flowfram}{Unknown
heading command '\ff@sechead'}{}}{%
\begingroup
\edef\flf@next{\hangafter=\the\hangafter
\hangindent=\the\hangindent}\FLForgpar\flf@next
\let\par=\FLForgpar
\edef\flf@next{\prevgraf=\the\prevgraf}%
\csname @ff@old\ff@sechead\endcsname[#1]{\@ff@parshape\flf@next 
#2}%
\xdef\flf@next{\@ff@parshape
\prevgraf=\the\prevgraf}%
\endgroup}%
\mbox{}\flf@next\let\flf@next\undefined}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@setsecthead}
% Define command to switch to adjusted section headings:
%    \begin{macrocode}
\newcommand*{\@ff@setsecthead}{%
\let\@ff@oldsection=\section
\let\@ff@oldsubsection=\subsection
\let\@ff@oldsubsubsection=\subsubsection
\let\@ff@oldparagraph=\paragraph
\let\@ff@oldsubparagraph=\subparagraph
\def\section{\@ff@sectionhead{section}}%
\def\subsection{\@ff@sectionhead{subsection}}%
\def\subsubsection{\@ff@sectionhead{subsubsection}}%
\def\paragraph{\@ff@sectionhead{paragraph}}%
\def\subparagraph{\@ff@sectionhead{subparagraph}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@getshape}
% Determine what shape command is being used:
%    \begin{macrocode}
\def\@ff@getshape#1#2\relax{%
\ifx#1\parshape
\def\ff@shape{1}%
\else
\ifx#1\shapepar
\def\ff@shape{2}%
\else
\ifx#1\relax
\def\ff@shape{0}%
\else
\PackageError{flowfram}{Unknown shape \string#1}{}%
\def\ff@shape{2}%
\fi
\fi
\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@disablesec}
% Disable sectioning commands
%    \begin{macrocode}
\newcommand*{\@ff@disablesec}{%
\def\section{\PackageError{flowfram}{You can't have
sectioning commands within a \string\shapepar}{}}%
\def\subsection{\PackageError{flowfram}{You can't have
sectioning commands within a \string\shapepar}{}}%
\def\subsubsection{\PackageError{flowfram}{You can't have
sectioning commands within a \string\shapepar}{}}%
\def\paragraph{\PackageError{flowfram}{You can't have
sectioning commands within a \string\shapepar}{}}%
\def\subparagraph{\PackageError{flowfram}{You can't have
sectioning commands within a \string\shapepar}{}}%
}
%    \end{macrocode}
%\end{macro}
%
%\begin{environment}{staticcontents}
% Set the contents of the \gls{static} given by its \gls{idn}.
% Syntax: "\begin{staticcontents}"\marg{idn}.
%    \begin{macrocode}
\newbox\staticframe
\newenvironment{staticcontents}[1]{%
\@ifundefined{@staticframe@\romannumeral#1}{%
\PackageError{flowfram}{Static frame '#1' not defined}{}}{}%
\expandafter\let\expandafter\@ff@parshape\csname @sf@shape@\romannumeral#1\endcsname
\expandafter\@ff@getshape\@ff@parshape\relax
\ifcase\ff@shape
% no shape
\edef\@sf@mpg{%
\noexpand
\begin{minipage}\csname @sf@dim@\romannumeral#1\endcsname
\noexpand\begingroup
\noexpand\let\noexpand\FLForgpar=\noexpand\par
}%
\or
% \parshape
\edef\@sf@mpg{%
\noexpand
\begin{minipage}\csname @sf@dim@\romannumeral#1\endcsname
\@ff@parshape
\noexpand\begingroup
\noexpand\let\noexpand\FLForgpar=\noexpand\par
\noexpand\let\noexpand\par=\noexpand\ffpshpar
\noexpand\@ff@setsecthead
}%
\or
% \shapepar
\edef\@sf@mpg{%
\noexpand
\begin{minipage}\csname @sf@dim@\romannumeral#1\endcsname
\noexpand\begingroup
\noexpand\@ff@disablesec
\noexpand\@ff@parshape
}%
\fi
\edef\@sf@thisframe{\csname @staticframe@\romannumeral#1\endcsname}%
\begin{lrbox}{\staticframe}%
\edef\ff@txtcol{\csname @sf@txtcol@\romannumeral#1\endcsname}%
\@s@tfftextcol\noindent
\@sf@mpg
\setlength\parindent\sdfparindent
}{\ifnum\ff@shape=2\par
\else\FLForgpar\fi\endgroup\end{minipage}\end{lrbox}%
\expandafter\global\expandafter\sbox\@sf@thisframe{%
\usebox\staticframe}\ignorespaces
}
%    \end{macrocode}
%\end{environment}
%\begin{environment}{staticcontents*}
% Set the contents of the \gls{static} given by its \gls{idl}.
% Syntax: "\begin{staticcontents*}"\marg{label}.
%    \begin{macrocode}
\newenvironment{staticcontents*}[1]{\@staticframeid{#1}%
\begin{staticcontents}{\ff@id}}{\end{staticcontents}}
%    \end{macrocode}
%\end{environment}
%\begin{macro}{\setstaticcontents}
% Provide a command version.
% Syntax: \cs{setstaticcontents}\marg{idn}\marg{text}.
%    \begin{macrocode}
\newcommand{\setstaticcontents}{%
\@ifstar\@sstaticconts\@staticconts}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sstaticconts}
% Starred version: \gls{static} identified by label.
%    \begin{macrocode}
\newcommand{\@sstaticconts}[1]{\@staticframeid{#1}%
\@staticconts{\ff@id}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@staticconts}
% Unstarred version: \gls{static} identified by \gls{idn}.
%    \begin{macrocode}
\newcommand{\@staticconts}[2]{\begin{staticcontents}{#1}%
#2\end{staticcontents}}
%    \end{macrocode}
%\end{macro}
%
%\begin{macro}{\@@staticframeswapcoords}
% Swap odd and even offsets for a given \gls{static}. Do the main stuff for 
% a given \gls{static} \gls{idn}.
%    \begin{macrocode}
\newcommand*{\@@staticframeswapcoords}[1]{%
\setlength{\@ff@tmp@x}%
{\csname @sf@\romannumeral#1@evenx\endcsname}
\expandafter\setlength\csname @sf@\romannumeral#1@evenx\endcsname
{\csname @sf@\romannumeral#1@posx\endcsname}%
\expandafter\setlength\csname @sf@\romannumeral#1@posx\endcsname
{\@ff@tmp@x}%
\setlength{\@ff@tmp@y}%
{\csname @sf@\romannumeral#1@eveny\endcsname}
\expandafter\setlength\csname @sf@\romannumeral#1@eveny\endcsname
{\csname @sf@\romannumeral#1@posy\endcsname}%
\expandafter\setlength\csname @sf@\romannumeral#1@posy\endcsname
{\@ff@tmp@y}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\sfswapoddeven}
% Allow user to specify \gls{flow} either by \gls{idn} or \gls{idl}:
%    \begin{macrocode}
\newcommand*{\sfswapoddeven}{%
\@ifstar\@sstaticframeswapcoords\@staticframeswapcoords}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sstaticframeswapcoords}
% Starred form
%    \begin{macrocode}
\newcommand*{\@sstaticframeswapcoords}[1]{%
\@for\@ff@id:=#1\do{%
\@staticframeid{\@ff@id}%
\@@staticframeswapcoords{\ff@id}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@staticframeswapcoords}
% Unstarred form:
%    \begin{macrocode}
\newcommand*{\@staticframeswapcoords}[1]{%
\ifthenelse{\equal{#1}{all}}{%
\ff@id=0\relax
\whiledo{\ff@id<\c@maxflow}{\advance\ff@id by 1\relax
\@@staticframeswapcoords{\ff@id}}%
}{%
\ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{%
\ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}%
\whiledo{\@colN<\c@maxflow\TE@or\@colN=\c@maxflow}{%
\@@staticframeswapcoords{\@colN}%
\advance\@colN by 2\relax}%
}{%
\@for\@ff@id:=#1\do{%
\def\@ff@numstart{0}\def\@ff@numend{10000}%
\@ff@getrange{\@ff@id}%
\ifnum\@ff@numstart=0\relax
  \def\@ff@numstart{1}%
\fi
\ifnum\@ff@numend>\c@maxflow
  \def\@ff@numend{\c@maxflow}%
\fi
\@colN=\@ff@numstart
\whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{%
\@@staticframeswapcoords{\@colN}%
\advance\@colN by 1\relax
}}}}}
%    \end{macrocode}
%\end{macro}
%
% \subsection{Dynamic Frames}
% Now deal with the \glspl{dynamic}. These are very similar
% to the \glspl{static}, but instead of having a savebox,
% the contents of the \gls{dynamic} are stored in a macro.
%\begin{macro}{\newdynamicframe}
% Syntax:\newline
% \cs{newdynamicframe}\oarg{pages}\marg{width}\marg{height}\marg{x}\marg{y}\oarg{label}
%    \begin{macrocode}
\newcommand*{\newdynamicframe}{%
\@n@wdynamicframe}
\newcommand*{\@n@wdynamicframe}{%
\global\advance\c@maxdynamic by 1\relax
\newboolean{dynamicframe\romannumeral\c@maxdynamic}
\@ifstar\@snewdynamicframe\@newdynamicframe
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@snewdynamicframe}
% Starred version: has a border.
%    \begin{macrocode}
\newcommand*{\@snewdynamicframe}{%
\setboolean{dynamicframe\romannumeral\c@maxdynamic}{true}%
\@@newdynamicframe}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@newdynamicframe}
% Unstarred version: no border.
%    \begin{macrocode}
\newcommand*{\@newdynamicframe}{%
\setboolean{dynamicframe\romannumeral\c@maxdynamic}{false}%
\@@newdynamicframe}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@newdynamicframe}
% Create new \gls{dynamic}:
%    \begin{macrocode}
\newcommand*{\@@newdynamicframe}[5][all]{%
\expandafter
\gdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{}%
\expandafter
\newlength\csname @df@\romannumeral\c@maxdynamic @posx\endcsname
\expandafter
\newlength\csname @df@\romannumeral\c@maxdynamic @posy\endcsname
\expandafter\setlength
\csname @df@\romannumeral\c@maxdynamic @posx\endcsname{#4}%
\expandafter\setlength
\csname @df@\romannumeral\c@maxdynamic @posy\endcsname{#5}%
\expandafter\newlength
\csname @df@\romannumeral\c@maxdynamic @evenx\endcsname
\expandafter\newlength
\csname @df@\romannumeral\c@maxdynamic @eveny\endcsname
\expandafter\setlength
\csname @df@\romannumeral\c@maxdynamic @evenx\endcsname{#4}%
\expandafter\setlength
\csname @df@\romannumeral\c@maxdynamic @eveny\endcsname{#5}%
{\@ff@tmp@x=#2\relax
\@ff@tmp@y=#3\relax
\expandafter
\xdef\csname @df@dim@\romannumeral\c@maxdynamic\endcsname{%
[c][\the\@ff@tmp@y][t]{\the\@ff@tmp@x}}}%
\expandafter
\gdef\csname @df@col@\romannumeral\c@maxdynamic\endcsname{%
\flowframecol}%
\expandafter
\gdef\csname @df@txtcol@\romannumeral\c@maxdynamic\endcsname{%
\flowframetextcol}%
\expandafter
\gdef\csname @df@backcol@\romannumeral\c@maxdynamic\endcsname{%
{none}}%
\expandafter
\gdef\csname @df@pages@\romannumeral\c@maxdynamic\endcsname{#1}%
\expandafter
\gdef\csname @df@frametype@\romannumeral\c@maxdynamic\endcsname{%
fbox}%
\expandafter
\gdef\csname @df@style@\romannumeral\c@maxdynamic\endcsname{relax}%
\expandafter
\gdef\csname @df@offset@\romannumeral\c@maxdynamic\endcsname{compute}%
\expandafter
\gdef\csname @df@angle@\romannumeral\c@maxdynamic\endcsname{0}%
\expandafter
\gdef\csname @df@shape@\romannumeral\c@maxdynamic\endcsname{\relax}%
\newboolean{@df@clear@\romannumeral\c@maxdynamic}%
\setboolean{@df@clear@\romannumeral\c@maxdynamic}{false}%
\@ifnextchar[{\@s@tdynamicframeid{\c@maxdynamic}}%
{\@s@tdynamicframeid{\c@maxdynamic}[\number\c@maxdynamic]}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@s@tdynamicframeid}
% Set the label for the given \gls{dynamic}:
%    \begin{macrocode}
\def\@s@tdynamicframeid#1[#2]{%
\edef\ff@label{#2}%
\@df@checkuniqueidl{#1}{\ff@label}%
\expandafter
\xdef\csname @df@id@\romannumeral#1\endcsname{\ff@label}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@df@checkuniqueidl}
% Check \gls{idl} "#2" for \gls{static} "#1" is unique
%    \begin{macrocode}
\newcommand*{\@df@checkuniqueidl}[2]{%
\@colN=0\relax
\whiledo{\@colN<\c@maxdynamic}{%
\advance\@colN by 1\relax
\ifnum\@colN=#1\relax
\else
\ifthenelse{\equal{#2}%
{\csname @df@id@\romannumeral\@colN\endcsname}}{%
\PackageError{flowfram}{Dynamic frame IDL '#2' already defined}{%
You can't assign this label, as it is already defined
for dynamic frame \number\@colN}}{}%
\fi
}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dynamicframeid}
% Determine the \gls{idn} of the \gls{dynamic} from its label.
% The \gls{idn} is stored in "\ff@id".
%    \begin{macrocode}
\newcommand*{\@dynamicframeid}[1]{\@colN=0\relax
\ff@id=0\relax
\whiledo{\@colN<\c@maxdynamic}{\advance\@colN by 1\relax
\ifthenelse{%
\equal{#1}{\csname @df@id@\romannumeral\@colN\endcsname}}{%
\ff@id=\@colN\relax
% break out of loop
\@colN=\c@maxdynamic}{}}%
\ifnum\ff@id=0\PackageError{flowfram}{Can't find dynamic frame 
id '#1'}{}\fi}
%    \end{macrocode}
%\end{macro}
% Make it easier to get the x and y values for dynamic
% frames. (Width and height stored differently.)
%\begin{macro}{\dynamicframex}
%    \begin{macrocode}
\newcommand*{\dynamicframex}[1]{%
\csname @df@\romannumeral#1@posx\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\dynamicframey}
%    \begin{macrocode}
\newcommand*{\dynamicframey}[1]{%
\csname @df@\romannumeral#1@posy\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\dynamicframeevenx}
%    \begin{macrocode}
\newcommand*{\dynamicframeevenx}[1]{%
\csname @df@\romannumeral#1@evenx\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\dynamicframeeveny}
%    \begin{macrocode}
\newcommand*{\dynamicframeeveny}[1]{%
\csname @df@\romannumeral#1@eveny\endcsname}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\setalldynamicframes}
% Change the settings for all the \glspl{dynamic}:
%    \begin{macrocode}
\newcommand*{\setalldynamicframes}[1]{%
\@colN=0\whiledo{\@colN<\c@maxdynamic}{\advance\@colN by 1\relax
\@@setdynamicframe{\@colN}{#1}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\setdynamicframe}
% Change the settings for specified \glspl{dynamic}:
%    \begin{macrocode}
\newcommand*{\setdynamicframe}{%
\@ifstar\@ssetdynamicframe\@setdynamicframe}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ssetdynamicframe}
% Starred version: iterate through comma-separated list
% of labels.
%    \begin{macrocode}
\newcommand*{\@ssetdynamicframe}[2]{%
\@for\@ff@id:=#1\do{%
\@dynamicframeid{\@ff@id}%
\@@setdynamicframe{\ff@id}{#2}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@setdynamicframe}
% Unstarred version: iterate through comma-separated list
% of ID numbers. Include provision for number ranges.
% If necessary, modify number ranges to ensure they are valid.
%    \begin{macrocode}
\newcommand*{\@setdynamicframe}[2]{%
\ifthenelse{\equal{#1}{all}}{%
\setalldynamicframes{#2}}{%
\ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{%
\ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}%
\whiledo{\@colN<\c@maxdynamic\TE@or\@colN=\c@maxdynamic}{%
\@@setdynamicframe{\@colN}{#2}%
\advance\@colN by 2\relax}%
}{%
\@for\@ff@id:=#1\do{%
\def\@ff@numstart{0}\def\@ff@numend{10000}%
\@ff@getrange{\@ff@id}%
\ifnum\@ff@numstart=0\relax
  \def\@ff@numstart{1}%
\fi
\ifnum\@ff@numend>\c@maxdynamic
  \def\@ff@numend{\c@maxdynamic}%
\fi
\@colN=\@ff@numstart
\whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{%
\@@setdynamicframe{\@colN}{#2}%
\advance\@colN by 1\relax
}}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@setdynamicframe}
% Change the setting for the \gls{dynamic} given by its \gls{idn}.
%    \begin{macrocode}
\newcommand*{\@@setdynamicframe}[2]{%
\expandafter\expandafter\expandafter
\@ff@getstaticpos\csname @df@dim@\romannumeral#1\endcsname
\def\ff@frame{}\edef\ff@width{\the\@ff@tmp@x}%
\edef\ff@height{\the\@ff@tmp@y}\def\ff@style{}\def\ff@frametype{}%
\def\ff@x{}\def\ff@y{}\def\ff@col{}\def\ff@txtcol{}\def\ff@backcol{}%
\def\ff@clear{}\def\ff@margin{}\def\ff@offset{}\def\ff@pages{}%
\def\ff@label{}\def\ff@evenx{}\def\ff@eveny{}%
\def\ff@oddx{}\def\ff@oddy{}\def\ff@angle{}\def\ff@shape{0}%
\setkeys{flowframe}{#2}%
\ifthenelse{\equal{\ff@frame}{}}{}{%
\setboolean{dynamicframe\romannumeral#1}{\ff@frame}}%
\ifthenelse{\equal{\ff@x}{}}{}{%
\expandafter\global\expandafter\setlength
\csname @df@\romannumeral#1@posx\endcsname{\ff@x}%
\expandafter\global\expandafter\setlength
\csname @df@\romannumeral#1@evenx\endcsname{\ff@x}}%
\ifthenelse{\equal{\ff@y}{}}{}{%
\expandafter\global\expandafter\setlength
\csname @df@\romannumeral#1@posy\endcsname{\ff@y}%
\expandafter\global\expandafter\setlength
\csname @df@\romannumeral#1@eveny\endcsname{\ff@y}}%
\ifthenelse{\equal{\ff@evenx}{}}{}{%
\expandafter\global\expandafter\setlength
\csname @df@\romannumeral#1@evenx\endcsname{\ff@evenx}}%
\ifthenelse{\equal{\ff@eveny}{}}{}{%
\expandafter\global\expandafter\setlength
\csname @df@\romannumeral#1@eveny\endcsname{\ff@eveny}}%
\ifthenelse{\equal{\ff@oddx}{}}{}{%
\expandafter\global\expandafter\setlength
\csname @df@\romannumeral#1@posx\endcsname{\ff@oddx}}%
\ifthenelse{\equal{\ff@oddy}{}}{}{%
\expandafter\global\expandafter\setlength
\csname @df@\romannumeral#1@posy\endcsname{\ff@oddy}}%
\expandafter\xdef\csname @df@dim@\romannumeral#1\endcsname{%
[c][\ff@height][\ff@valign]{\ff@width}}%
\ifthenelse{\equal{\ff@label}{}}{}{%
\@s@tdynamicframeid{#1}[\ff@label]}
\ifthenelse{\equal{\ff@frametype}{}}{}{%
\expandafter
\xdef\csname @df@frametype@\romannumeral#1\endcsname{%
\ff@frametype}}%
\ifthenelse{\equal{\ff@col}{}}{}{%
\expandafter\@setframecol\ff@col\end{#1}{col}{df}}%
\ifthenelse{\equal{\ff@txtcol}{}}{}{%
\expandafter\@setframecol\ff@txtcol\end{#1}{txtcol}{df}}%
\ifthenelse{\equal{\ff@backcol}{}}{}{%
\expandafter\@setframecol\ff@backcol\end{#1}{backcol}{df}}%
\ifthenelse{\equal{\ff@offset}{}}{}{%
\expandafter
\xdef\csname @df@offset@\romannumeral#1\endcsname{\ff@offset}}%
\ifthenelse{\equal{\ff@angle}{}}{}{%
\expandafter
\xdef\csname @df@angle@\romannumeral#1\endcsname{\ff@angle}}%
\if0\ff@shape
\else
\expandafter\global\expandafter
\let\csname @df@shape@\romannumeral#1\endcsname\ff@shape
\fi
\ifthenelse{\equal{\ff@pages}{}}{}{%
\expandafter\xdef\csname @df@pages@\romannumeral#1\endcsname{%
\ff@pages}}%
\ifthenelse{\equal{\ff@style}{}}{}{%
\@ifundefined{\ff@style}{\PackageError{flowfram}%
{Unknown style '\ff@style'}{The command \expandafter
\string\csname\ff@style\endcsname\space has not been defined}}{%
\expandafter
\xdef\csname @df@style@\romannumeral#1\endcsname{\ff@style}}}%
\ifthenelse{\equal{\ff@clear}{}}{}{%
\setboolean{@df@clear@\romannumeral\c@maxdynamic}{true}%
}%
\ifthenelse{\equal{\ff@margin}{}}{}{%
\PackageError{flowfram}{Key 'margin' not available for dynamic 
frames}{dynamic frames don't have marginal notes}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@dynamicframeswapcoords}
% Swap odd and even offsets for a given \gls{static}. Do the main stuff for 
% a given \gls{static} \gls{idn}.
%    \begin{macrocode}
\newcommand*{\@@dynamicframeswapcoords}[1]{%
\setlength{\@ff@tmp@x}%
{\csname @df@\romannumeral#1@evenx\endcsname}%
\expandafter\setlength
\csname @df@\romannumeral#1@evenx\endcsname
{\csname @df@\romannumeral#1@posx\endcsname}%
\expandafter\setlength
\csname @df@\romannumeral#1@posx\endcsname{\@ff@tmp@x}%
\setlength{\@ff@tmp@y}%
{\csname @df@\romannumeral#1@eveny\endcsname}%
\expandafter\setlength
\csname @df@\romannumeral#1@eveny\endcsname
{\csname @df@\romannumeral#1@posy\endcsname}%
\expandafter\setlength\csname @df@\romannumeral#1@posy\endcsname
{\@ff@tmp@y}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\dfswapoddeven}
% Allow user to specify \gls{flow} either by \gls{idn} or \gls{idl}:
%    \begin{macrocode}
\newcommand*{\dfswapoddeven}{%
\@ifstar\@sdynamicframeswapcoords\@dynamicframeswapcoords}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sdynamicframeswapcoords}
% Starred form
%    \begin{macrocode}
\newcommand*{\@sdynamicframeswapcoords}[1]{%
\@for\@ff@id:=#1\do{%
\@dynamicframeid{\@ff@id}%
\@@dynamicframeswapcoords{\ff@id}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dynamicframeswapcoords}
% Unstarred form:
%    \begin{macrocode}
\newcommand*{\@dynamicframeswapcoords}[1]{%
\ifthenelse{\equal{#1}{all}}{%
\ff@id=0\relax
\whiledo{\ff@id<\c@maxflow}{\advance\ff@id by 1\relax
\@@dynamicframeswapcoords{\ff@id}}%
}{%
\ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{%
\ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}%
\whiledo{\@colN<\c@maxflow\TE@or\@colN=\c@maxflow}{%
\@@dynamicframeswapcoords{\@colN}%
\advance\@colN by 2\relax}%
}{%
\@for\@ff@id:=#1\do{%
\def\@ff@numstart{0}\def\@ff@numend{10000}%
\@ff@getrange{\@ff@id}%
\ifnum\@ff@numstart=0\relax
  \def\@ff@numstart{1}%
\fi
\ifnum\@ff@numend>\c@maxflow
  \def\@ff@numend{\c@maxflow}%
\fi
\@colN=\@ff@numstart
\whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{%
\@@dynamicframeswapcoords{\@colN}%
\advance\@colN by 1\relax
}}}}}
%    \end{macrocode}
%\end{macro}
% Set the contents of a \gls{dynamic}.
%
%\begin{environment}{dynamiccontents}
% Syntax: "\begin{dynamiccontents}"\marg{idn}
%
% The contents of the \env{dynamiccontents} environment needs
% to be stored in the control sequence "\@dynamicframe@"\meta{rn}
% (where \meta{rn} is the \meta{idn} as a roman numeral.)
% Start of the environment (unstarred):
%    \begin{macrocode}
\def\dynamiccontents#1{%
\edef\@flf@{\@currenvir}%
\def\@flf@idn{#1}%
\toks@{}\@flf@get@body
}
%    \end{macrocode}
% Get the body of the environment:
%    \begin{macrocode}
\long\def\@flf@get@body#1\end
 {\toks@\expandafter{\the\toks@#1}\@flf@find@end}
%    \end{macrocode}
% Find the end of the environment:
%    \begin{macrocode}
\def\@flf@find@end#1{%
\def\@tempa{#1}%
\ifx\@tempa\@flf@
\expandafter\@flf@enddynamiccontents
\else
\toks@\expandafter
 {\the\toks@\end{#1}}\expandafter\@flf@get@body\fi
}
%    \end{macrocode}
% End of the environment:
%    \begin{macrocode}
\let\enddynamiccontents\relax
\def\@flf@enddynamiccontents{%
\ifnum\@flf@idn>\c@maxdynamic
\PackageError{flowfram}{Dynamic frame \number\@flf@idn\ does not exist}{%
You have specified dynamic frame number \number\@flf@idn, but there are 
only \number\c@maxdynamic\space dynamic frames currently defined}%
\else
\expandafter
\xdef\csname @dynamicframe@\romannumeral\@flf@idn\endcsname{\the\toks@}%
\expandafter
\fi
\expandafter\end\expandafter{\@flf@}}
%    \end{macrocode}
%\end{environment}
%\begin{environment}{dynamiccontents*}
% Starred version:
%    \begin{macrocode}
\expandafter\def\csname dynamiccontents*\endcsname#1{%
\edef\@flf@{\@currenvir}%
\@dynamicframeid{#1}%
\edef\@flf@idn{\number\ff@id}%
\toks@{}\@flf@get@body
}
%    \end{macrocode}
%\end{environment}
%\begin{macro}{\setdynamiccontents}
%    \begin{macrocode}
\newcommand{\setdynamiccontents}{%
\@ifstar\@ssetdynamiccontents\@setdynamiccontents}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ssetdynamiccontents}
% Starred version: identify \gls{dynamic} by its \gls{idl}:
%    \begin{macrocode}
\newcommand{\@ssetdynamiccontents}[2]{%
\@dynamicframeid{#1}\@setdynamiccontents{\ff@id}{#2}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@setdynamiccontents}
% Unstarred version: identify \gls{dynamic} by its \gls{idn}:
%    \begin{macrocode}
\newcommand{\@setdynamiccontents}[2]{%
\ifnum#1>\c@maxdynamic
\PackageError{flowfram}{Dynamic frame \number#1\ does not exist}{%
You have specified dynamic frame number \number#1, but there are 
only \number\c@maxdynamic\space dynamic frames currently defined}%
\else
\expandafter
\gdef\csname @dynamicframe@\romannumeral#1\endcsname{#2}%
\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\appenddynamiccontents}
% Append information to \gls{dynamic}. First check to
% see if starred or unstarred version is being used.
%    \begin{macrocode}
\newcommand{\appenddynamiccontents}{%
\@ifstar\@sappenddynamic\@appenddynamic}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sappenddynamic}
% Starred version: find the \gls{idn} and pass it to
% the unstarred version.
%    \begin{macrocode}
\newcommand{\@sappenddynamic}[2]{%
\@dynamicframeid{#1}\@appenddynamic{\ff@id}{#2}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@appenddynamic}
% Unstarred version.
%    \begin{macrocode}
\newcommand{\@appenddynamic}[2]{%
\ifnum#1>\c@maxdynamic
\PackageError{flowfram}{Dynamic frame \number#1 does not exist}{%
You have specified dynamic frame number \number#1, 
but there are only
\number\c@maxdynamic\space dynamic frames currently defined}%
\else
\expandafter\@ff@addtolist
\csname @dynamicframe@\romannumeral#1\endcsname\entry{#2}%
\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@addtolist}
% Append "#2" onto the end of "#1".
%    \begin{macrocode}
\newtoks\flf@ta \newtoks\flf@tb
\long\def\@ff@addtolist#1\entry#2{\flf@ta={{#2}}%
\flf@tb=\expandafter{#1}%
\xdef#1{\the\flf@tb\the\flf@ta}}
%    \end{macrocode}
%\end{macro}
%
%\subsection{Determining Dimensions and Locations}
%\begin{macro}{\computeleftedgeodd}
% Compute the position of the left most edge of the page, 
% relative to the left side of the \gls{typeblock}. Since odd and
% even pages may have a different offset if "\oddsidemargin"
% and "\evensidemargin" have different values, it is necessary
% to have two separate commands for odd and even pages.
% First the odd pages.
%    \begin{macrocode}
\newcommand*{\computeleftedgeodd}[1]{%
\setlength{#1}{-1in}%
\addtolength{#1}{-\hoffset}%
\addtolength{#1}{-\oddsidemargin}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\computeleftedgeeven}
% Now for the even pages
%    \begin{macrocode}
\newcommand*{\computeleftedgeeven}[1]{%
\setlength{#1}{-1in}%
\addtolength{#1}{-\hoffset}%
\addtolength{#1}{-\evensidemargin}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\computetopedge}
% Compute the top edge of the page, relative to the bottom of 
% the \gls{typeblock}.
%    \begin{macrocode}
\newcommand*{\computetopedge}[1]{%
\setlength{#1}{\textheight}%
\addtolength{#1}{\headheight}%
\addtolength{#1}{\headsep}%
\addtolength{#1}{1in}%
\addtolength{#1}{\voffset}%
\addtolength{#1}{\topmargin}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\computebottomedge}
% Compute the bottom edge of the page, relative to the bottom 
% of the \gls{typeblock}.
%    \begin{macrocode}
\newcommand*{\computebottomedge}[1]{%
\computetopedge{#1}%
\addtolength{#1}{-\paperheight}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\computerightedgeodd}
% Compute the right edge of the page, relative to the left edge 
% of the \gls{typeblock}. Again, two commands are needed for odd
% and even pages. First the odd pages.
%    \begin{macrocode}
\newcommand*{\computerightedgeodd}[1]{%
\computeleftedgeodd{#1}%
\addtolength{#1}{\paperwidth}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\computerightedgeeven}
% Now for the even pages.
%    \begin{macrocode}
\newcommand*{\computerightedgeeven}[1]{%
\computeleftedgeeven{#1}%
\addtolength{#1}{\paperwidth}}
%    \end{macrocode}
%\end{macro}
% Compute the minimum area surrounding the listed \glspl{flow}.
% Values stored in "\ffareawidth", "\ffareaheight", "\ffareax"
% and "\ffareay"
%    \begin{macrocode}
\newlength\ffareawidth
\newlength\ffareaheight
\newlength\ffareax
\newlength\ffareay
%    \end{macrocode}
%\begin{macro}{\computeflowframearea}
% Starred version identifies frame by \gls{idl}, unstarred
% version identifies frame by \gls{idn}.
%    \begin{macrocode}
\newcommand*{\computeflowframearea}{%
\@ifstar\@scomputeffarea\@computeffarea}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@scomputeffarea}
% Starred version.
%    \begin{macrocode}
\newcommand*{\@scomputeffarea}[1]{%
\setlength{\ffareax}{\paperwidth}%
\setlength{\ffareay}{\paperheight}%
\setlength{\@ff@tmp@x}{0pt}%
\setlength{\@ff@tmp@y}{0pt}%
\@for\@ff@id:=#1\do{\@flowframeid{\@ff@id}%
%\ff@id is the IDN
\ifnum\ffareax>\flowframex{\ff@id}%
\setlength{\ffareax}{\flowframex{\ff@id}}%
\fi
\ifnum\ffareay>\flowframey{\ff@id}%
\setlength{\ffareay}{\flowframey{\ff@id}}%
\fi
\setlength{\@ff@offset}{\flowframex{\ff@id}}%
\addtolength{@ff@offset}{\flowframewidth{\ff@id}}%
\ifnum\@ff@tmp@x<\@ff@offset
\setlength{\@ff@tmp@x}{\@ff@offset}%
\fi
\setlength{\@ff@offset}{\flowframey{\ff@id}}%
\addtolength{@ff@offset}{\flowframeheight{\ff@id}}%
\ifnum\@ff@tmp@y<\@ff@offset
\setlength{\@ff@tmp@y}{\@ff@offset}%
\fi
}%
\setlength{\ffareawidth}{\@ff@tmp@x}%
\addtolength{\ffareawidth}{-\ffareax}%
\setlength{\ffareaheight}{\@ff@tmp@y}%
\addtolength{\ffareaheight}{-\ffareay}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@computeffarea}
% Unstarred version.
%    \begin{macrocode}
\newcommand*{\@computeffarea}[1]{%
\setlength{\ffareax}{\paperwidth}%
\setlength{\ffareay}{\paperheight}%
\setlength{\@ff@tmp@x}{0pt}%
\setlength{\@ff@tmp@y}{0pt}%
\@for\@ff@id:=#1\do{%
\ff@id=\@ff@id\relax
\setlength{\@ff@offset}{\flowframex{\ff@id}}%
\ifdim\ffareax>\@ff@offset
\setlength{\ffareax}{\@ff@offset}%
\fi
\setlength{\@ff@offset}{\flowframey{\ff@id}}%
\ifdim\ffareay>\@ff@offset
\setlength{\ffareay}{\@ff@offset}%
\fi
\setlength{\@ff@offset}{\flowframex{\ff@id}}%
\addtolength{\@ff@offset}{\flowframewidth{\ff@id}}%
\ifdim\@ff@tmp@x<\@ff@offset
\setlength{\@ff@tmp@x}{\@ff@offset}%
\fi
\setlength{\@ff@offset}{\flowframey{\ff@id}}%
\addtolength{\@ff@offset}{\flowframeheight{\ff@id}}%
\ifdim\@ff@tmp@y<\@ff@offset
\setlength{\@ff@tmp@y}{\@ff@offset}%
\fi
}%
\setlength{\ffareawidth}{\@ff@tmp@x}%
\addtolength{\ffareawidth}{-\ffareax}%
\setlength{\ffareaheight}{\@ff@tmp@y}%
\addtolength{\ffareaheight}{-\ffareay}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@swaplen}
% Swap the values of two lengths
%    \begin{macrocode}
\newcommand*{\@ff@swaplen}[2]{%
\setlength{\@ff@tmp@x}{#1}%
\setlength{#1}{#2}%
\setlength{#2}{\@ff@tmp@x}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@getdim}
% Get the dimensions for the given type of frame.
% The first parameter should be a number indictating
% type of frame : 1 (flow), 2 (static), 3 (dynamic).
% The second number is its \gls{idn}. Values are stored in
% "\ffareax", "\ffareay", "\ffareawidth" and "\ffareaheight".
%    \begin{macrocode}
\newcommand*{\@ff@getdim}[2]{%
\ifnum#2<1\relax
\PackageError{flowfram}{Frame IDNs start from 1}{%
You have specified a frame IDN of '\number#2'}%
\fi
\ifcase#1
\PackageError{flowfram}{Unknown frame ID type '#1'}{%
Frame ID types are: 1 (flow), 2 (static) and 3 (dynamic)}
\or 
\ifnum#2>\c@maxflow
\PackageError{flowfram}{Invalid flow frame IDN '\number#2'}{%
Flow frame IDNs go from 1 to \number\c@maxflow}
\else
\setlength{\ffareax}{\flowframex{#2}}
\setlength{\ffareay}{\flowframey{#2}}
\setlength{\ffareawidth}{\flowframewidth{#2}}
\setlength{\ffareaheight}{\flowframeheight{#2}}
\fi
\or
\ifnum#2>\c@maxstatic
\PackageError{flowfram}{Invalid static frame IDN '\number#2'}{%
Static frame IDNs go from 1 to \number\c@maxstatic}
\else
\setlength{\ffareax}{\staticframex{#2}}
\setlength{\ffareay}{\staticframey{#2}}
\expandafter\expandafter\expandafter
\@ff@getstaticpos
\csname @sf@dim@\romannumeral#2\endcsname
\setlength{\ffareawidth}{\@ff@tmp@x}%
\setlength{\ffareaheight}{\@ff@tmp@y}%
\fi
\or 
\ifnum#2>\c@maxdynamic
\PackageError{flowfram}{Invalid dynamic frame IDN '\number#2'}{%
Dynamic frame IDNs go from 1 to \number\c@maxdynamic}
\else
\setlength{\ffareax}{\dynamicframex{#2}}
\setlength{\ffareay}{\dynamicframey{#2}}
\expandafter\expandafter\expandafter
\@ff@getstaticpos
\csname @df@dim@\romannumeral#2\endcsname
\setlength{\ffareawidth}{\@ff@tmp@x}%
\setlength{\ffareaheight}{\@ff@tmp@y}%
\fi
\else
\PackageError{flowfram}{Unknown frame ID type '#1'}{%
Frame ID types are: 1 (flow), 2 (static) and 3 (dynamic)}
\fi
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\getstaticbounds}
% Convenience method for calling the above. Firstly for static
% frames:
%    \begin{macrocode}
\newcommand*{\getstaticbounds}{%
\@ifstar\@sgetstaticbounds\@getstaticbounds}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sgetstaticbounds}
% Starred version (specify by \gls{idl}):
%    \begin{macrocode}
\newcommand*{\@sgetstaticbounds}[1]{%
\@staticframeid{#1}\@getstaticbounds{\ff@id}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@getstaticbounds}
% Unstarred version (specify by \gls{idn}):
%    \begin{macrocode}
\newcommand*{\@getstaticbounds}[1]{\@ff@getdim{1}{#1}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\getflowbounds}
% Next flow frames:
%    \begin{macrocode}
\newcommand*{\getflowbounds}{%
\@ifstar\@sgetflowbounds\@getflowbounds}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sgetflowbounds}
% Starred version (specify by \gls{idl}):
%    \begin{macrocode}
\newcommand*{\@sgetflowbounds}[1]{%
\@flowframeid{#1}\@getflowbounds{\ff@id}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@getflowbounds}
% Unstarred version (specify by \gls{idn}):
%    \begin{macrocode}
\newcommand*{\@getflowbounds}[1]{\@ff@getdim{2}{#1}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\getdynamicbounds}
% Next dynamic frames:
%    \begin{macrocode}
\newcommand*{\getdynamicbounds}{%
\@ifstar\@sgetdynamicbounds\@getdynamicbounds}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sgetdynamicbounds}
% Starred version (specify by \gls{idl}):
%    \begin{macrocode}
\newcommand*{\@sgetdynamicbounds}[1]{%
\@dynamicframeid{#1}\@getdynamicbounds{\ff@id}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@getdynamicbounds}
% Unstarred version (specify by \gls{idn}):
%    \begin{macrocode}
\newcommand*{\@getdynamicbounds}[1]{\@ff@getdim{3}{#1}}
%    \end{macrocode}
%\end{macro}
%
%\subsection{Initialise Flow Frames}
%\begin{macro}{\setinitialframe}
% Specify initial frame. This should be the first flow 
% frame that is defined on the first page of the document.
% Having another \gls{flow} as the initial frame is not
% a good idea, and may have unexpected results.
%    \begin{macrocode}
\newcommand*{\setinitialframe}[1]{\c@thisframe=#1%
\global\usedframebreaktrue
\global\setlength{\hsize}{%
\csname colwidth\romannumeral\c@thisframe\endcsname}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\setframes}
% Set the initial frame.
%    \begin{macrocode}
\newif\if@setfr@mes
\@setfr@mesfalse
\newcommand*{\setframes}{%
\ifnum\c@thisframe=0\relax
\PackageWarning{flowfram}{Can't find a flow frame on page 1.
\MessageBreak
Attempting to find the first page with a flow frame}%
\@nxtcol=1\relax
\c@curpg=1\relax
\@g@tnextcol{\@nxtcol}%
%    \end{macrocode}
% shipout pages without flow frames
%    \begin{macrocode}
\advance\c@curpg by -1\relax
  \whiledo{\c@curpg>0}{\advance\c@curpg by -1\relax
  \setbox\@outputbox\vbox{\hbox to \textwidth{\@ff@do@allframes}}%
\@outputpage}%
\c@thisframe=\@nxtcol
\fi
\@setcol{\c@thisframe}\relax
\@setfr@mestrue
\edef\ff@txtcol{%
\csname @ff@txtcol@\romannumeral\c@thisframe\endcsname}%
\@s@tfftextcol
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\emulatetwocolumn}
% Emulate original "\twocolumn" declaration.
% This is provided for backward compatibilty, and
% may be removed in later versions.
%    \begin{macrocode}
\newcommand{\emulatetwocolumn}[1][]{%
\finishthispage
\setallflowframes{pages=none}%
\settoheight{\@ff@staticH}{#1}%
\settodepth{\@ff@tmp@y}{#1}%
\addtolength{\@ff@staticH}{\@ff@tmp@y}%
\ifdim\@ff@staticH>0pt\relax
\twocolumnStop[\c@page]{\@ff@staticH}%
\c@thisframe=\c@maxflow
\advance\c@thisframe by -1\relax
\@twocolumn[>\c@page]%
\setstaticcontents{\c@maxstatic}{#1}%
\else
\@twocolumn
\c@thisframe=\c@maxflow
\advance\c@thisframe by -1\relax
\fi
\@setcol{\c@thisframe}\relax
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\emulateonecolumn}
% Emulate original "\onecolumn" declaration.
% This is provided for backward compatibilty, and
% may be removed in later versions.
%    \begin{macrocode}
\newcommand{\emulateonecolumn}[1][]{%
\finishthispage
\setallflowframes{pages=none}%
\settoheight{\@ff@staticH}{#1}%
\settodepth{\@ff@tmp@y}{#1}%
\addtolength{\@ff@staticH}{\@ff@tmp@y}%
\ifdim\@ff@staticH>0pt\relax
\onecolumnStop[\c@page]{\@ff@staticH}%
\c@thisframe=\c@maxflow
\advance\c@thisframe by -1\relax
\@onecolumn[>\c@page]%
\setstaticcontents{\c@maxstatic}{#1}%
\else
\@twocolumn
\c@thisframe=\c@maxflow
\advance\c@thisframe by -1\relax
\fi
\@setcol{\c@thisframe}\relax
}
%    \end{macrocode}
%\end{macro}
% If no flow frames have been defined, create one big one
% the size of the \gls{typeblock}, and initialise the frames.
%    \begin{macrocode}
\AtBeginDocument{%
\ifnum\c@maxflow=0\relax
\PackageWarning{flowfram}{No flow frames, adding one}%
\@onecolumn
\fi
\setframes
\renewcommand{\onecolumn}[1][]{\PackageWarning{flowfram}{%
Ignoring \string\onecolumn\space found in document environment.
Frames must be defined in the preamble}#1}%
\renewcommand{\twocolumn}[1][]{\PackageWarning{flowfram}{%
Ignoring \string\twocolumn\space found in document environment.
Frames must be defined in the preamble}#1}%
}
%    \end{macrocode}
% If the document finishes before the last frame on the last
% page, need to finish off to ensure the final page is
% shipped out, otherwise the text on the last page will be lost.  
%    \begin{macrocode}
%\AtEndDocument{\finishthispage}
%    \end{macrocode}
%\subsection{Output Routine}
%\begin{macro}{\@setcol}
% Set up the output box so it has the correct dimensions for
% specified \gls{flow}. This is used by the output routine.
%    \begin{macrocode}
\newcommand{\@setcol}[1]{%
\ifnum\c@maxflow<#1\relax
\PackageError{flowfram}{Can't set frame '\number#1', doesn't
exist}{}%
\else
\expandafter\global\expandafter\columnwidth
\csname colwidth\romannumeral#1\endcsname
\ifdim\hsize=\columnwidth
\else
 \ifusedframebreak
 \else
   \PackageWarning{flowfram}{Moving to flow frame of unequal
width,\MessageBreak use of \string\framebreak\space advised, 
or text might not appear correctly}%
 \fi
\fi
\global\usedframebreakfalse
\global\hsize\columnwidth
\expandafter\global
\expandafter\vsize\csname colheight\romannumeral#1\endcsname
\global\@colht\vsize
\global\@colroom\@colht
\global\linewidth\columnwidth
\setmargin
\fi
}
%    \end{macrocode}
%\end{macro}
% Modify the output routine so that it uses "\vsize"
% instead of "\textheight". 
%    \begin{macrocode}
\output={\let\par\@@par
\ifnum\outputpenalty <-\@M
  \@specialoutput
\else
  \@makecol
  \@opcol \@startcolumn
  \@whilesw \if@fcolmade \fi {\@opcol \@startcolumn }%
\fi
\ifnum\outputpenalty>-\@Miv
  \ifdim\@colroom<1.5\baselineskip
    \ifdim\@colroom<\vsize
      \@latex@warning@no@line{Text page \thepage \space 
      contains only floats}\@emptycol
    \else
      \global\vsize\@colroom
    \fi
  \else
    \global\vsize\@colroom
  \fi
\else
  \global\vsize\maxdimen
\fi
}
%    \end{macrocode}
%\begin{macro}{\@doclearpage}
% Modify "\@doclearpage", again replace "\textheight"
% with "\vsize", and only use the twocolumn stuff.
%    \begin{macrocode}
\def\@doclearpage{%
\ifvoid\footins
  \setbox\@tempboxa\vsplit\@cclv to\z@
  \unvbox\@tempboxa
  \setbox\@tempboxa\box\@cclv
  \xdef\@deferlist{\@toplist\@botlist\@deferlist}%
\global\let\@toplist\@empty
\global\let\@botlist\@empty
\global\@colroom\@colht
  \ifx\@currlist\@empty
  \else
    \@latexerr{Float(s) lost}\@ehb
    \global\let\@currlist\@empty
  \fi
  \@makefcolumn
  \@deferlist
  \@whilesw \if@fcolmade \fi {\@opcol
     \@makefcolumn
     \@deferlist}%
\if@firstcolumn
     \xdef\@dbldeferlist{\@dbltoplist\@dbldeferlist}%
\global\let\@dbltoplist\@empty
\global\@colht\vsize
\begingroup
  \@dblfloatplacement
  \@makefcolumn
  \@dbldeferlist
  \@whilesw \if@fcolmade \fi {\@outputpage
\@makefcolumn\@dbldeferlist}%
\endgroup
\else
  \vbox{}\clearpage
\fi
\else
  \setbox\@cclv\vbox{\box\@cclv\vfil}%
\@makecol\@opcol\clearpage\fi}
%    \end{macrocode}
%\end{macro}
% Modify "\@outputpage" slightly. Add provision for
% turning headers and footers into \glspl{dynamic}.
%
%\begin{macro}{\@dothehead}
% First define macro to do the header. This will be
% modified if it is turned into a \gls{dynamic}.
%    \begin{macrocode}
\newcommand{\@dothehead}{\vbox to \headheight{%
\color@hbox\normalcolor\hbox to \textwidth{%
\@thehead}\color@endbox}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dothefoot}
% Same again for the footer.
%    \begin{macrocode}
\newcommand{\@dothefoot}{%
\color@hbox\normalcolor\hbox to \textwidth{%
\@thefoot}\color@endbox}
\newcommand{\@dodynamicthehead}{}
\newcommand{\@dodynamicthefoot}{}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@outputpage}
% Now for the modified version of "\@outputpage". The 
% page style stuff has been moved to "\@outputdblcol"
% so that the headers and footers can be set in \glspl{dynamic}
% before the \glspl{dynamic} are put on the page.
%    \begin{macrocode}
\def\@outputpage{%
\begingroup
  \let\protect\noexpand
  \@resetactivechars
  \global\let\@@if@newlist\if@newlist
  \global\@newlistfalse\@parboxrestore
  \shipout\vbox{\set@typeset@protect
  \aftergroup
  \endgroup
  \aftergroup
  \set@typeset@protect
  \reset@font\normalsize\normalsfcodes
  \let\label\@gobble
  \let\index\@gobble
  \let\glossary\@gobble
  \baselineskip\z@skip
  \lineskip\z@skip
  \lineskiplimit\z@
    \vskip\topmargin\moveright\@themargin
    \vbox{%
    \vskip\headheight
    \vskip\headsep
    \box\@outputbox
    }}\global\let\if@newlist\@@if@newlist
    \stepcounter{page}\let\firstmark\botmark}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\makedfheaderfooter}
% Make the headers and footers be in \glspl{dynamic}. There
% will initially be no difference in appearance until
% the settings are changed using "\setdynamicframe".
% The header frame is given the \gls{idl} "header", and the
% footer is given the \gls{idl} "footer".
%    \begin{macrocode}
\newcommand*{\makedfheaderfooter}{%
% create dynamic frames at the standard location
\setlength{\@ff@tmp@y}{\textheight}%
\addtolength{\@ff@tmp@y}{\headsep}%
\newdynamicframe{\textwidth}{\headheight}{0pt}{\@ff@tmp@y}[header]%
\newdynamicframe{\textwidth}{\headheight}{0pt}{-\footskip}[footer]%
\renewcommand{\@dothehead}{}%
\renewcommand{\@dothefoot}{}%
\renewcommand{\@dodynamicthehead}{%
\@dynamicframeid{header}%
\expandafter
\def\csname @dynamicframe@\romannumeral\ff@id\endcsname{%
\vfill\@thehead\vfill}%
}%
\renewcommand{\@dodynamicthefoot}{%
\@dynamicframeid{footer}%
\expandafter
\def\csname @dynamicframe@\romannumeral\ff@id\endcsname{%
\vfill\@thefoot\vfill}%
}%
}
%    \end{macrocode}
%\end{macro}
% This should only be done in the preamble.
%    \begin{macrocode}
\@onlypreamble{\makedfheaderfooter}
%    \end{macrocode}
%\begin{macro}{\footnotecolor}
% Set footnotes in "\footnotecolor" rather than "\normalcolor"
% This ensures that the footnotes appear in the same colour
% as the text colour for the \gls{flow} to which they belong.
%    \begin{macrocode}
\newcommand{\footnotecolor}{%
\@ifundefined{@ff@txtcol@\romannumeral\c@thisframe}{%
\normalcolor}{%
\edef\ff@txtcol{%
\csname @ff@txtcol@\romannumeral\c@thisframe\endcsname}%
\@s@tfftextcol}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@makecol}
% Modify "\@makecol" so that the footnotes, and the 
% footnote rule are in the colour for that frame.
%    \begin{macrocode}
\renewcommand{\@makecol}{%
\ifvoid\footins 
  \setbox\@outputbox\box\@cclv 
\else 
  \setbox\@outputbox\vbox{%
\boxmaxdepth\@maxdepth\@tempdima\dp\@cclv 
    \unvbox\@cclv 
    \vskip\skip\footins 
    \color@begingroup 
      \footnotecolor 
      \footnoterule 
      \unvbox\footins 
    \color@endgroup 
}\fi 
\xdef\@freelist{\@freelist \@midlist }%
\global\let\@midlist\@empty 
\@combinefloats 
\ifvbox\@kludgeins 
  \@makespecialcolbox 
\else 
  \setbox\@outputbox\vbox to\@colht{%
\@texttop\dimen@\dp\@outputbox 
  \unvbox \@outputbox
  \vskip -\dimen@\@textbottom 
}\fi 
\global\maxdepth\@maxdepth}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@opcol}
% Modify "\@opcol", as "\if@twocolumn" is now
% irrelevant.
%    \begin{macrocode}
\def\@opcol{\@outputdblcol
\global\@mparbottom\z@
\global\@textfloatsheight\z@
\@floatplacement
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@checkifmoreframes}
% Check to see if there are more \glspl{flow} defined, and
% set "\if@ff@moreframes" as appropriate. This involves
% iterating through all \glspl{flow}, and through each 
% frame's \gls{pglist}.
%    \begin{macrocode}
\newif\if@ff@moreframes
\newcommand*{\@ff@checkifmoreframes}{%
\@ff@moreframesfalse
\@colN=\c@thisframe
\whiledo{\@colN<\c@maxflow}{%
\advance\@colN by 1\relax
\edef\ff@pages{\csname @ff@pages@\romannumeral\@colN\endcsname}%
\@ff@checkpages{\ff@pages}%
}%
\if@ff@moreframes
\else
\@ff@tmpN=\c@page
\advance\@ff@tmpN by 1\relax
\@colN=0\relax
\whiledo{\@colN<\c@thisframe}{%
\advance\@colN by 1\relax
\edef\ff@pages{\csname @ff@pages@\romannumeral\@colN\endcsname}%
\@ff@checkpages[\@ff@tmpN]{\ff@pages}%
}%
\fi
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@checkpages}
% Check to see if the current page lies in the \gls{pglist}
% given by "#1".
%    \begin{macrocode}
\newcommand*{\@ff@checkpages}[2][\c@page]{%
\@for\@ff@pp:=#2\do{%
\@ff@checkthispage{#1}{\@ff@pp}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@checkthispage}
% Check to see if the current page lies in the \gls{pgrange}
% given by "#1". If the \gls{pgrange} is specified by
% "all", "odd" or "even" then there are definitely more
% frames available, otherwise check to see if the current page 
% lies within the number range. If the \gls{pgrange} is "none", 
% ignore it.
%    \begin{macrocode}
\newcommand*{\@ff@checkthispage}[2]{%
\ifthenelse{\equal{#2}{all}\or\equal{#2}{even}\or\equal{#2}{odd}}{%
\@ff@moreframestrue}{%
\ifthenelse{\equal{#2}{none}}{}{%
\@ff@checknumrange{#1}{#2}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@checknumrange}
% The number range could be a single number, a closed range
% (e.g.\ "2-6") or an open range (e,g.\ "<4" or ">10").
% Use "\@ff@getrange" to find the start and end ranges.
% For open ended ranges assume a maximum value of 10000.
% If the current page is less than or equal to the maximum, 
% there are still more \glspl{flow} available.
%    \begin{macrocode}
\newcommand*{\@ff@checknumrange}[2]{%
\def\@ff@numstart{0}\def\@ff@numend{10000}%
\@ff@getrange{#2}%
\ifnum\@ff@numend>#1\relax
\@ff@moreframestrue
\else
\ifnum\@ff@numend=#1\relax
\@ff@moreframestrue
\fi
\fi
}
%    \end{macrocode}
%\end{macro}
% Work out the minimum and maximum values of a number range
% which could either be a single number, a closed number
% range or an open number range. If the first character
% is "<" or ">" then it is an open range, otherwise it is
% a closed range or a single number. Define a counter
% to use whilst determining the range.
%    \begin{macrocode}
\newcount\c@ffrangenum
%    \end{macrocode}
%\begin{macro}{\@ff@getrange}
% Now to find out what kind of range it is. If it is a single
% number, e.g.\ "24", then it will do, e.g.\ 
% "\@ff@@getrange24-\relax".
% If it is a closed range, e.g. "30-40", it will do , e.g.\ 
% "\@ff@@getrange30-40-\relax". If it is an open range, e.g.\ 
% ">25", it will do, e.g.\ "\@ff@@getrange>25-\relax".
%    \begin{macrocode}
\newcommand*{\@ff@getrange}[1]{%
\expandafter\@ff@@getrange#1-\relax\end}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@@getrange}
% The ranges can now be picked out. If the first character
% is a "<" or ">" it is an open ended range, otherwise it
% is either a single value, or a close ended range.
%    \begin{macrocode}
\def\@ff@@getrange#1#2\end{%
\ifx#1<\relax
 \@ff@getrangeless#1#2\end
\else
  \ifx#1>\relax
    \@ff@getrangegreater#1#2\end
  \else
    \@@ff@getrange#1#2\end
  \fi
\fi
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@getrangeless}
% Get the values for an open ended range with an
% upper bound. A minimum value of "0" is assumed.
%    \begin{macrocode}
\def\@ff@getrangeless<#1-\relax\end{%
\c@ffrangenum=#1\relax
\advance\c@ffrangenum by -1\relax
\def\@ff@numstart{0}%
\edef\@ff@numend{\number\c@ffrangenum}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@getrangegreater}
% Get the values for an open ended range with a lower
% bound. A maximum value of "10000" is assumed.
%    \begin{macrocode}
\def\@ff@getrangegreater>#1-\relax\end{%
\c@ffrangenum=#1\relax
\advance\c@ffrangenum by 1\relax
\edef\@ff@numstart{\number\c@ffrangenum}%
\def\@ff@numend{10000}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@ff@getrange}
% Determine whether we have a single number or
% a closed range. If "#2" is "\relax", it is a single
% value, otherwise it is a range.
%    \begin{macrocode}
\def\@@ff@getrange#1-#2\end{%
\ifx\relax#2\relax
\def\@ff@numstart{#1}\def\@ff@numend{#1}%
\else
\def\@ff@numstart{#1}%
\@@@ff@getrange#2\end
\fi
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@@ff@getrange}
% Extract the end value from the closed range.
%    \begin{macrocode}
\def\@@@ff@getrange#1-\relax\end{%
\def\@ff@numend{#1}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@g@tnextcol}
% Find the next \gls{flow}. If there are no more flow
% frames, define a new one the size of the \gls{typeblock}.
% (Otherwise the remaining document text will be lost.)
%    \begin{macrocode}
\newif\if@notthiscol
\newif\if@ff@nwpg
\newcount\c@curpg
\newcommand*{\@g@tnextcol}[1]{%
\@ff@checkifmoreframes
\if@ff@moreframes
\else
% No more frames, add new frame
\PackageWarning{flowfram}{Run out of flows frames, 
adding new one}%
\@onecolumn
#1=\c@maxflow
\fi
\@notthiscoltrue
\@ff@nwpgfalse
\@colN=#1\relax
\c@curpg=\c@page
\loop
\ifnum\@colN=\c@maxflow
 \@colN=1\@ff@nwpgtrue
 \advance\c@curpg by 1\relax
\else
 \advance\@colN by 1\relax
\fi
\@ff@chckifthispg{\c@curpg}{\@colN}%
\if@notthiscol
\repeat
#1=\@colN
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@chckifthispg}
% This is used to determine the next \gls{flow}, since not
% all \glspl{flow} may be defined on every page. Checks to
% see if \gls{flow} "#2" is defined on page "#1".
% First set up some variables.
%    \begin{macrocode}
\newcommand*{\@ff@chckifthispg}[2]{%
\@notthiscoltrue
\edef\ff@pages{\csname @ff@pages@\romannumeral#2\endcsname}%
\@@ff@chckifthispg{#1}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@ff@chckifthispg}
% Now go ahead and check.
%    \begin{macrocode}
\newcommand*{\@@ff@chckifthispg}[1]{%
\ifthenelse{\equal{\ff@pages}{none}}{}{%
\ifthenelse{\equal{\ff@pages}{all}}{\@notthiscolfalse}{%
\ifthenelse{\equal{\ff@pages}{odd}}{%
\ifodd#1\@notthiscolfalse\fi}{%
\ifthenelse{\equal{\ff@pages}{even}}{%
\ifodd#1\else\@notthiscolfalse\fi}{%
% check through list of page numbers
\@for\@ff@pp:=\ff@pages\do{%
\def\@ff@numstart{0}\def\@ff@numend{0}%
\@ff@getrange{\@ff@pp}%
\ifthenelse{#1<\@ff@numstart \or #1>\@ff@numend}{}{%
\@notthiscolfalse}%
}%
}}}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sf@chckifthispg}
% Checks to see if \gls{static} "#1" is defined on the
% current page.
%    \begin{macrocode}
\newcommand*{\@sf@chckifthispg}[1]{%
\@notthiscoltrue
\edef\ff@pages{\csname @sf@pages@\romannumeral#1\endcsname}%
\@@ff@chckifthispg{\c@page}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@df@chckifthispg}
% Checks to see if \gls{dynamic} "#1" is defined on the
% current page.
%    \begin{macrocode}
\newcommand*{\@df@chckifthispg}[1]{%
\@notthiscoltrue
\edef\ff@pages{\csname @df@pages@\romannumeral#1\endcsname}%
\@@ff@chckifthispg{\c@page}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@setcolbox}
% Sets the \TeX\ box defining the \gls{flow} to the output
% box. This saves the output until the page is shipped out after
% all the \glspl{flow} have been filled for that page.
%    \begin{macrocode}
\newcommand*{\@setcolbox}[1]{%
\expandafter\global\expandafter\setbox
\csname column\romannumeral#1\endcsname\box\@outputbox
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@docolbox}
% Put \gls{flow} on the page with the correct border, if it
% has one.
%    \begin{macrocode}
\newcommand*{\@docolbox}[1]{%
\edef\ff@frametype{%
\csname @ff@frametype@\romannumeral#1\endcsname}%
\edef\ff@col{\csname @ff@col@\romannumeral#1\endcsname}%
\edef\ff@txtcol{\csname @ff@txtcol@\romannumeral#1\endcsname}%
\edef\ff@backcol{\csname @ff@backcol@\romannumeral#1\endcsname}%
\@ff@setoffset{#1}%
\rotateframe{\csname @ff@angle@\romannumeral#1\endcsname}{%
\ifthenelse{\boolean{columnframe\romannumeral#1}}{%
\@ff@fbox{\csname colwidth\romannumeral#1\endcsname}%
{\csname colheight\romannumeral#1\endcsname}{%
\expandafter\box\csname column\romannumeral#1\endcsname}{%
\csname\ff@frametype\endcsname}%
}{%
\@ff@box{\csname colwidth\romannumeral#1\endcsname}%
{\csname colheight\romannumeral#1\endcsname}{%
\expandafter\box\csname column\romannumeral#1\endcsname}%
}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@docolbbox}
% Do the \gls{bbox} for given \gls{flow}.
%    \begin{macrocode}
\newcommand*{\@docolbbox}[1]{%
\@ff@setoffset{#1}%
\def\ff@col{}\def\ff@txtcol{}%
\@fr@meifdraft{%
\@ff@box{\csname colwidth\romannumeral#1\endcsname}%
{\csname colheight\romannumeral#1\endcsname}{%
\expandafter\box\csname column\romannumeral#1\endcsname}}%
{F:\number#1;\csname @col@id@\romannumeral#1\endcsname}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@fbox}
% Put the \TeX\ box "#3" of width "#1" and
% height "#2", and frame making command
% specified by "#4".
%    \begin{macrocode}
\newcommand{\@ff@fbox}[4]{{%
\fboxsep=\flowframesep\fboxrule=\flowframerule\@s@tffcol 
\kern\@ff@offset
#4{\@ff@box{#1}{#2}{#3}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@box}
% Put the \TeX\ box "#3" of width "#1" and height "#2" on
% the page.
%    \begin{macrocode}
\newcommand{\@ff@box}[3]{{\@ffbackground{\vbox to#2
{\hb@xt@ #1{\hss{\@s@tfftextcol #3}\hss}\vss\kern\z@}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@putcolbox}
% Display the \gls{flow} on the page, at its given position.
% If the document is two-sided, need to check whether
% the current page is odd or even to determine the correct
% location.
%    \begin{macrocode}
\newcommand*{\@putcolbox}[1]{%
\@ff@chckifthispg{\c@page}{#1}%
\if@notthiscol
\else
\@killglue
\if@twoside
\ifodd\c@page
\expandafter\raise\csname col@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname col@\romannumeral#1@posx\endcsname
\@docolbox{#1}\hss}%
\else
\expandafter\raise\csname col@\romannumeral#1@eveny\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname col@\romannumeral#1@evenx\endcsname
\@docolbox{#1}\hss}%
\fi
\else
\expandafter\raise\csname col@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname col@\romannumeral#1@posx\endcsname
\@docolbox{#1}\hss}%
\fi
\fi
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@putcolbbox}
% Same for \gls{flow} \gls{bbox}:
%    \begin{macrocode}
\newcommand*{\@putcolbbox}[1]{%
\@ff@chckifthispg{\c@page}{#1}%
\if@notthiscol
\else
\@killglue
\if@twoside
\ifodd\c@page
\expandafter\raise\csname col@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname col@\romannumeral#1@posx\endcsname
\@docolbbox{#1}\hss}%
\else
\expandafter\raise\csname col@\romannumeral#1@eveny\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname col@\romannumeral#1@evenx\endcsname
\@docolbbox{#1}\hss}%
\fi
\else
\expandafter\raise\csname col@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname col@\romannumeral#1@posx\endcsname
\@docolbbox{#1}\hss}%
\fi
\fi
}
%    \end{macrocode}
%\end{macro}
% If an offset hasn't been specified, compute it.  If the 
% frame making command is known (e.g. doublebox), compute
% the offset according to known specifications, otherwise
% set the negative offset to "\flowframesep" plus 
% "\flowframerule", which may or may not be correct.
%
%\begin{macro}{\@ff@s@t@doubleboxoffset}
% Compute offset for "\doublebox":
%    \begin{macrocode}
\newcommand*{\@ff@s@t@doubleboxoffset}{%
\setlength{\@ff@offset}{-\flowframesep}%
\addtolength{\@ff@offset}{-3.75\flowframerule}%
\addtolength{\@ff@offset}{-.5pt}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@s@t@ovalboxoffset}
% Compute offset for "\ovalbox":
%    \begin{macrocode}
\newcommand*{\@ff@s@t@ovalboxoffset}{%
\@ff@offset=-\fontdimen 8\tenln\relax
\advance\@ff@offset by -\flowframesep\relax
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@s@t@Ovalboxoffset}
% Compute offset for "\ovalbox":
%    \begin{macrocode}
\newcommand*{\@ff@s@t@Ovalboxoffset}{%
\@ff@offset=-\fontdimen 8\tenlnw\relax
\advance\@ff@offset by -\flowframesep\relax
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@s@t@defaultoffset}
% Compute default offset:
%    \begin{macrocode}
\newcommand*{\@ff@s@t@defaultoffset}{%
\@ff@offset=-\flowframesep\relax
\addtolength{\@ff@offset}{-\flowframerule}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@setoffset}
% Compute offset for \gls{flow} "#1". Stores offset value
% in "\ff@offset".
%    \begin{macrocode}
\newcommand*{\@ff@setoffset}[1]{%
\ifthenelse{\equal{\csname @ff@offset@\romannumeral#1\endcsname}%
{compute}}{%
\ifthenelse{\boolean{columnframe\romannumeral#1}}{%
\ifthenelse{%
\equal{\csname @ff@frametype@\romannumeral#1\endcsname}%
{doublebox}}{%
\@ff@s@t@doubleboxoffset
}{%
\ifthenelse{%
\equal{\csname @ff@frametype@\romannumeral#1\endcsname}%
{ovalbox}}{%
\@ff@s@t@ovalboxoffset
}{%
\ifthenelse{%
\equal{\csname @ff@frametype@\romannumeral#1\endcsname}%
{Ovalbox}}{%
\@ff@s@t@Ovalboxoffset}{%
\@ff@s@t@defaultoffset
}}}%
}{}%
}{%
\setlength{\@ff@offset}%
{\csname @ff@offset@\romannumeral#1\endcsname}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sf@setoffset}
% Compute offset for \gls{static} "#1". Stores offset value
% in "\ff@offset".
%    \begin{macrocode}
\newcommand*{\@sf@setoffset}[1]{%
\ifthenelse{%
\equal{\csname @sf@offset@\romannumeral#1\endcsname}%
{compute}}{%
\ifthenelse{\boolean{staticframe\romannumeral#1}}{%
\ifthenelse{%
\equal{\csname @sf@frametype@\romannumeral#1\endcsname}%
{doublebox}}{%
\@ff@s@t@doubleboxoffset
}{%
\ifthenelse{%
\equal{\csname @sf@frametype@\romannumeral#1\endcsname}%
{ovalbox}}{%
\@ff@s@t@ovalboxoffset
}{%
\ifthenelse{%
\equal{\csname @sf@frametype@\romannumeral#1\endcsname}%
{Ovalbox}}{%
\@ff@s@t@Ovalboxoffset
}{%
\@ff@s@t@defaultoffset
}}}%
}{}%
}{%
\setlength{\@ff@offset}%
{\csname @sf@offset@\romannumeral#1\endcsname}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@df@setoffset}
% Compute offset for \gls{dynamic} "#1". Stores offset value
% in "\ff@offset".
%    \begin{macrocode}
\newcommand*{\@df@setoffset}[1]{%
\ifthenelse{%
\equal{\csname @df@offset@\romannumeral#1\endcsname}%
{compute}}{%
\setlength{\@ff@offset}{0pt}%
\ifthenelse{\boolean{dynamicframe\romannumeral#1}}{%
\ifthenelse{%
\equal{\csname @df@frametype@\romannumeral#1\endcsname}%
{doublebox}}{%
\@ff@s@t@doubleboxoffset
}{%
\ifthenelse{%
\equal{\csname @df@frametype@\romannumeral#1\endcsname}%
{ovalbox}}{%
\@ff@s@t@ovalboxoffset
}{%
\ifthenelse{%
\equal{\csname @df@frametype@\romannumeral#1\endcsname}%
{Ovalbox}}{%
\@ff@s@t@Ovalboxoffset}{%
\@ff@s@t@defaultoffset
}}}%
}{}%
}{%
\setlength{\@ff@offset}%
{\csname @df@offset@\romannumeral#1\endcsname}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@putmarginbox}
% Draw box representing the margin for \gls{flow} "#1".
%    \begin{macrocode}
\newcommand*{\@putmarginbox}[1]{%
\@ff@chckifthispg{\c@page}{#1}%
\if@notthiscol
\else
\@killglue
\if@twoside
\ifodd\c@page
\edef\ff@x{\csname col@\romannumeral#1@posx\endcsname}%
\edef\ff@y{\csname col@\romannumeral#1@posy\endcsname}%
\else
\edef\ff@x{\csname col@\romannumeral#1@evenx\endcsname}%
\edef\ff@y{\csname col@\romannumeral#1@eveny\endcsname}%
\fi
\else
\edef\ff@x{\csname col@\romannumeral#1@posx\endcsname}%
\edef\ff@y{\csname col@\romannumeral#1@posy\endcsname}%
\fi
\setlength{\@ff@tmp@x}{\ff@x}%
\setlength{\@ff@tmp@y}{\ff@y}%
\@getmarginpos{\csname @ff@margin@\romannumeral#1\endcsname}%
\ifthenelse{\equal{\ff@margin}{left}}{%
\addtolength{\@ff@tmp@x}{-\marginparwidth}%
\addtolength{\@ff@tmp@x}{-\marginparsep}%
\ifthenelse{\boolean{columnframe\romannumeral#1}}{%
}{}%
}{%
\addtolength{\@ff@tmp@x}%
{\csname colwidth\romannumeral#1\endcsname}%
\addtolength{\@ff@tmp@x}{\marginparsep}%
\ifthenelse{\boolean{columnframe\romannumeral#1}}{%
}{}%
}%
\raise\@ff@tmp@y
\hb@xt@\z@{%
\expandafter\kern\@ff@tmp@x
\@fr@meifdraft{\@ff@box{\marginparwidth}%
{\csname colheight\romannumeral#1\endcsname}{}}%
{M:\number#1}\hss}\fi
\ignorespaces}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@drawmargins}
% Draw all the margins associated with the \glspl{flow} defined
% on the current page.
%    \begin{macrocode}
\newcommand*{\@ff@drawmargins}{%
\@colN=0\relax
\whiledo{\@colN<\c@maxflow}{%
\advance\@colN by 1\relax
\makebox[0pt][l]{\@putmarginbox{\@colN}}%
}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@getstaticpos}
% Extract the width and height for static or \gls{dynamic}
% specified in the form \oarg{c}\oarg{height}\oarg{valign}\marg{width}
%    \begin{macrocode}
\def\@ff@getstaticpos[#1][#2][#3]#4{\@ff@tmp@x=#4\relax
\@ff@tmp@y=#2\relax
\def\ff@valign{#3}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dostaticbox}
% Display the savebox associated with \gls{static} "#1"
%    \begin{macrocode}
\newcommand*{\@dostaticbox}[1]{%
\edef\ff@frametype{%
\csname @sf@frametype@\romannumeral#1\endcsname}%
\edef\ff@col{\csname @sf@col@\romannumeral#1\endcsname}%
\edef\ff@backcol{\csname @sf@backcol@\romannumeral#1\endcsname}%
\@sf@setoffset{#1}%
\expandafter\expandafter\expandafter
\@ff@getstaticpos\csname @sf@dim@\romannumeral#1\endcsname
\rotateframe{\csname @sf@angle@\romannumeral#1\endcsname}{%
\ifthenelse{\boolean{staticframe\romannumeral#1}}{%
\@ff@fbox{\@ff@tmp@x}{\@ff@tmp@y}{%
\expandafter\usebox\csname @staticframe@\romannumeral#1\endcsname}
{\csname\ff@frametype\endcsname}%
}{%
\@ff@box{\@ff@tmp@x}{\@ff@tmp@y}%
{\expandafter\usebox\csname @staticframe@\romannumeral#1\endcsname}%
}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dostaticbbox}
% Now for the \gls{bbox}:
%    \begin{macrocode}
\newcommand*{\@dostaticbbox}[1]{%
\edef\ff@col{}%
\@sf@setoffset{#1}%
\expandafter\expandafter\expandafter
\@ff@getstaticpos\csname @sf@dim@\romannumeral#1\endcsname
\@fr@meifdraft{%
\@ff@box{\@ff@tmp@x}{\@ff@tmp@y}%
{\expandafter\usebox\csname @staticframe@\romannumeral#1\endcsname}%
}{S:\number#1;\csname @sf@id@\romannumeral#1\endcsname}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@putstaticbox}
% Put the static box "#1" at its given position, with its
% associated border.
%    \begin{macrocode}
\newcommand*{\@putstaticbox}[1]{%
\@sf@chckifthispg{#1}%
\if@notthiscol\else
\@killglue
\if@twoside
\ifodd\c@page
\expandafter\raise\csname @sf@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @sf@\romannumeral#1@posx\endcsname
\@dostaticbox{#1}\hss}%
\else
\expandafter\raise\csname @sf@\romannumeral#1@eveny\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @sf@\romannumeral#1@evenx\endcsname
\@dostaticbox{#1}\hss}%
\fi
\else
\expandafter\raise\csname @sf@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @sf@\romannumeral#1@posx\endcsname
\@dostaticbox{#1}\hss}%
\fi
\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@putstaticbbox}
% Now for the \gls{bbox}:
%    \begin{macrocode}
\newcommand*{\@putstaticbbox}[1]{%
\@sf@chckifthispg{#1}%
\if@notthiscol\else
\@killglue
\if@twoside
\ifodd\c@page
\expandafter\raise\csname @sf@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @sf@\romannumeral#1@posx\endcsname
\@dostaticbbox{#1}\hss}\ignorespaces
\else
\expandafter\raise\csname @sf@\romannumeral#1@eveny\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @sf@\romannumeral#1@evenx\endcsname
\@dostaticbbox{#1}\hss}\ignorespaces
\fi
\else
\expandafter\raise\csname @sf@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @sf@\romannumeral#1@posx\endcsname
\@dostaticbbox{#1}\hss}\ignorespaces
\fi
\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@resetst@tics}
% Clear the contents of all the \glspl{static} that have
% the "clear" option set.
%    \begin{macrocode}
\newcommand*{\@resetst@tics}{%
\@colN=0\relax
\whiledo{\@colN<\c@maxstatic}{\advance\@colN by 1\relax
\ifthenelse{\boolean{@sf@clear@\romannumeral\@colN}}{%
\global\sbox{%
\csname @staticframe@\romannumeral\@colN\endcsname}{}}{}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@resetdyn@mics}
% Clear the contents of the \glspl{dynamic} that have the "clear" option
% set.
%    \begin{macrocode}
\newcommand*{\@resetdyn@mics}{%
\@colN=0\relax
\whiledo{\@colN<\c@maxdynamic}{\advance\@colN by 1\relax
\ifthenelse{\boolean{@df@clear@\romannumeral\@colN}}{%
\expandafter\global\expandafter
\gdef\csname @dynamicframe@\romannumeral\@colN\endcsname{}}{}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dodfparbox}
% Display contents of dynamic box (contents stored in
% "\ff@contents", style given by "\ff@style"):
%    \begin{macrocode}
\newcommand*{\@dodfparbox}[1]{%
\expandafter\let\expandafter
\@ff@parshape\csname @df@shape@\romannumeral#1\endcsname
\expandafter\@ff@getshape\@ff@parshape\relax
\ifcase\ff@shape
% no shape
\expandafter\expandafter\expandafter
\parbox\csname @df@dim@\romannumeral#1\endcsname
{%
\setlength\parindent\sdfparindent
\csname\ff@style\endcsname{\ff@contents}}%
\or
% \parshape
\expandafter\expandafter\expandafter
\parbox\csname @df@dim@\romannumeral#1\endcsname
{%
\setlength\parindent\sdfparindent
\csname\ff@style\endcsname{{%
\let\oldpar=\par
\let\par=\ffpshpar
\@ff@setsecthead
\@ff@parshape
\ff@contents\oldpar}}}%
\or
% \shapepar
\expandafter\expandafter\expandafter
\parbox\csname @df@dim@\romannumeral#1\endcsname
{%
\setlength\parindent\sdfparindent
\csname\ff@style\endcsname{{\@ff@disablesec\@ff@parshape
\ff@contents\par}}}%
\fi
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dodynamicbox}
% Typeset the dynamic box with its associated border.
%    \begin{macrocode}
\newcommand*{\@dodynamicbox}[1]{%
\edef\ff@frametype{%
\csname @df@frametype@\romannumeral#1\endcsname}%
\edef\ff@col{\csname @df@col@\romannumeral#1\endcsname}%
\edef\ff@txtcol{\csname @df@txtcol@\romannumeral#1\endcsname}%
\edef\ff@backcol{\csname @df@backcol@\romannumeral#1\endcsname}%
\edef\ff@style{\csname @df@style@\romannumeral#1\endcsname}%
\def\ff@contents{\csname @dynamicframe@\romannumeral#1\endcsname}%
\@df@setoffset{#1}%
\expandafter\expandafter\expandafter
\@ff@getstaticpos\csname @df@dim@\romannumeral#1\endcsname
\rotateframe{\csname @df@angle@\romannumeral#1\endcsname}{%
\ifthenelse{\boolean{dynamicframe\romannumeral#1}}{%
\@ff@fbox{\@ff@tmp@x}{\@ff@tmp@y}%
{\@dodfparbox{#1}}%
{\csname\ff@frametype\endcsname}%
}{%
\@ff@box{\@ff@tmp@x}{\@ff@tmp@y}{%
\@dodfparbox{#1}}%
}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dodynamicbbox}
% Now for the \gls{bbox}:
%    \begin{macrocode}
\newcommand*{\@dodynamicbbox}[1]{%
\edef\ff@col{}%
\@df@setoffset{#1}%
\expandafter\expandafter\expandafter
\@ff@getstaticpos\csname @df@dim@\romannumeral#1\endcsname
\@fr@meifdraft{%
\@ff@box{\@ff@tmp@x}{\@ff@tmp@y}{%
\expandafter\expandafter\expandafter
\parbox\csname @df@dim@\romannumeral#1\endcsname
{}}%
}{D:\number#1;\csname @df@id@\romannumeral#1\endcsname}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@putdynamicbox}
% Put the \gls{dynamic} "#1" at its given position
%    \begin{macrocode}
\newcommand*{\@putdynamicbox}[1]{%
\@df@chckifthispg{#1}%
\if@notthiscol\else
\@killglue
\if@twoside
\ifodd\c@page
\expandafter\raise\csname @df@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @df@\romannumeral#1@posx\endcsname
\@dodynamicbox{#1}\hss}\ignorespaces
\else
\expandafter\raise\csname @df@\romannumeral#1@eveny\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @df@\romannumeral#1@evenx\endcsname
\@dodynamicbox{#1}\hss}\ignorespaces
\fi
\else
\expandafter\raise\csname @df@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @df@\romannumeral#1@posx\endcsname
\@dodynamicbox{#1}\hss}\ignorespaces
\fi
\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@putdynamicbbox}
% Bounding box:
%    \begin{macrocode}
\newcommand*{\@putdynamicbbox}[1]{%
\@df@chckifthispg{#1}%
\if@notthiscol\else
\@killglue
\if@twoside
\ifodd\c@page
\expandafter\raise\csname @df@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @df@\romannumeral#1@posx\endcsname
\@dodynamicbbox{#1}\hss}\ignorespaces
\else
\expandafter\raise\csname @df@\romannumeral#1@eveny\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @df@\romannumeral#1@evenx\endcsname
\@dodynamicbbox{#1}\hss}\ignorespaces
\fi
\else
\expandafter\raise\csname @df@\romannumeral#1@posy\endcsname
\hb@xt@\z@{%
\expandafter\kern \csname @df@\romannumeral#1@posx\endcsname
\@dodynamicbbox{#1}\hss}\ignorespaces
\fi
\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@doheader}
% Do standard header in the standard place.
%    \begin{macrocode}
\newcommand*{\@@doheader}{%
\setlength\@ff@tmp@y{\textheight}%
\addtolength{\@ff@tmp@y}{\headsep}%
\def\ff@col{}%
\def\ff@txtcol{}%
\def\ff@backcol{{none}}%
\@ff@box{0pt}{\@ff@tmp@y}{\makebox[0pt][l]{\@dothehead}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@dofooter}
% Do standard footer in the standard place.
%    \begin{macrocode}
\newcommand*{\@@dofooter}{%
\setlength\@ff@tmp@y{-\footskip}%
\def\ff@col{}%
\def\ff@txtcol{}%
\def\ff@backcol{{none}}%
\@ff@box{0pt}{\@ff@tmp@y}{\makebox[0pt][l]{\@dothefoot}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@s@tfr@mes}
% This is a modified version of the way the picture environment 
% works:
%    \begin{macrocode}
\newcommand{\@s@tfr@mes}[1]{{\@picht\textheight
\setbox\@picbox\hb@xt@ \textwidth 
\bgroup \hbox \bgroup #1\relax
\egroup
\hss \egroup 
\ht\@picbox\@picht \dp\@picbox 
\z@ \mbox{\box \@picbox}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@doallflowframes}
% Puts all the \glspl{flow} defined on the current page
%    \begin{macrocode}
\newcommand*{\@ff@doallflowframes}{%
\@colN=0\relax
\whiledo{\@colN<\c@maxflow}{\advance\@colN by 1\relax
\@putcolbox{\@colN}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@doallflowframesbbox}
% Flow frame \glspl{bbox}:
%    \begin{macrocode}
\newcommand*{\@ff@doallflowframesbbox}{%
\@colN=0\relax
\whiledo{\@colN<\c@maxflow}{\advance\@colN by 1\relax
\@putcolbbox{\@colN}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@doallstatics}
% Puts all \glspl{static} defined on the current page
%    \begin{macrocode}
\newcommand*{\@ff@doallstatics}{%
\@colN=0\relax
\whiledo{\@colN<\c@maxstatic}{\advance\@colN by 1\relax
\@putstaticbox{\@colN}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@doallstaticsbbox}
% Static frame \glspl{bbox}:
%    \begin{macrocode}
\newcommand*{\@ff@doallstaticsbbox}{%
\@colN=0\relax
\whiledo{\@colN<\c@maxstatic}{\advance\@colN by 1\relax
\@putstaticbbox{\@colN}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@doalldynamics}
% Puts all the \glspl{dynamic} defined on the current page
%    \begin{macrocode}
\newcommand*{\@ff@doalldynamics}{%
\@colN=0\relax
\whiledo{\@colN<\c@maxdynamic}{\advance\@colN by 1\relax
\@putdynamicbox{\@colN}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@doalldynamicsbbox}
% Dynamic frame \glspl{bbox}:
%    \begin{macrocode}
\newcommand*{\@ff@doalldynamicsbbox}{%
\@colN=0\relax
\whiledo{\@colN<\c@maxdynamic}{\advance\@colN by 1\relax
\@putdynamicbbox{\@colN}}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@dotypeblock}
% Draw \gls{typeblock} frame if draft.
%    \begin{macrocode}
\newcommand*{\@ff@dotypeblock}{%
\makebox[0pt][l]{\@fr@meifdraft[\setffdrafttypeblockcolor]{%
\vbox to \textheight{\hbox to \textwidth{}}}{}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ff@do@allframes}
% Put all frames defined on the current page.
%    \begin{macrocode}
\newlength\ffevenoffset
\newcommand*{\@ff@do@allframes}{%
\ffevenoffset=0pt\relax
\if@twoside
  \ifodd\c@page
  \else
    \ffevenoffset=-\oddsidemargin\relax
    \advance\ffevenoffset by \evensidemargin\relax
    \kern\ffevenoffset\relax
  \fi
\fi
\setlength{\@ff@tmp@x}{\textwidth}%
\advance\@ff@tmp@x by -\ffevenoffset\relax
\makebox[\@ff@tmp@x][l]{%
\@s@tfr@mes{%
\@ff@doallstatics
\@@doheader
\@@dofooter
\@ff@doallflowframes
\@ff@doalldynamics
\ifshowtypeblock
  \@ff@dotypeblock
\fi
\ifshowframebbox
  \@ff@doallstaticsbbox
  \@ff@doallflowframesbbox
  \@ff@doalldynamicsbbox
\fi
\ifshowmargins
  \@ff@drawmargins
\fi
}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@outputdblcol}
% This was modified from the output routine for standard
% two column format. After "\@g@tnextcol", the register
% "\c@curpg" contains the page that the next \gls{flow}
% is on. If "\c@curpg" minus "\c@page" is greater
% than 1, then there is at least one page without a \gls{flow}.
% These pages will have to be shipped before \TeX\ can
% continue with the rest of the document.
%    \begin{macrocode}
\newcount\@nxtcol
\def\@outputdblcol{%
\@nxtcol=\c@thisframe
\c@curpg=\c@page
\@g@tnextcol{\@nxtcol}%
\if@ff@nwpg % next flow frame starts on new page
  \global\@firstcolumntrue
  \@setcolbox\c@thisframe
  \if@specialpage
    \global\@specialpagefalse
    \@nameuse{ps@\@specialstyle}\relax
  \fi
  \if@twoside
    \ifodd\count\z@
      \let\@thehead\@oddhead
      \let\@thefoot\@oddfoot
    \else
      \let\@thehead\@evenhead
      \let\@thefoot\@evenfoot
    \fi
  \else
    \let\@thehead\@oddhead
    \let\@thefoot\@oddfoot
  \fi
  \@begindvi
  \@dodynamicthehead\@dodynamicthefoot
  \vbadness=\@M
  \setbox\@outputbox\vbox{\hbox to \textwidth{\@ff@do@allframes}}%
  \@combinedblfloats
  \@outputpage
%shipout pages without flow frames
\advance\c@curpg by -\c@page\relax
  \whiledo{\c@curpg>0}{\advance\c@curpg by -1\relax
  \setbox\@outputbox\vbox{\hbox to \textwidth{\@ff@do@allframes}}%
\@outputpage} 
  \begingroup
    \@dblfloatplacement
    \@startdblcolumn
    \@whilesw \if@fcolmade \fi
       {\@outputpage \@startdblcolumn }\endgroup
  \@resetst@tics
  \@resetdyn@mics
\else % still on same page, save contents of box255
  \global\@firstcolumnfalse
  \@setcolbox\c@thisframe
\fi
\global\c@thisframe=\@nxtcol
\@setcol{\c@thisframe}\relax
\global\@colht\vsize
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dblfloatplacement}
% Modify "\@dblfloatplacement" replacing "\textheight"
% with "\vsize".
%    \begin{macrocode}
\def\@dblfloatplacement{%
  \global\@dbltopnum\c@dbltopnumber
  \global\@dbltoproom\dbltopfraction\@colht\@textmin
  \@colht\advance\@textmin -\@dbltoproom
  \@fpmin\dblfloatpagefraction\vsize
  \@fptop \@dblfptop \@fpsep \@dblfpsep \@fpbot \@dblfpbot}
%    \end{macrocode}
%\end{macro}
%
%\subsection{Static versions of floats}
% Floats can not go in saveboxes or minipages, so define
% static versions to go in static and \glspl{dynamic}.
% These just set "\@captype" so that the "\caption"
% command may be used.
%\begin{environment}{statictable}
%    \begin{macrocode}
\newenvironment{statictable}{\def\@captype{table}}{}
%    \end{macrocode}
%\end{environment}
%\begin{environment}{staticfigure}
%    \begin{macrocode}
\newenvironment{staticfigure}{\def\@captype{figure}}{}
%    \end{macrocode}
%\end{environment}
%
%\subsection{Standard Layouts}
%\subsubsection{Column Styles}
% Redefine "\twocolumn" and "\onecolumn" to set up \glspl{flow} from
% the dimensions of the \gls{typeblock}. Ignore the optional argument.
% The \gls{flow} height will be adjusted to make sure that it
% is an integer multiple of "\baselineskip", unless
% "\ffvajdustfalse" is used. 
%    \begin{macrocode}
\newif\ifffvadjust
\ffvadjusttrue
%    \end{macrocode}
%\begin{macro}{\onecolumn}
% "\onecolumn" will make a single \gls{flow} that takes
% up the entire area of the \gls{typeblock} (adjusted according
% to "\ifffvadjust".) Frames should only be created in 
% the preamble, otherwise the next \gls{flow} may not
% be detected by the output routine. The exception to this
% is when the output routine can't find any more \glspl{flow}
% to use, in which case it creates a single \gls{flow} using
% "\@onecolumn". Therefore, make "\onecolumn" use "\@onecolumn",
% and then set "\onecolumn" as a preamble command, so it
% can't be used in the document, but the output routine can
% use "\@onecolumn". Syntax: \cs{onecolumn}\oarg{pages}, 
% where \meta{pages} is the \gls{pglist} for which the new
% \gls{flow} is defined.
%    \begin{macrocode}
\renewcommand*{\onecolumn}{\@onecolumn}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@onecolumn}
%    \begin{macrocode}
\newcommand*{\@onecolumn}[1][all]{%
\@onecolumninarea[#1]{\textwidth}{\textheight}{0pt}{0pt}}
%    \end{macrocode}
%\end{macro}
% Need a length to store the height of
% the \gls{flow} so that it can be adjusted.
%    \begin{macrocode}
\newlength\columnheight
%    \end{macrocode}
%\begin{macro}{\onecolumninarea}
% "\onecolumn" is in fact a special case of "\onecolumninarea"
% which sets up one \gls{flow} in the specified area, given
% by bottom left corner (\meta{x}, \meta{y}),
% relative to the \gls{typeblock}, with width \meta{w} 
% and height \meta{h}.
% The only difference between "\onecolumninarea" and
% explicitly creating the \gls{flow} using "\newflowframe"
% is the "\onecolumninarea" will adjust the vertical height
% the ensure it is a multiple of "\baselineskip". There
% is also no starred version, so if you want a border, you
% will need to set it explicitly using "\setflowframe". 
% Syntax:\newline
% \cs{onecolumninarea}\oarg{pages}\marg{w}\marg{h}\marg{x}\marg{y}.
%    \begin{macrocode}
\newcommand*{\onecolumninarea}{\@onecolumninarea}
\@onlypreamble{\onecolumninarea}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@onecolumninarea}
%    \begin{macrocode}
\newcommand*{\@onecolumninarea}[5][all]{%
\setlength{\columnheight}{#3}%
\ifffvadjust\adjustheight{\columnheight}\fi%
\@n@wflowframe[#1]{#2}{\columnheight}{#4}{#5}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumn}
% Set up two \glspl{flow} parallel to each other
% with a distance of "\columnsep" between them, to
% fill the entire \gls{typeblock} (although the frames may
% end up marginally shorter than "\textheight" after
% they have been adjusted.) Again, these commands may only
% be used in the preamble. Note that unlike the standard
% "\twocolumn" command, this one has an optional argument
% that indicates which pages the two \glspl{flow} should
% appear on. Syntax: \cs{twocolumn}\oarg{pages}.
%    \begin{macrocode}
\renewcommand*{\twocolumn}{\@twocolumn}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@twocolumn}
%    \begin{macrocode}
\newcommand*{\@twocolumn}[1][all]{%
\@twocolumninarea[#1]{\textwidth}{\textheight}{0pt}{0pt}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumninarea}
% Again, "\twocolumn" is actually a special case of
% "\twocolumninarea".
% Syntax:\newline
% \cs{twocolumninarea}\oarg{pages}\marg{w}\marg{h}\marg{x}\marg{y}.
%    \begin{macrocode}
\newcommand*{\twocolumninarea}{\@twocolumninarea}
\@onlypreamble{\twocolumninarea}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@twocolumninarea}
%    \begin{macrocode}
\newcommand*{\@twocolumninarea}[5][all]{%
\setlength{\columnheight}{#3}%
\ifffvadjust\adjustheight{\columnheight}\fi%
\setlength{\columnwidth}{#2}%
\addtolength{\columnwidth}{-\columnsep}%
\divide\columnwidth by 2\relax
\setlength{\@ff@tmp@x}{#4}%
\addtolength{\@ff@tmp@x}{\columnwidth}%
\addtolength{\@ff@tmp@x}{\columnsep}%
\@n@wflowframe[#1]{\columnwidth}{\columnheight}{#4}{#5}%
\setflowframe{\c@maxflow}{margin=left}%
\@n@wflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{#5}%
\setflowframe{\c@maxflow}{margin=right}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\Ncolumn}
% Again for an aribtrary number of columns (\meta{n}). Syntax:
% \cs{Ncolumn}\oarg{pages}\marg{n}.
%    \begin{macrocode}
\newcommand*{\Ncolumn}[2][all]{%
\Ncolumninarea[#1]{#2}{\textwidth}{\textheight}{0pt}{0pt}}
\@onlypreamble{\Ncolumn}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\Ncolumninarea}
% Check the number of \glspl{flow} requested, and do one
% of the special cases if available.
% Syntax:\newline
% \cs{Ncolumninarea}\oarg{pages}\marg{n}\marg{w}\marg{h}\marg{x}\marg{y}.
%    \begin{macrocode}
\newcommand*{\Ncolumninarea}[6][all]{%
\ifnum#2>2\relax
  \@Ncolumninarea[#1]{#2}{#3}{#4}{#5}{#6}%
\else
  \ifcase#2\relax
    \PackageError{flowfram}{% 
    You have requested 0 flowframes!}{%
    It does not make much sense to ask to create 0 flow frames}%
  \or
    \onecolumninarea[#1]{#3}{#4}{#5}{#6}%
  \or
    \twocolumninarea[#1]{#3}{#4}{#5}{#6}%
  \else
    \PackageError{flowfram}{%
    Can't create a negative number of flow frames!}{%
    You have asked for \number#2 \space flow frames
    which really doesn't make sense}%
  \fi
\fi
}

\@onlypreamble{\Ncolumninarea}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@Ncolumninarea}
% Set up \meta{n} columns in the area specified.
% There is a horizontal distance of "\columnsep"
% between them all.
%    \begin{macrocode}
\newcommand*{\@Ncolumninarea}[6][all]{%
\@colN=#2\relax
\advance\@colN by -1\relax
\setlength{\columnwidth}{#3}%
\addtolength{\columnwidth}{-\@colN\columnsep}%
\divide\columnwidth by #2\relax
\setlength{\@ff@tmp@x}{#5}%
\setlength{\columnheight}{#4}%
\ifffvadjust\adjustheight{\columnheight}\fi%
\@colN=0\relax
\loop
\advance\@colN by 1\relax
\newflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{#6}%
\addtolength{\@ff@tmp@x}{\columnwidth}%
\addtolength{\@ff@tmp@x}{\columnsep}%
\ifnum\@colN<#2
\repeat
}
%    \end{macrocode}
%\end{macro}
%
% Set up something similar but have another frame (of type
% \meta{type}) at the top of  the other frames.
%\begin{macro}{\vcolumnsep}
% The vertical distance between the top frames and column flow
% frames when created using "\Ncolumnhead" etc is given by:
%    \begin{macrocode}
\newlength{\vcolumnsep}
\setlength{\vcolumnsep}{\columnsep}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\onecolumntop}
% "\onecolumntop" makes one \gls{flow}, and one \meta{type} 
% frame in the area specified, where the \meta{type} frame is 
% \meta{H} high.
% The distance between the top frame and the column \gls{flow}
% will be approximately "\vcolumnsep". (The height of \gls{flow}
% may be adjusted to make it an integer multiple of 
% "\baselineskip".) 
%
% First the special case where the area is the \gls{typeblock}.
% Syntax:\newline
% \cs{onecolumntop}\oarg{pages}\marg{type}\marg{H}
%    \begin{macrocode}
\newcommand*{\onecolumntop}[3][all]{%
\onecolumntopinarea[#1]{#2}{#3}{\textwidth}{\textheight}{0pt}{0pt}}
\@onlypreamble{\onecolumntop}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\onecolumnStop}
% Special case for \gls{static}.
% Syntax: \cs{onecolumnStop}\oarg{pages}\marg{H}
%    \begin{macrocode}
\newcommand*{\onecolumnStop}[2][all]{%
\onecolumntopinarea[#1]{static}{#2}{\textwidth}{\textheight}{0pt}{0pt}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\onecolumnDtop}
% Special case for \gls{dynamic}.
% Syntax: \cs{onecolumnDtop}\oarg{pages}\marg{H}
%    \begin{macrocode}
\newcommand*{\onecolumnDtop}[2][all]{%
\onecolumntopinarea[#1]{dynamic}{#2}{\textwidth}{\textheight}{0pt}{0pt}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\newframe}
% Create a frame of given type.
% Syntax:\newline
% \cs{newframe}\oarg{pages}\marg{type}\marg{w}\marg{h}\marg{x}\marg{y}.
%    \begin{macrocode}
\newcommand*{\newframe}[6][all]{%
\ifthenelse{\equal{#2}{flow}}{%
\@n@wflowframe[#1]{#3}{#4}{#5}{#6}%
}{%
\ifthenelse{\equal{#2}{dynamic}}{%
\@n@wdynamicframe[#1]{#3}{#4}{#5}{#6}}{%
\ifthenelse{\equal{#2}{static}}{%
\@n@wstaticframe[#1]{#3}{#4}{#5}{#6}}{%
\PackageError{flowfram}{Unknown frame type '#2'}{%
Available frame types are: 'flow', 'static' and 'dynamic'}}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\onecolumntopinarea}
% Now for a specified area.
% Syntax:\newline
% \cs{onecolumntopinarea}\oarg{pages}\marg{type}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}.
%    \begin{macrocode}
\newlength\@ff@staticH

\newcommand*{\onecolumntopinarea}[7][all]{%
\setlength{\@ff@staticH}{#3}%
\setlength{\@ff@tmp@y}{#5}%
\addtolength{\@ff@tmp@y}{-\@ff@staticH}%
\setlength{\columnheight}{\@ff@tmp@y}%
\addtolength{\columnheight}{-\vcolumnsep}%
\ifffvadjust\adjustheight{\columnheight}\fi%
\addtolength{\@ff@tmp@y}{#7}%
\newframe[#1]{#2}{#4}{\@ff@staticH}{#6}{\@ff@tmp@y}%
\@n@wflowframe[#1]{#4}{\columnheight}{#6}{#7}%
}

\@onlypreamble{\onecolumntopinarea}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\onecolumnStopinarea}
% Special case for \gls{static}.
% Syntax:\newline
% \cs{onecolumnStopinarea}\oarg{pages}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}.
%    \begin{macrocode}
\newcommand*{\onecolumnStopinarea}[6][all]{%
\onecolumntopinarea[#1]{static}{#2}{#3}{#4}{#5}{#6}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\onecolumnDtopinarea}
% Special case for \gls{dynamic}.
% Syntax:\newline
% \cs{onecolumnDtopinarea}\oarg{pages}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}.
%    \begin{macrocode}
\newcommand*{\onecolumnDtopinarea}[6][all]{%
\onecolumntopinarea[#1]{dynamic}{#2}{#3}{#4}{#5}{#6}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumntop}
% Now for two \glspl{flow}, with a single \meta{type} frame
% above both of them.
% Syntax:\newline
% \cs{twocolumntop}\oarg{pages}\marg{type}\marg{H}
%
% First the special case where the area is the entire
% \gls{typeblock}:
%    \begin{macrocode}
\newcommand*{\twocolumntop}[3][all]{%
\twocolumntopinarea[#1]{#2}{#3}{\textwidth}{\textheight}{0pt}{0pt}}
\@onlypreamble{\twocolumntop}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumnStop}
% Special case for \gls{static}.
%    \begin{macrocode}
\newcommand*{\twocolumnStop}[2][all]{%
\@twocolumntopinarea[#1]{static}{#2}{\textwidth}{\textheight}{0pt}{0pt}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumnDtop}
% Special case for \gls{dynamic}.
%    \begin{macrocode}
\newcommand*{\twocolumnDtop}[2][all]{%
\twocolumntop[#1]{dynamic}{#2}}
%    \end{macrocode}
%\end{macro}
%
% Now for a general area.
%\begin{macro}{\twocolumntopinarea}
% Syntax:\newline
% \cs{twocolumntopinarea}\oarg{pages}\marg{type}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}.
%    \begin{macrocode}
\newcommand*{\twocolumntopinarea}{\@twocolumntopinarea}
\newcommand*{\@twocolumntopinarea}[7][all]{%
\setlength{\@ff@staticH}{#3}%
% work out where to put the static frame
\setlength{\@ff@tmp@y}{#5}%
\addtolength{\@ff@tmp@y}{-\@ff@staticH}%
\setlength{\columnheight}{\@ff@tmp@y}%
\addtolength{\@ff@tmp@y}{#7}%
\newframe[#1]{#2}{#4}{\@ff@staticH}{#6}{\@ff@tmp@y}%
% work out height of the flow frames
\addtolength{\columnheight}{-\vcolumnsep}%
\ifffvadjust\adjustheight{\columnheight}\fi%
% work out the widths of the flow frames
\setlength{\columnwidth}{#4}%
\addtolength{\columnwidth}{-\columnsep}%
\divide\columnwidth by 2\relax
% work out the offset of the second column
\setlength{\@ff@tmp@x}{\columnwidth}%
\addtolength{\@ff@tmp@x}{\columnsep}%
\addtolength{\@ff@tmp@x}{#6}%
\@n@wflowframe[#1]{\columnwidth}{\columnheight}{#6}{#7}%
\setflowframe{\c@maxflow}{margin=left}%
\@n@wflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{#7}%
\setflowframe{\c@maxflow}{margin=right}%
}
\@onlypreamble{\twocolumntopinarea}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumnStopinarea}
% Special case for \gls{static}.
%    \begin{macrocode}
\newcommand*{\twocolumnStopinarea}[6][all]{%
\twocolumntopinarea[#1]{static}{#2}{#3}{#4}{#5}{#6}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumnDtopinarea}
% Special case for \gls{dynamic}.
%    \begin{macrocode}
\newcommand*{\twocolumnDtopinarea}[6][all]{%
\twocolumntopinarea[#1]{dynamic}{#2}{#3}{#4}{#5}{#6}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\Ncolumntop}
% Similarly for an arbitrary number of \glspl{flow}.
% Special case where the area is the \gls{typeblock}.
%
% Syntax:\newline
% \cs{Ncolumntop}\oarg{pages}\marg{type}\marg{n}\marg{H}
%    \begin{macrocode}
\newcommand*{\Ncolumntop}[4][all]{%
\Ncolumntopinarea[#1]{#2}{#3}{#4}{\textwidth}{\textheight}{0pt}{0pt}}
\@onlypreamble{\Ncolumntop}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\NcolumnStop}
% Special case for \gls{static}.
%    \begin{macrocode}
\newcommand*{\NcolumnStop}[3][all]{%
\Ncolumntop[#1]{static}{#2}{#3}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\NcolumnDtop}
% Special case for \gls{dynamic}.
%    \begin{macrocode}
\newcommand*{\NcolumnDtop}[3][all]{%
\Ncolumntop[#1]{dynamic}{#2}{#3}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\Ncolumntopinarea}
% Again test to make sure the user requested a sensible
% number.
%    \begin{macrocode}
\newcommand*{\Ncolumntopinarea}[8][all]{%
\ifnum#3>2\relax
  \@Ncolumntopinarea[#1]{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
\else
  \ifcase#3\relax
    \PackageError{flowfram}{% 
    You have requested 0 flowframes!}{%
    It does not make much sense to ask to create 0 flow frames}
  \or
    \onecolumntopinarea[#1]{#2}{#4}{#5}{#6}{#7}{#8}%
  \or
    \twocolumntopinarea[#1]{#2}{#4}{#5}{#6}{#7}{#8}%
  \else
    \PackageError{flowfram}{%
    Can't create a negative number of flow frames!}{%
    You have asked for \number#3 \space flow frames
    which really doesn't make sense}%
  \fi
\fi
}
\@onlypreamble{\Ncolumntopinarea}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@Ncolumntopinarea}
% Fit the frames into specified area.
% Syntax:\newline
% \cs{Ncolumntopinarea}\oarg{pages}\marg{type}\marg{n}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}.
%    \begin{macrocode}
\newcommand*{\@Ncolumntopinarea}[8][all]{%
\setlength{\@ff@staticH}{#4}%
%    \end{macrocode}
% work out where to put the static frame
%    \begin{macrocode}
\setlength{\@ff@tmp@y}{#6}%
\addtolength{\@ff@tmp@y}{-\@ff@staticH}%
\setlength{\columnheight}{\@ff@tmp@y}%
\addtolength{\@ff@tmp@y}{#8}%
\newframe[#1]{#2}{#5}{\@ff@staticH}{#7}{\@ff@tmp@y}%
%    \end{macrocode}
% work out height of the flow frames
%    \begin{macrocode}
\addtolength{\columnheight}{-\vcolumnsep}%
%    \end{macrocode}
% adjust the flow frame height so that it is a multiple of 
% \cs{baselineskip}
%    \begin{macrocode}
\ifffvadjust\adjustheight{\columnheight}\fi%
%    \end{macrocode}
% work out the widths of the flow frames
%    \begin{macrocode}
\@colN=#3\relax
\advance\@colN by -1\relax
\setlength{\columnwidth}{#5}%
\addtolength{\columnwidth}{-\@colN\columnsep}%
\divide\columnwidth by #3\relax
\setlength{\@ff@tmp@x}{#7}%
\@colN=0\relax
\loop
\advance\@colN by 1\relax
\newflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{#8}%
% work out the offset for the next column
\addtolength{\@ff@tmp@x}{\columnwidth}%
\addtolength{\@ff@tmp@x}{\columnsep}%
\ifnum\@colN<#3
\repeat
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\NcolumnStopinarea}
% Specific case for \gls{static}.
%    \begin{macrocode}
\newcommand*{\NcolumnStopinarea}[7][all]{%
\Ncolumntopinarea[#1]{static}{#2}{#3}{#4}{#5}{#6}{#7}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\NcolumnDtopinarea}
% Specific case for \gls{dynamic}.
%    \begin{macrocode}
\newcommand*{\NcolumnDtopinarea}[7][all]{%
\Ncolumntopinarea[#1]{dynamic}{#2}{#3}{#4}{#5}{#6}{#7}}
%    \end{macrocode}
%\end{macro}
% Now the same kind of thing but with the \meta{type} frame at the
% bottom. Firstly, a single \gls{flow} with a \meta{type}
% frame below it. 
%
%\begin{macro}{\onecolumnbottom}
% Syntax:\newline
% \cs{onecolumnbottom}\oarg{pages}\marg{type}\marg{H}
%    \begin{macrocode}
\newcommand*{\onecolumnbottom}[3][all]{%
\onecolumnSbottominarea[#1]{#2}{#3}{\textwidth}{\textheight}{0pt}{0pt}}
%    \end{macrocode}
%\end{macro}
% This command may only be used in the preamble.
%    \begin{macrocode}
\@onlypreamble{\onecolumnbottom}
%    \end{macrocode}
%\begin{macro}{\onecolumnSbottom}
% Special case for \gls{static}.
%    \begin{macrocode}
\newcommand*{\onecolumnSbottom}[2][all]{%
\onecolumnbottom[#1]{static}{#2}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\onecolumnDbottom}
% Special case for \gls{dynamic}.
%    \begin{macrocode}
\newcommand*{\onecolumnDbottom}[2][all]{%
\onecolumnbottom[#1]{dynamic}{#2}}
%    \end{macrocode}
%\end{macro}
%
% General case of the above, but fit in specified area.
%\begin{macro}{\onecolumnbottominarea}
% Syntax:\newline
% \cs{onecolumnbottominarea}\oarg{pages}\marg{type}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y},\newline
% where \meta{H} is the \meta{type} frame's height.
% The area is defined by bottom
% left co-ordinates (\meta{x}, \meta{y}) width \meta{w}, and 
% height \meta{h}.
%    \begin{macrocode}
\newcommand*{\onecolumnbottominarea}[7][all]{%
\setlength{\@ff@staticH}{#3}%
\setlength{\columnheight}{#5}%
\addtolength{\columnheight}{-\@ff@staticH}%
\addtolength{\columnheight}{-\vcolumnsep}%
\ifffvadjust\adjustheight{\columnheight}\fi%
\setlength{\@ff@tmp@y}{#5}%
\addtolength{\@ff@tmp@y}{-\columnheight}%
\addtolength{\@ff@tmp@y}{#7}%
\newframe[#1]{#2}{#4}{\@ff@staticH}{#6}{#7}%
\newflowframe[#1]{#4}{\columnheight}{#6}{\@ff@tmp@y}%
}
%    \end{macrocode}
%\end{macro}
% Again, this command may only be used in the preamble.
%    \begin{macrocode}
\@onlypreamble{\onecolumnbottominarea}
%    \end{macrocode}
%\begin{macro}{\onecolumnSbottominarea}
% Special case for \gls{static}.
%    \begin{macrocode}
\newcommand*{\onecolumnSbottominarea}[6][all]{%
\onecolumnbottominarea[#1]{static}{#2}{#3}{#4}{#5}{#6}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\onecolumnDbottominarea}
% Special case for \gls{dynamic}.
%    \begin{macrocode}
\newcommand*{\onecolumnDbottominarea}[6][all]{%
\onecolumnbottominarea[#1]{dynamic}{#2}{#3}{#4}{#5}{#6}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumnbottom}
% Now for two \glspl{flow} side by side with a static
% frame underneath both of them. Firstly, the specific
% case where the area is the entire \gls{typeblock}.
% Syntax:\newline
% \cs{twocolumnbottom}\oarg{pages}\marg{type}\marg{H}.
%    \begin{macrocode}
\newcommand*{\twocolumnbottom}[3][all]{%
\twocolumnSbottominarea[#1]{#2}{#3}{\textwidth}{\textheight}{0pt}{0pt}}
\@onlypreamble{\twocolumnbottom}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumnSbottom}
% Special case for \gls{static}.
%    \begin{macrocode}
\newcommand*{\twocolumnSbottom}[2][all]{%
\twocolumnbottom[#1]{static}{#2}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumnDbottom}
% Special case for \gls{dynamic}.
%    \begin{macrocode}
\newcommand*{\twocolumnDbottom}[2][all]{%
\twocolumnbottom[#1]{dynamic}{#2}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumnbottominarea}
% Now for a general area.
% Syntax:\newline
% \cs{twocolumnbottominarea}\oarg{pages}\marg{type}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}.
%    \begin{macrocode}
\newcommand*{\twocolumnbottominarea}[7][all]{%
\setlength{\@ff@staticW}{#4}%
\setlength{\@ff@staticH}{#3}%
%    \end{macrocode}
% work out height of the flow frames
%    \begin{macrocode}
\setlength{\columnheight}{#5}%
\addtolength{\columnheight}{-\@ff@staticH}%
\addtolength{\columnheight}{-\vcolumnsep}%
\ifffvadjust\adjustheight{\columnheight}\fi%
\newframe[#1]{#2}{\@ff@staticW}{\@ff@staticH}{#6}{#7}%
%    \end{macrocode}
% work out the $y$ position of the flow frames
%    \begin{macrocode}
\setlength{\@ff@tmp@y}{#5}%
\addtolength{\@ff@tmp@y}{-\columnheight}%
\addtolength{\@ff@tmp@y}{#7}%
%    \end{macrocode}
% work out the widths of the flow frames
%    \begin{macrocode}
\setlength{\columnwidth}{\@ff@staticW}%
\addtolength{\columnwidth}{-\columnsep}%
\divide\columnwidth by 2\relax
%    \end{macrocode}
% work out the $x$ offset of the second column
%    \begin{macrocode}
\setlength{\@ff@tmp@x}{\columnwidth}%
\addtolength{\@ff@tmp@x}{\columnsep}%
\addtolength{\@ff@tmp@x}{#6}%
\newflowframe[#1]{\columnwidth}{\columnheight}{#6}{\@ff@tmp@y}%
\setflowframe{\c@maxflow}{margin=left}%
\newflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{\@ff@tmp@y}%
\setflowframe{\c@maxflow}{margin=right}%
}
\@onlypreamble{\twocolumnbottominarea}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumnSbottominarea}
% Special case for \gls{static}.
%    \begin{macrocode}
\newcommand*{\twocolumnSbottominarea}[6][all]{%
\twocolumnbottominarea[#1]{static}{#2}{#3}{#4}{#5}{#6}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\twocolumnDbottominarea}
% Special case for \gls{dynamic}.
%    \begin{macrocode}
\newcommand*{\twocolumnDbottominarea}[6][all]{%
\twocolumnbottominarea[#1]{dynamic}{#2}{#3}{#4}{#5}{#6}}
%    \end{macrocode}
%\end{macro}
% Now for an arbitrary number of parallel \glspl{flow}
% with a \gls{static} beneath all of them.
%
%\begin{macro}{\Ncolumnbottom}
% First make them fill the entire \gls{typeblock}.
% Syntax:\newline
% \cs{Ncolumnbottom}\oarg{pages}\marg{type}\marg{H}.
%    \begin{macrocode}
\newcommand*{\Ncolumnbottom}[4][all]{%
\Ncolumnbottominarea[#1]{#2}{#3}{#4}{\textwidth}{\textheight}{0pt}{0pt}}
\@onlypreamble{\Ncolumnbottom}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\NcolumnSbottom}
% Special case for \gls{static}.
%    \begin{macrocode}
\newcommand*{\NcolumnSbottom}[3][all]{%
\Ncolumnbottom[#1]{static}{#2}{#3}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\NcolumnDbottom}
% Special case for \gls{dynamic}.
%    \begin{macrocode}
\newcommand*{\NcolumnDbottom}[3][all]{%
\Ncolumnbottom[#1]{dynamic}{#2}{#3}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\Ncolumnbottominarea}
% Again check the user has requested a sensible number.
%    \begin{macrocode}
\newcommand*{\Ncolumnbottominarea}[8][all]{%
\ifnum#3>2\relax
  \@Ncolumnbottominarea[#1]{#2}{#3}{#4}{#5}{#6}{#7}{#8}%
\else
  \ifcase#3\relax
    \PackageError{flowfram}{% 
    You have requested 0 flowframes!}{%
    It does not make much sense to ask to create 0 flow frames}
  \or
    \onecolumnbottominarea[#1]{#2}{#4}{#5}{#6}{#7}{#8}%
  \or
    \twocolumnbottominarea[#1]{#2}{#4}{#5}{#6}{#7}{#8}%
  \else
    \PackageError{flowfram}{%
    Can't create a negative number of flow frames!}{%
    You have asked for \number#3 \space flow frames
    which really doesn't make sense}%
  \fi
\fi
}
\@onlypreamble{\Ncolumnbottominarea}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@NcolumnSbottominarea}
% An arbitrary number of columns with a \gls{static}
% underneath them all, filling the specified area.
%    \begin{macrocode}
\newcommand*{\@NcolumnSbottominarea}[8][all]{%
\setlength{\@ff@staticH}{#4}%
%    \end{macrocode}
% work out height of the flow frames
%    \begin{macrocode}
\setlength{\columnheight}{#6}%
\addtolength{\columnheight}{-\@ff@staticH}%
\addtolength{\columnheight}{-\vcolumnsep}%
%    \end{macrocode}
% adjust the flow frame height so that it is a multiple of 
% \cs{baselineskip}
%    \begin{macrocode}
\ifffvadjust\adjustheight{\columnheight}\fi
\newframe[#1]{#2}{#5}{\@ff@staticH}{#7}{#8}%
%    \end{macrocode}
% work out the $y$ offset of the flow frames
%    \begin{macrocode}
\setlength{\@ff@tmp@y}{#6}%
\addtolength{\@ff@tmp@y}{-\columnheight}%
\addtolength{\@ff@tmp@y}{#8}%
%    \end{macrocode}
% work out the widths of the flow frames
%    \begin{macrocode}
\@colN=#3\relax
\advance\@colN by -1\relax
\setlength{\columnwidth}{#5}%
\addtolength{\columnwidth}{-\@colN\columnsep}%
\divide\columnwidth by #3\relax
\setlength{\@ff@tmp@x}{#7}%
\@colN=0\relax
\loop
\advance\@colN by 1\relax
\newflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{\@ff@tmp@y}%
%    \end{macrocode}
% work out the offset for the next column
%    \begin{macrocode}
\addtolength{\@ff@tmp@x}{\columnwidth}%
\addtolength{\@ff@tmp@x}{\columnsep}%
\ifnum\@colN<#3
\repeat
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\NcolumnSbottominarea}
% Specific case for \gls{static}.
%    \begin{macrocode}
\newcommand*{\NcolumnSbottominarea}[1][all]{%
\Ncolumnbottominarea[#1]{static}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\NcolumnDbottominarea}
% Specific case for \gls{dynamic}.
%    \begin{macrocode}
\newcommand*{\NcolumnDbottominarea}[1][all]{%
\Ncolumnbottominarea[#1]{dynamic}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\adjustheight}
% Given a height "#1" (a length), adjust it so that it is a multiple of "\baselineskip".
%    \begin{macrocode}
\newcount\@ff@adjh
\newcommand*{\adjustheight}[1]{%
%    \end{macrocode}
% convert to an integer
%    \begin{macrocode}
\@ff@adjh=#1\relax
\divide\@ff@adjh by \baselineskip\relax
#1=\baselineskip\relax
\multiply#1 by \@ff@adjh\relax
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\adjustcolsep}
% Adjust the value of "\columnsep" so that the margins will fit between columns.
%    \begin{macrocode}
\newcommand*{\adjustcolsep}{%
\multiply\columnsep by 2\relax
\addtolength{\columnsep}{\marginparwidth}}
%    \end{macrocode}
%\end{macro}
%
%\subsubsection{Backdrop Effects}
% Set up some commands to make \glspl{static} for different styles 
% of backdrop.
%\begin{macro}{\vtwotone}
% Syntax:\newline
% \cs{vtwotone}\oarg{pages}\oarg{xoffset}\marg{W1}\marg{C1}\marg{L1}\marg{W2}\marg{C2}\marg{L2}
%\newline where the first frame
% has width \meta{W1} with background colour \meta{C1} and label \meta{L1}. 
% The second frame has width \meta{W2} with background colour \meta{C2}
% and label \meta{L2}. Unlike earlier commands, the $x$-offset is 
% relative to the left page edge \emph{not} the \gls{typeblock}. 
% This is because they are designed for backdrops, which
% tend to span the entire page.
% Note that the colour specs must be
% completely enclosed in braces. e.g.\ "{[gray]{0.5}}" \emph{not} "[gray]{0.5}".
%
% Need a length to store the width of the \gls{static}.
%    \begin{macrocode}
\newlength\@ff@staticW
%    \end{macrocode}
% Vertical two tone effect where the height of the static
% frames is equal to the paper height.
%    \begin{macrocode}
\newcommand*{\vtwotone}[1][all]{%
\def\ff@pages{#1}\@vtwotone}

\newcommand*{\@vtwotone}[1][0pt]{\@@vtwotonebottom{#1}{\paperheight}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\vtwotonebottom}
% Vertical two tone effect along the bottom of the page, of
% height \meta{H}.
% Syntax:\newline
% \cs{vtwotonebottom}\oarg{pages}\oarg{xoffset}\marg{H}\marg{W1}\marg{C1}\marg{L1}\marg{W2}\marg{C2}\marg{L2}
% where the first frame starts at \meta{xoffset}.
%    \begin{macrocode}
\newcommand*{\@@vtwotonebottom}[8]{%
\computeleftedgeodd{\@ff@tmp@x}%
\if@twoside
  \computeleftedgeeven{\@ff@tmp@x@even}%
\else
  \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}%
\fi
\computebottomedge{\@ff@tmp@y}%
\addtolength{\@ff@tmp@x}{#1}%
\addtolength{\@ff@tmp@x@even}{#1}%
\@nextvband{\ff@pages}{#2}{#3}{#4}{#5}%
\@nextvband{\ff@pages}{#2}{#6}{#7}{#8}%
}

\@onlypreamble{\vtwotone}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\vtwotonebottom}
% Border strip along the bottom of the page
%    \begin{macrocode}
\newcommand*{\vtwotonebottom}[1][all]{%
\def\ff@pages{#1}\@vtwotonebottom}

\@onlypreamble{\vtwotonebottom}

\newcommand*{\@vtwotonebottom}[2][0pt]{\@@vtwotonebottom{#1}{#2}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\vtwotonetop}
% Border strip along the top of the page
%    \begin{macrocode}
\newcommand*{\vtwotonetop}[1][all]{%
\def\ff@pages{#1}\@vtwotonetop}

\newcommand*{\@vtwotonetop}[2][0pt]{\@@vtwotonetop{#1}{#2}}

\newcommand*{\@@vtwotonetop}[8]{%
\computeleftedgeodd{\@ff@tmp@x}%
\if@twoside
  \computeleftedgeeven{\@ff@tmp@x@even}%
\else
  \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}%
\fi
\computetopedge{\@ff@tmp@y}%
\addtolength{\@ff@tmp@y}{-#2}%
\addtolength{\@ff@tmp@x}{#1}%
\addtolength{\@ff@tmp@x@even}{#1}%
\@nextvband{\ff@pages}{#2}{#3}{#4}{#5}%
\@nextvband{\ff@pages}{#2}{#6}{#7}{#8}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@nextvband}
% Make next \gls{static}. Syntax:\newline
% \cs{@nextvband}\marg{pages}\marg{height}\marg{width}\marg{colour specs}\marg{label}\newline
% $x$ and $y$ offsets are given by "\@ff@tmp@x" and "\@ff@tmp@y". 
% On exit, "\@ff@tmp@x" is set to the right border.
%    \begin{macrocode}
\newcommand*{\@nextvband}[5]{%
\setlength{\@ff@staticW}{#3}%
\ifthenelse{\equal{#5}{}}{%
\newstaticframe[#1]{\@ff@staticW}{#2}{\@ff@tmp@x}{\@ff@tmp@y}}%
{\newstaticframe[#1]{\@ff@staticW}{#2}{\@ff@tmp@x}{\@ff@tmp@y}[#5]}%
\expandafter\global\expandafter\setlength
 \csname @sf@\romannumeral\c@maxstatic @evenx\endcsname{%
   \@ff@tmp@x@even}%
\@setframecol#4\end{\c@maxstatic}{backcol}{sf}%
\addtolength{\@ff@tmp@x}{\@ff@staticW}%
\addtolength{\@ff@tmp@x@even}{\@ff@staticW}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\vNtone}
% Similarly for N colours. Syntax:\newline
% \cs{vNtone}\oarg{pages}\oarg{xoffset}\marg{n}\marg{W1}\marg{C1}\marg{L1}\ldots\marg{Wn}\marg{Cn}\marg{Ln}\newline
% where the first frame has width \meta{W1} with background 
% colour \meta{C1} and label \meta{L1} all the way up to
% the \meta{n}th frame which has width \meta{Wn}, background
% colour \meta{Cn} and \gls{idl} \meta{Ln}.
%
% Keep track of which strip we are doing.
%    \begin{macrocode}
\newcount\@thisstrip
%    \end{macrocode}
% This command needs two optional arguments, so store
% first optional argument, and look for the next.
%    \begin{macrocode}
\newcommand*{\vNtone}[1][all]{%
\def\ff@pages{#1}\@vNtone}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@vNtone}
% Got the first argument, now get the next.
%    \begin{macrocode}
\newcommand*{\@vNtone}[2][0pt]{%
\@@vNtone{#1}{#2}{\paperheight}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@vNtone}
% Vertical \meta{n} tone aligned along the
% bottom of the page with height "#3".
%    \begin{macrocode}
\newcommand*{\@@vNtone}[3]{%
\computeleftedgeodd{\@ff@tmp@x}%
\if@twoside
  \computeleftedgeeven{\@ff@tmp@x@even}%
\else
  \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}%
\fi
\computebottomedge{\@ff@tmp@y}%
\addtolength{\@ff@tmp@x}{#1}%
\addtolength{\@ff@tmp@x@even}{#1}%
\@thisstrip=#2\relax
\setlength{\@ff@staticH}{#3}%
\@nextvNband%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@nextvNband}
% Recursively do the next strip.
%    \begin{macrocode}
\newcommand*{\@nextvNband}{%
\ifnum\@thisstrip>0\relax
 \let\flf@next\@@nextvNband
\else
 \let\flf@next\relax
\fi
\advance\@thisstrip by -1\relax
\flf@next}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@nextvNband}
% Do current strip, and go on to next one.
%    \begin{macrocode}
\newcommand*{\@@nextvNband}[3]{%
\@nextvband{\ff@pages}{\@ff@staticH}{#1}{#2}{#3}\@nextvNband}

\@onlypreamble{\vNtone}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\vNtonebottom}
% Border strip along the bottom of the page. Same as above
% but user specifies the height.
%    \begin{macrocode}
\newcommand*{\vNtonebottom}[1][all]{%
\def\ff@pages{#1}\@vNtonebottom}
\@onlypreamble{\vNtonebottom}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@vNtonebottom}
%    \begin{macrocode}
\newcommand*{\@vNtonebottom}[3][0pt]{%
\@@vNtone{#1}{#2}{#3}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\vNtonetop}
% Border strip along the top of the page. Again two
% optional arguments are required. Get first optional
% argument.
%    \begin{macrocode}
\newcommand*{\vNtonetop}[1][all]{%
\def\ff@pages{#1}\@vNtonetop}
\@onlypreamble{\vNtonetop}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@vNtonetop}
% Get next optional argument.
%    \begin{macrocode}
\newcommand*{\@vNtonetop}[3][0pt]{%
\@@vNtonetop{#1}{#2}{#3}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@vNtonetop}
% Now get on with it.  Again, it has to be done 
% recursively.
%    \begin{macrocode}
\newcommand*{\@@vNtonetop}[3]{%
\computeleftedgeodd{\@ff@tmp@x}%
\if@twoside
  \computeleftedgeeven{\@ff@tmp@x@even}%
\else
  \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}%
\fi
\computetopedge{\@ff@tmp@y}%
\addtolength{\@ff@tmp@y}{-#3}%
\addtolength{\@ff@tmp@x}{#1}%
\addtolength{\@ff@tmp@x@even}{#1}%
\@thisstrip=#2\relax
\setlength{\@ff@staticH}{#3}%
\@nextvNband%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\htwotone}
% Now do horizontal strips. Syntax:\newline
% \cs{htwotone}\oarg{pages}\oarg{y offset}\marg{H1}\marg{C1}\marg{L1}\marg{H2}\marg{C2}\marg{L2}
%    \begin{macrocode}
\newcommand*{\htwotone}[1][all]{%
\def\ff@pages{#1}\@htwotone}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@htwotone}
%    \begin{macrocode}
\newcommand*{\@htwotone}[1][0pt]{\@@htwotoneleft{#1}{\paperwidth}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@htwotoneleft}
% This is all done in much the same way as the vertical
% strips.
%    \begin{macrocode}
\newcommand*{\@@htwotoneleft}[8]{%
\computeleftedgeodd{\@ff@tmp@x}%
\if@twoside
  \computeleftedgeeven{\@ff@tmp@x@even}%
\else
  \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}%
\fi
\computebottomedge{\@ff@tmp@y}%
\addtolength{\@ff@tmp@y}{#1}%
\@nexthband{\ff@pages}{#2}{#3}{#4}{#5}%
\@nexthband{\ff@pages}{#2}{#6}{#7}{#8}%
}

\@onlypreamble{\htwotone}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\htwotoneleft}
% Two tone horizontal strips along left border
% Syntax: \cs{htwotoneleft}\oarg{pages}\oarg{y offset}\marg{width}\marg{H1}\marg{C1}\marg{L1}\marg{H2}\marg{C2}\marg{L2}
%    \begin{macrocode}
\newcommand*{\htwotoneleft}[1][all]{%
\def\ff@pages{#1}\@htwotoneleft}
\@onlypreamble{\htwotoneleft}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@htwotoneleft}
%    \begin{macrocode}
\newcommand*{\@htwotoneleft}[2][0pt]{\@@htwotoneleft{#1}{#2}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\htwotoneright}
% Two tone horizontal strips along right border
%    \begin{macrocode}
\newcommand*{\htwotoneright}[1][all]{%
\def\ff@pages{#1}\@htwotoneright}
\@onlypreamble{\htwotoneright}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@htwotoneright}
%    \begin{macrocode}
\newcommand*{\@htwotoneright}[2][0pt]{\@@htwotoneright{#1}{#2}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@htwotoneright}
%    \begin{macrocode}
\newcommand*{\@@htwotoneright}[8]{%
\computerightedgeodd{\@ff@tmp@x}%
\if@twoside
  \computerightedgeeven{\@ff@tmp@x@even}%
\else
  \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}%
\fi
\computebottomedge{\@ff@tmp@y}%
\addtolength{\@ff@tmp@y}{#1}%
\addtolength{\@ff@tmp@x}{-#2}%
\addtolength{\@ff@tmp@x@even}{-#2}%
\@nexthband{\ff@pages}{#2}{#3}{#4}{#5}%
\@nexthband{\ff@pages}{#2}{#6}{#7}{#8}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\hNtone}
% Now for \meta{N} coloured horizontal strips
%    \begin{macrocode}
\newcommand*{\hNtone}[1][all]{%
\def\ff@pages{#1}\@hNtone}
\@onlypreamble{\hNtone}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@hNtone}
%    \begin{macrocode}
\newcommand*{\@hNtone}[2][0pt]{%
\@@hNtone{#1}{#2}{\paperwidth}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@hNtone}
%    \begin{macrocode}
\newcommand*{\@@hNtone}[3]{%
\computeleftedgeodd{\@ff@tmp@x}%
\if@twoside
  \computeleftedgeeven{\@ff@tmp@x@even}%
\else
  \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}%
\fi
\computebottomedge{\@ff@tmp@y}%
\addtolength{\@ff@tmp@y}{#1}%
\@thisstrip=#2\relax
\setlength{\@ff@staticW}{#3}%
\@nexthNband%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\hNtoneleft}
% Now for the N tone strips along the left border
%    \begin{macrocode}
\newcommand*{\hNtoneleft}[1][all]{%
\def\ff@pages{#1}\@hNtoneleft}
\@onlypreamble{\hNtoneleft}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@hNtoneleft}
%    \begin{macrocode}
\newcommand*{\@hNtoneleft}[3][0pt]{%
\@@hNtone{#1}{#2}{#3}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\hNtoneright}
% Border strip along the right border
%    \begin{macrocode}
\newcommand*{\hNtoneright}[1][all]{%
\def\ff@pages{#1}\@hNtoneright}
\@onlypreamble{\hNtoneright}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@hNtoneright}
%    \begin{macrocode}
\newcommand*{\@hNtoneright}[3][0pt]{%
\@@hNtoneright{#1}{#2}{#3}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@hNtoneright}
%    \begin{macrocode}
\newcommand*{\@@hNtoneright}[3]{%
\computerightedgeodd{\@ff@tmp@x}%
\if@twoside
  \computerightedgeeven{\@ff@tmp@x@even}%
\else
  \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}%
\fi
\computebottomedge{\@ff@tmp@y}%
\addtolength{\@ff@tmp@y}{#1}%
\addtolength{\@ff@tmp@x}{-#3}%
\addtolength{\@ff@tmp@x@even}{-#3}%
\@thisstrip=#2\relax
\setlength{\@ff@staticW}{#3}%
\@nexthNband%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@nexthband}
% Make next \gls{static}. Syntax:\newline
% \cs{@nexthband}\marg{pages}\marg{width}\marg{height}\marg{colour specs}\marg{label}\newline
% $x$ and $y$ offsets are given by "\@ff@tmp@x" and "\@ff@tmp@y". 
% On exit, "\@ff@tmp@y" is set to the top border.
%    \begin{macrocode}
\newcommand*{\@nexthband}[5]{%
\setlength{\@ff@staticH}{#3}%
\ifthenelse{\equal{#5}{}}{%
\newstaticframe[#1]{#2}{\@ff@staticH}{\@ff@tmp@x}{\@ff@tmp@y}}%
{\newstaticframe[#1]{#2}{\@ff@staticH}{\@ff@tmp@x}{\@ff@tmp@y}[#5]}%
\expandafter\global\expandafter
\setlength\csname @sf@\romannumeral\c@maxstatic @evenx\endcsname{%
\@ff@tmp@x@even}%
\@setframecol#4\end{\c@maxstatic}{backcol}{sf}%
\addtolength{\@ff@tmp@y}{\@ff@staticH}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@nexthNband}
% Get next horizontal strip recursively.
%    \begin{macrocode}
\newcommand*{\@nexthNband}{%
\ifnum\@thisstrip>0\relax
 \let\flf@next\@@nexthNband%
\else
 \let\flf@next\relax%
\fi
\advance\@thisstrip by -1\relax
\flf@next}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@nexthNband}
%    \begin{macrocode}
\newcommand*{\@@nexthNband}[3]{%
\@nexthband{\ff@pages}{\@ff@staticW}{#1}{#2}{#3}\@nexthNband}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\makebackgroundframe}
% Make one big \gls{static} that covers the entire page.
% This command should come before all other commands that create 
% \glspl{static}, otherwise it will obscure all the ones defined
% before it. Syntax:\newline
% \cs{makebackgroundframe}\oarg{pages}\oarg{label}.
%    \begin{macrocode}
\newcommand*{\makebackgroundframe}[1][all]{%
\ifnum\c@maxstatic>0\relax
  \PackageWarning{flowfram}{Background frame is not
  first static frame to be defined. All previously defined
  static frames may be obscured.}%
\fi
\computeleftedgeodd{\@ff@tmp@x}%
\if@twoside
  \computeleftedgeeven{\@ff@tmp@x@even}%
\else
  \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}%
\fi
\computebottomedge{\@ff@tmp@y}%
\newstaticframe[#1]{\paperwidth}{\paperheight}{\@ff@tmp@x}%
{\@ff@tmp@y}%
\expandafter\global\expandafter
\setlength\csname @sf@\romannumeral\c@maxstatic @evenx\endcsname
{\@ff@tmp@x@even}}
%    \end{macrocode}
%\end{macro}
%
%\subsubsection{Lines Between Frames}
%\DescribeMacro{\insertvrule}
% Insert a \gls{static} between two frames with a vertical
% rule that goes from the maximum height of the highest
% to the minimum height of the lowest, equidistant from
% both frames. Syntax:\newline
% \cs{insertvrule}\oarg{y top}\oarg{y bottom}\marg{frame1 type}\marg{IDN2}\marg{frame2 type}\meta{IDN2}.
% The starred version uses \glspl{idl} instead of \glspl{idn}.
% The optional arguments indicate to continue above the highest
% point by \meta{y top} or continue below the lowest point
% by \meta{y bottom}.
%
%\begin{macro}{\ffcolumnseprule}
% This has changed in v1.09. Define "\ffcolumnseprule" and use
% instead of "\columnseprule"
%    \begin{macrocode}
\newlength\ffcolumnseprule
\setlength{\ffcolumnseprule}{2pt}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\insertvrule}
% Determine whether or not the starred version is being
% used.
%    \begin{macrocode}
\newcommand*{\insertvrule}{\@ifstar\@sinsertvrule\@insertvrule}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@insertvrule}
% Two optional arguments required.
%    \begin{macrocode}
\newcommand*{\@insertvrule}[1][0pt]{%
\@ifnextchar[{\@@insertvrule[#1]}{\@@insertvrule[#1][0pt]}}
%    \end{macrocode}
%\end{macro}
% Need some lengths:
%    \begin{macrocode}
\newlength\@ff@left@x
\newlength\@ff@left@y
\newlength\@ff@left@evenx
\newlength\@ff@left@eveny
\newlength\@ff@left@width
\newlength\@ff@left@height
%    \end{macrocode}
%\begin{macro}{\@@insertvrule}
% Arguments all accounted for. Convert the frame type
% into a number to make life easier
%    \begin{macrocode}
\def\@@insertvrule[#1][#2]#3#4#5#6{%
\ifthenelse{\equal{#3}{flow}}{%
\def\@ff@type@i{1}}{\ifthenelse{\equal{#3}{static}}{%
\def\@ff@type@i{2}}{\ifthenelse{\equal{#3}{dynamic}}{%
\def\@ff@type@i{3}}{\PackageError{flowfram}{Unknown frame
type '#3'}{Available frame types are: 'flow', 'static'
or 'dynamic'}}}}%
\ifthenelse{\equal{#5}{flow}}{%
\def\@ff@type@ii{1}}{\ifthenelse{\equal{#5}{static}}{%
\def\@ff@type@ii{2}}{\ifthenelse{\equal{#5}{dynamic}}{%
\def\@ff@type@ii{3}}{\PackageError{flowfram}{Unknown frame
type '#5'}{Available frame types are: 'flow', 'static'
or 'dynamic'}}}}%
\@@insert@vrule{#1}{#2}{\@ff@type@i}{#4}{\@ff@type@ii}{#6}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@insert@vrule}
% Insert a new \gls{static} between the two specified frames.
% Check to make sure which one is on the left and which one
% is on the right.
% Syntax:\newline
%\cs{@@insert@vrule}\marg{y top}\marg{y bottom}\marg{type ID}\marg{IDN}\marg{type ID}\marg{IDN}.
%    \begin{macrocode}
\newcommand*{\@@insert@vrule}[6]{%
\@ff@getdim{#3}{#4}%
\setlength{\@ff@left@x}{\ffareax}%
\setlength{\@ff@left@y}{\ffareay}%
\setlength{\@ff@left@width}{\ffareawidth}%
\setlength{\@ff@left@height}{\ffareaheight}%
\@ff@getdim{#5}{#6}%
\ifnum\@ff@left@x>\ffareax\relax
  \@ff@swaplen{\@ff@left@x}{\ffareax}%
  \@ff@swaplen{\@ff@left@y}{\ffareax}%
  \@ff@swaplen{\@ff@left@evenx}{\ffareaevenx}%
  \@ff@swaplen{\@ff@left@eveny}{\ffareaevenx}%
  \@ff@swaplen{\@ff@left@width}{\ffareawidth}%
  \@ff@swaplen{\@ff@left@height}{\ffareaheight}%
\fi
\setlength{\@ff@tmp@x}{\@ff@left@x}
\addtolength{\@ff@tmp@x}{\@ff@left@width}%
\setlength{\@ff@staticW}{\ffareax}%
\addtolength{\@ff@staticW}{-\@ff@tmp@x}%
\setlength{\@ff@staticH}{\@ff@left@y}%
\addtolength{\@ff@staticH}{\@ff@left@height}%
\setlength{\@ff@tmp@y}{\ffareay}%
\addtolength{\@ff@tmp@y}{\ffareaheight}%
\ifnum\@ff@tmp@y>\@ff@staticH
  \setlength{\@ff@staticH}{\@ff@tmp@y}%
\fi
\ifnum\@ff@left@y<\ffareay\relax
  \setlength{\@ff@tmp@y}{\@ff@left@y}%
\else
  \setlength{\@ff@tmp@y}{\ffareay}%
\fi
\addtolength{\@ff@staticH}{-\@ff@tmp@y}%
\newstaticframe{\@ff@staticW}{\@ff@staticH}%
{\@ff@tmp@x}{\@ff@tmp@y}%
\addtolength{\@ff@staticH}{#1}%
\addtolength{\@ff@staticH}{#2}%
\setstaticcontents{\c@maxstatic}{\hfill
\rule[-#2]{\ffcolumnseprule}{\@ff@staticH}\hfill\mbox{}}%
\ifcase#3\relax
\or \edef\@ff@pages{\csname @ff@pages@\romannumeral#4\endcsname}%
\or \edef\@ff@pages{\csname @sf@pages@\romannumeral#4\endcsname}%
\or \edef\@ff@pages{\csname @df@pages@\romannumeral#4\endcsname}%
\fi
\setstaticframe{\c@maxstatic}{pages=\@ff@pages}%
%    \end{macrocode}
% check the difference between odd and even page co-ordinates
% and shift new frame in same direction. (Assumes the two
% original frames stay in the same relative position.)
%    \begin{macrocode}
\addtolength{\@ff@tmp@x}{\@ff@left@evenx}%
\addtolength{\@ff@tmp@x}{-\@ff@left@x}%
\addtolength{\@ff@tmp@y}{\@ff@left@eveny}%
\addtolength{\@ff@tmp@y}{-\@ff@left@y}%
\setstaticframe{\c@maxstatic}{evenx=\@ff@tmp@x,eveny=\@ff@tmp@y}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sinsertvrule}
% Starred version. Two optional arguments required.
%    \begin{macrocode}
\newcommand*{\@sinsertvrule}[1][0pt]{%
\@ifnextchar[{\@@sinsertvrule[#1]}{\@@sinsertvrule[#1][0pt]}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@sinsertvrule}
% Find out the frame types and their \gls{idn}.
%    \begin{macrocode}
\def\@@sinsertvrule[#1][#2]#3#4#5#6{%
\ifthenelse{\equal{#3}{flow}}{%
\def\@ff@type@i{1}\@flowframeid{#4}\@ff@tmpN=\ff@id}{%
\ifthenelse{\equal{#3}{static}}{%
\def\@ff@type@i{2}\@staticframeid{#4}\@ff@tmpN=\ff@id}{%
\ifthenelse{\equal{#3}{dynamic}}{%
\def\@ff@type@i{3}\@dynamicframeid{#4}\@ff@tmpN=\ff@id}{%
\PackageError{flowfram}{Unknown frame
type '#3'}{Available frame types are: 'flow', 'static'
or 'dynamic'}}}}%
\ifthenelse{\equal{#5}{flow}}{%
\def\@ff@type@ii{1}\@flowframeid{#6}}{%
\ifthenelse{\equal{#5}{static}}{%
\def\@ff@type@ii{2}\@staticframeid{#6}}{%
\ifthenelse{\equal{#5}{dynamic}}{%
\def\@ff@type@ii{3}\@dynamicframeid{#6}}{%
\PackageError{flowfram}{Unknown frame
type '#5'}{Available frame types are: 'flow', 'static'
or 'dynamic'}}}}%
\@@insert@vrule{#1}{#2}{\@ff@type@i}{\@ff@tmpN}%
{\@ff@type@ii}{\ff@id}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\inserthrule}
% Now for a horizontal rule. Syntax similar to "\insertvrule".
% Determine whether or not the starred version is being
% used.
%    \begin{macrocode}
\newcommand*{\inserthrule}{\@ifstar\@sinserthrule\@inserthrule}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@inserthrule}
% Two optional arguments required.
%    \begin{macrocode}
\newcommand*{\@inserthrule}[1][0pt]{%
\@ifnextchar[{\@@inserthrule[#1]}{\@@inserthrule[#1][0pt]}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@inserthrule}
% Arguments all accounted for. Convert the frame type
% into a number to make life easier
%    \begin{macrocode}
\def\@@inserthrule[#1][#2]#3#4#5#6{%
\ifthenelse{\equal{#3}{flow}}{%
\def\@ff@type@i{1}}{\ifthenelse{\equal{#3}{static}}{%
\def\@ff@type@i{2}}{\ifthenelse{\equal{#3}{dynamic}}{%
\def\@ff@type@i{3}}{\PackageError{flowfram}{Unknown frame
type '#3'}{Available frame types are: 'flow', 'static'
or 'dynamic'}}}}%
\ifthenelse{\equal{#5}{flow}}{%
\def\@ff@type@ii{1}}{\ifthenelse{\equal{#5}{static}}{%
\def\@ff@type@ii{2}}{\ifthenelse{\equal{#5}{dynamic}}{%
\def\@ff@type@ii{3}}{\PackageError{flowfram}{Unknown frame
type '#5'}{Available frame types are: 'flow', 'static'
or 'dynamic'}}}}%
\@@insert@hrule{#1}{#2}{\@ff@type@i}{#4}{\@ff@type@ii}{#6}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@insert@hrule}
% Insert a new \gls{static} between the two specified frames.
% Check to make sure which one is on the top and which one
% is on the bottom.
% Syntax:\newline
%\cs{@@insert@hrule}\marg{x left}\marg{x right}\marg{type ID}\marg{IDN}\marg{type ID}\marg{IDN}.
%    \begin{macrocode}
\newcommand*{\@@insert@hrule}[6]{%
\@ff@getdim{#3}{#4}%
\setlength{\@ff@left@x}{\ffareax}%
\setlength{\@ff@left@y}{\ffareay}%
\setlength{\@ff@left@width}{\ffareawidth}%
\setlength{\@ff@left@height}{\ffareaheight}%
\@ff@getdim{#5}{#6}%
\ifnum\@ff@left@y>\ffareay\relax
  \@ff@swaplen{\@ff@left@x}{\ffareax}%
  \@ff@swaplen{\@ff@left@y}{\ffareay}%
  \@ff@swaplen{\@ff@left@width}{\ffareawidth}%
  \@ff@swaplen{\@ff@left@height}{\ffareaheight}%
\fi
\setlength{\@ff@tmp@y}{\@ff@left@y}%
\addtolength{\@ff@tmp@y}{\@ff@left@height}%
\setlength{\@ff@staticH}{\ffareay}%
\addtolength{\@ff@staticH}{-\@ff@tmp@y}%
\setlength{\@ff@staticW}{\@ff@left@x}%
\addtolength{\@ff@staticW}{\@ff@left@width}%
\setlength{\@ff@tmp@x}{\ffareax}%
\addtolength{\@ff@tmp@x}{\ffareawidth}%
\ifnum\@ff@tmp@x>\@ff@staticW\relax
  \setlength{\@ff@staticW}{\@ff@tmp@x}%
\fi
\ifnum\@ff@left@x<\ffareax\relax
  \setlength{\@ff@tmp@x}{\@ff@left@x}%
\else
  \setlength{\@ff@tmp@x}{\ffareax}%
\fi
\addtolength{\@ff@staticW}{-\@ff@tmp@x}%
\newstaticframe{\@ff@staticW}{\@ff@staticH}%
{\@ff@tmp@x}{\@ff@tmp@y}%
\addtolength{\@ff@staticW}{#1}%
\addtolength{\@ff@staticW}{#2}%
\setstaticcontents{\c@maxstatic}{%
\hspace*{-#1}\rule{\@ff@staticW}{\ffcolumnseprule}}%
\ifcase#3\relax
\or \edef\@ff@pages{\csname @ff@pages@\romannumeral#4\endcsname}%
\or \edef\@ff@pages{\csname @sf@pages@\romannumeral#4\endcsname}%
\or \edef\@ff@pages{\csname @df@pages@\romannumeral#4\endcsname}%
\fi
\setstaticframe{\c@maxstatic}{pages=\@ff@pages}%
\addtolength{\@ff@tmp@x}{\@ff@left@evenx}%
\addtolength{\@ff@tmp@x}{-\@ff@left@x}%
\addtolength{\@ff@tmp@y}{\@ff@left@eveny}%
\addtolength{\@ff@tmp@y}{-\@ff@left@y}%
\setstaticframe{\c@maxstatic}{evenx=\@ff@tmp@x,eveny=\@ff@tmp@y}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sinserthrule}
% Starred version. Two optional arguments required.
%    \begin{macrocode}
\newcommand*{\@sinserthrule}[1][0pt]{%
\@ifnextchar[{\@@sinserthrule[#1]}{\@@sinserthrule[#1][0pt]}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@sinserthrule}
% Find out the frame types and their \gls{idn}.
%    \begin{macrocode}
\def\@@sinserthrule[#1][#2]#3#4#5#6{%
\ifthenelse{\equal{#3}{flow}}{%
\def\@ff@type@i{1}\@flowframeid{#4}\@ff@tmpN=\ff@id}{%
\ifthenelse{\equal{#3}{static}}{%
\def\@ff@type@i{2}\@staticframeid{#4}\@ff@tmpN=\ff@id}{%
\ifthenelse{\equal{#3}{dynamic}}{%
\def\@ff@type@i{3}\@dynamicframeid{#4}\@ff@tmpN=\ff@id}{%
\PackageError{flowfram}{Unknown frame
type '#3'}{Available frame types are: 'flow', 'static'
or 'dynamic'}}}}%
\ifthenelse{\equal{#5}{flow}}{%
\def\@ff@type@ii{1}\@flowframeid{#6}}{%
\ifthenelse{\equal{#5}{static}}{%
\def\@ff@type@ii{2}\@staticframeid{#6}}{%
\ifthenelse{\equal{#5}{dynamic}}{%
\def\@ff@type@ii{3}\@dynamicframeid{#6}}{%
\PackageError{flowfram}{Unknown frame
type '#5'}{Available frame types are: 'flow', 'static'
or 'dynamic'}}}}%
\@@insert@hrule{#1}{#2}{\@ff@type@i}{\@ff@tmpN}%
{\@ff@type@ii}{\ff@id}%
}
%    \end{macrocode}
%\end{macro}
%
% \subsection{Putting Chapter Headings in Dynamic Frames}
%\begin{macro}{\dfchaphead}
% Provide facility to make chapter headings appear
% in specified \gls{dynamic}. 
% I originally called this macro "\putchapterheadingsindynamicframe"
% which was descriptive, but overly long, so I changed it
% to the rather more cryptic name "\dfchaphead".
% If the starred form is used, the frame is identified by \gls{idl},
% the unstarred form identifies the frame \gls{idn}.
%    \begin{macrocode}
\newcommand*{\dfchaphead}{%
\@ifstar\@sdynamicchap\@dynamicchap}
%    \end{macrocode}
%\end{macro}
% Define style for the chapter heading. These commands
% are should only be used when "\dfchaphead" has been used.
%\begin{macro}{\DFchapterstyle}
%    \begin{macrocode}
\newcommand{\DFchapterstyle}[1]{#1}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\DFschapterstyle}
%    \begin{macrocode}
\newcommand{\DFschapterstyle}[1]{#1}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dynamicchap}
% Unstarred version.
%    \begin{macrocode}
\newcommand{\@dynamicchap}[1]{%
\@ifundefined{chapter}{\PackageError{flowfram}{Chapters aren't 
defined}{The document
class you are using does not define chapters}}{%
\let\@ff@OLDmakechapterhead\@makechapterhead
\let\@ff@OLDmakeschapterhead\@makeschapterhead
\renewcommand{\DFchapterstyle}[1]{\@ff@OLDmakechapterhead{##1}}%
\renewcommand{\DFschapterstyle}[1]{\@ff@OLDmakeschapterhead{##1}}%
%
\xdef\@makechapterhead##1{%
\noexpand\@setdynamiccontents{\number#1}{%
\noexpand\DFchapterstyle{##1}}}%
\xdef\@makeschapterhead##1{%
\noexpand\@setdynamiccontents{\number#1}{%
\noexpand\DFschapterstyle{##1}}}%
}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sdynamicchap}
% Starred form.
%    \begin{macrocode}
\newcommand{\@sdynamicchap}[1]{%
\@dynamicframeid{#1}\@dynamicchap{\ff@id}}
%    \end{macrocode}
%\end{macro}
% There is no facility for placing other sectional types
% in \glspl{dynamic}.  This is because, either (1) the sectioning
% command does not start a new page, in which case there
% is no way of telling where exactly the new section will start,
% and having a section title in some other location on the
% page is ambiguous, and would really confuse the reader, or
% (2) in the case of "\part" in report or book class files, the
% title appears on a page of its own, so where is the point in
% putting it in a \gls{dynamic}?
%
%\subsection{Thumbtabs}
% Define counter to keep track of total number of
% thumbtabs.
%    \begin{macrocode}
\newcounter{maxthumbtabs}
%    \end{macrocode}
%\begin{macro}{\defaultthumbtabtype}
% Check to see if chapters are defined, if they are make
% thumbtabs correspond to chapters, otherwise make
% thumbtabs correspond to sections.
%    \begin{macrocode}
\@ifundefined{chapter}{%
\newcommand*{\defaultthumbtabtype}{section}}{
\newcommand*{\defaultthumbtabtype}{chapter}
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ttb@type}
% Section type to assign to thumbtabs.
%    \begin{macrocode}
\newcommand*{\@ttb@type}{\defaultthumbtabtype}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\makethumbtabs}
% Make the thumbtabs. Read in information from ".ttb"
% file, and open it for output.
% Syntax:\newline
% \cs{makethumbtabs}\oarg{y offset}\marg{height}\oarg{sec type}.
%
% First check to see if there is a second optional argument.
%    \begin{macrocode}
\newcommand*{\makethumbtabs}[2][0pt]{%
\@ifnextchar[{\@makethumbtabs[#1]{#2}}{%
\@makethumbtabs[#1]{#2}[\defaultthumbtabtype]}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@makethumbtabs}
% Now all arguments are known, first redefine the 
% appropriate sectioning command, then input the ttb file,
% and create the thumbtabs.
%    \begin{macrocode}
\def\@makethumbtabs[#1]#2[#3]{%
\@ifundefined{#3}{\PackageError{flowfram}{%
Unknown section type '#3'}{}}{%
\renewcommand{\@ttb@type}{#3}%
\ifthenelse{\equal{#3}{chapter}}{\@makethumbchapter}{%
\ifthenelse{\equal{#3}{part}}{\@makethumbpart}{%
\@makethumbsection{#3}}}}
\@starttoc{ttb}%
\@dothumbtabs{#1}{#2}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@makethumbchapter}
% If thumbtabs correspond to chapters, redefine "\@chapter"
% so that each unstarred chapter writes an entry to the
% ".ttb" file.
%    \begin{macrocode}
\newcommand{\@makethumbchapter}{
\let\@ttb@old@chapter\@chapter
\def\@chapter[##1]##2{%
\@ttb@old@chapter[##1]{##2}%
\addtocontents{ttb}{\protect\thumbtab
  {\thepage}{\thechapter}{##1}{chapter.\thechapter}}%
\@afterheading
}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@makethumbpart}
% For parts in books or reports, the thumbtab needs to be
% saved after the part counter has been incremented, but
% before the page break so that the page number and part
% numbers are correct. If "\@endpart" is not defined, then
% the document class probably does not start a new page after
% "\part". (This can't be guaranteed for non standard class 
% files, but there's nothing that can be done about that.)
% If this happens, just redefine "\@part", and hope for the
% best.
%    \begin{macrocode}
\newcommand{\@makethumbpart}{
\let\@ttb@old@part\@part
\@ifundefined{@endpart}{%
\def\@part[##1]##2{\@ttb@old@part[##1]{##2}%
\addtocontents{ttb}{\protect\thumbtab
  {\thepage}{\thepart}{##1}{part.\thepage}}%
\@afterheading}}{%
\let\@ttb@old@endpart\@endpart
\def\@part[##1]##2{%
\def\@parttitle{##1}%
\@ttb@old@part[##1]{##2}%
}%
\def\@endpart{%
\addtocontents{ttb}{%
\protect\thumbtab{\thepage}%
{\thepart}{\@parttitle}{part.\thepage}}%
\@ttb@old@endpart
}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@makethumbsection}
% Thumbtabs defined for one of the remaining standard 
% sectioning commands. Since these commands use
% "\@startsection", it is necessary to redefine
% "\@sect" to add the thumbtab information to the .ttb file.
%    \begin{macrocode}
\newcommand*{\@makethumbsection}[1]{%
\let\@ttb@old@sect=\@sect
\def\@sect##1##2##3##4##5##6[##7]##8{%
\@ttb@old@sect{##1}{##2}{##3}{##4}{##5}{##6}[##7]{##8}%
\ifthenelse{\equal{##1}{#1}}{%
\addtocontents{ttb}{%
\protect\thumbtab{\thepage}{\csname the#1\endcsname}%
{##7}{#1.\csname the#1\endcsname}}%
\@afterheading}{}%
}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\thumbtab}
% The thumbtab file, ".ttb", will have a series of "\thumbtab"
% commands, when this file is read in, just store the 
% information for now.
%    \begin{macrocode}
\newcommand{\thumbtab}[4]{%
\stepcounter{maxthumbtabs}%
\expandafter
\gdef\csname thumbtab@pages@\romannumeral\c@maxthumbtabs\endcsname
{#1}%
\expandafter
\gdef\csname thumbtab@num@\romannumeral\c@maxthumbtabs\endcsname
{#2}%
\expandafter
\gdef\csname thumbtab@title@\romannumeral\c@maxthumbtabs\endcsname
{#3}%
\expandafter
\gdef\csname thumbtab@link@\romannumeral\c@maxthumbtabs\endcsname
{#4}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@dothumbtabs}
% Once the thumbtab information has been read in and stored
% in the thumbtab macros, create the thumbtabs using this
% information.  First need to work out the \glspl{pgrange} between
% each thumbtab. If the following thumbtab starts on the
% same page as the previous one, leave the page varable
% as a single number (this may happen if the thumbtabs
% correspond to sections rather than chapters). If the
% following thumbtab starts on a different page to the
% one before it, the preceding thumbtab page variable so
% be a range from its own initial page up to the page before
% the next thumbtab starts. The final thumbtab has an open
% ended range. This final thumbtab will continue to be displayed
% until cancelled by "\disablethumbtabs".
%
% Syntax: \cs{@dothumbtabs}\marg{y offset}\marg{height}.
%    \begin{macrocode}
\newcommand*{\@dothumbtabs}[2]{%
\@colN=0\relax
\whiledo{\@colN<\c@maxthumbtabs}{%
  \advance\@colN by 1\relax
  \edef\ff@pages{%
    \csname thumbtab@pages@\romannumeral\@colN\endcsname}%
  \ifnum\@colN=\c@maxthumbtabs
    \expandafter
      \xdef\csname thumbtab@pages@\romannumeral\@colN\endcsname{%
        \ff@pages,>\ff@pages}%
  \else
    \advance\@colN by 1\relax
    \edef\ff@endpage{%
      \csname thumbtab@pages@\romannumeral\@colN\endcsname}%
    \advance\@colN by -1\relax
    \@ff@tmpN=\ff@endpage\relax
    \advance\@ff@tmpN by -1\relax
    \ifnum\@ff@tmpN>\ff@pages
      \expandafter
        \xdef\csname thumbtab@pages@\romannumeral\@colN\endcsname{%
          \ff@pages-\number\@ff@tmpN}%
    \fi
  \fi
}%
\@@dothumbtabs{#1}{#2}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\thumbtabwidth}
% Default thumbtab width.
%    \begin{macrocode}
\newlength{\thumbtabwidth}
\setlength{\thumbtabwidth}{1cm}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\thumbtabindexformat}
% Thumbtab format. If hyperlinks have been defined,
% use a hyperlink in the thumbtab index.
% Syntax: \cs{thumbtabindexformat}\marg{link}\marg{text}\marg{height}
%    \begin{macrocode}
\@ifundefined{hyperlink}{%
\newcommand{\thumbtabindexformat}[3]{%
\thumbtabformat{#2}{#3}}}{%
\newcommand{\thumbtabindexformat}[3]{%
\hyperlink{#1}{\thumbtabformat{#2}{#3}}}
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\thumbtabformat}
% Individual thumbtab format. If rotating has
% been disabled, stack the letters vertically (this 
% doesn't look very good).
% Syntax: \cs{thumbtabformat}\marg{text}\marg{height}
%    \begin{macrocode}
\newcommand{\thumbtabformat}[2]{%
\if@ttb@rotate
\rotatebox{-90}{\parbox[c][\thumbtabwidth]{#2}{%
\centering#1}}%
\else
\parbox[c][#2]{\thumbtabwidth}{%
\centering\@ttb@stack{#1}}%
\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@flf@subsp}
% Substitute spaces for \cs{space}. Stores resulting text in
% \cs{@flf@subsptext} which should be set to empty before use.
%\changes{1.10}{2007/08/21}{new}
%    \begin{macrocode}
\def\@flf@subsp#1 #2{%
\expandafter\flf@ta\expandafter{\@flf@subsptext}%
\flf@tb{#1}%
\edef\@flf@subsptext{\the\flf@ta\the\flf@tb}%
\def\@flf@tmp{#2}%
\ifx\@flf@tmp\@nnil
  \let\@flf@donextsubsp=\@gobble
\else
  \expandafter\flf@ta\expandafter{\@flf@subsptext}%
  \edef\@flf@subsptext{\the\flf@ta\noexpand\space}%
  \let\@flf@donextsubsp=\@flf@subsp
\fi
\@flf@donextsubsp{#2}%
}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ttb@stack}
% Stack letters vertically. 
% Any spaces first need to be substituted
% with \cs{space}, otherwise they will be ignored.
%\changes{1.10}{2007/08/21}{spaces now replaced with \cs{space}}
%    \begin{macrocode}
\newcommand{\@ttb@stack}[1]{%
\def\@flf@subsptext{}%
\expandafter\@flf@subsp#1 \@nil\relax
\begin{tabular}{l}%
\expandafter\@@ttb@stack\@flf@subsptext\@nil\relax
\end{tabular}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@ttb@stack}
%\changes{1.10}{2007/08/21}{now uses \cs{mbox}}
%    \begin{macrocode}
\def\@@ttb@stack#1#2{%
\def\@flf@tmp{#1}%
\ifx\@flf@tmp\@nnil
  \let\flf@next\relax
\else
  #1\\%
  \def\@flf@tmp{#2}%
  \ifx\@nnil#2\relax
    \let\flf@next\@gobble
  \else
    \let\flf@next\@@ttb@stack
  \fi
\fi
\flf@next{#2}}
%    \end{macrocode}
%\end{macro}
%
%\begin{macro}{\@greyscale}
% Count register to compute the grey scale.
%    \begin{macrocode}
\newcount\@greyscale
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@dothumbtabs}
% Once the \gls{pgrange} have been sorted, create the
% \glspl{dynamic} associated with each thumbtab.
% Thumbtabs will initially have a grey background, but
% this can be changed by the user. Each thumbtab is given
% an \gls{idl} "thumbtab"\meta{n} where \meta{n} is the index of
% the thumbtab (starting from 1 for the topmost thumbtab.)
% Each frame in the thumbtab index is given an \gls{idl} 
% "thumbtabindex"\meta{n}, where \meta{n} is as before.
%    \begin{macrocode}
\newcommand{\@@dothumbtabs}[2]{%
\setlength{\@ff@tmp@y}{\textheight}%
\addtolength{\@ff@tmp@y}{-#2}%
\addtolength{\@ff@tmp@y}{-#1}%
\computerightedgeodd{\@ff@tmp@x}%
\addtolength{\@ff@tmp@x}{-\thumbtabwidth}%
\computeleftedgeeven{\@ff@tmp@x@even}%
\@ff@tmpN=0\relax
\whiledo{\@ff@tmpN<\c@maxthumbtabs}{%
  \advance\@ff@tmpN by 1\relax
  \@greyscale=\@ff@tmpN\relax
  \multiply\@greyscale by 60\relax
  \divide\@greyscale by \c@maxthumbtabs
  \advance\@greyscale by 25\relax
  \edef\@ff@greyscale{0.\number\@greyscale}%
%    \end{macrocode}
% Thumbtab
%    \begin{macrocode}
  \newdynamicframe[none]{\thumbtabwidth}{#2}%
    {\@ff@tmp@x}{\@ff@tmp@y}[thumbtab\number\@ff@tmpN]%
  \expandafter\global\expandafter
    \setlength\csname @df@\romannumeral\c@maxdynamic @evenx\endcsname
    {\@ff@tmp@x@even}%
%    \end{macrocode}
% set the contents of the dynamic frame
%    \begin{macrocode}
  \ifthenelse{\boolean{@ttb@title}\and\boolean{@ttb@num}}{%
    \expandafter
    \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{%
    \noexpand\thumbtabformat{%
    \csname thumbtab@num@\romannumeral\@ff@tmpN\endcsname\
    \csname thumbtab@title@\romannumeral\@ff@tmpN\endcsname
    }{#2}}%
  }{%
    \if@ttb@title
      \expandafter
      \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{%
        \noexpand\thumbtabformat{%
        \csname thumbtab@title@\romannumeral\@ff@tmpN\endcsname
        }{#2}}%
    \fi
    \if@ttb@num
      \expandafter
      \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{%
        \noexpand\thumbtabformat{%
        \csname thumbtab@num@\romannumeral\@ff@tmpN\endcsname
        }{#2}}%
    \fi
  }%
  \expandafter
    \xdef\csname @df@backcol@\romannumeral\c@maxdynamic\endcsname
    {[gray]{\@ff@greyscale}}
%    \end{macrocode}
% Thumbtab index
%    \begin{macrocode}
  \newdynamicframe[none]{\thumbtabwidth}{#2}%
    {\@ff@tmp@x}{\@ff@tmp@y}[thumbtabindex\number\@ff@tmpN]%
  \expandafter\global\expandafter
  \setlength\csname @df@\romannumeral\c@maxdynamic @evenx\endcsname
  {\@ff@tmp@x@even}%
  \expandafter
%    \end{macrocode}
% set the contents of the dynamic frame
%    \begin{macrocode}
  \ifthenelse{\boolean{@ttb@title}\and\boolean{@ttb@num}}{%
    \expandafter
    \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{%
      \noexpand\thumbtabindexformat{%
      \csname thumbtab@link@\romannumeral\@ff@tmpN\endcsname}{%
      \csname thumbtab@num@\romannumeral\@ff@tmpN\endcsname\
      \csname thumbtab@title@\romannumeral\@ff@tmpN\endcsname
      }{#2}}%
  }{%
    \if@ttb@title
      \expandafter
      \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{%
        \noexpand\thumbtabindexformat{%
        \csname thumbtab@link@\romannumeral\@ff@tmpN\endcsname}{%
        \csname thumbtab@title@\romannumeral\@ff@tmpN\endcsname
        }{#2}}%
    \fi
    \if@ttb@num
    \expandafter
      \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{%
        \noexpand\thumbtabindexformat{%
        \csname thumbtab@link@\romannumeral\@ff@tmpN\endcsname}{%
        \csname thumbtab@num@\romannumeral\@ff@tmpN\endcsname
        }{#2}}%
    \fi
  }%
  \expandafter
    \xdef\csname @df@backcol@\romannumeral\c@maxdynamic\endcsname
    {[gray]{\@ff@greyscale}}
  \addtolength{\@ff@tmp@y}{-#2}%
}%
}%
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\enablethumbtabs}
% Enable thumbtabs. Once the \gls{idn} is obtained for the
% first thumbtab, the rest can be found by incrementing the
% number by 2 (the frames in between correspond to the 
% thumbtab index.)
%    \begin{macrocode}
\newcommand*{\enablethumbtabs}{%
\ifnum\c@maxthumbtabs>0
\@ff@tmpN=0\relax
\@dynamicframeid{thumbtab1}%
\whiledo{\@ff@tmpN<\c@maxthumbtabs}{%
\advance\@ff@tmpN by 1\relax
%    \end{macrocode}
% thumbtab
%    \begin{macrocode}
\edef\@ff@pages{\csname thumbtab@pages@\romannumeral\@ff@tmpN\endcsname}%
\@@setdynamicframe{\ff@id}{pages=\@ff@pages}%
\advance\ff@id by 2\relax
}%
\else\PackageWarning{flowfram}{No thumb tabs defined}\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\disablethumbtabs}
% Disable all thumbtabs.
%    \begin{macrocode}
\newcommand*{\disablethumbtabs}{%
\ifnum\c@maxthumbtabs>0
\@ff@tmpN=0\relax
\@dynamicframeid{thumbtab1}%
\whiledo{\@ff@tmpN<\c@maxthumbtabs}{%
\advance\@ff@tmpN by 1\relax
%    \end{macrocode}
%thumbtab
%    \begin{macrocode}
\expandafter\xdef\csname @df@pages@\romannumeral\ff@id\endcsname
{none}%
\advance\ff@id by 1\relax
%    \end{macrocode}
%thumbtab index
%    \begin{macrocode}
\expandafter\xdef\csname @df@pages@\romannumeral\ff@id\endcsname
{none}%
\advance\ff@id by 1\relax
}\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\thumbtabindex}
% Show thumbtab index on current page.
% The "\@ff@doafter" bit circumvents the problem of duplicate page 
% numbers, as the table of contents
% is quite frequently on page i while the first chapter starts on page 1.
%    \begin{macrocode}
\newcommand*{\thumbtabindex}{%
\ifnum\c@maxthumbtabs>0\relax
\@ff@tmpN=0\relax
\@dynamicframeid{thumbtabindex1}%
\whiledo{\@ff@tmpN<\c@maxthumbtabs}{%
\advance\@ff@tmpN by 1\relax
\expandafter
\xdef\csname @df@pages@\romannumeral\ff@id\endcsname{\c@page}%
\edef\@ff@doafter{%
\noexpand\afterpage{%
\noexpand\setdynamicframe{\number\ff@id}{pages=none}}}
\@ff@doafter
\advance\ff@id by 2\relax
}\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\setthumbtab}
% Modify the settings for all the thumbtabs (including thumbtab 
% index).  Since the thumbtabs are \glspl{dynamic}
% you could just use "\setdynamicframe", however, the thumbtabs 
% will not be generated on the first run, as there will be no 
% information in the ttb file, so "\setdynamicframe" would 
% generate an error.  "\setthumbtab" will only give
% a warning message if it can not find the thumbtab. 
% The argument "#1" is the index of the thumbtab (starting 
% from 1), the second argument "#2" is the
% frame settings.
%    \begin{macrocode}
\newcommand{\setthumbtab}[2]{%
\ifthenelse{\equal{#1}{all}}{%
\@ff@tmpN=0\relax
\whiledo{\@ff@tmpN<\c@maxthumbtabs}{%
\advance\@ff@tmpN by 1\relax
\@setthumbtab{\@ff@tmpN}{#2}}}{%
\@for\@ttb@id:=#1\do{\@setthumbtab{\@ttb@id}{#2}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@setthumbtab}
% Set individual thumbtab and its index tab.
%    \begin{macrocode}
\newcommand{\@setthumbtab}[2]{%
% check if this thumbtab exists
\ifthenelse{\(\c@maxthumbtabs<#1\) \or \(#1<1\)}{%
\PackageWarning{flowfram}{Can't find thumbtab number '#1', 
ttb file may not be up-to-date}}{%
\@dynamicframeid{thumbtab\number#1}%
\@@setdynamicframe{\ff@id}{#2}%
\@dynamicframeid{thumbtabindex\number#1}%
\@@setdynamicframe{\ff@id}{#2}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\setthumbtabindex}
% Only change settings for the thumbtab index. This can
% take a comma-separated number list.
%    \begin{macrocode}
\newcommand{\setthumbtabindex}[2]{%
\ifthenelse{\equal{#1}{all}}{%
\@ff@tmpN=0\relax
\whiledo{\@ff@tmpN<\c@maxthumbtabs}{%
\advance\@ff@tmpN by 1\relax
\@setthumbtabindex{\@ff@tmpN}{#2}}}{%
\@for\@ttb@id:=#1\do{\@setthumbtabindex{\@ttb@id}{#2}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@setthumbtabindex}
% Change setting for individual thumbtab index entry.
%    \begin{macrocode}
\newcommand{\@setthumbtabindex}[2]{%
% check if this thumbtab exists
\ifthenelse{\(\c@maxthumbtabs<#1\) \or \(#1<1\)}{%
\PackageWarning{flowfram}{Can't find thumbtab number `\number#1', 
ttb file may not be up-to-date}}{%
\@dynamicframeid{thumbtabindex\number#1}%
\@@setdynamicframe{\ff@id}{#2}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\tocandhumbtabindex}
% Do both the table of contents and the thumbtab index
%    \begin{macrocode}
\newcommand*{\tocandthumbtabindex}{%
\aligntoctrue
\tableofcontents
\thumbtabindex
\aligntocfalse
}
%    \end{macrocode}
%\end{macro}
%
% \subsection{Minitocs}
%\begin{macro}{\@ttb@minitoctype}
% Sectioning type for the minitoc, by default it is the
% same as the thumbtabs
%    \begin{macrocode}
\newcommand*{\@ttb@minitoctype}{\@ttb@type}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@starttoc}
% In order to align the table of contents with the thumbtabs,
% or to use minitocs, the toc information must be stored,
% rather than simply input.
% Therefore, modify "\@starttoc" so that it can store the contents
% of the file. "\if@storetoc" is used to determine whether
% to store the contents, or act as normal.
%    \begin{macrocode}
\let\@ttb@old@starttoc\@starttoc
\newif\if@storetoc
\@storetocfalse
\renewcommand*{\@starttoc}[1]{%
\if@storetoc
  \@ttb@storetoc{#1}%
\else
  \@ttb@old@starttoc{#1}%
\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@ttb@storetoc}
% store the contents of the file with the given extension
%    \begin{macrocode}
\newcommand*{\@ttb@storetoc}[1]{%
\begingroup
\makeatletter
\@storefileconts{\jobname.#1}%
\if@filesw
 \expandafter\newwrite\csname tf@#1\endcsname
 \immediate\openout\csname tf@#1\endcsname\jobname.#1\relax
\fi
\@nobreakfalse
\endgroup}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@storefileconts}
% store the contents of named file, if it exists.
%\changes{1.10}{2007/08/21}{uses \cs{PackageInfo} instead of
% \cs{typeout}}
%    \begin{macrocode}
\newcommand*{\@storefileconts}[1]{\IfFileExists{#1}{%
\@@storefileconts\@filef@und}{%
\PackageInfo{flowfram}{No file #1.}}}
%    \end{macrocode}
%\end{macro}
% store the number of units corresponding to the 
% thumbtab type, and minitoc units. These will usually
% have the same value, but this is not always
% guaranteed.
%\begin{macro}{\c@maxtocunits}
% Total number of toc units
%    \begin{macrocode}
\newcount\c@maxtocunits
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\c@maxminitoc}
% Total number of minitoc units
%    \begin{macrocode}
\newcount\c@maxminitoc
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@storefileconts}
% Read each line in from the file, and add to the contents
% list.
%    \begin{macrocode}
\newcommand{\@@storefileconts}[1]{%
\@ifundefined{\@ttb@minitoctype}{\@ttb@minitoclevel=6\relax}{%
\expandafter\@ttb@minitoclevel\expandafter
  =\csname @ttb@\@ttb@minitoctype @level\endcsname}%
\newread\@ttb@toc
\openin\@ttb@toc=#1\relax
\c@maxtocunits=0\relax
\c@maxminitoc=0\relax
\whiledo{\not\boolean{eof}\@ttb@toc}{%
\read\@ttb@toc to\tocline
\@addtotoclist{\tocline}{\c@maxtocunits}%
}%
\closein\@ttb@toc}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@addtotoclist}
% Before each line is added to the contents list, it is
% first checked to see whether the line starts with
% "\contentsline".  If it does, then check to see if the
% sectioning type corresponds to the thumbtab level. If
% it does, then start a new list. There will be "\c@maxtocunits"
% lists, each one corresponding to each thumbtab group.
% In addition, each contents line needs to be added to 
% the minitoclists, but only if the sectioning type level
% is greater than "\@ttb@minitoctype". The number of minitoc
% lists is given by "\c@maxminitoc".
%    \begin{macrocode}
\newif\if@contsline
\newcount\@ttb@level
\newcount\@ttb@minitoclevel

\newcommand{\@addtotoclist}[2]{%
\expandafter\@checkcontentsline#1\end
\if@contsline
\expandafter\@gettype#1\end
\ifthenelse{\equal{\@ttb@contstype}{\@ttb@type}}{%
\global\advance#2 by 1\relax
}{%
}%
\fi
\@ifundefined{@toc@\romannumeral#2}{%
\flf@ta=\expandafter{#1}%
\expandafter\xdef\csname @toc@\romannumeral#2\endcsname{\the\flf@ta}}{%
\flf@ta=\expandafter{#1}%
\flf@tb=\expandafter\expandafter\expandafter{\csname @toc@\romannumeral#2\endcsname}%
\expandafter\xdef\csname @toc@\romannumeral#2\endcsname{\the\flf@tb\the\flf@ta}}%
%    \end{macrocode}
% now do minitoc stuff. If the sectioning type is unknown,
% assume it comes last
%    \begin{macrocode}
\if@minitoc
  \if@contsline
    \@ifundefined{\@ttb@contstype}{\@ttb@level=6}{%
      \@ttb@level=\csname @ttb@\@ttb@contstype @level\endcsname}%
    \relax
    \ifnum\@ttb@level=\@ttb@minitoclevel
      \global\advance\c@maxminitoc by 1\relax
      \expandafter
         \gdef\csname @minitoc@\romannumeral\c@maxminitoc\endcsname{}%
    \else
      \ifnum\@ttb@level>\@ttb@minitoclevel
        \flf@ta=\expandafter{#1}\relax
        \flf@tb=\expandafter\expandafter\expandafter
         {\csname @minitoc@\romannumeral\c@maxminitoc\endcsname}\relax
        \expandafter
          \xdef\csname @minitoc@\romannumeral\c@maxminitoc\endcsname{%
           \the\flf@tb\the\flf@ta}
      \fi
    \fi
  \fi
\fi
}
%    \end{macrocode}
%\end{macro}
% Is there already a way of determining the sectioning
% level from its name?
%    \begin{macrocode}
\def\@ttb@part@level{-1}
\def\@ttb@chapter@level{0}
\def\@ttb@section@level{1}
\def\@ttb@subsection@level{2}
\def\@ttb@subsubsection@level{3}
\def\@ttb@paragraph@level{4}
\def\@ttb@subparagraph@level{5}
%    \end{macrocode}
%\begin{macro}{\@checkcontentsline}
% Check to see if line starts with "\contentsline"
%    \begin{macrocode}
\long\def\@checkcontentsline#1#2\end{%
\ifx#1\contentsline
  \@contslinetrue
\else
  \@contslinefalse
\fi}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@gettype}
% Given that the line starts with "\contentsline", extract
% the first argument of "\contentsline" to get the sectioning
% type.
%    \begin{macrocode}
\def\@gettype\contentsline#1#2\end{%
\def\@ttb@contstype{#1}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\tableofcontents}
% Modify "\tableofcontents". It first stores the contents
% of the toc file, and then, either simply prints it on the
% page (so it appears no different to the standard
% "\tableofcontents"), or it prints it out so that each
% thumbtab unit has the same height as the thumbtabs.
% Note: this assumes that the actual table of contents
% starts at the same height as the thumbtabs. The thumbtab
% vertical position may need to be adjusted to compensate
% for space taken up by the contents title.
%    \begin{macrocode}
\newif\ifaligntoc
\aligntocfalse

\let\@ttb@old@tableofcontents\tableofcontents
\renewcommand{\tableofcontents}{%
\@storetoctrue
\@ttb@old@tableofcontents
\ifaligntoc
  \@printalignedtoc
\else
  \@printtoc
\fi
\@storetocfalse
\global\c@minitoc=0\relax}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\beforeminitocskip}
% Vertical space to add before minitoc.
%    \begin{macrocode}
\newlength\beforeminitocskip
\setlength{\beforeminitocskip}{0pt}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\afterminitocskip}
% Vertical space to add after minitoc.
%    \begin{macrocode}
\newlength\afterminitocskip
\setlength{\afterminitocskip}{\baselineskip}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\dominitoc}
% Do the minitoc for unit "#1". Check first that
% minitocs have been enabled.
%    \begin{macrocode}
\newcommand*{\dominitoc}[1]{%
\if@minitoc \@dominitoc{#1}\fi}
\newcommand*{\@dominitoc}[1]{\@@dominitoc{#1}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\minitocstyle}
% Style in which to display the minitoc.
%    \begin{macrocode}
\newcommand{\minitocstyle}[1]{\normalfont\normalsize\normalcolor
#1}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@@dominitoc}
% Now do the actual minitoc for unit "#1".
%    \begin{macrocode}
\newcommand*{\@@dominitoc}[1]{%
{\minitocstyle{%
\vskip\beforeminitocskip
\csname @minitoc@\romannumeral#1\endcsname}}
\vskip\afterminitocskip}
%    \end{macrocode}
%\end{macro}
%
%\begin{macro}{\appenddfminitoc}
% Modify "\dominitoc" so that the minitoc is appended
% to specified \gls{dynamic}. Starred version uses
% \gls{dynamic} \gls{idl}, unstarred version uses \gls{dynamic}
% \gls{idn}. I originally called this macro "\appendminitoctodynamicframe"
% but decided it was too long, for I've opted instead
% for a slightly more cryptic name.
%    \begin{macrocode}
\newcommand*{\appenddfminitoc}{%
\renewcommand{\beforeminitocskip}{\baselineskip}%
\@ifstar\@sappendminitocdf\@appendminitocdf}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@sappendminitocdf}
% Starred version
%    \begin{macrocode}
\newcommand*{\@sappendminitocdf}[1]{%
\renewcommand{\@dominitoc}[1]{%
\@sappenddynamic{#1}{\@@dominitoc{##1}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@appendminitocdf}
% Unstarred version
%    \begin{macrocode}
\newcommand*{\@appendminitocdf}[1]{%
\renewcommand{\@dominitoc}[1]{%
\@appenddynamic{#1}{\@@dominitoc{##1}}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@printtoc}
% Do the table of contents, which has been stored
% in "\c@maxtocunits" macros. (or possibly 
% "\c@maxtocunits + 1", if information was added
% before the first group---which corresponds to
% "\@colN=0".)
%    \begin{macrocode}
\newcommand*{\@printtoc}{%
\@colN=0\relax
\csname @toc@\romannumeral\@colN\endcsname
\whiledo{\@colN<\c@maxtocunits}{%
\advance\@colN by 1\relax
\csname @toc@\romannumeral\@colN\endcsname}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@printalignedtoc}
% Print the table of contents so that each unit is
% has vertical height the same as the height of the
% thumbtabs. Note that you may have to adjust the
% vertical offset of the thumbtabs (in "\makethumbtabs")
% in order to make them correctly aligned.
%    \begin{macrocode}
\newcommand{\@printalignedtoc}{%
\@ff@tmpN=0\relax
\@ifundefined{@toc@\romannumeral\@ff@tmpN}{%
}{%
\csname @toc@\romannumeral\@ff@tmpN\endcsname
\par\noindent\hrulefill
}%
\whiledo{\@ff@tmpN<\c@maxtocunits}{%
\advance\@ff@tmpN by 1\relax
\ifnum\@ff@tmpN>\c@maxthumbtabs
\csname @toc@\romannumeral\@ff@tmpN\endcsname
\else
\@dynamicframeid{thumbtabindex\number\@ff@tmpN}%
\expandafter\expandafter\expandafter
\@ff@getstaticpos\csname @df@dim@\romannumeral\ff@id\endcsname
\vbox to \@ff@tmp@y{%
\noindent\parbox{\linewidth}{%
\csname @toc@\romannumeral\@ff@tmpN\endcsname}%
\vfill
\par\noindent\hrulefill
}%
\fi}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\enableminitoc}
% Make mini tocs appear at the start of given sectional unit.
%    \begin{macrocode}
\newcounter{minitoc}
\newif\if@minitoc
\@minitocfalse

\newcommand*{\enableminitoc}[1][\@ttb@type]{%
\@minitoctrue
\setcounter{minitoc}{0}%
\@ifundefined{#1}{%
\PackageError{flowfram}{Sectioning type `#1' not defined}{}}{%
\renewcommand{\@ttb@minitoctype}{#1}%
\ifthenelse{\equal{#1}{chapter}}{\@makeminitocchapter}{%
\ifthenelse{\equal{#1}{part}}{\@makeminitocpart}{%
\@makeminitocsection{#1}}}}%
}
%    \end{macrocode}
%\end{macro}
% This command should only appear in the preamble. (This
% ensures that it is used before "\tableofcontents".
%    \begin{macrocode}
\@onlypreamble{\enableminitoc}
%    \end{macrocode}
%\begin{macro}{\@makeminitocchapter}
% If minitocs are associated with chapters, redefine
% "\@chapter" so that the minitoc appears after the 
% chapter heading.
%    \begin{macrocode}
\newcommand{\@makeminitocchapter}{
\let\@mtoc@old@chapter\@chapter
\def\@chapter[##1]##2{%
\@mtoc@old@chapter[##1]{##2}%
\stepcounter{minitoc}%
\dominitoc{\c@minitoc}%
\@afterheading
}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@makeminitocpart}
% Again, for parts. As before, need to redefine
% "\@endpart" if it exists, otherwise redefine
% "\@part".
%    \begin{macrocode}
\newcommand{\@makeminitocpart}{
\@ifundefined{@endpart}{%
\let\@mtoc@old@part\@part
\def\@part[##1]##2{%
\@mtoc@old@part[##1]{##2}%
\stepcounter{minitoc}%
\dominitoc{\c@minitoc}%
\@afterheading
}}{%
\let\@mtoc@old@endpart\@endpart
\def\@endpart{%
\stepcounter{minitoc}%
\dominitoc{\c@minitoc}%
\@mtoc@old@endpart
}}}
%    \end{macrocode}
%\end{macro}
%\begin{macro}{\@makeminitocsection}
% Now for the remaining sectional units.
%    \begin{macrocode}
\newcommand{\@makeminitocsection}[1]{%
\let\@mtoc@old@sect=\@sect
\def\@sect##1##2##3##4##5##6[##7]##8{%
\@mtoc@old@sect{##1}{##2}{##3}{##4}{##5}{##6}[##7]{##8}%
\ifthenelse{\equal{##1}{#1}}{%
\stepcounter{minitoc}%
\dominitoc{\c@minitoc}\@afterheading}{}%
}}
%    \end{macrocode}
%\end{macro}
%\iffalse
%    \begin{macrocode}
%</flowfram.sty>
%    \end{macrocode}
%\fi
%\Finale
\endinput
