summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/latex/flowfram/flowfram.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/doc/latex/flowfram/flowfram.dtx')
-rw-r--r--Master/texmf-dist/doc/latex/flowfram/flowfram.dtx7678
1 files changed, 7678 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/latex/flowfram/flowfram.dtx b/Master/texmf-dist/doc/latex/flowfram/flowfram.dtx
new file mode 100644
index 00000000000..7ad71e5b94c
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/flowfram/flowfram.dtx
@@ -0,0 +1,7678 @@
+%\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 2008/7/1 14:05
+%\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) 2008 Nicola Talbot, all rights reserved.
+% \fi
+% \iffalse
+%<*driver>
+\documentclass{ltxdoc}
+
+\CheckSum{9387}
+\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.11}
+%\author{Nicola L. C. Talbot}
+%\date{28th June 2008}
+%\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}[2008/06/27 v1.11]
+% \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 register to store the number of \glspl{flow} that have been defined:
+% \begin{macrocode}
+\newcounter{maxflow}
+\c@maxflow=0\relax
+% \end{macrocode}
+% Next define a counter to keep track of the \gls{idn} of the current
+% \gls{flow}.
+% \begin{macrocode}
+\newcounter{thisframe}
+\c@thisframe=0\relax
+\@ifpackageloaded{hyperref}{%
+\def\theHthisframe{\thepage.\arabic{thisframe}}}{}
+% \end{macrocode}
+%\begin{macro}{\labelflowidn}
+%\changes{1.11}{2008/06/27}{new}
+% Define a command to label the current \gls{flow} so that its
+% \gls{idn} can be referenced:
+% \begin{macrocode}
+\newcommand*{\labelflowidn}[1]{%
+{\def\@currentlabel{\thethisframe}\label{#1}}}
+% \end{macrocode}
+%\end{macro}
+% Define a counter to store the current frame index for the current
+% page. This will be the same as the \gls{idn} if all \glspl{flow}
+% are displayed on the current page, but may be different to the
+% \gls{idn} if some \glspl{flow} are not displayed.
+%\changes{1.11}{2008/06/27}{displayedframe counter added}
+% \begin{macrocode}
+\newcounter{displayedframe}
+\c@displayedframe=0
+\@ifpackageloaded{hyperref}{%
+\def\theHdisplayedframe{\thepage.\arabic{displayedframe}}}{}
+% \end{macrocode}
+%\begin{macro}{\labelflow}
+%\changes{1.11}{2008/06/27}{new}
+% Define a command to label the current \gls{flow} so that its
+% displayed index can be referenced:
+% \begin{macrocode}
+\newcommand*{\labelflow}[1]{%
+{\def\@currentlabel{\thedisplayedframe}\label{#1}}}
+% \end{macrocode}
+%\end{macro}
+% 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}{\getflowlabel}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{getflowlabel}\marg{idn}
+% Gets the \gls{idl} for the \gls{flow} identified by its
+% \gls{idn}.
+% \begin{macrocode}
+\newcommand*{\getflowlabel}[1]{%
+\csname @col@id@\romannumeral#1\endcsname}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\getflowid}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{getflowid}\marg{cmd}\marg{idl}
+% Gets the \gls{idn} for the \gls{flow} identified by its
+% \gls{idl} and stores in \meta{cmd} which must be a control
+% sequence.
+% \begin{macrocode}
+\newcommand*{\getflowid}[2]{%
+\@flowframeid{#2}\edef#1{\number\ff@id}}
+% \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\relax
+ \def\@ff@numend{\c@maxflow}%
+\fi
+\@colN=\@ff@numstart\relax
+\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.
+%\changes{1.11}{2008/06/27}{removed unwanted spaces}
+% \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}{\getstaticlabel}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{getstaticlabel}\marg{idn}
+% Gets the \gls{idl} for the \gls{static} identified by its
+% \gls{idn}.
+% \begin{macrocode}
+\newcommand*{\getstaticlabel}[1]{%
+\csname @sf@id@\romannumeral#1\endcsname}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\getstaticid}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{getstaticid}\marg{cmd}\marg{idl}
+% Gets the \gls{idn} for the \gls{static} identified by its
+% \gls{idl} and stores in \meta{cmd} which must be a control
+% sequence.
+% \begin{macrocode}
+\newcommand*{\getstaticid}[2]{%
+\@staticframeid{#2}\edef#1{\number\ff@id}}
+% \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\relax
+ \def\@ff@numend{\c@maxstatic}%
+\fi
+\@colN=\@ff@numstart\relax
+\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]{%
+\let\continueonframe=\@staticcontinueonframe
+\@beginstaticcontents{#1}%
+}{%
+\@endstaticcontents
+\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}%
+\let\continueonframe=\@staticscontinueonframe
+\@beginstaticcontents{\ff@id}%
+}{%
+\@endstaticcontents
+\ignorespaces}
+% \end{macrocode}
+%\end{environment}
+%
+% Begin staticcontents stuff.
+% \begin{macrocode}
+\newcommand{\@beginstaticcontents}[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
+}
+% \end{macrocode}
+% End staticcontents stuff
+% \begin{macrocode}
+\newcommand*{\@endstaticcontents}{%
+\ifnum\ff@shape=2\par
+\else\FLForgpar\fi\endgroup\end{minipage}\end{lrbox}%
+\expandafter\global\expandafter\sbox\@sf@thisframe{%
+\usebox\staticframe}}
+% \end{macrocode}
+%
+%\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}[2]{\begin{staticcontents*}{#1}%
+#2\end{staticcontents*}}
+% \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}{\getdynamiclabel}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{getdynamiclabel}\marg{idn}
+% Gets the \gls{idl} for the \gls{dynamic} identified by its
+% \gls{idn}.
+% \begin{macrocode}
+\newcommand*{\getdynamiclabel}[1]{%
+\csname @df@id@\romannumeral#1\endcsname}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\getdynamicid}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{getdynamicid}\marg{cmd}\marg{idl}
+% Gets the \gls{idn} for the \gls{dynamic} identified by its
+% \gls{idl} and stores in \meta{cmd} which must be a control
+% sequence.
+% \begin{macrocode}
+\newcommand*{\getdynamicid}[2]{%
+\@dynamicframeid{#2}\edef#1{\number\ff@id}}
+% \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}
+%
+%\begin{macro}{\@getframeid}
+% \cs{@getframeid}\marg{type}\marg{idl}
+%
+% Gets the \gls{idl} for the frame of type \meta{type} whose \gls{idl}
+% is given by \meta{idl}. The \gls{idn} is stored in "\ff@id".
+% \begin{macrocode}
+\newcommand*{\@getframeid}[2]{%
+\@ifdefined{@#1frameid}{\csname @#1frameid\endcsname{#2}}{%
+\PackageError{flowfram}{Unknown frame type `#1'}{Frame types can
+be one of: flow, static or dynamic}}}
+% \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\relax
+ \def\@ff@numend{\c@maxdynamic}%
+\fi
+\@colN=\@ff@numstart\relax
+\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}.
+%\changes{1.11}{2008/06/27}{removed unwanted space}
+%\changes{1.11}{2008/06/27}{fixed bug in clear key}
+% \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#1}{\ff@clear}%
+}%
+\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.)
+% \begin{macrocode}
+\newenvironment{dynamiccontents}[1]{%
+\def\@flf@{dynamiccontents}%
+\xdynamiccontents{#1}}{%
+\endxdynamiccontents
+}
+% \end{macrocode}
+%\end{environment}
+% Token to store contents of environment:
+% \begin{macrocode}
+\newtoks\@dynamictok
+% \end{macrocode}
+% Start of the environment (unstarred):
+% \begin{macrocode}
+\def\xdynamiccontents#1{%
+\def\@flf@idn{#1}%
+\@dynamictok{}\@flf@get@body
+}
+% \end{macrocode}
+% Get the body of the environment:
+% \begin{macrocode}
+\long\def\@flf@get@body#1\end{%
+\@flf@checkcontinued#1\continueonframe\@nil
+\ifdfcontinued
+ \expandafter\flf@ta\expandafter{\@flf@tmpa}%
+ \edef\@flf@tmp{\the\@dynamictok\the\flf@ta}%
+ \@dynamictok\expandafter{\@flf@tmp}%
+\else
+ \@dynamictok\expandafter{\the\@dynamictok#1}%
+\fi
+\@flf@find@end}
+% \end{macrocode}
+% Check if \cs{continueonframe} has been used.
+% \begin{macrocode}
+\newif\ifdfcontinued
+\long\def\@flf@checkcontinued#1\continueonframe#2\@nil{%
+\long\def\@flf@tmpa{#1}\long\def\@flf@tmpb{#2}%
+\ifx\@flf@tmpb\@lempty
+ \dfcontinuedfalse
+\else
+ \dfcontinuedtrue
+ \flf@getcontargs#2\@ff@text\@ff@nextid\@ff@rest
+\fi
+}
+% \end{macrocode}
+% Long equivalent of \cs{@empty}:
+% \begin{macrocode}
+\long\def\@lempty{}
+% \end{macrocode}
+% Get the first optional argument and store in the forth argument
+% (which should be a control sequence). Get the second argument and
+% store in the fifth argument (which should be a control sequence).
+% Get the third argument and
+% store in the sixth argument (which should be a control sequence).
+% \begin{macrocode}
+\def\flf@getcontargs{%
+\@ifnextchar[{\@flf@getcontargs}{\@flf@getcontargs[]}}
+% \end{macrocode}
+% \begin{macrocode}
+\long\def\@flf@getcontargs[#1]#2#3\continueonframe#4#5#6{%
+\def#4{#1}\def#5{#2}\def#6{#3}%
+}
+% \end{macrocode}
+% Find the end of the environment:
+% \begin{macrocode}
+\def\@flf@find@end#1{%
+\def\@tempa{#1}%
+\global\let\flf@next=\relax
+\ifdfcontinued
+ \@dynamictok\expandafter
+ {\the\@dynamictok\ffcontinuedtextlayout}%
+ \protected@edef\@tmpa{\the\@dynamictok{\@ff@text}}%
+ \@dynamictok\expandafter{\@tmpa}%
+ \toks@\expandafter{\@ff@rest}%
+ \edef\flf@next{\noexpand\@flf@get@body\noexpand\end{#1}%
+ \noexpand\begin{#1}{\@ff@nextid}\noexpand\par
+ \noexpand\noindent\noexpand\ignorespaces
+ \the\toks@\noexpand\end{#1}}%
+\else
+ \ifx\@tempa\@flf@
+ \let\flf@next=\@flf@endxdynamiccontents
+ \else
+ \@dynamictok\expandafter
+ {\the\@dynamictok\end{#1}}%
+ \let\flf@next=\@flf@get@body
+ \fi
+\fi
+\flf@next
+}
+% \end{macrocode}
+% End of the environment:
+% \begin{macrocode}
+\let\endxdynamiccontents\relax
+\def\@flf@endxdynamiccontents{%
+\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\@dynamictok}%
+ \expandafter
+\fi
+\expandafter\end\expandafter{\@flf@}%
+}
+% \end{macrocode}
+%\begin{environment}{dynamiccontents*}
+% Starred version
+% \begin{macrocode}
+\newenvironment{dynamiccontents*}[1]{%
+\def\@flf@{dynamiccontents*}%
+\@dynamicframeid{#1}%
+\xdynamiccontents{\ff@id}}{%
+\enddynamiccontents
+}
+% \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}
+%
+%\begin{macro}{\continueonframe}
+% \cs{continueonframe}\oarg{text}\marg{id}
+% Ends current \env{staticcontents} or \env{dynamiccontents}
+% environment and starts environment of the same type for frame
+% given by \meta{id}. Can only be used inside \env{staticcontents}
+% or \env{dynamiccontents} environments. If the starred version of
+% the environment is used, \marg{id} refers to the \gls{idl}, otherwise
+% it refers to the \gls{idn} of the new frame.
+% \begin{macrocode}
+\newcommand{\continueonframe}{\PackageError{flowfram}{Can't continue
+to new frame: not in static or dynamic frame}{%
+\string\continueonframe\space may only
+be used inside `staticcontents' or `dynamiccontents' environments
+(of their starred versions)}}
+% \end{macrocode}
+%\end{macro}
+% \cs{@scontinueonframe} and \cs{@continueonframe} are set
+% by \env{staticcontents} and \env{dynamiccontents} environments
+% (and their starred forms).
+%
+% Static starred version uses \gls{idl}
+% \begin{macrocode}
+\newcommand*{\@staticscontinueonframe}[2][]{%
+\ffcontinuedtextlayout{#1}%
+\end{staticcontents*}%
+\begin{staticcontents*}{#2}\par\noindent\ignorespaces}
+% \end{macrocode}
+% Static unstarred version uses \gls{idn}
+% \begin{macrocode}
+\newcommand*{\@staticcontinueonframe}[2][]{%
+\ffcontinuedtextlayout{#1}%
+\end{staticcontents}%
+\begin{staticcontents}{#2}\par\noindent\ignorespaces}
+% \end{macrocode}
+%
+%\begin{macro}{\ffcontinuedtextlayout}
+%Displays the continued text used by \cs{continueonframe}.
+% \begin{macrocode}
+\newcommand{\ffcontinuedtextlayout}[1]{%
+\parfillskip=0pt\par\hfill\ffcontinuedtextfont{#1}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\ffcontinuedtextfont}
+%Sets the font to display the continuation text used by
+%\cs{continueonframe}
+% \begin{macrocode}
+\newcommand*{\ffcontinuedtextfont}[1]{\emph{\small #1}}
+% \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\relax
+ \PackageError{flowfram}{Unknown frame ID type '#1'}{%
+ Frame ID types are: 1 (flow), 2 (static) and 3 (dynamic)}%
+\or
+ \ifnum#2>\c@maxflow\relax
+ \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\relax
+ \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\relax
+ \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}{\@ff@getevendim}
+%\changes{1.11}{2008/06/27}{new}
+% Get the dimensions for the given type of frame on even pages.
+% 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@getevendim}[2]{%
+\ifnum#2<1\relax
+ \PackageError{flowfram}{Frame IDNs start from 1}{%
+ You have specified a frame IDN of '\number#2'}%
+\fi
+\ifcase#1\relax
+ \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}{\flowframeevenx{#2}}%
+ \setlength{\ffareay}{\flowframeeveny{#2}}%
+ \setlength{\ffareawidth}{\flowframewidth{#2}}%
+ \setlength{\ffareaheight}{\flowframeheight{#2}}%
+ \fi
+\or
+ \ifnum#2>\c@maxstatic\relax
+ \PackageError{flowfram}{Invalid static frame IDN '\number#2'}{%
+ Static frame IDNs go from 1 to \number\c@maxstatic}%
+ \else
+ \setlength{\ffareax}{\staticframeevenx{#2}}%
+ \setlength{\ffareay}{\staticframeeveny{#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\relax
+ \PackageError{flowfram}{Invalid dynamic frame IDN '\number#2'}{%
+ Dynamic frame IDNs go from 1 to \number\c@maxdynamic}%
+ \else
+ \setlength{\ffareax}{\dynamicframeevenx{#2}}%
+ \setlength{\ffareay}{\dynamicframeeveny{#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}):
+%\changes{1.11}{2008/06/27}{fixed bug: changed frame id from
+% 1 to 2 (thanks to Lutz Goldmann for pointing it out)}
+% \begin{macrocode}
+\newcommand*{\@getstaticbounds}[1]{\@ff@getdim{2}{#1}}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\getstaticevenbounds}
+%\changes{1.11}{2008/06/27}{new}
+% Even pages
+% \begin{macrocode}
+\newcommand*{\getstaticevenbounds}{%
+\@ifstar\@sgetstaticevenbounds\@getstaticevenbounds}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@sgetstaticevenbounds}
+% Starred version (specify by \gls{idl}):
+% \begin{macrocode}
+\newcommand*{\@sgetstaticevenbounds}[1]{%
+\@staticframeid{#1}\@getstaticevenbounds{\ff@id}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@getstaticevenbounds}
+%\changes{1.11}{2008/06/27}{new}
+% Unstarred version (specify by \gls{idn}):
+% \begin{macrocode}
+\newcommand*{\@getstaticevenbounds}[1]{\@ff@getevendim{2}{#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}):
+%\changes{1.11}{2008/06/27}{fixed bug: changed frame id from
+% 2 to 1 (thanks to Lutz Goldmann for pointing it out)}
+% \begin{macrocode}
+\newcommand*{\@getflowbounds}[1]{\@ff@getdim{1}{#1}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\getflowevenbounds}
+%\changes{1.11}{2008/06/27}{new}
+% Even pages:
+% \begin{macrocode}
+\newcommand*{\getflowevenbounds}{%
+\@ifstar\@sgetflowevenbounds\@getflowevenbounds}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@sgetflowevenbounds}
+%\changes{1.11}{2008/06/27}{new}
+% Starred version (specify by \gls{idl}):
+% \begin{macrocode}
+\newcommand*{\@sgetflowevenbounds}[1]{%
+\@flowframeid{#1}\@getflowevenbounds{\ff@id}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@getflowevenbounds}
+%\changes{1.11}{2008/06/27}{new}
+% Unstarred version (specify by \gls{idn}):
+% \begin{macrocode}
+\newcommand*{\@getflowevenbounds}[1]{\@ff@getevendim{1}{#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}
+%
+%\begin{macro}{\getdynamicevenbounds}
+% Even pages:
+% \begin{macrocode}
+\newcommand*{\getdynamicevenbounds}{%
+\@ifstar\@sgetdynamicevenbounds\@getdynamicevenbounds}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@sgetdynamicevenbounds}
+% Starred version (specify by \gls{idl}):
+% \begin{macrocode}
+\newcommand*{\@sgetdynamicevenbounds}[1]{%
+\@dynamicframeid{#1}\@getdynamicevenbounds{\ff@id}}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@getdynamicevenbounds}
+% Unstarred version (specify by \gls{idn}):
+% \begin{macrocode}
+\newcommand*{\@getdynamicevenbounds}[1]{\@ff@getevendim{3}{#1}}
+% \end{macrocode}
+%\end{macro}
+%
+% \subsection{Determining the relative location of one frame from
+% another}
+%\changes{1.11}{2008/06/27}{added relative location commands}
+% The commands in this section set the following boolean variables:
+% \begin{macrocode}
+\newif\ifFLFabove
+\newif\ifFLFbelow
+\newif\ifFLFleft
+\newif\ifFLFright
+% \end{macrocode}
+% These can then be used after one of the \cs{checkifframe}\meta{loc}
+% commands defined below. For example:
+%\begin{verbatim}
+%\checkifframeabove{static}{1}{flow}{1}
+%\ifFLFabove
+% Static frame is above flow frame.
+%\else
+% Static frame isn't above flow frame.
+%\fi
+%\end{verbatim}
+%
+%\begin{macro}{\checkifframeabove}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{checkifframeabove}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+%
+% Checks if the first frame is above the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2}. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be above the
+% second frame if they overlap. This code checks the page number to
+% determine whether to use \cs{oddcheckifframeabove} or
+% \cs{evencheckifframeabove} so it should not be used in the
+% first paragraph of the first \gls{flow} on the page if the paragraph
+% spans the page break.
+% \begin{macrocode}
+\newcommand*{\checkifframeabove}{%
+\@ifstar\@scheckifframeabove\@checkifframeabove}
+% \end{macrocode}
+% Starred version:
+% \begin{macrocode}
+\newcommand*{\@scheckifframeabove}[4]{%
+\ifodd\c@page
+ \@soddcheckifframeabove{#1}{#2}{#3}{#4}%
+\else
+ \@sevencheckifframeabove{#1}{#2}{#3}{#4}%
+\fi}
+% \end{macrocode}
+% Unstarred version:
+% \begin{macrocode}
+\newcommand*{\@checkifframeabove}[4]{%
+\ifodd\c@page
+ \@oddcheckifframeabove{#1}{#2}{#3}{#4}%
+\else
+ \@evencheckifframeabove{#1}{#2}{#3}{#4}%
+\fi}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\oddcheckifframeabove}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{oddcheckifframeabove}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+% Checks if the first frame is above the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2} for odd pages. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be above the
+% second frame if they overlap.
+% \begin{macrocode}
+\newcommand*{\oddcheckifframeabove}{%
+\@ifstar\@soddcheckifframeabove\@oddcheckifframeabove}
+% \end{macrocode}
+% The starred version
+% \begin{macrocode}
+\newcommand*{\@soddcheckifframeabove}[4]{%
+\@ifundefined{@sget#1bounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#1bounds\endcsname{#2}%
+\edef\@ff@check{\the\ffareay}%
+\@ifundefined{@sget#3bounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#3bounds\endcsname{#4}%
+\advance\ffareay by \ffareaheight\relax
+\expandafter\ifdim\@ff@check>\ffareay
+ \FLFabovetrue
+\else
+ \FLFabovefalse
+\fi
+}
+% \end{macrocode}
+% The unstarred version
+% \begin{macrocode}
+\newcommand*{\@oddcheckifframeabove}[4]{%
+\@ifundefined{@get#1bounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#1bounds\endcsname{#2}%
+\edef\@ff@check{\the\ffareay}%
+\@ifundefined{@get#3bounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#3bounds\endcsname{#4}%
+\advance\ffareay by \ffareaheight\relax
+\expandafter\ifdim\@ff@check>\ffareay
+ \FLFabovetrue
+\else
+ \FLFabovefalse
+\fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\checkifframebelow}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{checkifframebelow}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+% Checks if the first frame is below the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2}. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be below the
+% second frame if they overlap. This code checks the page number to
+% determine whether to use \cs{oddcheckifframebelow} or
+% \cs{evencheckifframebelow} so it should not be used in the
+% first paragraph of the first \gls{flow} on the page if the paragraph
+% spans the page break.
+% \begin{macrocode}
+\newcommand*{\checkifframebelow}{%
+\@ifstar\@scheckifframebelow\@checkifframebelow}
+% \end{macrocode}
+% Starred version:
+% \begin{macrocode}
+\newcommand*{\@scheckifframebelow}[4]{%
+\ifodd\c@page
+ \@soddcheckifframebelow{#1}{#2}{#3}{#4}%
+\else
+ \@sevencheckifframebelow{#1}{#2}{#3}{#4}%
+\fi}
+% \end{macrocode}
+% Unstarred version:
+% \begin{macrocode}
+\newcommand*{\@checkifframebelow}[4]{%
+\ifodd\c@page
+ \@oddcheckifframebelow{#1}{#2}{#3}{#4}%
+\else
+ \@evencheckifframebelow{#1}{#2}{#3}{#4}%
+\fi}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\oddcheckifframebelow}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{oddcheckifframebelow}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+%
+% Checks if the first frame is below the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2} on odd pages. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be below the
+% second frame if they overlap.
+% \begin{macrocode}
+\newcommand*{\oddcheckifframebelow}{%
+\@ifstar\@soddcheckifframebelow\@oddcheckifframebelow}
+% \end{macrocode}
+% The starred version
+% \begin{macrocode}
+\newcommand*{\@soddcheckifframebelow}[4]{%
+\@ifundefined{@sget#1bounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#1bounds\endcsname{#2}%
+\advance\ffareay by \ffareaheight\relax
+\edef\@ff@check{\the\ffareay}%
+\@ifundefined{@sget#3bounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#3bounds\endcsname{#4}%
+\expandafter\ifdim\@ff@check<\ffareay
+ \FLFbelowtrue
+\else
+ \FLFbelowfalse
+\fi
+}
+% \end{macrocode}
+% The unstarred version
+% \begin{macrocode}
+\newcommand*{\@oddcheckifframebelow}[4]{%
+\@ifundefined{@get#1bounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#1bounds\endcsname{#2}%
+\advance\ffareay by \ffareaheight\relax
+\edef\@ff@check{\the\ffareay}%
+\@ifundefined{@get#3bounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#3bounds\endcsname{#4}%
+\expandafter\ifdim\@ff@check<\ffareay
+ \FLFbelowtrue
+\else
+ \FLFbelowfalse
+\fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\checkifframeleft}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{checkifframeleft}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+% Checks if the first frame is to the left of the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2}. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be to the
+% left of the second frame if they overlap. This code checks the page number to
+% determine whether to use \cs{oddcheckifframeleft} or
+% \cs{evencheckifframeleft} so it should not be used in the
+% first paragraph of the first \gls{flow} on the page if the paragraph
+% spans the page break.
+% \begin{macrocode}
+\newcommand*{\checkifframeleft}{%
+\@ifstar\@scheckifframeleft\@checkifframeleft}
+% \end{macrocode}
+% Starred version:
+% \begin{macrocode}
+\newcommand*{\@scheckifframeleft}[4]{%
+\ifodd\c@page
+ \@soddcheckifframeleft{#1}{#2}{#3}{#4}%
+\else
+ \@sevencheckifframeleft{#1}{#2}{#3}{#4}%
+\fi}
+% \end{macrocode}
+% Unstarred version:
+% \begin{macrocode}
+\newcommand*{\@checkifframeleft}[4]{%
+\ifodd\c@page
+ \@oddcheckifframeleft{#1}{#2}{#3}{#4}%
+\else
+ \@evencheckifframeleft{#1}{#2}{#3}{#4}%
+\fi}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\oddcheckifframeleft}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{oddcheckifframeleft}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+%
+% Checks if the first frame is to the left of the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2} on odd pages. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be to the
+% left of the second frame if they overlap.
+% \begin{macrocode}
+\newcommand*{\oddcheckifframeleft}{%
+\@ifstar\@soddcheckifframeleft\@oddcheckifframeleft}
+% \end{macrocode}
+% The starred version
+% \begin{macrocode}
+\newcommand*{\@soddcheckifframeleft}[4]{%
+\@ifundefined{@sget#1bounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#1bounds\endcsname{#2}%
+\advance\ffareax by \ffareawidth\relax
+\edef\@ff@check{\the\ffareax}%
+\@ifundefined{@sget#3bounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#3bounds\endcsname{#4}%
+\expandafter\ifdim\@ff@check<\ffareax
+ \FLFlefttrue
+\else
+ \FLFleftfalse
+\fi
+}
+% \end{macrocode}
+% The unstarred version
+% \begin{macrocode}
+\newcommand*{\@oddcheckifframeleft}[4]{%
+\@ifundefined{@get#1bounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#1bounds\endcsname{#2}%
+\advance\ffareax by \ffareawidth\relax
+\edef\@ff@check{\the\ffareax}%
+\@ifundefined{@get#3bounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#3bounds\endcsname{#4}%
+\expandafter\ifdim\@ff@check<\ffareax
+ \FLFlefttrue
+\else
+ \FLFleftfalse
+\fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\checkifframeright}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{checkifframeright}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+% Checks if the first frame is to the right of the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2}. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be to the
+% right of the second frame if they overlap. This code checks the page number to
+% determine whether to use \cs{oddcheckifframeright} or
+% \cs{evencheckifframeright} so it should not be used in the
+% first paragraph of the first \gls{flow} on the page if the paragraph
+% spans the page break.
+% \begin{macrocode}
+\newcommand*{\checkifframeright}{%
+\@ifstar\@scheckifframeright\@checkifframeright}
+% \end{macrocode}
+% Starred version:
+% \begin{macrocode}
+\newcommand*{\@scheckifframeright}[4]{%
+\ifodd\c@page
+ \@soddcheckifframeright{#1}{#2}{#3}{#4}%
+\else
+ \@sevencheckifframeright{#1}{#2}{#3}{#4}%
+\fi}
+% \end{macrocode}
+% Unstarred version:
+% \begin{macrocode}
+\newcommand*{\@checkifframeright}[4]{%
+\ifodd\c@page
+ \@oddcheckifframeright{#1}{#2}{#3}{#4}%
+\else
+ \@evencheckifframeright{#1}{#2}{#3}{#4}%
+\fi}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\oddcheckifframeright}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{oddcheckifframeright}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+%
+% Checks if the first frame is to the right of the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2} on odd pages. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be to the
+% right of the second frame if they overlap.
+% \begin{macrocode}
+\newcommand*{\oddcheckifframeright}{%
+\@ifstar\@soddcheckifframeright\@oddcheckifframeright}
+% \end{macrocode}
+% The starred version
+% \begin{macrocode}
+\newcommand*{\@soddcheckifframeright}[4]{%
+\@ifundefined{@sget#1bounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#1bounds\endcsname{#2}%
+\edef\@ff@check{\the\ffareax}%
+\@ifundefined{@sget#3bounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#3bounds\endcsname{#4}%
+\advance\ffareax by \ffareawidth\relax
+\expandafter\ifdim\@ff@check>\ffareax
+ \FLFrighttrue
+\else
+ \FLFrightfalse
+\fi
+}
+% \end{macrocode}
+% The unstarred version
+% \begin{macrocode}
+\newcommand*{\@oddcheckifframeright}[4]{%
+\@ifundefined{@get#1bounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#1bounds\endcsname{#2}%
+\edef\@ff@check{\the\ffareax}%
+\@ifundefined{@get#3bounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#3bounds\endcsname{#4}%
+\advance\ffareax by \ffareawidth\relax
+\expandafter\ifdim\@ff@check>\ffareax
+ \FLFrighttrue
+\else
+ \FLFrightfalse
+\fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\evencheckifframeabove}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{evencheckifframeabove}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+% Checks if the first frame is above the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2} for even pages.
+% The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be above the
+% second frame if they overlap.
+% \begin{macrocode}
+\newcommand*{\evencheckifframeabove}{%
+\@ifstar\@sevencheckifframeabove\@evencheckifframeabove}
+% \end{macrocode}
+% The starred version
+% \begin{macrocode}
+\newcommand*{\@sevencheckifframeabove}[4]{%
+\@ifundefined{@sget#1evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#1evenbounds\endcsname{#2}%
+\edef\@ff@check{\the\ffareay}%
+\@ifundefined{@sget#3evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#3evenbounds\endcsname{#4}%
+\advance\ffareay by \ffareaheight\relax
+\expandafter\ifdim\@ff@check>\ffareay
+ \FLFabovetrue
+\else
+ \FLFabovefalse
+\fi
+}
+% \end{macrocode}
+% The unstarred version
+% \begin{macrocode}
+\newcommand*{\@evencheckifframeabove}[4]{%
+\@ifundefined{@get#1evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#1evenbounds\endcsname{#2}%
+\edef\@ff@check{\the\ffareay}%
+\@ifundefined{@get#3evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#3evenbounds\endcsname{#4}%
+\advance\ffareay by \ffareaheight\relax
+\expandafter\ifdim\@ff@check>\ffareay
+ \FLFabovetrue
+\else
+ \FLFabovefalse
+\fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\evencheckifframebelow}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{checkifframebelow}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+% Checks if the first frame is below the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2}. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be below the
+% second frame if they overlap.
+% \begin{macrocode}
+\newcommand*{\evencheckifframebelow}{%
+\@ifstar\@sevencheckifframebelow\@evencheckifframebelow}
+% \end{macrocode}
+% The starred version
+% \begin{macrocode}
+\newcommand*{\@sevencheckifframebelow}[4]{%
+\@ifundefined{@sget#1evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#1evenbounds\endcsname{#2}%
+\advance\ffareay by \ffareaheight\relax
+\edef\@ff@check{\the\ffareay}%
+\@ifundefined{@sget#3evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#3evenbounds\endcsname{#4}%
+\expandafter\ifdim\@ff@check<\ffareay
+ \FLFbelowtrue
+\else
+ \FLFbelowfalse
+\fi
+}
+% \end{macrocode}
+% The unstarred version
+% \begin{macrocode}
+\newcommand*{\@evencheckifframebelow}[4]{%
+\@ifundefined{@get#1evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#1evenbounds\endcsname{#2}%
+\advance\ffareay by \ffareaheight\relax
+\edef\@ff@check{\the\ffareay}%
+\@ifundefined{@get#3evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#3evenbounds\endcsname{#4}%
+\expandafter\ifdim\@ff@check<\ffareay
+ \FLFbelowtrue
+\else
+ \FLFbelowfalse
+\fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\evencheckifframeleft}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{evencheckifframeleft}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+% Checks if the first frame is to the left of the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2}. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be to the
+% left of the second frame if they overlap.
+% \begin{macrocode}
+\newcommand*{\evencheckifframeleft}{%
+\@ifstar\@sevencheckifframeleft\@evencheckifframeleft}
+% \end{macrocode}
+% The starred version
+% \begin{macrocode}
+\newcommand*{\@sevencheckifframeleft}[4]{%
+\@ifundefined{@sget#1evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#1evenbounds\endcsname{#2}%
+\advance\ffareax by \ffareawidth\relax
+\edef\@ff@check{\the\ffareax}%
+\@ifundefined{@sget#3evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#3evenbounds\endcsname{#4}%
+\expandafter\ifdim\@ff@check<\ffareax
+ \FLFlefttrue
+\else
+ \FLFleftfalse
+\fi
+}
+% \end{macrocode}
+% The unstarred version
+% \begin{macrocode}
+\newcommand*{\@evencheckifframeleft}[4]{%
+\@ifundefined{@get#1evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#1evenbounds\endcsname{#2}%
+\advance\ffareax by \ffareawidth\relax
+\edef\@ff@check{\the\ffareax}%
+\@ifundefined{@get#3evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#3evenbounds\endcsname{#4}%
+\expandafter\ifdim\@ff@check<\ffareax
+ \FLFlefttrue
+\else
+ \FLFleftfalse
+\fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\evencheckifframeright}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{evencheckifframeright}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+% Checks if the first frame is to the right of the second frame where the
+% first frame is of type \meta{type1} with \gls{idn} given by
+% \meta{id1} and the second frame is of type \meta{type2} with \gls{idn}
+% given by \meta{id2}. The starred version uses the \gls{idl} instead
+% of the \gls{idn}. The first frame is not considered to be to the
+% right of the second frame if they overlap.
+% \begin{macrocode}
+\newcommand*{\evencheckifframeright}{%
+\@ifstar\@sevencheckifframeright\@evencheckifframeright}
+% \end{macrocode}
+% The starred version
+% \begin{macrocode}
+\newcommand*{\@sevencheckifframeright}[4]{%
+\@ifundefined{@sget#1evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#1evenbounds\endcsname{#2}%
+\edef\@ff@check{\the\ffareax}%
+\@ifundefined{@sget#3evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @sget#3evenbounds\endcsname{#4}%
+\advance\ffareax by \ffareawidth\relax
+\expandafter\ifdim\@ff@check>\ffareax
+ \FLFrighttrue
+\else
+ \FLFrightfalse
+\fi
+}
+% \end{macrocode}
+% The unstarred version
+% \begin{macrocode}
+\newcommand*{\@evencheckifframeright}[4]{%
+\@ifundefined{@get#1evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#1'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#1evenbounds\endcsname{#2}%
+\edef\@ff@check{\the\ffareax}%
+\@ifundefined{@get#3evenbounds}{\PackageError{flowfram}{Unknown frame
+type `#3'}{Frame types may only be one of: static, dynamic or
+flow}}{}%
+\csname @get#3evenbounds\endcsname{#4}%
+\advance\ffareax by \ffareawidth\relax
+\expandafter\ifdim\@ff@check>\ffareax
+ \FLFrighttrue
+\else
+ \FLFrightfalse
+\fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+% Textual labels used to indicate relative location of one frame
+% to another.
+%\begin{macro}{\FFaboveleft}
+%\changes{1.11}{2008/06/27}{new}
+% \begin{macrocode}
+\newcommand*{\FFaboveleft}{above left}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\FFaboveright}
+%\changes{1.11}{2008/06/27}{new}
+% \begin{macrocode}
+\newcommand*{\FFaboveright}{above right}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\FFbelowleft}
+%\changes{1.11}{2008/06/27}{new}
+% \begin{macrocode}
+\newcommand*{\FFbelowleft}{below left}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\FFbelowright}
+%\changes{1.11}{2008/06/27}{new}
+% \begin{macrocode}
+\newcommand*{\FFbelowright}{below right}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\FFleft}
+%\changes{1.11}{2008/06/27}{new}
+% \begin{macrocode}
+\newcommand*{\FFleft}{on the left}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\FFbelowright}
+%\changes{1.11}{2008/06/27}{new}
+% \begin{macrocode}
+\newcommand*{\FFright}{on the right}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\FFabove}
+%\changes{1.11}{2008/06/27}{new}
+% \begin{macrocode}
+\newcommand*{\FFabove}{above}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\FFbelow}
+%\changes{1.11}{2008/06/27}{new}
+% \begin{macrocode}
+\newcommand*{\FFbelow}{below}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\FFoverlap}
+%\changes{1.11}{2008/06/27}{new}
+% \begin{macrocode}
+\newcommand*{\FFoverlap}{overlap}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\relativeframelocation}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{relativeframelocation}\marg{type1}\marg{id1}\marg{type2}\marg{id2}
+% Displays one of the above commands depending on the relative
+% locations of the first frame to the second frame. The arguments
+% \meta{id1} and \meta{id2} refer to the \gls{idn} for the unstarred
+% version and to the \gls{idl} for the starred version.
+% \begin{macrocode}
+\DeclareRobustCommand*{\relativeframelocation}{%
+\@ifstar\@srelativeframelocation\@relativeframelocation}
+% \end{macrocode}
+% Starred version:
+% \begin{macrocode}
+\newcommand*{\@srelativeframelocation}[4]{%
+\@scheckifframeabove{#1}{#2}{#3}{#4}%
+\@scheckifframebelow{#1}{#2}{#3}{#4}%
+\@scheckifframeleft{#1}{#2}{#3}{#4}%
+\@scheckifframeright{#1}{#2}{#3}{#4}%
+\ifFLFabove
+ \ifFLFleft
+ \FFaboveleft
+ \else
+ \ifFLFright
+ \FFaboveright
+ \else
+ \FFabove
+ \fi
+ \fi
+\else
+ \ifFLFbelow
+ \ifFLFleft
+ \FFbelowleft
+ \else
+ \ifFLFright
+ \FFbelowright
+ \else
+ \FFbelow
+ \fi
+ \fi
+ \else
+ \ifFLFleft
+ \FFleft
+ \else
+ \ifFLFright
+ \FFright
+ \else
+ \FFoverlap
+ \fi
+ \fi
+ \fi
+\fi
+}
+% \end{macrocode}
+% Unstarred version:
+% \begin{macrocode}
+\newcommand*{\@relativeframelocation}[4]{%
+\@checkifframeabove{#1}{#2}{#3}{#4}%
+\@checkifframebelow{#1}{#2}{#3}{#4}%
+\@checkifframeleft{#1}{#2}{#3}{#4}%
+\@checkifframeright{#1}{#2}{#3}{#4}%
+\ifFLFabove
+ \ifFLFleft
+ \FFaboveleft
+ \else
+ \ifFLFright
+ \FFaboveright
+ \else
+ \FFabove
+ \fi
+ \fi
+\else
+ \ifFLFbelow
+ \ifFLFleft
+ \FFbelowleft
+ \else
+ \ifFLFright
+ \FFbelowright
+ \else
+ \FFbelow
+ \fi
+ \fi
+ \else
+ \ifFLFleft
+ \FFleft
+ \else
+ \ifFLFright
+ \FFright
+ \else
+ \FFoverlap
+ \fi
+ \fi
+ \fi
+\fi
+}
+% \end{macrocode}
+%\end{macro}
+%
+% Short cut commands for \glspl{frame} of the same type.
+%\begin{macro}{\reldynamicloc}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{reldynamicloc}\marg{id1}\marg{id2}
+% \begin{macrocode}
+\DeclareRobustCommand*{\reldynamicloc}{%
+\@ifstar\@sreldynamicloc\@reldynamicloc}
+% \end{macrocode}
+% Starred version:
+% \begin{macrocode}
+\newcommand*{\@sreldynamicloc}[2]{
+\@srelativeframelocation{dynamic}{#1}{dynamic}{#2}}
+% \end{macrocode}
+% Unstarred version:
+% \begin{macrocode}
+\newcommand*{\@reldynamicloc}[2]{
+\@relativeframelocation{dynamic}{#1}{dynamic}{#2}}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\relstaticloc}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{relstaticloc}\marg{id1}\marg{id2}
+% \begin{macrocode}
+\DeclareRobustCommand*{\relstaticloc}{%
+\@ifstar\@srelstaticloc\@relstaticloc}
+% \end{macrocode}
+% Starred version:
+% \begin{macrocode}
+\newcommand*{\@srelstaticloc}[2]{
+\@srelativeframelocation{static}{#1}{static}{#2}}
+% \end{macrocode}
+% Unstarred version:
+% \begin{macrocode}
+\newcommand*{\@relstaticloc}[2]{
+\@relativeframelocation{static}{#1}{static}{#2}}
+% \end{macrocode}
+%\end{macro}
+%
+%\begin{macro}{\relflowloc}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{relflowloc}\marg{id1}\marg{id2}
+% \begin{macrocode}
+\DeclareRobustCommand*{\relflowloc}{%
+\@ifstar\@srelflowloc\@relflowloc}
+% \end{macrocode}
+% Starred version:
+% \begin{macrocode}
+\newcommand*{\@srelflowloc}[2]{
+\@srelativeframelocation{flow}{#1}{flow}{#2}}
+% \end{macrocode}
+% Unstarred version:
+% \begin{macrocode}
+\newcommand*{\@relflowloc}[2]{
+\@relativeframelocation{flow}{#1}{flow}{#2}}
+% \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.
+%\changes{1.11}{2008/06/27}{added displayedframe increment}
+% \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
+\stepcounter{displayedframe}%
+}
+% \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}%
+ \setcounter{displayedframe}{0}%
+ \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 "\Ncolumntop" 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]{%
+\onecolumnbottominarea[#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{IDN1}\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}{\ffruledeclarations}
+%\changes{1.11}{2008/06/27}{new}
+% This can be redefined to use declarations that affect how the
+% rule appears. For example, it can be used to set the colour of
+% the rule.
+% \begin{macrocode}
+\newcommand*{\ffruledeclarations}{}
+% \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}{%
+\ffruledeclarations
+\ffvrule{#2}{\ffcolumnseprule}{\@ff@staticH}}%
+\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}{\ffvrule}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{ffvrule}\marg{offset}\marg{width}\marg{height}\par
+% Draws the rule for \cs{insertvrule}
+% \begin{macrocode}
+\newcommand*{\ffvrule}[3]{%
+\hfill \rule[-#1]{#2}{#3}\hfill\mbox{}}
+% \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}{%
+\ffruledeclarations
+\ffhrule{#1}{\@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}{\ffhrule}
+%\changes{1.11}{2008/06/27}{new}
+%\cs{ffhrule}\marg{offset}\marg{width}\marg{height}\par
+% Draws the rule for \cs{inserthrule}
+% \begin{macrocode}
+\newcommand*{\ffhrule}[3]{%
+\hspace*{-#1}\rule{#2}{#3}}
+% \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