%\iffalse % flowfram.dtx generated using makedtx version 0.94b (c) Nicola Talbot % Command line args: % -src "flowfram.sty\Z=>flowfram.sty" % -doc "docstub.tex" % -author "Nicola Talbot" % -dir "source" % flowfram % Created on 2007/8/21 13:54 %\fi %\iffalse %<*package> %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z %% Digits \0\1\2\3\4\5\6\7\8\9 %% Exclamation \! Double quote \" Hash (number) \# %% Dollar \$ Percent \% Ampersand \& %% Acute accent \' Left paren \( Right paren \) %% Asterisk \* Plus \+ Comma \, %% Minus \- Point \. Solidus \/ %% Colon \: Semicolon \; Less than \< %% Equals \= Greater than \> Question mark \? %% Commercial at \@ Left bracket \[ Backslash \\ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} % %\fi % \iffalse % Doc-Source file to use with LaTeX2e % Copyright (C) 2007 Nicola Talbot, all rights reserved. % \fi % \iffalse %<*driver> \documentclass{ltxdoc} \CheckSum{8345} \PageIndex \usepackage{url} \usepackage[colorlinks,hyperindex=false, pdfauthor={Nicola L C Talbot}, pdftitle={Documented Source Code for flowfram.sty}]{hyperref} \usepackage[style=altlist,toc,nonumberlist]{glossaries} \newglossary[slg]{secondary}{sgi}{sgo}{Glossary} \renewcommand{\acronymtype}{secondary} \MakeShortVerb" \DeleteShortVerb| \newcommand{\sty}[1]{\textsf{#1}} \newcommand{\env}[1]{\textsf{#1}} \renewcommand{\usage}[1]{\textit{\hyperpage{#1}}} \renewcommand{\main}[1]{\hyperpage{#1}} \newcommand{\see}[2]{\emph{see} #1} \makeatletter \def\index@prologue{\section*{Index} \addcontentsline{toc}{section}{Index}} \makeatother \newglossaryentry{typeblock}{name=typeblock,description={The area of the page where the main body of the text goes. The width and height of this area are given by \cs{textwidth} and \cs{textheight}},type=secondary} \newglossaryentry{flow}{name=flow frame,description={The frames in a document such that the contents of the \env{document} environment flow from one frame to the next in the order that they were defined. There must be at least one flow frame on every page},type=secondary} \newglossaryentry{static}{name=static frame,description={Frames in which text is fixed in place. The contents are fixed until explicitly changed},type=secondary} \newglossaryentry{dynamic}{name=dynamic frame,description={Frames in which text is fixed in place, but the contents are re-typeset after each page},type=secondary} \newglossaryentry{frame}{name=frame,description={A rectangular area of the page in which text can be placed (not to be confused with a frame making command). There are three types: flow, static and dynamic},type=secondary} \newglossaryentry{fcmd}{name=frame making command,description={A \LaTeX\ command which places some kind of border around its argument. For example: \cs{fbox}},type=secondary} \newglossaryentry{pglist}{name=page list,description={A list of pages. This can either be a single keyword: \texttt{all}, \texttt{odd}, \texttt{even} or \texttt{none}, or it can be a comma-separated list of individual page numbers or page ranges. For example: \texttt{\textless3,5,7-11,\textgreater15} indicates pages 1,2,5,7,8,9,10,11 and all pages after page 15. Note that these numbers refer to the actual value of the page counter, not the absolute physical page number}, type=secondary} \newglossaryentry{pgrange}{name=page range,description={Page ranges can be closed, e.g.\ \texttt{5-10}, or open, e.g. \texttt{\textless7} or \texttt{\textgreater9}}, type=secondary} \newglossaryentry{bbox}{name=bounding box,plural=bounding boxes, description={The smallest possible rectangle that completely encompasses the object}, type=secondary} \newacronym[name={identification number (IDN)}, description={A unique number assigned to each frame, which you can use to identify the frame when modifying its appearance. Example: if you have defined 3 flow frames, 2 static frames and 1 dynamic frame, the flow frames will have IDNs 1, 2 and 3, the static frames will have IDNs 1 and 2, and the dynamic frame will have IDN 1}]{idn}{IDN}{identification number} \newacronym[name={identification label (IDL)}, description={A unique label which can be assigned to a frame, enabling you to refer to the frame by label instead of by its IDN}]{idl}{IDL}{identification label} \makeglossaries \begin{document} \DocInput{flowfram.dtx} \end{document} % %\fi %\title{Documented Source Code for flowfram.sty v1.10} %\author{Nicola L. C. Talbot} %\date{20th Aug 2007} %\maketitle % %This is the documented source code for the flowfram package. %For a user manual, see \url{ffuserguide.pdf}. % %\tableofcontents % %\printglossary[type=secondary] % %\StopEventually{\PrintIndex} % % %\section{The Code} %\iffalse % \begin{macrocode} %<*flowfram.sty> % \end{macrocode} %\fi % \subsection{Package Initialisation} % Declare package, and identify it as a \LaTeXe\ package. % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{flowfram}[2007/08/21 v1.10] % \end{macrocode} % Load packages needed by this package % \begin{macrocode} \RequirePackage{ifthen} \RequirePackage{keyval} \RequirePackage{graphics} \RequirePackage{afterpage} \@ifundefined{@ldc@l@r}{\RequirePackage{color}}{} % \end{macrocode} % The colour of the \gls{bbox} borders when the draft % option is specified is given by the commands: % \begin{macrocode} \newcommand{\setffdraftcolor}{\color[gray]{0.8}} \newcommand{\setffdrafttypeblockcolor}{\color[gray]{0.9}} % \end{macrocode} %\begin{macro}{\fflabelsep} % In draft mode, each \gls{bbox} (apart from the one indicating % the \gls{typeblock}), has a label positioned to the right of the % box, at a distance of "\fflabelsep" from the right hand % border.\DescribeMacro{\fflabelsep} % \begin{macrocode} \newlength\fflabelsep \fflabelsep=1pt % \end{macrocode} %\end{macro} %\begin{macro}{\fflabelfont} % The appearance of the label is set by the declaration: % \begin{macrocode} \newcommand*{\fflabelfont}{\small\sffamily} % \end{macrocode} %\end{macro} % The command "\@ffdraft" is used to switch to draft mode. % Allow user the option to show particular types of bounding % boxes. % \begin{macrocode} \newif\ifshowtypeblock \newif\ifshowmargins \newif\ifshowframebbox % \end{macrocode} %\begin{macro}{\@ffdraft} % Set all draft settings. % \begin{macrocode} \newcommand*{\@ffdraft}{% \showtypeblocktrue \showmarginstrue \showframebboxtrue } % \end{macrocode} %\end{macro} %\begin{macro}{\@ffnodraft} % Unset all draft settings. % \begin{macrocode} \newcommand*{\@ffnodraft}{% \showtypeblockfalse \showmarginsfalse \showframebboxfalse } % \end{macrocode} %\end{macro} %\begin{macro}{\@fr@meifdraft} % Draw \gls{bbox}. % \begin{macrocode} \newcommand*{\@fr@meifdraft}[3][\setffdraftcolor]{% \def\ff@backcol{{none}}% \@ifundefined{color}{\frame{#2}}{#1\frame{#2}}% \ifthenelse{\equal{#3}{}}{}{% \makebox[0pt][l]{\hskip\fflabelsep\fflabelfont{[#3]}}}}% % \end{macrocode} %\end{macro} % Colour setting commands, do nothing by default: % \begin{macrocode} \newcommand*{\@s@tffcol}{} \newcommand*{\@s@tfftextcol}{} % \end{macrocode} %\begin{macro}{\@ffbackground} % Deal with \gls{frame} background colour. Note that the background colour only % extends to the limit of the \gls{frame}['s] \gls{bbox}. If you want the background % colour to be flush with the \glspl{frame} border, you will have to create your own % customised border. % \begin{macrocode} \newcommand*{\@ffbackground}[1]{#1} % \end{macrocode} %\end{macro} % Now declare the options. If draft, switch to draft definitions. % \begin{macrocode} \DeclareOption{draft}{\@ffdraft} % \end{macrocode} % If not draft, reset commands so that no \glspl{bbox} % are drawn. % \begin{macrocode} \DeclareOption{final}{\@ffnodraft} % \end{macrocode} %\begin{macro}{\if@ttb@rotate} % Allow provision to prevent rotation in the thumbtabs. % If no rotation, thumbtab text will be stacked vertically. % This will also affect whether or not to rotate \glspl{frame}. % \begin{macrocode} \newif\if@ttb@rotate \@ttb@rotatetrue \DeclareOption{rotate}{\@ttb@rotatetrue} \DeclareOption{norotate}{\@ttb@rotatefalse} % \end{macrocode} %\end{macro} %\begin{macro}{\rotateframe} % Define command that will only rotate box if rotate option % set. % \begin{macrocode} \newcommand{\rotateframe}[2]{\if@ttb@rotate \rotatebox{#1}{#2}% \else #2\relax \fi} % \end{macrocode} %\end{macro} % Should the thumbtabs include number, title, both or % neither? % \begin{macrocode} \newif\if@ttb@num \newif\if@ttb@title \@ttb@numfalse \@ttb@titletrue \DeclareOption{ttbtitle}{\@ttb@titletrue} \DeclareOption{ttbnotitle}{\@ttb@titlefalse} \DeclareOption{ttbnum}{\@ttb@numtrue} \DeclareOption{ttbnonum}{\@ttb@numfalse} % \end{macrocode} % If color option specified, set up the default colours % for the borders and text for all \gls{frame} types. Note that % the colour name has to be grouped within the definition % of "\flowframecol" and "\flowframetextcol". This % was done so that you could do, for example, % "\renewcommand{\flowframecol}{[rgb]{1,1,0}}" so that % you can specify the colour model as well. % The commands "\@s@tffcol" and "\@s@tfftextcol" % switch to the border and text colour, respectively. They % both assume that "\ff@col" has been set to the % relevant colour before use. % \begin{macrocode} \DeclareOption{color}{% \def\flowframecol{{black}}\def\flowframetextcol{{black}} \renewcommand*\@s@tffcol{\ifthenelse{\equal{\ff@col}{}}{}{% \expandafter\color\ff@col}} \renewcommand*\@s@tfftextcol{\ifthenelse{\equal{\ff@txtcol}{}}{}{% \expandafter\color\ff@txtcol}} \renewcommand*{\@ffbackground}[1]{% \ifthenelse{\equal{\ff@backcol}{{none}}}{% #1}{{\fboxsep=0pt\expandafter\colorbox\ff@backcol{#1}}}} } % \end{macrocode} % If nocolor is specified, ensure that the colour changing % commands do nothing. % \begin{macrocode} \DeclareOption{nocolor}{% \def\flowframetextcol{}% \def\flowframecol{}% \renewcommand{\@s@tffcol}{}\renewcommand{\@s@tfftextcol}{} \renewcommand{\@ffbackground}[1]{#1} } % \end{macrocode} % Check to see if the document class has the draft option % set. The easiest way to do this is to check the length % of "\overfullrule" (the marker that indicates overfull % hboxes). % \begin{macrocode} \ifdim\overfullrule=0pt \ExecuteOptions{final} \else \ExecuteOptions{draft} \fi % \end{macrocode} % If the "\normalcolor" command is something other than % "\relax", then implement % the color option as the default, otherwise implement the % nocolor option as the default. % \begin{macrocode} \ifx\normalcolor\relax \ExecuteOptions{nocolor} \else \ExecuteOptions{color} \fi % \end{macrocode} % Now the defaults have all been set, the package options % specified by the user can be processed: % \begin{macrocode} \ProcessOptions % \end{macrocode} % If color option has been specified, but no color % package has been loaded yet, load color.sty % \begin{macrocode} \ifx\normalcolor\relax \ifthenelse{\equal{\flowframetextcol}{}}{}{% \RequirePackage{color}} \fi % \end{macrocode} % User may want a non standard style for the first page of % each chapter, so modify chapter commands to take this into % account.\DescribeMacro{\chapterfirstpagestyle} % \begin{macrocode} \@ifundefined{chapter}{}{% \newcommand*{\chapterfirstpagestyle}{plain} \let\@ff@OLD@chapter\@chapter \let\@ff@OLD@schapter\@schapter \renewcommand{\@chapter}{% \thispagestyle{\chapterfirstpagestyle}\@ff@OLD@chapter} \renewcommand{\@schapter}{% \thispagestyle{\chapterfirstpagestyle}\@ff@OLD@schapter} } % \end{macrocode} % Now get on with the package. First we need to set up % a count register to store the number of \glspl{flow}, and % one to store the id number of the current \gls{flow}: % \begin{macrocode} \newcounter{maxflow} \newcounter{thisframe} \c@maxflow=0\relax \c@thisframe=0\relax % \end{macrocode} % Define a counter to store the total number of \glspl{static}: % \begin{macrocode} \newcounter{maxstatic} \c@maxstatic=0\relax % \end{macrocode} % Define a counter to store the total number of \glspl{dynamic}: % \begin{macrocode} \newcounter{maxdynamic} \c@maxdynamic=0\relax % \end{macrocode} % Define some temporary variables % \begin{macrocode} \newcount\@colN \newcount\@ff@tmpN \newcount\ff@id \newlength\@ff@offset \newlength\@ff@tmp@x \newlength\@ff@tmp@x@even \newlength\@ff@tmp@y % \end{macrocode} %\begin{macro}{\sdfparindent} % Define a length to govern paragraph indentation within % static and dynamic frames. % This is 0pt by default. % \begin{macrocode} \newlength\sdfparindent % \end{macrocode} %\end{macro} % % \subsection{Flow Frames} %\begin{macro}{\flowframesep} % Set up default lengths. The gap between the text and the % border is given by: % \begin{macrocode} \newlength\flowframesep \flowframesep=\fboxsep % \end{macrocode} %\end{macro} %\begin{macro}{\flowframerule} % The width of the frame is given by: % \begin{macrocode} \newlength\flowframerule \flowframerule=\fboxrule % \end{macrocode} %\end{macro} %\begin{macro}{\flowframeshowlayout} % Define command to show page layout. This finishes the current % page, temporarily sets draft mode, and prints an empty page. % Only the \glspl{frame} for that page will be shown. %\DescribeMacro{\flowframeshowlayout} % \begin{macrocode} \newcommand*{\flowframeshowlayout}{% \finishthispage {\@ffdraft\mbox{}\finishthispage\clearpage}} % \end{macrocode} %\end{macro} %\begin{macro}{\framebreak} % If the \glspl{flow} are not all of the same width, the change % in "\hsize" will not come into effect until the end % of the paragraph. Provide a command to simulate a paragraph % break, without making it look as though there is a paragraph. % Provides an optional argument that is passed to % "\pagebreak". Make sure it is grouped to localise % the change in "\parfillskip" and "\parskip". % \begin{macrocode} \newif\ifusedframebreak \newcommand{\framebreak}[1][4]{% \usedframebreaktrue {\parfillskip=0pt\pagebreak[#1]\parskip=0pt\par\noindent}} % \end{macrocode} %\end{macro} %\begin{macro}{\finishthispage} % The commands "\newpage" and % "\pagebreak" can be used to move on to the next % \gls{flow}, but to finish the entire page, use % "\finishthispage". % \begin{macrocode} \newcommand{\finishthispage}{% \@colN=\c@thisframe \newpage \whiledo{\@colN<\c@maxflow}{\advance\@colN by 1\relax \@ff@chckifthispg{\c@page}{\@colN}% \if@notthiscol\else \mbox{}\newpage% \fi }} % \end{macrocode} %\end{macro} %\begin{macro}{\cleardoublepage} % Modify the definition of "\cleardoublepage". This may % or may not be defined so use "\def". % \begin{macrocode} \def\cleardoublepage{\finishthispage \if@twoside \ifodd\c@page \else \hbox{}\finishthispage \fi \fi} % \end{macrocode} %\end{macro} % Disable "@twocolumn" flag, as it makes no sense. % \begin{macrocode} \@twocolumnfalse % \end{macrocode} % Disable "@mparswitch" flag, as each \gls{flow} has % its own predefined margin setting. % \begin{macrocode} \@mparswitchfalse % \end{macrocode} %\begin{macro}{\globalreversemargin} % The margins get switched during the output routine, so % need the effect to be global. % \begin{macrocode} \newcommand{\globalreversemargin}{% \global\@mparbottom\z@\global\@reversemargintrue} \newcommand{\globalnormalmargin}{% \global\@mparbottom\z@\global\@reversemarginfalse} % \end{macrocode} %\end{macro} %\begin{macro}{\@getmarginpos} % Determine whether the margin should be on the right % or left. This depends on the setting, which can either % be "right" or "left" (self explanatory) or "inner" (on the % spine side, so left for odd pages and right for even % pages) or "outer" (on the outside of the page, so right % for odd pages and left for even pages.) When "\@getmarginpos" % is finished, the setting is stored in "\ff@margin". % \begin{macrocode} \newcommand{\@getmarginpos}[1]{% \ifthenelse{\equal{#1}{inner}}{% \if@twoside \ifodd\c@page\def\ff@margin{left}\else\def\ff@margin{right}\fi \else \def\ff@margin{left}% \fi }{% \ifthenelse{\equal{#1}{outer}}{% \if@twoside \ifodd\c@page\def\ff@margin{right}\else\def\ff@margin{left}\fi \else \def\ff@margin{right}% \fi }{% \def\ff@margin{#1}}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\setmargin} % Set the margin for current \gls{flow}. % \begin{macrocode} \newcommand{\setmargin}{% \@getmarginpos{% \csname @ff@margin@\romannumeral\c@thisframe\endcsname}% \ifthenelse{\equal{\ff@margin}{left}}% {\globalreversemargin}{\globalnormalmargin}% } % \end{macrocode} %\end{macro} %\begin{macro}{\newflowframe} % Create a new \gls{flow}. Syntax:\newline % \cs{newflowframe}\oarg{pages}\marg{width}\marg{height}\marg{x}\marg{y}\oarg{label} % % First increment "\c@maxflow", and define boolean % to indicate whether or not the \gls{flow} has a border, % Then check to see whether or not the starred version is % begin used. All the settings must be global: the % output routine will create a new \gls{flow}, if there are no % more defined, and since changes made in the output routine % are localised, the new \gls{frame} will be lost unless it is % globally defined. Flow frames should only be set up in the % preamble, but if there are not enough \glspl{frame} to fit all % the document text, the output routine will create a new \gls{flow}. % So, define "\newflowframe" so that it calls % "\@n@wflowframe" % \begin{macrocode} \newcommand{\newflowframe}{\@n@wflowframe} % \end{macrocode} %\end{macro} % Set the external command for use only in the preamble, an % make the output routine use the internal command % \begin{macrocode} \@onlypreamble{\newflowframe} % \end{macrocode} %\begin{macro}{\@n@wflowframe} % \begin{macrocode} \newcommand{\@n@wflowframe}{% \global\advance\c@maxflow by 1\relax \expandafter\global\expandafter \newif\csname ifcolumnframe\romannumeral\c@maxflow\endcsname \@ifstar\@snewflowframe\@newflowframe } % \end{macrocode} %\end{macro} %\begin{macro}{\@snewflowframe} % Starred version sets boolean flag to indicate a border % \begin{macrocode} \newcommand{\@snewflowframe}{% \expandafter\global\expandafter \let\csname ifcolumnframe\romannumeral\c@maxflow\endcsname\iftrue \@@newflowframe} % \end{macrocode} %\end{macro} %\begin{macro}{\@newflowframe} % The unstarred version unsets boolean flag to indicate % no border. % \begin{macrocode} \newcommand{\@newflowframe}{% \expandafter\global\expandafter \let\csname ifcolumnframe\romannumeral\c@maxflow\endcsname\iffalse \@@newflowframe} % \end{macrocode} %\end{macro} %\begin{macro}{\@@newflowframe} % Now get on with initialising the \gls{flow}. By default, it % will apply the \gls{flow} to all pages, the optional argument % can override this. % \begin{macrocode} \newcommand{\@@newflowframe}[5][all]{% \expandafter\global\expandafter \newbox\csname column\romannumeral\c@maxflow\endcsname \expandafter\global\expandafter \newlength\csname colwidth\romannumeral\c@maxflow\endcsname \expandafter\global\expandafter \newlength\csname colheight\romannumeral\c@maxflow\endcsname \expandafter\global\expandafter \newlength\csname col@\romannumeral\c@maxflow @posx\endcsname \expandafter\global\expandafter \newlength\csname col@\romannumeral\c@maxflow @posy\endcsname \expandafter\global\expandafter \setlength\csname colwidth\romannumeral\c@maxflow\endcsname{#2} \expandafter\global\expandafter \setlength\csname colheight\romannumeral\c@maxflow\endcsname{#3} \expandafter\global\expandafter \setlength\csname col@\romannumeral\c@maxflow @posx\endcsname{#4} \expandafter\global\expandafter \setlength\csname col@\romannumeral\c@maxflow @posy\endcsname{#5} \expandafter\global\expandafter \newlength\csname col@\romannumeral\c@maxflow @evenx\endcsname \expandafter\global\expandafter \newlength\csname col@\romannumeral\c@maxflow @eveny\endcsname \expandafter\global\expandafter \setlength\csname col@\romannumeral\c@maxflow @evenx\endcsname{#4} \expandafter\global\expandafter \setlength\csname col@\romannumeral\c@maxflow @eveny\endcsname{#5} \expandafter \gdef\csname @ff@frametype@\romannumeral\c@maxflow\endcsname{fbox}% \expandafter \gdef\csname @ff@col@\romannumeral\c@maxflow\endcsname{\flowframecol} \expandafter \gdef\csname @ff@txtcol@\romannumeral\c@maxflow\endcsname{% \flowframetextcol} \expandafter \gdef\csname @ff@backcol@\romannumeral\c@maxflow\endcsname{{none}} \expandafter \gdef\csname @ff@pages@\romannumeral\c@maxflow\endcsname{#1} \expandafter \gdef\csname @ff@offset@\romannumeral\c@maxflow\endcsname{compute} \expandafter \gdef\csname @ff@angle@\romannumeral\c@maxflow\endcsname{0}% \expandafter \gdef\csname @ff@margin@\romannumeral\c@maxflow\endcsname{right} \ifnum\c@thisframe=0\relax \ifthenelse{\equal{#1}{all}\TE@or\equal{#1}{odd}}{% \c@thisframe=\c@maxflow \global\setlength{\hsize}{#2}% \global\usedframebreaktrue }{\ifthenelse{\equal{#1}{even}\TE@or\equal{#1}{none}}{}{% \def\ff@pages{#1}% \@for\@ff@pp:=\ff@pages\do{% \def\@ff@numstart{0}\def\@ff@numend{0}% \@ff@getrange{\@ff@pp}% \ifnum\@ff@numstart=0\def\@ff@numstart{1}\fi \ifnum\@ff@numstart=1\relax \c@thisframe=\c@maxflow \global\setlength{\hsize}{#2}% \global\usedframebreaktrue \fi }}}% \fi \@ifnextchar[{\@s@tflowframeid{\c@maxflow}}{% \@s@tflowframeid{\c@maxflow}[\number\c@maxflow]}} % \end{macrocode} %\end{macro} %\begin{macro}{\@s@tflowframeid} % If square brackets occur after "\newflowframe", take % the contents to be the label, otherwise the label will be % the \gls{flow} number. % \begin{macrocode} \def\@s@tflowframeid#1[#2]{% \edef\ff@label{#2}% \@ff@checkuniqueidl{#1}{\ff@label}% \expandafter \xdef\csname @col@id@\romannumeral#1\endcsname{\ff@label}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@checkuniqueidl} % Check \gls{idl} "#2" for \gls{flow} "#1" is unique % \begin{macrocode} \newcommand*{\@ff@checkuniqueidl}[2]{% {\@colN=0\relax \whiledo{\@colN<\c@maxflow}{% \advance\@colN by 1\relax \ifnum\@colN=#1\relax \else \ifthenelse{\equal{#2}{% \csname @col@id@\romannumeral\@colN\endcsname}}{% \PackageError{flowfram}{Flow frame IDL '#2' already defined}{% You can't assign this label, as it is already defined for flow frame \number\@colN}}{}% \fi }}} % \end{macrocode} %\end{macro} %\begin{macro}{\@flowframeid} % Work out the \gls{flow} \gls{idn} from the label. This % iterates through the \glspl{flow}, so if you have a lot of % them it is quicker to identifiy them by their \gls{idn} % rather than their \gls{idl}. % The \gls{idn} stored in "\ff@id". % \begin{macrocode} \newcommand*{\@flowframeid}[1]{\@colN=0\relax \ff@id=0\relax \whiledo{\@colN<\c@maxflow}{\advance\@colN by 1\relax \ifthenelse{% \equal{#1}{\csname @col@id@\romannumeral\@colN\endcsname}}{% \ff@id=\@colN\relax % break out of loop \@colN=\c@maxflow}{}}% \ifnum\ff@id=0\relax \PackageError{flowfram}{Can't find flow frame id '#1'}{}\fi} % \end{macrocode} %\end{macro} % Set up the keys for use with "\setflowframe", % "\setstaticframe" and "\setdynamicframe". % % Frame width is stored in "\ff@width". % \begin{macrocode} \define@key{flowframe}{width}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'width' key}{}}{}% \def\ff@width{#1}} % \end{macrocode} % Frame height is stored in "\ff@height". % \begin{macrocode} \define@key{flowframe}{height}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'height' key}{}}{}% \def\ff@height{#1}} % \end{macrocode} % Frame $x$ co-ordinate (odd and even pages) is stored % in "\ff@x". % \begin{macrocode} \define@key{flowframe}{x}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'x' key}{}}{}% \def\ff@x{#1}} % \end{macrocode} % Frame $y$ co-ordinate (odd and even pages) is stored % in "\ff@y". % \begin{macrocode} \define@key{flowframe}{y}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'y' key}{}}{}% \def\ff@y{#1}} % \end{macrocode} % Frame $x$ co-ordinate (even pages only) is stored % in "\ff@evenx". % \begin{macrocode} \define@key{flowframe}{evenx}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'evenx' key}{}}{}% \def\ff@evenx{#1}} % \end{macrocode} % Frame $y$ co-ordinate (even pages only) is stored in % "\ff@eveny". % \begin{macrocode} \define@key{flowframe}{eveny}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'eveny' key}{}}{}% \def\ff@eveny{#1}} % \end{macrocode} % Frame $x$ co-ordinate (odd pages only if twoside implemented) % is stored in "\ff@oddx". % \begin{macrocode} \define@key{flowframe}{oddx}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'oddx' key}{}}{}% \def\ff@oddx{#1}} % \end{macrocode} % Frame $y$ co-ordinate (odd pages only if twoside implemented) % is stored in "\ff@oddy". % \begin{macrocode} \define@key{flowframe}{oddy}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'oddy' key}{}}{}% \def\ff@oddy{#1}} % \end{macrocode} % New \gls{idl} for \gls{frame} is stored in "\ff@label". % \begin{macrocode} \define@key{flowframe}{label}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'label' key}{}}{}% \def\ff@label{#1}} % \end{macrocode} % Frame border. If "none", define "\ff@frame" as "false", % otherwise define "\ff@frame" as "true". If "plain", define % "\ff@frametype" as "fbox", otherwise define it to be % the specified type, which should be the name of a % \gls{fcmd} without the preceding backslash. % \begin{macrocode} \define@key{flowframe}{border}[plain]{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'border' key - use 'none' for no border}{}}{}% \ifthenelse{\equal{#1}{none}}{% \def\ff@frame{false}}{\def\ff@frame{true}% \ifthenelse{\equal{#1}{plain}}{\def\ff@frametype{fbox}}{% \def\ff@frametype{#1}}}} % \end{macrocode} % Frame's border colour. (This may not work for non-standard % \glspl{fcmd}.) % \begin{macrocode} \define@key{flowframe}{bordercolor}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'bordercolor' key}{}}{}% \def\ff@col{#1}} % \end{macrocode} % Frame's text colour. % \begin{macrocode} \define@key{flowframe}{textcolor}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'textcolor' key}{}}{}% \def\ff@txtcol{#1}} % \end{macrocode} % The background colour of the \gls{frame}. Note this only covers % the region of the \gls{bbox}, not any extra space between % the \gls{bbox} and the border. If you want the background % colour to go right up to the border, you will need to % define your own customised border. % \begin{macrocode} \define@key{flowframe}{backcolor}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'backcolor' key}{}}{}% \def\ff@backcol{#1}} % \end{macrocode} % \Gls{pglist} for which the \gls{frame} should appear. % \begin{macrocode} \define@key{flowframe}{pages}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'pages' key}{}}{}% \def\ff@pages{#1}} % \end{macrocode} % The border takes up extra space, which needs to be % adjusted. This can be done for standard border types, % but non-standard borders may require some help. % \begin{macrocode} \define@key{flowframe}{offset}{\def\ff@offset{#1}% \ifthenelse{\equal{#1}{}}{\PackageError{flowframe}{% Invalid value for key 'offset'}{% 'offset' can either be 'compute' (to compute it according to certain pre-defined rules) or a length}}{}} % \end{macrocode} % Angle to rotate \gls{flow}: % \begin{macrocode} \define@key{flowframe}{angle}{\def\ff@angle{#1}% } % \end{macrocode} % This key is only for \glspl{flow}: % \begin{macrocode} \define@key{flowframe}{margin}{% \ifthenelse{\equal{#1}{left} \or \equal{#1}{right} \or \equal{#1}{inner} \or \equal{#1}{outer}}{% \def\ff@margin{#1}}{\PackageError{flowfram}{invalid value of 'margin' key}{Key 'margin' can only take the values 'left' or 'right'}}} % \end{macrocode} % This key is only for \glspl{static}: % \begin{macrocode} \define@key{flowframe}{clear}[true]{% \ifthenelse{\equal{#1}{true}\or\equal{#1}{false}}{% \def\ff@clear{#1}}{\PackageError{flowfram}{Key 'clear' is boolean}{You can only specify the values 'true' or 'false'}}} % \end{macrocode} % This key is only for \glspl{dynamic}: % \begin{macrocode} \define@key{flowframe}{style}{\ifthenelse{\equal{#1}{}}{% \PackageError{flowfram}{Missing value for 'style' key}{}}{}% \ifthenelse{\equal{#1}{none}}{\def\ff@style{relax}}{\def\ff@style{#1}}} % \end{macrocode} % This key is only for \glspl{static} and \glspl{dynamic}. % \begin{macrocode} \define@key{flowframe}{shape}{\def\ff@shape{#1}% } % \end{macrocode} % This key is only for \glspl{static} and \glspl{dynamic}. % \begin{macrocode} \define@key{flowframe}{valign}{\ifthenelse{\equal{#1}{c} \or \equal{#1}{t} \or \equal{#1}{b}}{\def\ff@valign{#1}}{% \PackageError{flowfram}{Invalid value for 'valign' key}{You may only specify 'c', 't' or 'b'}}} % \end{macrocode} %\begin{macro}{\setallflowframes} % Provide a command to change the settings for all flow % frames. This just iterates through all the \glspl{flow}, % and sets each one in turn. % \begin{macrocode} \newcommand*{\setallflowframes}[1]{% \@colN=0\whiledo{\@colN<\c@maxflow}{\advance\@colN by 1\relax \@@setflowframe{\@colN}{#1}}} % \end{macrocode} %\end{macro} %\begin{macro}{\setflowframe} % Define "\setflowframe" command. Check to see % whether or not the starred version is being used. % \begin{macrocode} \newcommand*{\setflowframe}{\@ifstar\@ssetflowframe\@setflowframe} % \end{macrocode} %\end{macro} %\begin{macro}{\@ssetflowframe} % This is the starred version. It finds the \gls{idn} for % each label in the comma-separated list (first argument), % and applies the setting for that numbered \gls{flow}. % \begin{macrocode} \newcommand{\@ssetflowframe}[2]{% \@for\@ff@id:=#1\do{% \@flowframeid{\@ff@id}% \@@setflowframe{\ff@id}{#2}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@setflowframe} % This is the unstarred version. It iterates through % each \gls{idn} in the comma-separated list passed % as the first argument, but it also checks for number % ranges, and sets the values for that \gls{flow}. Ensures % that number ranges do not lie out of bounds. % \begin{macrocode} \newcommand*{\@setflowframe}[2]{% \ifthenelse{\equal{#1}{all}}{% \setallflowframes{#2}}{% \ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{% \ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}% \whiledo{\@colN<\c@maxflow\TE@or\@colN=\c@maxflow}{% \@@setflowframe{\@colN}{#2}% \advance\@colN by 2\relax}% }{% \@for\@ff@id:=#1\do{% \def\@ff@numstart{0}\def\@ff@numend{10000}% \@ff@getrange{\@ff@id}% \ifnum\@ff@numstart=0\relax \def\@ff@numstart{1}% \fi \ifnum\@ff@numend>\c@maxflow \def\@ff@numend{\c@maxflow}% \fi \@colN=\@ff@numstart \whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{% \@@setflowframe{\@colN}{#2}% \advance\@colN by 1\relax }}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@setflowframe} % This is the command that actually sets the values for % the \gls{flow} whose \gls{idn} is specified by the first % parameter. % \begin{macrocode} \newcommand*{\@@setflowframe}[2]{% \def\ff@frame{}\def\ff@width{}\def\ff@height{}\def\ff@margin{}% \def\ff@x{}\def\ff@y{}\def\ff@frametype{}\def\ff@col{}% \def\ff@valign{}\def\ff@style{}% \def\ff@txtcol{}\def\ff@clear{}\def\ff@offset{}\def\ff@pages{}% \def\ff@label{}\def\ff@backcol{}\def\ff@evenx{}\def\ff@eveny{}% \def\ff@oddx{}\def\ff@oddy{}\def\ff@angle{}\def\ff@shape{\empty}% \setkeys{flowframe}{#2}% \ifthenelse{\equal{\ff@frame}{}}{}{% \setboolean{columnframe\romannumeral#1}{\ff@frame}}% \ifthenelse{\equal{\ff@width}{}}{}{% \expandafter\setlength\csname colwidth\romannumeral#1\endcsname {\ff@width}}% \ifthenelse{\equal{\ff@height}{}}{}{% \expandafter\setlength\csname colheight\romannumeral#1\endcsname {\ff@height}}% \ifthenelse{\equal{\ff@x}{}}{}{% \expandafter\setlength\csname col@\romannumeral#1@posx\endcsname {\ff@x}% \expandafter\setlength\csname col@\romannumeral#1@evenx\endcsname {\ff@x}} \ifthenelse{\equal{\ff@y}{}}{}{% \expandafter\setlength\csname col@\romannumeral#1@posy\endcsname {\ff@y}% \expandafter\setlength\csname col@\romannumeral#1@eveny\endcsname {\ff@y}} \ifthenelse{\equal{\ff@evenx}{}}{}{% \expandafter\setlength\csname col@\romannumeral#1@evenx\endcsname {\ff@evenx}} \ifthenelse{\equal{\ff@eveny}{}}{}{% \expandafter\setlength\csname col@\romannumeral#1@eveny\endcsname {\ff@eveny}} \ifthenelse{\equal{\ff@oddx}{}}{}{% \expandafter\setlength\csname col@\romannumeral#1@posx\endcsname {\ff@oddx}} \ifthenelse{\equal{\ff@oddy}{}}{}{% \expandafter\setlength\csname col@\romannumeral#1@posy\endcsname {\ff@oddy}} \ifthenelse{\equal{\ff@label}{}}{}{% \@s@tflowframeid{#1}[\ff@label]} \ifthenelse{\equal{\ff@frametype}{}}{}{% \expandafter\edef\csname @ff@frametype@\romannumeral#1\endcsname {\ff@frametype}} \ifthenelse{\equal{\ff@col}{}}{}{% \expandafter\@setframecol\ff@col\end{#1}{col}{ff}} \ifthenelse{\equal{\ff@txtcol}{}}{}{% \expandafter\@setframecol\ff@txtcol\end{#1}{txtcol}{ff}}% \ifthenelse{\equal{\ff@backcol}{}}{}{% \expandafter\@setframecol\ff@backcol\end{#1}{backcol}{ff}}% \ifthenelse{\equal{\ff@margin}{}}{}{% \expandafter\xdef\csname @ff@margin@\romannumeral#1\endcsname {\ff@margin}}% \ifthenelse{\equal{\ff@pages}{}}{}{% \expandafter\xdef\csname @ff@pages@\romannumeral#1\endcsname {\ff@pages}}% \ifthenelse{\equal{\ff@offset}{}}{}{% \expandafter\xdef\csname @ff@offset@\romannumeral#1\endcsname {\ff@offset}}% \ifthenelse{\equal{\ff@angle}{}}{}{% \expandafter\xdef\csname @ff@angle@\romannumeral#1\endcsname {\ff@angle}}% \ifthenelse{\equal{\ff@clear}{}}{}{% \PackageError{flowfram}% {Key 'clear' not available for flow frames}{}}% \ifthenelse{\equal{\ff@style}{}}{}{% \PackageError{flowfram}% {Key 'style' not available for flow frames}{}}% \if\ff@shape\empty \else \PackageError{flowfram}% {Key 'shape' not available for flow frames}{}% \fi \ifthenelse{\equal{\ff@valign}{}}{}{% \PackageError{flowfram}% {Key 'valign' not available for flow frames}{}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\ffswapoddeven} % Swap odd and even offsets for a given \gls{flow}. Do the main stuff for % a given \gls{flow} \gls{idn}. % \begin{macrocode} \newcommand*{\@@flowframeswapcoords}[1]{% \setlength{\@ff@tmp@x}% {\csname col@\romannumeral#1@evenx\endcsname} \expandafter\setlength\csname col@\romannumeral#1@evenx\endcsname {\csname col@\romannumeral#1@posx\endcsname}% \expandafter\setlength\csname col@\romannumeral#1@posx\endcsname {\@ff@tmp@x}% \setlength{\@ff@tmp@y}% {\csname col@\romannumeral#1@eveny\endcsname} \expandafter\setlength\csname col@\romannumeral#1@eveny\endcsname {\csname col@\romannumeral#1@posy\endcsname}% \expandafter\setlength\csname col@\romannumeral#1@posy\endcsname {\@ff@tmp@y}% } % \end{macrocode} %\end{macro} %\begin{macro}{\ffswapoddeven} % Allow user to specify \gls{flow} either by \gls{idn} or \gls{idl}: % \begin{macrocode} \newcommand*{\ffswapoddeven}{% \@ifstar\@sflowframeswapcoords\@flowframeswapcoords} % \end{macrocode} %\end{macro} %\begin{macro}{\@sflowframeswapcoords} % Starred form % \begin{macrocode} \newcommand*{\@sflowframeswapcoords}[1]{% \@for\@ff@id:=#1\do{% \@flowframeid{\@ff@id}% \@@flowframeswapcoords{\ff@id}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@flowframeswapcoords} % Unstarred form: % \begin{macrocode} \newcommand*{\@flowframeswapcoords}[1]{% \ifthenelse{\equal{#1}{all}}{% \ff@id=0\relax \whiledo{\ff@id<\c@maxflow}{\advance\ff@id by 1\relax \@@flowframeswapcoords{\ff@id}}% }{% \ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{% \ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}% \whiledo{\@colN<\c@maxflow\TE@or\@colN=\c@maxflow}{% \@@flowframeswapcoords{\@colN}% \advance\@colN by 2\relax}% }{% \@for\@ff@id:=#1\do{% \def\@ff@numstart{0}\def\@ff@numend{10000}% \@ff@getrange{\@ff@id}% \ifnum\@ff@numstart=0\relax \def\@ff@numstart{1}% \fi \ifnum\@ff@numend>\c@maxflow \def\@ff@numend{\c@maxflow}% \fi \@colN=\@ff@numstart \whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{% \@@flowframeswapcoords{\@colN}% \advance\@colN by 1\relax }}}}} % \end{macrocode} %\end{macro} % % Allow user to get the dimensions of \gls{flow} (useful for % \glspl{flow} created using "\Ncolumns" etc.) Only the \gls{idn} can % be used for these commands. %\begin{macro}{\flowframex} % \begin{macrocode} \newcommand*{\flowframex}[1]{% \csname col@\romannumeral#1@posx\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\flowframey} % \begin{macrocode} \newcommand*{\flowframey}[1]{% \csname col@\romannumeral#1@posy\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\flowframeevenx} % \begin{macrocode} \newcommand*{\flowframeevenx}[1]{% \csname col@\romannumeral#1@evenx\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\flowframeeveny} % \begin{macrocode} \newcommand*{\flowframeeveny}[1]{% \csname col@\romannumeral#1@eveny\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\flowframewidth} % \begin{macrocode} \newcommand{\flowframewidth}[1]{% \csname colwidth\romannumeral#1\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\flowframeheight} % \begin{macrocode} \newcommand*{\flowframeheight}[1]{% \csname colheight\romannumeral#1\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\@setframecol} % Set the colour of the frame, this is a little tricky % because the model may need to be specified in square % brackets. First check to see if a colour model has been % specified % \begin{macrocode} \def\@setframecol{\@ifnextchar[\@@setframecol\@@setfr@mecol} % \end{macrocode} %\end{macro} %\begin{macro}{\@@setframecol} % A colour model has been specified. % \begin{macrocode} \def\@@setframecol[#1]#2\end#3#4#5{% \expandafter\edef\csname @#5@#4@\romannumeral#3\endcsname{% [#1]{#2}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@setfr@mecol} % A colour model has not been specified. % \begin{macrocode} \def\@@setfr@mecol#1\end#2#3#4{% \expandafter\edef\csname @#4@#3@\romannumeral#2\endcsname{{#1}}} % \end{macrocode} %\end{macro} % % \subsection{Static Frames} %\begin{macro}{\newstaticframe} % Now deal with setting up the \glspl{static}. This is % similar to the \glspl{flow}, except it has an % associated \LaTeX\ savebox rather than a \TeX\ box. % Syntax:\newline % \cs{newstaticframe}\oarg{pages}\marg{width}\marg{height}\marg{x}\marg{y}\oarg{label}\par % As with "\newflowframe", the final optional argument is % dealt with at the end. % \begin{macrocode} \newcommand*{\newstaticframe}{\@n@wstaticframe} % \end{macrocode} %\end{macro} %\begin{macro}{\@n@wstaticframe} % \begin{macrocode} \newcommand*{\@n@wstaticframe}{% \global\advance\c@maxstatic by 1\relax \newboolean{staticframe\romannumeral\c@maxstatic}% \@ifstar\@snewstaticframe\@newstaticframe } % \end{macrocode} %\end{macro} %\begin{macro}{\@snewstaticframe} % Starred version (has a border): % \begin{macrocode} \newcommand{\@snewstaticframe}{% \setboolean{staticframe\romannumeral\c@maxstatic}{true}% \@@newstaticframe} % \end{macrocode} %\end{macro} %\begin{macro}{\@newstaticframe} % Unstarred version (no border): % \begin{macrocode} \newcommand{\@newstaticframe}{% \setboolean{staticframe\romannumeral\c@maxstatic}{false}% \@@newstaticframe} % \end{macrocode} %\end{macro} %\begin{macro}{\@@newstaticframe} % Now set up the \gls{static}: % \begin{macrocode} \newcommand*{\@@newstaticframe}[5][all]{% \expandafter \newbox\csname @staticframe@\romannumeral\c@maxstatic\endcsname \expandafter \newlength\csname @sf@\romannumeral\c@maxstatic @posx\endcsname \expandafter \newlength\csname @sf@\romannumeral\c@maxstatic @posy\endcsname \expandafter\setlength \csname @sf@\romannumeral\c@maxstatic @posx\endcsname{#4}% \expandafter\setlength \csname @sf@\romannumeral\c@maxstatic @posy\endcsname{#5}% \expandafter\newlength \csname @sf@\romannumeral\c@maxstatic @evenx\endcsname \expandafter\newlength \csname @sf@\romannumeral\c@maxstatic @eveny\endcsname \expandafter\setlength \csname @sf@\romannumeral\c@maxstatic @evenx\endcsname{#4}% \expandafter\setlength \csname @sf@\romannumeral\c@maxstatic @eveny\endcsname{#5}% {\@ff@tmp@x=#2\relax \@ff@tmp@y=#3\relax \expandafter \xdef\csname @sf@dim@\romannumeral\c@maxstatic\endcsname{% [c][\the\@ff@tmp@y][c]{\the\@ff@tmp@x}}}% \expandafter \def\csname @sf@col@\romannumeral\c@maxstatic\endcsname{% \flowframecol}% \expandafter \def\csname @sf@txtcol@\romannumeral\c@maxstatic\endcsname{% \flowframetextcol}% \expandafter \def\csname @sf@backcol@\romannumeral\c@maxstatic\endcsname{% {none}}% \expandafter \xdef\csname @sf@pages@\romannumeral\c@maxstatic\endcsname{#1}% \expandafter \gdef\csname @sf@offset@\romannumeral\c@maxstatic\endcsname{% compute}% \expandafter \gdef\csname @sf@angle@\romannumeral\c@maxstatic\endcsname{0}% \expandafter \gdef\csname @sf@shape@\romannumeral\c@maxstatic\endcsname{\relax}% \expandafter \def\csname @sf@frametype@\romannumeral\c@maxstatic\endcsname{% fbox}% \newboolean{@sf@clear@\romannumeral\c@maxstatic}% \setboolean{@sf@clear@\romannumeral\c@maxstatic}{false} \@ifnextchar[{\@s@tstaticframeid{\c@maxstatic}}% {\@s@tstaticframeid{\c@maxstatic}[\number\c@maxstatic]}} % \end{macrocode} %\end{macro} %\begin{macro}{\@s@tstaticframeid} % Set the label for the \gls{static}: % \begin{macrocode} \def\@s@tstaticframeid#1[#2]{% \edef\ff@label{#2}% \@sf@checkuniqueidl{#1}{\ff@label}% \expandafter \xdef\csname @sf@id@\romannumeral#1\endcsname{\ff@label}} % \end{macrocode} %\end{macro} %\begin{macro}{\@sf@checkuniqueidl} % Check \gls{idl} "#2" for \gls{static} "#1" is unique % \begin{macrocode} \newcommand*{\@sf@checkuniqueidl}[2]{% \@colN=0\relax \whiledo{\@colN<\c@maxstatic}{% \advance\@colN by 1\relax \ifnum\@colN=#1\relax \else \ifthenelse{% \equal{#2}{\csname @sf@id@\romannumeral\@colN\endcsname}}{% \PackageError{flowfram}{Static frame IDL '#2' already defined}{% You can't assign this label, as it is already defined for static frame \number\@colN}}{}% \fi }} % \end{macrocode} %\end{macro} %\begin{macro}{\@staticframeid} % Work out the \gls{idn} of the \gls{static} with the % given label. This iterates through each \gls{static}, % so if there are a lot of \glspl{static}, it may take a while. % The \gls{idn} stored in "\ff@id". % \begin{macrocode} \newcommand*{\@staticframeid}[1]{\@colN=0\relax \ff@id=0\relax \whiledo{\@colN<\c@maxstatic}{\advance\@colN by 1\relax \ifthenelse{% \equal{#1}{\csname @sf@id@\romannumeral\@colN\endcsname}}{% \ff@id=\@colN\relax % break out of loop \@colN=\c@maxstatic}{}}% \ifnum\ff@id=0\PackageError{flowfram}{Can't find static frame id '#1'}{}\fi} % \end{macrocode} %\end{macro} % % Make it easier to get the x and y values for static % frames. (Width and height stored differently.) %\begin{macro}{\staticframex} % \begin{macrocode} \newcommand*{\staticframex}[1]{% \csname @sf@\romannumeral#1@posx\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\staticframey} % \begin{macrocode} \newcommand*{\staticframey}[1]{% \csname @sf@\romannumeral#1@posy\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\staticframeevenx} % \begin{macrocode} \newcommand*{\staticframeevenx}[1]{% \csname @sf@\romannumeral#1@evenx\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\staticframeeveny} % \begin{macrocode} \newcommand*{\staticframeeveny}[1]{% \csname @sf@\romannumeral#1@eveny\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\setallstaticframes} % Modify the settings for all the \glspl{static}: % \begin{macrocode} \newcommand*{\setallstaticframes}[1]{% \@colN=0\whiledo{\@colN<\c@maxstatic}{\advance\@colN by 1\relax \@@setstaticframe{\@colN}{#1}}} % \end{macrocode} %\end{macro} %\begin{macro}{\setstaticframe} % Modify the settings for the specified \glspl{static}: % \begin{macrocode} \newcommand*{\setstaticframe}{% \@ifstar\@ssetstaticframe\@setstaticframe} % \end{macrocode} %\end{macro} %\begin{macro}{\@ssetstaticframe} % Starred version: Iterate through the comma-separated % list of labels. % \begin{macrocode} \newcommand*{\@ssetstaticframe}[2]{% \@for\@ff@id:=#1\do{% \@staticframeid{\@ff@id}% \@@setstaticframe{\ff@id}{#2}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@setstaticframe} % Unstarred version. Iterate through the comma-separated % list of \glspl{idn}, and check for number ranges. % Ensures that number ranges do not lie out of bounds. % \begin{macrocode} \newcommand*{\@setstaticframe}[2]{% \ifthenelse{\equal{#1}{all}}{% \setallstaticframes{#2}}{% \ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{% \ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}% \whiledo{\@colN<\c@maxstatic\TE@or\@colN=\c@maxstatic}{% \@@setstaticframe{\@colN}{#2}% \advance\@colN by 2\relax}% }{% \@for\@ff@id:=#1\do{% \def\@ff@numstart{0}\def\@ff@numend{10000}% \@ff@getrange{\@ff@id}% \ifnum\@ff@numstart=0\relax \def\@ff@numstart{1}% \fi \ifnum\@ff@numend>\c@maxstatic \def\@ff@numend{\c@maxstatic}% \fi \@colN=\@ff@numstart \whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{% \@@setstaticframe{\@colN}{#2}% \advance\@colN by 1\relax }}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@setstaticframe} % Modify the settings for the \gls{static} whose \gls{idn}\ % is given by the first argument. % \begin{macrocode} \newcommand*{\@@setstaticframe}[2]{% \expandafter\expandafter\expandafter \@ff@getstaticpos\csname @sf@dim@\romannumeral#1\endcsname \def\ff@frame{}\edef\ff@width{\the\@ff@tmp@x}\def\ff@angle{}% \edef\ff@height{\the\@ff@tmp@y}\def\ff@style{}\def\ff@frametype{}% \def\ff@x{}\def\ff@y{}\def\ff@col{}\def\ff@txtcol{}% \def\ff@backcol{}\def\ff@shape{0}% \def\ff@clear{}\def\ff@margin{}\def\ff@offset{}\def\ff@pages{}% \def\ff@label{}\def\ff@evenx{}\def\ff@eveny{}% \def\ff@oddx{}\def\ff@oddy{}% \setkeys{flowframe}{#2}% \ifthenelse{\equal{\ff@frame}{}}{}{% \setboolean{staticframe\romannumeral#1}{\ff@frame}}% \ifthenelse{\equal{\ff@x}{}}{}{% \expandafter\global \expandafter\setlength\csname @sf@\romannumeral#1@posx\endcsname {\ff@x}% \expandafter\global \expandafter\setlength\csname @sf@\romannumeral#1@evenx\endcsname {\ff@x}}% \ifthenelse{\equal{\ff@y}{}}{}{% \expandafter\global \expandafter\setlength\csname @sf@\romannumeral#1@posy\endcsname {\ff@y}% \expandafter\global \expandafter\setlength\csname @sf@\romannumeral#1@eveny\endcsname {\ff@y}}% \ifthenelse{\equal{\ff@evenx}{}}{}{% \expandafter\global \expandafter\setlength\csname @sf@\romannumeral#1@evenx\endcsname {\ff@evenx}}% \ifthenelse{\equal{\ff@eveny}{}}{}{% \expandafter\global \expandafter\setlength\csname @sf@\romannumeral#1@eveny\endcsname {\ff@eveny}}% \ifthenelse{\equal{\ff@oddx}{}}{}{% \expandafter\global \expandafter\setlength\csname @sf@\romannumeral#1@posx\endcsname {\ff@oddx}}% \ifthenelse{\equal{\ff@oddy}{}}{}{% \expandafter\global \expandafter\setlength\csname @sf@\romannumeral#1@posy\endcsname {\ff@oddy}}% \expandafter \xdef\csname @sf@dim@\romannumeral#1\endcsname{% [c][\ff@height][\ff@valign]{\ff@width}}% \ifthenelse{\equal{\ff@frametype}{}}{}{% \expandafter \xdef\csname @sf@frametype@\romannumeral#1\endcsname{% \ff@frametype}}% \ifthenelse{\equal{\ff@label}{}}{}{% \@s@tstaticframeid{#1}[\ff@label]} \ifthenelse{\equal{\ff@col}{}}{}{% \expandafter\@setframecol\ff@col\end{#1}{col}{sf}}% \ifthenelse{\equal{\ff@txtcol}{}}{}{% \expandafter\@setframecol\ff@txtcol\end{#1}{txtcol}{sf}}% \ifthenelse{\equal{\ff@backcol}{}}{}{% \expandafter\@setframecol\ff@backcol\end{#1}{backcol}{sf}}% \ifthenelse{\equal{\ff@offset}{}}{}{% \expandafter \xdef\csname @sf@offset@\romannumeral#1\endcsname{\ff@offset}}% \ifthenelse{\equal{\ff@angle}{}}{}{% \expandafter \xdef\csname @sf@angle@\romannumeral#1\endcsname{\ff@angle}}% \if0\ff@shape \else \expandafter\global\expandafter \let\csname @sf@shape@\romannumeral#1\endcsname\ff@shape \fi \ifthenelse{\equal{\ff@pages}{}}{}{% \expandafter \xdef\csname @sf@pages@\romannumeral#1\endcsname{\ff@pages}}% \ifthenelse{\equal{\ff@clear}{}}{}{% \setboolean{@sf@clear@\romannumeral#1}{\ff@clear}}% \ifthenelse{\equal{\ff@margin}{}}{}{% \PackageError{flowfram}{Key 'margin' not available for static frames}{Static frames don't have marginal notes}}% \ifthenelse{\equal{\ff@style}{}}{}{% \PackageError{flowfram}{Key 'style' not available for static frames}{}}% } % \end{macrocode} %\end{macro} % %\begin{macro}{\simpar} % Simulate paragraph break inside "\shapepar" % \begin{macrocode} %\newcommand*{\simpar}{\hfil\vadjust{\vskip\parskip}\break\indent} \newcommand*{\simpar}{\hfill\\\indent\mbox{}} % \end{macrocode} %\end{macro} %\begin{macro}{\ffpshpar} % Provide means to allow parshape to be carried over a paragraph % break. % \begin{macrocode} \let\FLForgpar\par \newcommand{\ffpshpar}{\edef\flf@next{\hangafter=\the\hangafter \hangindent=\the\hangindent}\FLForgpar\flf@next \edef\flf@next{\prevgraf=\the\prevgraf}\@ff@parshape\indent\mbox{}\flf@next} % \end{macrocode} %\end{macro} % % Provide a means to have section headings within "\parshape". %\begin{macro}{\@ff@parshape} % \begin{macrocode} \def\@ff@parshape{\parshape=0} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@sectionhead} % \begin{macrocode} \newcommand*{\@ff@sectionhead}[1]{% \def\ff@sechead{#1}% \ffpshpar \@ifstar{\@s@ff@heading}{\@dblarg\@ff@heading}} % \end{macrocode} %\end{macro} %\begin{macro}{\@s@ff@heading} % \begin{macrocode} \def\@s@ff@heading#1{% \@ifundefined{@ff@old\ff@sechead}{\PackageError{flowfram}{Unknown heading command '\ff@sechead'}{}}{% \begingroup \edef\flf@next{\hangafter=\the\hangafter \hangindent=\the\hangindent}\FLForgpar\flf@next \let\par=\FLForgpar \edef\flf@next{\prevgraf=\the\prevgraf}% \csname @ff@old\ff@sechead\endcsname*{\@ff@parshape\flf@next #1}% \xdef\flf@next{\@ff@parshape \prevgraf=\the\prevgraf}% \endgroup }% \mbox{}\flf@next\let\flf@next\undefined} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@heading} % \begin{macrocode} \def\@ff@heading[#1]#2{% \@ifundefined{@ff@old\ff@sechead}{\PackageError{flowfram}{Unknown heading command '\ff@sechead'}{}}{% \begingroup \edef\flf@next{\hangafter=\the\hangafter \hangindent=\the\hangindent}\FLForgpar\flf@next \let\par=\FLForgpar \edef\flf@next{\prevgraf=\the\prevgraf}% \csname @ff@old\ff@sechead\endcsname[#1]{\@ff@parshape\flf@next #2}% \xdef\flf@next{\@ff@parshape \prevgraf=\the\prevgraf}% \endgroup}% \mbox{}\flf@next\let\flf@next\undefined} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@setsecthead} % Define command to switch to adjusted section headings: % \begin{macrocode} \newcommand*{\@ff@setsecthead}{% \let\@ff@oldsection=\section \let\@ff@oldsubsection=\subsection \let\@ff@oldsubsubsection=\subsubsection \let\@ff@oldparagraph=\paragraph \let\@ff@oldsubparagraph=\subparagraph \def\section{\@ff@sectionhead{section}}% \def\subsection{\@ff@sectionhead{subsection}}% \def\subsubsection{\@ff@sectionhead{subsubsection}}% \def\paragraph{\@ff@sectionhead{paragraph}}% \def\subparagraph{\@ff@sectionhead{subparagraph}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@getshape} % Determine what shape command is being used: % \begin{macrocode} \def\@ff@getshape#1#2\relax{% \ifx#1\parshape \def\ff@shape{1}% \else \ifx#1\shapepar \def\ff@shape{2}% \else \ifx#1\relax \def\ff@shape{0}% \else \PackageError{flowfram}{Unknown shape \string#1}{}% \def\ff@shape{2}% \fi \fi \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@disablesec} % Disable sectioning commands % \begin{macrocode} \newcommand*{\@ff@disablesec}{% \def\section{\PackageError{flowfram}{You can't have sectioning commands within a \string\shapepar}{}}% \def\subsection{\PackageError{flowfram}{You can't have sectioning commands within a \string\shapepar}{}}% \def\subsubsection{\PackageError{flowfram}{You can't have sectioning commands within a \string\shapepar}{}}% \def\paragraph{\PackageError{flowfram}{You can't have sectioning commands within a \string\shapepar}{}}% \def\subparagraph{\PackageError{flowfram}{You can't have sectioning commands within a \string\shapepar}{}}% } % \end{macrocode} %\end{macro} % %\begin{environment}{staticcontents} % Set the contents of the \gls{static} given by its \gls{idn}. % Syntax: "\begin{staticcontents}"\marg{idn}. % \begin{macrocode} \newbox\staticframe \newenvironment{staticcontents}[1]{% \@ifundefined{@staticframe@\romannumeral#1}{% \PackageError{flowfram}{Static frame '#1' not defined}{}}{}% \expandafter\let\expandafter\@ff@parshape\csname @sf@shape@\romannumeral#1\endcsname \expandafter\@ff@getshape\@ff@parshape\relax \ifcase\ff@shape % no shape \edef\@sf@mpg{% \noexpand \begin{minipage}\csname @sf@dim@\romannumeral#1\endcsname \noexpand\begingroup \noexpand\let\noexpand\FLForgpar=\noexpand\par }% \or % \parshape \edef\@sf@mpg{% \noexpand \begin{minipage}\csname @sf@dim@\romannumeral#1\endcsname \@ff@parshape \noexpand\begingroup \noexpand\let\noexpand\FLForgpar=\noexpand\par \noexpand\let\noexpand\par=\noexpand\ffpshpar \noexpand\@ff@setsecthead }% \or % \shapepar \edef\@sf@mpg{% \noexpand \begin{minipage}\csname @sf@dim@\romannumeral#1\endcsname \noexpand\begingroup \noexpand\@ff@disablesec \noexpand\@ff@parshape }% \fi \edef\@sf@thisframe{\csname @staticframe@\romannumeral#1\endcsname}% \begin{lrbox}{\staticframe}% \edef\ff@txtcol{\csname @sf@txtcol@\romannumeral#1\endcsname}% \@s@tfftextcol\noindent \@sf@mpg \setlength\parindent\sdfparindent }{\ifnum\ff@shape=2\par \else\FLForgpar\fi\endgroup\end{minipage}\end{lrbox}% \expandafter\global\expandafter\sbox\@sf@thisframe{% \usebox\staticframe}\ignorespaces } % \end{macrocode} %\end{environment} %\begin{environment}{staticcontents*} % Set the contents of the \gls{static} given by its \gls{idl}. % Syntax: "\begin{staticcontents*}"\marg{label}. % \begin{macrocode} \newenvironment{staticcontents*}[1]{\@staticframeid{#1}% \begin{staticcontents}{\ff@id}}{\end{staticcontents}} % \end{macrocode} %\end{environment} %\begin{macro}{\setstaticcontents} % Provide a command version. % Syntax: \cs{setstaticcontents}\marg{idn}\marg{text}. % \begin{macrocode} \newcommand{\setstaticcontents}{% \@ifstar\@sstaticconts\@staticconts} % \end{macrocode} %\end{macro} %\begin{macro}{\@sstaticconts} % Starred version: \gls{static} identified by label. % \begin{macrocode} \newcommand{\@sstaticconts}[1]{\@staticframeid{#1}% \@staticconts{\ff@id}} % \end{macrocode} %\end{macro} %\begin{macro}{\@staticconts} % Unstarred version: \gls{static} identified by \gls{idn}. % \begin{macrocode} \newcommand{\@staticconts}[2]{\begin{staticcontents}{#1}% #2\end{staticcontents}} % \end{macrocode} %\end{macro} % %\begin{macro}{\@@staticframeswapcoords} % Swap odd and even offsets for a given \gls{static}. Do the main stuff for % a given \gls{static} \gls{idn}. % \begin{macrocode} \newcommand*{\@@staticframeswapcoords}[1]{% \setlength{\@ff@tmp@x}% {\csname @sf@\romannumeral#1@evenx\endcsname} \expandafter\setlength\csname @sf@\romannumeral#1@evenx\endcsname {\csname @sf@\romannumeral#1@posx\endcsname}% \expandafter\setlength\csname @sf@\romannumeral#1@posx\endcsname {\@ff@tmp@x}% \setlength{\@ff@tmp@y}% {\csname @sf@\romannumeral#1@eveny\endcsname} \expandafter\setlength\csname @sf@\romannumeral#1@eveny\endcsname {\csname @sf@\romannumeral#1@posy\endcsname}% \expandafter\setlength\csname @sf@\romannumeral#1@posy\endcsname {\@ff@tmp@y}% } % \end{macrocode} %\end{macro} %\begin{macro}{\sfswapoddeven} % Allow user to specify \gls{flow} either by \gls{idn} or \gls{idl}: % \begin{macrocode} \newcommand*{\sfswapoddeven}{% \@ifstar\@sstaticframeswapcoords\@staticframeswapcoords} % \end{macrocode} %\end{macro} %\begin{macro}{\@sstaticframeswapcoords} % Starred form % \begin{macrocode} \newcommand*{\@sstaticframeswapcoords}[1]{% \@for\@ff@id:=#1\do{% \@staticframeid{\@ff@id}% \@@staticframeswapcoords{\ff@id}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@staticframeswapcoords} % Unstarred form: % \begin{macrocode} \newcommand*{\@staticframeswapcoords}[1]{% \ifthenelse{\equal{#1}{all}}{% \ff@id=0\relax \whiledo{\ff@id<\c@maxflow}{\advance\ff@id by 1\relax \@@staticframeswapcoords{\ff@id}}% }{% \ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{% \ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}% \whiledo{\@colN<\c@maxflow\TE@or\@colN=\c@maxflow}{% \@@staticframeswapcoords{\@colN}% \advance\@colN by 2\relax}% }{% \@for\@ff@id:=#1\do{% \def\@ff@numstart{0}\def\@ff@numend{10000}% \@ff@getrange{\@ff@id}% \ifnum\@ff@numstart=0\relax \def\@ff@numstart{1}% \fi \ifnum\@ff@numend>\c@maxflow \def\@ff@numend{\c@maxflow}% \fi \@colN=\@ff@numstart \whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{% \@@staticframeswapcoords{\@colN}% \advance\@colN by 1\relax }}}}} % \end{macrocode} %\end{macro} % % \subsection{Dynamic Frames} % Now deal with the \glspl{dynamic}. These are very similar % to the \glspl{static}, but instead of having a savebox, % the contents of the \gls{dynamic} are stored in a macro. %\begin{macro}{\newdynamicframe} % Syntax:\newline % \cs{newdynamicframe}\oarg{pages}\marg{width}\marg{height}\marg{x}\marg{y}\oarg{label} % \begin{macrocode} \newcommand*{\newdynamicframe}{% \@n@wdynamicframe} \newcommand*{\@n@wdynamicframe}{% \global\advance\c@maxdynamic by 1\relax \newboolean{dynamicframe\romannumeral\c@maxdynamic} \@ifstar\@snewdynamicframe\@newdynamicframe } % \end{macrocode} %\end{macro} %\begin{macro}{\@snewdynamicframe} % Starred version: has a border. % \begin{macrocode} \newcommand*{\@snewdynamicframe}{% \setboolean{dynamicframe\romannumeral\c@maxdynamic}{true}% \@@newdynamicframe} % \end{macrocode} %\end{macro} %\begin{macro}{\@newdynamicframe} % Unstarred version: no border. % \begin{macrocode} \newcommand*{\@newdynamicframe}{% \setboolean{dynamicframe\romannumeral\c@maxdynamic}{false}% \@@newdynamicframe} % \end{macrocode} %\end{macro} %\begin{macro}{\@@newdynamicframe} % Create new \gls{dynamic}: % \begin{macrocode} \newcommand*{\@@newdynamicframe}[5][all]{% \expandafter \gdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{}% \expandafter \newlength\csname @df@\romannumeral\c@maxdynamic @posx\endcsname \expandafter \newlength\csname @df@\romannumeral\c@maxdynamic @posy\endcsname \expandafter\setlength \csname @df@\romannumeral\c@maxdynamic @posx\endcsname{#4}% \expandafter\setlength \csname @df@\romannumeral\c@maxdynamic @posy\endcsname{#5}% \expandafter\newlength \csname @df@\romannumeral\c@maxdynamic @evenx\endcsname \expandafter\newlength \csname @df@\romannumeral\c@maxdynamic @eveny\endcsname \expandafter\setlength \csname @df@\romannumeral\c@maxdynamic @evenx\endcsname{#4}% \expandafter\setlength \csname @df@\romannumeral\c@maxdynamic @eveny\endcsname{#5}% {\@ff@tmp@x=#2\relax \@ff@tmp@y=#3\relax \expandafter \xdef\csname @df@dim@\romannumeral\c@maxdynamic\endcsname{% [c][\the\@ff@tmp@y][t]{\the\@ff@tmp@x}}}% \expandafter \gdef\csname @df@col@\romannumeral\c@maxdynamic\endcsname{% \flowframecol}% \expandafter \gdef\csname @df@txtcol@\romannumeral\c@maxdynamic\endcsname{% \flowframetextcol}% \expandafter \gdef\csname @df@backcol@\romannumeral\c@maxdynamic\endcsname{% {none}}% \expandafter \gdef\csname @df@pages@\romannumeral\c@maxdynamic\endcsname{#1}% \expandafter \gdef\csname @df@frametype@\romannumeral\c@maxdynamic\endcsname{% fbox}% \expandafter \gdef\csname @df@style@\romannumeral\c@maxdynamic\endcsname{relax}% \expandafter \gdef\csname @df@offset@\romannumeral\c@maxdynamic\endcsname{compute}% \expandafter \gdef\csname @df@angle@\romannumeral\c@maxdynamic\endcsname{0}% \expandafter \gdef\csname @df@shape@\romannumeral\c@maxdynamic\endcsname{\relax}% \newboolean{@df@clear@\romannumeral\c@maxdynamic}% \setboolean{@df@clear@\romannumeral\c@maxdynamic}{false}% \@ifnextchar[{\@s@tdynamicframeid{\c@maxdynamic}}% {\@s@tdynamicframeid{\c@maxdynamic}[\number\c@maxdynamic]}} % \end{macrocode} %\end{macro} %\begin{macro}{\@s@tdynamicframeid} % Set the label for the given \gls{dynamic}: % \begin{macrocode} \def\@s@tdynamicframeid#1[#2]{% \edef\ff@label{#2}% \@df@checkuniqueidl{#1}{\ff@label}% \expandafter \xdef\csname @df@id@\romannumeral#1\endcsname{\ff@label}} % \end{macrocode} %\end{macro} %\begin{macro}{\@df@checkuniqueidl} % Check \gls{idl} "#2" for \gls{static} "#1" is unique % \begin{macrocode} \newcommand*{\@df@checkuniqueidl}[2]{% \@colN=0\relax \whiledo{\@colN<\c@maxdynamic}{% \advance\@colN by 1\relax \ifnum\@colN=#1\relax \else \ifthenelse{\equal{#2}% {\csname @df@id@\romannumeral\@colN\endcsname}}{% \PackageError{flowfram}{Dynamic frame IDL '#2' already defined}{% You can't assign this label, as it is already defined for dynamic frame \number\@colN}}{}% \fi }} % \end{macrocode} %\end{macro} %\begin{macro}{\@dynamicframeid} % Determine the \gls{idn} of the \gls{dynamic} from its label. % The \gls{idn} is stored in "\ff@id". % \begin{macrocode} \newcommand*{\@dynamicframeid}[1]{\@colN=0\relax \ff@id=0\relax \whiledo{\@colN<\c@maxdynamic}{\advance\@colN by 1\relax \ifthenelse{% \equal{#1}{\csname @df@id@\romannumeral\@colN\endcsname}}{% \ff@id=\@colN\relax % break out of loop \@colN=\c@maxdynamic}{}}% \ifnum\ff@id=0\PackageError{flowfram}{Can't find dynamic frame id '#1'}{}\fi} % \end{macrocode} %\end{macro} % Make it easier to get the x and y values for dynamic % frames. (Width and height stored differently.) %\begin{macro}{\dynamicframex} % \begin{macrocode} \newcommand*{\dynamicframex}[1]{% \csname @df@\romannumeral#1@posx\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\dynamicframey} % \begin{macrocode} \newcommand*{\dynamicframey}[1]{% \csname @df@\romannumeral#1@posy\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\dynamicframeevenx} % \begin{macrocode} \newcommand*{\dynamicframeevenx}[1]{% \csname @df@\romannumeral#1@evenx\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\dynamicframeeveny} % \begin{macrocode} \newcommand*{\dynamicframeeveny}[1]{% \csname @df@\romannumeral#1@eveny\endcsname} % \end{macrocode} %\end{macro} %\begin{macro}{\setalldynamicframes} % Change the settings for all the \glspl{dynamic}: % \begin{macrocode} \newcommand*{\setalldynamicframes}[1]{% \@colN=0\whiledo{\@colN<\c@maxdynamic}{\advance\@colN by 1\relax \@@setdynamicframe{\@colN}{#1}}} % \end{macrocode} %\end{macro} %\begin{macro}{\setdynamicframe} % Change the settings for specified \glspl{dynamic}: % \begin{macrocode} \newcommand*{\setdynamicframe}{% \@ifstar\@ssetdynamicframe\@setdynamicframe} % \end{macrocode} %\end{macro} %\begin{macro}{\@ssetdynamicframe} % Starred version: iterate through comma-separated list % of labels. % \begin{macrocode} \newcommand*{\@ssetdynamicframe}[2]{% \@for\@ff@id:=#1\do{% \@dynamicframeid{\@ff@id}% \@@setdynamicframe{\ff@id}{#2}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@setdynamicframe} % Unstarred version: iterate through comma-separated list % of ID numbers. Include provision for number ranges. % If necessary, modify number ranges to ensure they are valid. % \begin{macrocode} \newcommand*{\@setdynamicframe}[2]{% \ifthenelse{\equal{#1}{all}}{% \setalldynamicframes{#2}}{% \ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{% \ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}% \whiledo{\@colN<\c@maxdynamic\TE@or\@colN=\c@maxdynamic}{% \@@setdynamicframe{\@colN}{#2}% \advance\@colN by 2\relax}% }{% \@for\@ff@id:=#1\do{% \def\@ff@numstart{0}\def\@ff@numend{10000}% \@ff@getrange{\@ff@id}% \ifnum\@ff@numstart=0\relax \def\@ff@numstart{1}% \fi \ifnum\@ff@numend>\c@maxdynamic \def\@ff@numend{\c@maxdynamic}% \fi \@colN=\@ff@numstart \whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{% \@@setdynamicframe{\@colN}{#2}% \advance\@colN by 1\relax }}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@setdynamicframe} % Change the setting for the \gls{dynamic} given by its \gls{idn}. % \begin{macrocode} \newcommand*{\@@setdynamicframe}[2]{% \expandafter\expandafter\expandafter \@ff@getstaticpos\csname @df@dim@\romannumeral#1\endcsname \def\ff@frame{}\edef\ff@width{\the\@ff@tmp@x}% \edef\ff@height{\the\@ff@tmp@y}\def\ff@style{}\def\ff@frametype{}% \def\ff@x{}\def\ff@y{}\def\ff@col{}\def\ff@txtcol{}\def\ff@backcol{}% \def\ff@clear{}\def\ff@margin{}\def\ff@offset{}\def\ff@pages{}% \def\ff@label{}\def\ff@evenx{}\def\ff@eveny{}% \def\ff@oddx{}\def\ff@oddy{}\def\ff@angle{}\def\ff@shape{0}% \setkeys{flowframe}{#2}% \ifthenelse{\equal{\ff@frame}{}}{}{% \setboolean{dynamicframe\romannumeral#1}{\ff@frame}}% \ifthenelse{\equal{\ff@x}{}}{}{% \expandafter\global\expandafter\setlength \csname @df@\romannumeral#1@posx\endcsname{\ff@x}% \expandafter\global\expandafter\setlength \csname @df@\romannumeral#1@evenx\endcsname{\ff@x}}% \ifthenelse{\equal{\ff@y}{}}{}{% \expandafter\global\expandafter\setlength \csname @df@\romannumeral#1@posy\endcsname{\ff@y}% \expandafter\global\expandafter\setlength \csname @df@\romannumeral#1@eveny\endcsname{\ff@y}}% \ifthenelse{\equal{\ff@evenx}{}}{}{% \expandafter\global\expandafter\setlength \csname @df@\romannumeral#1@evenx\endcsname{\ff@evenx}}% \ifthenelse{\equal{\ff@eveny}{}}{}{% \expandafter\global\expandafter\setlength \csname @df@\romannumeral#1@eveny\endcsname{\ff@eveny}}% \ifthenelse{\equal{\ff@oddx}{}}{}{% \expandafter\global\expandafter\setlength \csname @df@\romannumeral#1@posx\endcsname{\ff@oddx}}% \ifthenelse{\equal{\ff@oddy}{}}{}{% \expandafter\global\expandafter\setlength \csname @df@\romannumeral#1@posy\endcsname{\ff@oddy}}% \expandafter\xdef\csname @df@dim@\romannumeral#1\endcsname{% [c][\ff@height][\ff@valign]{\ff@width}}% \ifthenelse{\equal{\ff@label}{}}{}{% \@s@tdynamicframeid{#1}[\ff@label]} \ifthenelse{\equal{\ff@frametype}{}}{}{% \expandafter \xdef\csname @df@frametype@\romannumeral#1\endcsname{% \ff@frametype}}% \ifthenelse{\equal{\ff@col}{}}{}{% \expandafter\@setframecol\ff@col\end{#1}{col}{df}}% \ifthenelse{\equal{\ff@txtcol}{}}{}{% \expandafter\@setframecol\ff@txtcol\end{#1}{txtcol}{df}}% \ifthenelse{\equal{\ff@backcol}{}}{}{% \expandafter\@setframecol\ff@backcol\end{#1}{backcol}{df}}% \ifthenelse{\equal{\ff@offset}{}}{}{% \expandafter \xdef\csname @df@offset@\romannumeral#1\endcsname{\ff@offset}}% \ifthenelse{\equal{\ff@angle}{}}{}{% \expandafter \xdef\csname @df@angle@\romannumeral#1\endcsname{\ff@angle}}% \if0\ff@shape \else \expandafter\global\expandafter \let\csname @df@shape@\romannumeral#1\endcsname\ff@shape \fi \ifthenelse{\equal{\ff@pages}{}}{}{% \expandafter\xdef\csname @df@pages@\romannumeral#1\endcsname{% \ff@pages}}% \ifthenelse{\equal{\ff@style}{}}{}{% \@ifundefined{\ff@style}{\PackageError{flowfram}% {Unknown style '\ff@style'}{The command \expandafter \string\csname\ff@style\endcsname\space has not been defined}}{% \expandafter \xdef\csname @df@style@\romannumeral#1\endcsname{\ff@style}}}% \ifthenelse{\equal{\ff@clear}{}}{}{% \setboolean{@df@clear@\romannumeral\c@maxdynamic}{true}% }% \ifthenelse{\equal{\ff@margin}{}}{}{% \PackageError{flowfram}{Key 'margin' not available for dynamic frames}{dynamic frames don't have marginal notes}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@@dynamicframeswapcoords} % Swap odd and even offsets for a given \gls{static}. Do the main stuff for % a given \gls{static} \gls{idn}. % \begin{macrocode} \newcommand*{\@@dynamicframeswapcoords}[1]{% \setlength{\@ff@tmp@x}% {\csname @df@\romannumeral#1@evenx\endcsname}% \expandafter\setlength \csname @df@\romannumeral#1@evenx\endcsname {\csname @df@\romannumeral#1@posx\endcsname}% \expandafter\setlength \csname @df@\romannumeral#1@posx\endcsname{\@ff@tmp@x}% \setlength{\@ff@tmp@y}% {\csname @df@\romannumeral#1@eveny\endcsname}% \expandafter\setlength \csname @df@\romannumeral#1@eveny\endcsname {\csname @df@\romannumeral#1@posy\endcsname}% \expandafter\setlength\csname @df@\romannumeral#1@posy\endcsname {\@ff@tmp@y}% } % \end{macrocode} %\end{macro} %\begin{macro}{\dfswapoddeven} % Allow user to specify \gls{flow} either by \gls{idn} or \gls{idl}: % \begin{macrocode} \newcommand*{\dfswapoddeven}{% \@ifstar\@sdynamicframeswapcoords\@dynamicframeswapcoords} % \end{macrocode} %\end{macro} %\begin{macro}{\@sdynamicframeswapcoords} % Starred form % \begin{macrocode} \newcommand*{\@sdynamicframeswapcoords}[1]{% \@for\@ff@id:=#1\do{% \@dynamicframeid{\@ff@id}% \@@dynamicframeswapcoords{\ff@id}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@dynamicframeswapcoords} % Unstarred form: % \begin{macrocode} \newcommand*{\@dynamicframeswapcoords}[1]{% \ifthenelse{\equal{#1}{all}}{% \ff@id=0\relax \whiledo{\ff@id<\c@maxflow}{\advance\ff@id by 1\relax \@@dynamicframeswapcoords{\ff@id}}% }{% \ifthenelse{\equal{#1}{odd} \TE@or \equal{#1}{even}}{% \ifthenelse{\equal{#1}{odd}}{\@colN=1}{\@colN=2}% \whiledo{\@colN<\c@maxflow\TE@or\@colN=\c@maxflow}{% \@@dynamicframeswapcoords{\@colN}% \advance\@colN by 2\relax}% }{% \@for\@ff@id:=#1\do{% \def\@ff@numstart{0}\def\@ff@numend{10000}% \@ff@getrange{\@ff@id}% \ifnum\@ff@numstart=0\relax \def\@ff@numstart{1}% \fi \ifnum\@ff@numend>\c@maxflow \def\@ff@numend{\c@maxflow}% \fi \@colN=\@ff@numstart \whiledo{\@colN<\@ff@numend \TE@or \@colN=\@ff@numend}{% \@@dynamicframeswapcoords{\@colN}% \advance\@colN by 1\relax }}}}} % \end{macrocode} %\end{macro} % Set the contents of a \gls{dynamic}. % %\begin{environment}{dynamiccontents} % Syntax: "\begin{dynamiccontents}"\marg{idn} % % The contents of the \env{dynamiccontents} environment needs % to be stored in the control sequence "\@dynamicframe@"\meta{rn} % (where \meta{rn} is the \meta{idn} as a roman numeral.) % Start of the environment (unstarred): % \begin{macrocode} \def\dynamiccontents#1{% \edef\@flf@{\@currenvir}% \def\@flf@idn{#1}% \toks@{}\@flf@get@body } % \end{macrocode} % Get the body of the environment: % \begin{macrocode} \long\def\@flf@get@body#1\end {\toks@\expandafter{\the\toks@#1}\@flf@find@end} % \end{macrocode} % Find the end of the environment: % \begin{macrocode} \def\@flf@find@end#1{% \def\@tempa{#1}% \ifx\@tempa\@flf@ \expandafter\@flf@enddynamiccontents \else \toks@\expandafter {\the\toks@\end{#1}}\expandafter\@flf@get@body\fi } % \end{macrocode} % End of the environment: % \begin{macrocode} \let\enddynamiccontents\relax \def\@flf@enddynamiccontents{% \ifnum\@flf@idn>\c@maxdynamic \PackageError{flowfram}{Dynamic frame \number\@flf@idn\ does not exist}{% You have specified dynamic frame number \number\@flf@idn, but there are only \number\c@maxdynamic\space dynamic frames currently defined}% \else \expandafter \xdef\csname @dynamicframe@\romannumeral\@flf@idn\endcsname{\the\toks@}% \expandafter \fi \expandafter\end\expandafter{\@flf@}} % \end{macrocode} %\end{environment} %\begin{environment}{dynamiccontents*} % Starred version: % \begin{macrocode} \expandafter\def\csname dynamiccontents*\endcsname#1{% \edef\@flf@{\@currenvir}% \@dynamicframeid{#1}% \edef\@flf@idn{\number\ff@id}% \toks@{}\@flf@get@body } % \end{macrocode} %\end{environment} %\begin{macro}{\setdynamiccontents} % \begin{macrocode} \newcommand{\setdynamiccontents}{% \@ifstar\@ssetdynamiccontents\@setdynamiccontents} % \end{macrocode} %\end{macro} %\begin{macro}{\@ssetdynamiccontents} % Starred version: identify \gls{dynamic} by its \gls{idl}: % \begin{macrocode} \newcommand{\@ssetdynamiccontents}[2]{% \@dynamicframeid{#1}\@setdynamiccontents{\ff@id}{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\@setdynamiccontents} % Unstarred version: identify \gls{dynamic} by its \gls{idn}: % \begin{macrocode} \newcommand{\@setdynamiccontents}[2]{% \ifnum#1>\c@maxdynamic \PackageError{flowfram}{Dynamic frame \number#1\ does not exist}{% You have specified dynamic frame number \number#1, but there are only \number\c@maxdynamic\space dynamic frames currently defined}% \else \expandafter \gdef\csname @dynamicframe@\romannumeral#1\endcsname{#2}% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\appenddynamiccontents} % Append information to \gls{dynamic}. First check to % see if starred or unstarred version is being used. % \begin{macrocode} \newcommand{\appenddynamiccontents}{% \@ifstar\@sappenddynamic\@appenddynamic} % \end{macrocode} %\end{macro} %\begin{macro}{\@sappenddynamic} % Starred version: find the \gls{idn} and pass it to % the unstarred version. % \begin{macrocode} \newcommand{\@sappenddynamic}[2]{% \@dynamicframeid{#1}\@appenddynamic{\ff@id}{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\@appenddynamic} % Unstarred version. % \begin{macrocode} \newcommand{\@appenddynamic}[2]{% \ifnum#1>\c@maxdynamic \PackageError{flowfram}{Dynamic frame \number#1 does not exist}{% You have specified dynamic frame number \number#1, but there are only \number\c@maxdynamic\space dynamic frames currently defined}% \else \expandafter\@ff@addtolist \csname @dynamicframe@\romannumeral#1\endcsname\entry{#2}% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@addtolist} % Append "#2" onto the end of "#1". % \begin{macrocode} \newtoks\flf@ta \newtoks\flf@tb \long\def\@ff@addtolist#1\entry#2{\flf@ta={{#2}}% \flf@tb=\expandafter{#1}% \xdef#1{\the\flf@tb\the\flf@ta}} % \end{macrocode} %\end{macro} % %\subsection{Determining Dimensions and Locations} %\begin{macro}{\computeleftedgeodd} % Compute the position of the left most edge of the page, % relative to the left side of the \gls{typeblock}. Since odd and % even pages may have a different offset if "\oddsidemargin" % and "\evensidemargin" have different values, it is necessary % to have two separate commands for odd and even pages. % First the odd pages. % \begin{macrocode} \newcommand*{\computeleftedgeodd}[1]{% \setlength{#1}{-1in}% \addtolength{#1}{-\hoffset}% \addtolength{#1}{-\oddsidemargin}} % \end{macrocode} %\end{macro} %\begin{macro}{\computeleftedgeeven} % Now for the even pages % \begin{macrocode} \newcommand*{\computeleftedgeeven}[1]{% \setlength{#1}{-1in}% \addtolength{#1}{-\hoffset}% \addtolength{#1}{-\evensidemargin}} % \end{macrocode} %\end{macro} %\begin{macro}{\computetopedge} % Compute the top edge of the page, relative to the bottom of % the \gls{typeblock}. % \begin{macrocode} \newcommand*{\computetopedge}[1]{% \setlength{#1}{\textheight}% \addtolength{#1}{\headheight}% \addtolength{#1}{\headsep}% \addtolength{#1}{1in}% \addtolength{#1}{\voffset}% \addtolength{#1}{\topmargin}} % \end{macrocode} %\end{macro} %\begin{macro}{\computebottomedge} % Compute the bottom edge of the page, relative to the bottom % of the \gls{typeblock}. % \begin{macrocode} \newcommand*{\computebottomedge}[1]{% \computetopedge{#1}% \addtolength{#1}{-\paperheight}} % \end{macrocode} %\end{macro} %\begin{macro}{\computerightedgeodd} % Compute the right edge of the page, relative to the left edge % of the \gls{typeblock}. Again, two commands are needed for odd % and even pages. First the odd pages. % \begin{macrocode} \newcommand*{\computerightedgeodd}[1]{% \computeleftedgeodd{#1}% \addtolength{#1}{\paperwidth}} % \end{macrocode} %\end{macro} %\begin{macro}{\computerightedgeeven} % Now for the even pages. % \begin{macrocode} \newcommand*{\computerightedgeeven}[1]{% \computeleftedgeeven{#1}% \addtolength{#1}{\paperwidth}} % \end{macrocode} %\end{macro} % Compute the minimum area surrounding the listed \glspl{flow}. % Values stored in "\ffareawidth", "\ffareaheight", "\ffareax" % and "\ffareay" % \begin{macrocode} \newlength\ffareawidth \newlength\ffareaheight \newlength\ffareax \newlength\ffareay % \end{macrocode} %\begin{macro}{\computeflowframearea} % Starred version identifies frame by \gls{idl}, unstarred % version identifies frame by \gls{idn}. % \begin{macrocode} \newcommand*{\computeflowframearea}{% \@ifstar\@scomputeffarea\@computeffarea} % \end{macrocode} %\end{macro} %\begin{macro}{\@scomputeffarea} % Starred version. % \begin{macrocode} \newcommand*{\@scomputeffarea}[1]{% \setlength{\ffareax}{\paperwidth}% \setlength{\ffareay}{\paperheight}% \setlength{\@ff@tmp@x}{0pt}% \setlength{\@ff@tmp@y}{0pt}% \@for\@ff@id:=#1\do{\@flowframeid{\@ff@id}% %\ff@id is the IDN \ifnum\ffareax>\flowframex{\ff@id}% \setlength{\ffareax}{\flowframex{\ff@id}}% \fi \ifnum\ffareay>\flowframey{\ff@id}% \setlength{\ffareay}{\flowframey{\ff@id}}% \fi \setlength{\@ff@offset}{\flowframex{\ff@id}}% \addtolength{@ff@offset}{\flowframewidth{\ff@id}}% \ifnum\@ff@tmp@x<\@ff@offset \setlength{\@ff@tmp@x}{\@ff@offset}% \fi \setlength{\@ff@offset}{\flowframey{\ff@id}}% \addtolength{@ff@offset}{\flowframeheight{\ff@id}}% \ifnum\@ff@tmp@y<\@ff@offset \setlength{\@ff@tmp@y}{\@ff@offset}% \fi }% \setlength{\ffareawidth}{\@ff@tmp@x}% \addtolength{\ffareawidth}{-\ffareax}% \setlength{\ffareaheight}{\@ff@tmp@y}% \addtolength{\ffareaheight}{-\ffareay}} % \end{macrocode} %\end{macro} %\begin{macro}{\@computeffarea} % Unstarred version. % \begin{macrocode} \newcommand*{\@computeffarea}[1]{% \setlength{\ffareax}{\paperwidth}% \setlength{\ffareay}{\paperheight}% \setlength{\@ff@tmp@x}{0pt}% \setlength{\@ff@tmp@y}{0pt}% \@for\@ff@id:=#1\do{% \ff@id=\@ff@id\relax \setlength{\@ff@offset}{\flowframex{\ff@id}}% \ifdim\ffareax>\@ff@offset \setlength{\ffareax}{\@ff@offset}% \fi \setlength{\@ff@offset}{\flowframey{\ff@id}}% \ifdim\ffareay>\@ff@offset \setlength{\ffareay}{\@ff@offset}% \fi \setlength{\@ff@offset}{\flowframex{\ff@id}}% \addtolength{\@ff@offset}{\flowframewidth{\ff@id}}% \ifdim\@ff@tmp@x<\@ff@offset \setlength{\@ff@tmp@x}{\@ff@offset}% \fi \setlength{\@ff@offset}{\flowframey{\ff@id}}% \addtolength{\@ff@offset}{\flowframeheight{\ff@id}}% \ifdim\@ff@tmp@y<\@ff@offset \setlength{\@ff@tmp@y}{\@ff@offset}% \fi }% \setlength{\ffareawidth}{\@ff@tmp@x}% \addtolength{\ffareawidth}{-\ffareax}% \setlength{\ffareaheight}{\@ff@tmp@y}% \addtolength{\ffareaheight}{-\ffareay}} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@swaplen} % Swap the values of two lengths % \begin{macrocode} \newcommand*{\@ff@swaplen}[2]{% \setlength{\@ff@tmp@x}{#1}% \setlength{#1}{#2}% \setlength{#2}{\@ff@tmp@x}} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@getdim} % Get the dimensions for the given type of frame. % The first parameter should be a number indictating % type of frame : 1 (flow), 2 (static), 3 (dynamic). % The second number is its \gls{idn}. Values are stored in % "\ffareax", "\ffareay", "\ffareawidth" and "\ffareaheight". % \begin{macrocode} \newcommand*{\@ff@getdim}[2]{% \ifnum#2<1\relax \PackageError{flowfram}{Frame IDNs start from 1}{% You have specified a frame IDN of '\number#2'}% \fi \ifcase#1 \PackageError{flowfram}{Unknown frame ID type '#1'}{% Frame ID types are: 1 (flow), 2 (static) and 3 (dynamic)} \or \ifnum#2>\c@maxflow \PackageError{flowfram}{Invalid flow frame IDN '\number#2'}{% Flow frame IDNs go from 1 to \number\c@maxflow} \else \setlength{\ffareax}{\flowframex{#2}} \setlength{\ffareay}{\flowframey{#2}} \setlength{\ffareawidth}{\flowframewidth{#2}} \setlength{\ffareaheight}{\flowframeheight{#2}} \fi \or \ifnum#2>\c@maxstatic \PackageError{flowfram}{Invalid static frame IDN '\number#2'}{% Static frame IDNs go from 1 to \number\c@maxstatic} \else \setlength{\ffareax}{\staticframex{#2}} \setlength{\ffareay}{\staticframey{#2}} \expandafter\expandafter\expandafter \@ff@getstaticpos \csname @sf@dim@\romannumeral#2\endcsname \setlength{\ffareawidth}{\@ff@tmp@x}% \setlength{\ffareaheight}{\@ff@tmp@y}% \fi \or \ifnum#2>\c@maxdynamic \PackageError{flowfram}{Invalid dynamic frame IDN '\number#2'}{% Dynamic frame IDNs go from 1 to \number\c@maxdynamic} \else \setlength{\ffareax}{\dynamicframex{#2}} \setlength{\ffareay}{\dynamicframey{#2}} \expandafter\expandafter\expandafter \@ff@getstaticpos \csname @df@dim@\romannumeral#2\endcsname \setlength{\ffareawidth}{\@ff@tmp@x}% \setlength{\ffareaheight}{\@ff@tmp@y}% \fi \else \PackageError{flowfram}{Unknown frame ID type '#1'}{% Frame ID types are: 1 (flow), 2 (static) and 3 (dynamic)} \fi } % \end{macrocode} %\end{macro} %\begin{macro}{\getstaticbounds} % Convenience method for calling the above. Firstly for static % frames: % \begin{macrocode} \newcommand*{\getstaticbounds}{% \@ifstar\@sgetstaticbounds\@getstaticbounds} % \end{macrocode} %\end{macro} %\begin{macro}{\@sgetstaticbounds} % Starred version (specify by \gls{idl}): % \begin{macrocode} \newcommand*{\@sgetstaticbounds}[1]{% \@staticframeid{#1}\@getstaticbounds{\ff@id}} % \end{macrocode} %\end{macro} %\begin{macro}{\@getstaticbounds} % Unstarred version (specify by \gls{idn}): % \begin{macrocode} \newcommand*{\@getstaticbounds}[1]{\@ff@getdim{1}{#1}} % \end{macrocode} %\end{macro} %\begin{macro}{\getflowbounds} % Next flow frames: % \begin{macrocode} \newcommand*{\getflowbounds}{% \@ifstar\@sgetflowbounds\@getflowbounds} % \end{macrocode} %\end{macro} %\begin{macro}{\@sgetflowbounds} % Starred version (specify by \gls{idl}): % \begin{macrocode} \newcommand*{\@sgetflowbounds}[1]{% \@flowframeid{#1}\@getflowbounds{\ff@id}} % \end{macrocode} %\end{macro} %\begin{macro}{\@getflowbounds} % Unstarred version (specify by \gls{idn}): % \begin{macrocode} \newcommand*{\@getflowbounds}[1]{\@ff@getdim{2}{#1}} % \end{macrocode} %\end{macro} %\begin{macro}{\getdynamicbounds} % Next dynamic frames: % \begin{macrocode} \newcommand*{\getdynamicbounds}{% \@ifstar\@sgetdynamicbounds\@getdynamicbounds} % \end{macrocode} %\end{macro} %\begin{macro}{\@sgetdynamicbounds} % Starred version (specify by \gls{idl}): % \begin{macrocode} \newcommand*{\@sgetdynamicbounds}[1]{% \@dynamicframeid{#1}\@getdynamicbounds{\ff@id}} % \end{macrocode} %\end{macro} %\begin{macro}{\@getdynamicbounds} % Unstarred version (specify by \gls{idn}): % \begin{macrocode} \newcommand*{\@getdynamicbounds}[1]{\@ff@getdim{3}{#1}} % \end{macrocode} %\end{macro} % %\subsection{Initialise Flow Frames} %\begin{macro}{\setinitialframe} % Specify initial frame. This should be the first flow % frame that is defined on the first page of the document. % Having another \gls{flow} as the initial frame is not % a good idea, and may have unexpected results. % \begin{macrocode} \newcommand*{\setinitialframe}[1]{\c@thisframe=#1% \global\usedframebreaktrue \global\setlength{\hsize}{% \csname colwidth\romannumeral\c@thisframe\endcsname}} % \end{macrocode} %\end{macro} %\begin{macro}{\setframes} % Set the initial frame. % \begin{macrocode} \newif\if@setfr@mes \@setfr@mesfalse \newcommand*{\setframes}{% \ifnum\c@thisframe=0\relax \PackageWarning{flowfram}{Can't find a flow frame on page 1. \MessageBreak Attempting to find the first page with a flow frame}% \@nxtcol=1\relax \c@curpg=1\relax \@g@tnextcol{\@nxtcol}% % \end{macrocode} % shipout pages without flow frames % \begin{macrocode} \advance\c@curpg by -1\relax \whiledo{\c@curpg>0}{\advance\c@curpg by -1\relax \setbox\@outputbox\vbox{\hbox to \textwidth{\@ff@do@allframes}}% \@outputpage}% \c@thisframe=\@nxtcol \fi \@setcol{\c@thisframe}\relax \@setfr@mestrue \edef\ff@txtcol{% \csname @ff@txtcol@\romannumeral\c@thisframe\endcsname}% \@s@tfftextcol } % \end{macrocode} %\end{macro} %\begin{macro}{\emulatetwocolumn} % Emulate original "\twocolumn" declaration. % This is provided for backward compatibilty, and % may be removed in later versions. % \begin{macrocode} \newcommand{\emulatetwocolumn}[1][]{% \finishthispage \setallflowframes{pages=none}% \settoheight{\@ff@staticH}{#1}% \settodepth{\@ff@tmp@y}{#1}% \addtolength{\@ff@staticH}{\@ff@tmp@y}% \ifdim\@ff@staticH>0pt\relax \twocolumnStop[\c@page]{\@ff@staticH}% \c@thisframe=\c@maxflow \advance\c@thisframe by -1\relax \@twocolumn[>\c@page]% \setstaticcontents{\c@maxstatic}{#1}% \else \@twocolumn \c@thisframe=\c@maxflow \advance\c@thisframe by -1\relax \fi \@setcol{\c@thisframe}\relax } % \end{macrocode} %\end{macro} %\begin{macro}{\emulateonecolumn} % Emulate original "\onecolumn" declaration. % This is provided for backward compatibilty, and % may be removed in later versions. % \begin{macrocode} \newcommand{\emulateonecolumn}[1][]{% \finishthispage \setallflowframes{pages=none}% \settoheight{\@ff@staticH}{#1}% \settodepth{\@ff@tmp@y}{#1}% \addtolength{\@ff@staticH}{\@ff@tmp@y}% \ifdim\@ff@staticH>0pt\relax \onecolumnStop[\c@page]{\@ff@staticH}% \c@thisframe=\c@maxflow \advance\c@thisframe by -1\relax \@onecolumn[>\c@page]% \setstaticcontents{\c@maxstatic}{#1}% \else \@twocolumn \c@thisframe=\c@maxflow \advance\c@thisframe by -1\relax \fi \@setcol{\c@thisframe}\relax } % \end{macrocode} %\end{macro} % If no flow frames have been defined, create one big one % the size of the \gls{typeblock}, and initialise the frames. % \begin{macrocode} \AtBeginDocument{% \ifnum\c@maxflow=0\relax \PackageWarning{flowfram}{No flow frames, adding one}% \@onecolumn \fi \setframes \renewcommand{\onecolumn}[1][]{\PackageWarning{flowfram}{% Ignoring \string\onecolumn\space found in document environment. Frames must be defined in the preamble}#1}% \renewcommand{\twocolumn}[1][]{\PackageWarning{flowfram}{% Ignoring \string\twocolumn\space found in document environment. Frames must be defined in the preamble}#1}% } % \end{macrocode} % If the document finishes before the last frame on the last % page, need to finish off to ensure the final page is % shipped out, otherwise the text on the last page will be lost. % \begin{macrocode} %\AtEndDocument{\finishthispage} % \end{macrocode} %\subsection{Output Routine} %\begin{macro}{\@setcol} % Set up the output box so it has the correct dimensions for % specified \gls{flow}. This is used by the output routine. % \begin{macrocode} \newcommand{\@setcol}[1]{% \ifnum\c@maxflow<#1\relax \PackageError{flowfram}{Can't set frame '\number#1', doesn't exist}{}% \else \expandafter\global\expandafter\columnwidth \csname colwidth\romannumeral#1\endcsname \ifdim\hsize=\columnwidth \else \ifusedframebreak \else \PackageWarning{flowfram}{Moving to flow frame of unequal width,\MessageBreak use of \string\framebreak\space advised, or text might not appear correctly}% \fi \fi \global\usedframebreakfalse \global\hsize\columnwidth \expandafter\global \expandafter\vsize\csname colheight\romannumeral#1\endcsname \global\@colht\vsize \global\@colroom\@colht \global\linewidth\columnwidth \setmargin \fi } % \end{macrocode} %\end{macro} % Modify the output routine so that it uses "\vsize" % instead of "\textheight". % \begin{macrocode} \output={\let\par\@@par \ifnum\outputpenalty <-\@M \@specialoutput \else \@makecol \@opcol \@startcolumn \@whilesw \if@fcolmade \fi {\@opcol \@startcolumn }% \fi \ifnum\outputpenalty>-\@Miv \ifdim\@colroom<1.5\baselineskip \ifdim\@colroom<\vsize \@latex@warning@no@line{Text page \thepage \space contains only floats}\@emptycol \else \global\vsize\@colroom \fi \else \global\vsize\@colroom \fi \else \global\vsize\maxdimen \fi } % \end{macrocode} %\begin{macro}{\@doclearpage} % Modify "\@doclearpage", again replace "\textheight" % with "\vsize", and only use the twocolumn stuff. % \begin{macrocode} \def\@doclearpage{% \ifvoid\footins \setbox\@tempboxa\vsplit\@cclv to\z@ \unvbox\@tempboxa \setbox\@tempboxa\box\@cclv \xdef\@deferlist{\@toplist\@botlist\@deferlist}% \global\let\@toplist\@empty \global\let\@botlist\@empty \global\@colroom\@colht \ifx\@currlist\@empty \else \@latexerr{Float(s) lost}\@ehb \global\let\@currlist\@empty \fi \@makefcolumn \@deferlist \@whilesw \if@fcolmade \fi {\@opcol \@makefcolumn \@deferlist}% \if@firstcolumn \xdef\@dbldeferlist{\@dbltoplist\@dbldeferlist}% \global\let\@dbltoplist\@empty \global\@colht\vsize \begingroup \@dblfloatplacement \@makefcolumn \@dbldeferlist \@whilesw \if@fcolmade \fi {\@outputpage \@makefcolumn\@dbldeferlist}% \endgroup \else \vbox{}\clearpage \fi \else \setbox\@cclv\vbox{\box\@cclv\vfil}% \@makecol\@opcol\clearpage\fi} % \end{macrocode} %\end{macro} % Modify "\@outputpage" slightly. Add provision for % turning headers and footers into \glspl{dynamic}. % %\begin{macro}{\@dothehead} % First define macro to do the header. This will be % modified if it is turned into a \gls{dynamic}. % \begin{macrocode} \newcommand{\@dothehead}{\vbox to \headheight{% \color@hbox\normalcolor\hbox to \textwidth{% \@thehead}\color@endbox}} % \end{macrocode} %\end{macro} %\begin{macro}{\@dothefoot} % Same again for the footer. % \begin{macrocode} \newcommand{\@dothefoot}{% \color@hbox\normalcolor\hbox to \textwidth{% \@thefoot}\color@endbox} \newcommand{\@dodynamicthehead}{} \newcommand{\@dodynamicthefoot}{} % \end{macrocode} %\end{macro} %\begin{macro}{\@outputpage} % Now for the modified version of "\@outputpage". The % page style stuff has been moved to "\@outputdblcol" % so that the headers and footers can be set in \glspl{dynamic} % before the \glspl{dynamic} are put on the page. % \begin{macrocode} \def\@outputpage{% \begingroup \let\protect\noexpand \@resetactivechars \global\let\@@if@newlist\if@newlist \global\@newlistfalse\@parboxrestore \shipout\vbox{\set@typeset@protect \aftergroup \endgroup \aftergroup \set@typeset@protect \reset@font\normalsize\normalsfcodes \let\label\@gobble \let\index\@gobble \let\glossary\@gobble \baselineskip\z@skip \lineskip\z@skip \lineskiplimit\z@ \vskip\topmargin\moveright\@themargin \vbox{% \vskip\headheight \vskip\headsep \box\@outputbox }}\global\let\if@newlist\@@if@newlist \stepcounter{page}\let\firstmark\botmark} % \end{macrocode} %\end{macro} %\begin{macro}{\makedfheaderfooter} % Make the headers and footers be in \glspl{dynamic}. There % will initially be no difference in appearance until % the settings are changed using "\setdynamicframe". % The header frame is given the \gls{idl} "header", and the % footer is given the \gls{idl} "footer". % \begin{macrocode} \newcommand*{\makedfheaderfooter}{% % create dynamic frames at the standard location \setlength{\@ff@tmp@y}{\textheight}% \addtolength{\@ff@tmp@y}{\headsep}% \newdynamicframe{\textwidth}{\headheight}{0pt}{\@ff@tmp@y}[header]% \newdynamicframe{\textwidth}{\headheight}{0pt}{-\footskip}[footer]% \renewcommand{\@dothehead}{}% \renewcommand{\@dothefoot}{}% \renewcommand{\@dodynamicthehead}{% \@dynamicframeid{header}% \expandafter \def\csname @dynamicframe@\romannumeral\ff@id\endcsname{% \vfill\@thehead\vfill}% }% \renewcommand{\@dodynamicthefoot}{% \@dynamicframeid{footer}% \expandafter \def\csname @dynamicframe@\romannumeral\ff@id\endcsname{% \vfill\@thefoot\vfill}% }% } % \end{macrocode} %\end{macro} % This should only be done in the preamble. % \begin{macrocode} \@onlypreamble{\makedfheaderfooter} % \end{macrocode} %\begin{macro}{\footnotecolor} % Set footnotes in "\footnotecolor" rather than "\normalcolor" % This ensures that the footnotes appear in the same colour % as the text colour for the \gls{flow} to which they belong. % \begin{macrocode} \newcommand{\footnotecolor}{% \@ifundefined{@ff@txtcol@\romannumeral\c@thisframe}{% \normalcolor}{% \edef\ff@txtcol{% \csname @ff@txtcol@\romannumeral\c@thisframe\endcsname}% \@s@tfftextcol}} % \end{macrocode} %\end{macro} %\begin{macro}{\@makecol} % Modify "\@makecol" so that the footnotes, and the % footnote rule are in the colour for that frame. % \begin{macrocode} \renewcommand{\@makecol}{% \ifvoid\footins \setbox\@outputbox\box\@cclv \else \setbox\@outputbox\vbox{% \boxmaxdepth\@maxdepth\@tempdima\dp\@cclv \unvbox\@cclv \vskip\skip\footins \color@begingroup \footnotecolor \footnoterule \unvbox\footins \color@endgroup }\fi \xdef\@freelist{\@freelist \@midlist }% \global\let\@midlist\@empty \@combinefloats \ifvbox\@kludgeins \@makespecialcolbox \else \setbox\@outputbox\vbox to\@colht{% \@texttop\dimen@\dp\@outputbox \unvbox \@outputbox \vskip -\dimen@\@textbottom }\fi \global\maxdepth\@maxdepth} % \end{macrocode} %\end{macro} %\begin{macro}{\@opcol} % Modify "\@opcol", as "\if@twocolumn" is now % irrelevant. % \begin{macrocode} \def\@opcol{\@outputdblcol \global\@mparbottom\z@ \global\@textfloatsheight\z@ \@floatplacement } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@checkifmoreframes} % Check to see if there are more \glspl{flow} defined, and % set "\if@ff@moreframes" as appropriate. This involves % iterating through all \glspl{flow}, and through each % frame's \gls{pglist}. % \begin{macrocode} \newif\if@ff@moreframes \newcommand*{\@ff@checkifmoreframes}{% \@ff@moreframesfalse \@colN=\c@thisframe \whiledo{\@colN<\c@maxflow}{% \advance\@colN by 1\relax \edef\ff@pages{\csname @ff@pages@\romannumeral\@colN\endcsname}% \@ff@checkpages{\ff@pages}% }% \if@ff@moreframes \else \@ff@tmpN=\c@page \advance\@ff@tmpN by 1\relax \@colN=0\relax \whiledo{\@colN<\c@thisframe}{% \advance\@colN by 1\relax \edef\ff@pages{\csname @ff@pages@\romannumeral\@colN\endcsname}% \@ff@checkpages[\@ff@tmpN]{\ff@pages}% }% \fi } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@checkpages} % Check to see if the current page lies in the \gls{pglist} % given by "#1". % \begin{macrocode} \newcommand*{\@ff@checkpages}[2][\c@page]{% \@for\@ff@pp:=#2\do{% \@ff@checkthispage{#1}{\@ff@pp}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@checkthispage} % Check to see if the current page lies in the \gls{pgrange} % given by "#1". If the \gls{pgrange} is specified by % "all", "odd" or "even" then there are definitely more % frames available, otherwise check to see if the current page % lies within the number range. If the \gls{pgrange} is "none", % ignore it. % \begin{macrocode} \newcommand*{\@ff@checkthispage}[2]{% \ifthenelse{\equal{#2}{all}\or\equal{#2}{even}\or\equal{#2}{odd}}{% \@ff@moreframestrue}{% \ifthenelse{\equal{#2}{none}}{}{% \@ff@checknumrange{#1}{#2}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@checknumrange} % The number range could be a single number, a closed range % (e.g.\ "2-6") or an open range (e,g.\ "<4" or ">10"). % Use "\@ff@getrange" to find the start and end ranges. % For open ended ranges assume a maximum value of 10000. % If the current page is less than or equal to the maximum, % there are still more \glspl{flow} available. % \begin{macrocode} \newcommand*{\@ff@checknumrange}[2]{% \def\@ff@numstart{0}\def\@ff@numend{10000}% \@ff@getrange{#2}% \ifnum\@ff@numend>#1\relax \@ff@moreframestrue \else \ifnum\@ff@numend=#1\relax \@ff@moreframestrue \fi \fi } % \end{macrocode} %\end{macro} % Work out the minimum and maximum values of a number range % which could either be a single number, a closed number % range or an open number range. If the first character % is "<" or ">" then it is an open range, otherwise it is % a closed range or a single number. Define a counter % to use whilst determining the range. % \begin{macrocode} \newcount\c@ffrangenum % \end{macrocode} %\begin{macro}{\@ff@getrange} % Now to find out what kind of range it is. If it is a single % number, e.g.\ "24", then it will do, e.g.\ % "\@ff@@getrange24-\relax". % If it is a closed range, e.g. "30-40", it will do , e.g.\ % "\@ff@@getrange30-40-\relax". If it is an open range, e.g.\ % ">25", it will do, e.g.\ "\@ff@@getrange>25-\relax". % \begin{macrocode} \newcommand*{\@ff@getrange}[1]{% \expandafter\@ff@@getrange#1-\relax\end} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@@getrange} % The ranges can now be picked out. If the first character % is a "<" or ">" it is an open ended range, otherwise it % is either a single value, or a close ended range. % \begin{macrocode} \def\@ff@@getrange#1#2\end{% \ifx#1<\relax \@ff@getrangeless#1#2\end \else \ifx#1>\relax \@ff@getrangegreater#1#2\end \else \@@ff@getrange#1#2\end \fi \fi } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@getrangeless} % Get the values for an open ended range with an % upper bound. A minimum value of "0" is assumed. % \begin{macrocode} \def\@ff@getrangeless<#1-\relax\end{% \c@ffrangenum=#1\relax \advance\c@ffrangenum by -1\relax \def\@ff@numstart{0}% \edef\@ff@numend{\number\c@ffrangenum}} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@getrangegreater} % Get the values for an open ended range with a lower % bound. A maximum value of "10000" is assumed. % \begin{macrocode} \def\@ff@getrangegreater>#1-\relax\end{% \c@ffrangenum=#1\relax \advance\c@ffrangenum by 1\relax \edef\@ff@numstart{\number\c@ffrangenum}% \def\@ff@numend{10000}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@ff@getrange} % Determine whether we have a single number or % a closed range. If "#2" is "\relax", it is a single % value, otherwise it is a range. % \begin{macrocode} \def\@@ff@getrange#1-#2\end{% \ifx\relax#2\relax \def\@ff@numstart{#1}\def\@ff@numend{#1}% \else \def\@ff@numstart{#1}% \@@@ff@getrange#2\end \fi } % \end{macrocode} %\end{macro} %\begin{macro}{\@@@ff@getrange} % Extract the end value from the closed range. % \begin{macrocode} \def\@@@ff@getrange#1-\relax\end{% \def\@ff@numend{#1}} % \end{macrocode} %\end{macro} %\begin{macro}{\@g@tnextcol} % Find the next \gls{flow}. If there are no more flow % frames, define a new one the size of the \gls{typeblock}. % (Otherwise the remaining document text will be lost.) % \begin{macrocode} \newif\if@notthiscol \newif\if@ff@nwpg \newcount\c@curpg \newcommand*{\@g@tnextcol}[1]{% \@ff@checkifmoreframes \if@ff@moreframes \else % No more frames, add new frame \PackageWarning{flowfram}{Run out of flows frames, adding new one}% \@onecolumn #1=\c@maxflow \fi \@notthiscoltrue \@ff@nwpgfalse \@colN=#1\relax \c@curpg=\c@page \loop \ifnum\@colN=\c@maxflow \@colN=1\@ff@nwpgtrue \advance\c@curpg by 1\relax \else \advance\@colN by 1\relax \fi \@ff@chckifthispg{\c@curpg}{\@colN}% \if@notthiscol \repeat #1=\@colN } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@chckifthispg} % This is used to determine the next \gls{flow}, since not % all \glspl{flow} may be defined on every page. Checks to % see if \gls{flow} "#2" is defined on page "#1". % First set up some variables. % \begin{macrocode} \newcommand*{\@ff@chckifthispg}[2]{% \@notthiscoltrue \edef\ff@pages{\csname @ff@pages@\romannumeral#2\endcsname}% \@@ff@chckifthispg{#1}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@@ff@chckifthispg} % Now go ahead and check. % \begin{macrocode} \newcommand*{\@@ff@chckifthispg}[1]{% \ifthenelse{\equal{\ff@pages}{none}}{}{% \ifthenelse{\equal{\ff@pages}{all}}{\@notthiscolfalse}{% \ifthenelse{\equal{\ff@pages}{odd}}{% \ifodd#1\@notthiscolfalse\fi}{% \ifthenelse{\equal{\ff@pages}{even}}{% \ifodd#1\else\@notthiscolfalse\fi}{% % check through list of page numbers \@for\@ff@pp:=\ff@pages\do{% \def\@ff@numstart{0}\def\@ff@numend{0}% \@ff@getrange{\@ff@pp}% \ifthenelse{#1<\@ff@numstart \or #1>\@ff@numend}{}{% \@notthiscolfalse}% }% }}}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@sf@chckifthispg} % Checks to see if \gls{static} "#1" is defined on the % current page. % \begin{macrocode} \newcommand*{\@sf@chckifthispg}[1]{% \@notthiscoltrue \edef\ff@pages{\csname @sf@pages@\romannumeral#1\endcsname}% \@@ff@chckifthispg{\c@page}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@df@chckifthispg} % Checks to see if \gls{dynamic} "#1" is defined on the % current page. % \begin{macrocode} \newcommand*{\@df@chckifthispg}[1]{% \@notthiscoltrue \edef\ff@pages{\csname @df@pages@\romannumeral#1\endcsname}% \@@ff@chckifthispg{\c@page}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@setcolbox} % Sets the \TeX\ box defining the \gls{flow} to the output % box. This saves the output until the page is shipped out after % all the \glspl{flow} have been filled for that page. % \begin{macrocode} \newcommand*{\@setcolbox}[1]{% \expandafter\global\expandafter\setbox \csname column\romannumeral#1\endcsname\box\@outputbox } % \end{macrocode} %\end{macro} %\begin{macro}{\@docolbox} % Put \gls{flow} on the page with the correct border, if it % has one. % \begin{macrocode} \newcommand*{\@docolbox}[1]{% \edef\ff@frametype{% \csname @ff@frametype@\romannumeral#1\endcsname}% \edef\ff@col{\csname @ff@col@\romannumeral#1\endcsname}% \edef\ff@txtcol{\csname @ff@txtcol@\romannumeral#1\endcsname}% \edef\ff@backcol{\csname @ff@backcol@\romannumeral#1\endcsname}% \@ff@setoffset{#1}% \rotateframe{\csname @ff@angle@\romannumeral#1\endcsname}{% \ifthenelse{\boolean{columnframe\romannumeral#1}}{% \@ff@fbox{\csname colwidth\romannumeral#1\endcsname}% {\csname colheight\romannumeral#1\endcsname}{% \expandafter\box\csname column\romannumeral#1\endcsname}{% \csname\ff@frametype\endcsname}% }{% \@ff@box{\csname colwidth\romannumeral#1\endcsname}% {\csname colheight\romannumeral#1\endcsname}{% \expandafter\box\csname column\romannumeral#1\endcsname}% }}} % \end{macrocode} %\end{macro} %\begin{macro}{\@docolbbox} % Do the \gls{bbox} for given \gls{flow}. % \begin{macrocode} \newcommand*{\@docolbbox}[1]{% \@ff@setoffset{#1}% \def\ff@col{}\def\ff@txtcol{}% \@fr@meifdraft{% \@ff@box{\csname colwidth\romannumeral#1\endcsname}% {\csname colheight\romannumeral#1\endcsname}{% \expandafter\box\csname column\romannumeral#1\endcsname}}% {F:\number#1;\csname @col@id@\romannumeral#1\endcsname}} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@fbox} % Put the \TeX\ box "#3" of width "#1" and % height "#2", and frame making command % specified by "#4". % \begin{macrocode} \newcommand{\@ff@fbox}[4]{{% \fboxsep=\flowframesep\fboxrule=\flowframerule\@s@tffcol \kern\@ff@offset #4{\@ff@box{#1}{#2}{#3}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@box} % Put the \TeX\ box "#3" of width "#1" and height "#2" on % the page. % \begin{macrocode} \newcommand{\@ff@box}[3]{{\@ffbackground{\vbox to#2 {\hb@xt@ #1{\hss{\@s@tfftextcol #3}\hss}\vss\kern\z@}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@putcolbox} % Display the \gls{flow} on the page, at its given position. % If the document is two-sided, need to check whether % the current page is odd or even to determine the correct % location. % \begin{macrocode} \newcommand*{\@putcolbox}[1]{% \@ff@chckifthispg{\c@page}{#1}% \if@notthiscol \else \@killglue \if@twoside \ifodd\c@page \expandafter\raise\csname col@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname col@\romannumeral#1@posx\endcsname \@docolbox{#1}\hss}% \else \expandafter\raise\csname col@\romannumeral#1@eveny\endcsname \hb@xt@\z@{% \expandafter\kern \csname col@\romannumeral#1@evenx\endcsname \@docolbox{#1}\hss}% \fi \else \expandafter\raise\csname col@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname col@\romannumeral#1@posx\endcsname \@docolbox{#1}\hss}% \fi \fi } % \end{macrocode} %\end{macro} %\begin{macro}{\@putcolbbox} % Same for \gls{flow} \gls{bbox}: % \begin{macrocode} \newcommand*{\@putcolbbox}[1]{% \@ff@chckifthispg{\c@page}{#1}% \if@notthiscol \else \@killglue \if@twoside \ifodd\c@page \expandafter\raise\csname col@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname col@\romannumeral#1@posx\endcsname \@docolbbox{#1}\hss}% \else \expandafter\raise\csname col@\romannumeral#1@eveny\endcsname \hb@xt@\z@{% \expandafter\kern \csname col@\romannumeral#1@evenx\endcsname \@docolbbox{#1}\hss}% \fi \else \expandafter\raise\csname col@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname col@\romannumeral#1@posx\endcsname \@docolbbox{#1}\hss}% \fi \fi } % \end{macrocode} %\end{macro} % If an offset hasn't been specified, compute it. If the % frame making command is known (e.g. doublebox), compute % the offset according to known specifications, otherwise % set the negative offset to "\flowframesep" plus % "\flowframerule", which may or may not be correct. % %\begin{macro}{\@ff@s@t@doubleboxoffset} % Compute offset for "\doublebox": % \begin{macrocode} \newcommand*{\@ff@s@t@doubleboxoffset}{% \setlength{\@ff@offset}{-\flowframesep}% \addtolength{\@ff@offset}{-3.75\flowframerule}% \addtolength{\@ff@offset}{-.5pt}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@s@t@ovalboxoffset} % Compute offset for "\ovalbox": % \begin{macrocode} \newcommand*{\@ff@s@t@ovalboxoffset}{% \@ff@offset=-\fontdimen 8\tenln\relax \advance\@ff@offset by -\flowframesep\relax } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@s@t@Ovalboxoffset} % Compute offset for "\ovalbox": % \begin{macrocode} \newcommand*{\@ff@s@t@Ovalboxoffset}{% \@ff@offset=-\fontdimen 8\tenlnw\relax \advance\@ff@offset by -\flowframesep\relax } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@s@t@defaultoffset} % Compute default offset: % \begin{macrocode} \newcommand*{\@ff@s@t@defaultoffset}{% \@ff@offset=-\flowframesep\relax \addtolength{\@ff@offset}{-\flowframerule}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@setoffset} % Compute offset for \gls{flow} "#1". Stores offset value % in "\ff@offset". % \begin{macrocode} \newcommand*{\@ff@setoffset}[1]{% \ifthenelse{\equal{\csname @ff@offset@\romannumeral#1\endcsname}% {compute}}{% \ifthenelse{\boolean{columnframe\romannumeral#1}}{% \ifthenelse{% \equal{\csname @ff@frametype@\romannumeral#1\endcsname}% {doublebox}}{% \@ff@s@t@doubleboxoffset }{% \ifthenelse{% \equal{\csname @ff@frametype@\romannumeral#1\endcsname}% {ovalbox}}{% \@ff@s@t@ovalboxoffset }{% \ifthenelse{% \equal{\csname @ff@frametype@\romannumeral#1\endcsname}% {Ovalbox}}{% \@ff@s@t@Ovalboxoffset}{% \@ff@s@t@defaultoffset }}}% }{}% }{% \setlength{\@ff@offset}% {\csname @ff@offset@\romannumeral#1\endcsname}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@sf@setoffset} % Compute offset for \gls{static} "#1". Stores offset value % in "\ff@offset". % \begin{macrocode} \newcommand*{\@sf@setoffset}[1]{% \ifthenelse{% \equal{\csname @sf@offset@\romannumeral#1\endcsname}% {compute}}{% \ifthenelse{\boolean{staticframe\romannumeral#1}}{% \ifthenelse{% \equal{\csname @sf@frametype@\romannumeral#1\endcsname}% {doublebox}}{% \@ff@s@t@doubleboxoffset }{% \ifthenelse{% \equal{\csname @sf@frametype@\romannumeral#1\endcsname}% {ovalbox}}{% \@ff@s@t@ovalboxoffset }{% \ifthenelse{% \equal{\csname @sf@frametype@\romannumeral#1\endcsname}% {Ovalbox}}{% \@ff@s@t@Ovalboxoffset }{% \@ff@s@t@defaultoffset }}}% }{}% }{% \setlength{\@ff@offset}% {\csname @sf@offset@\romannumeral#1\endcsname}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@df@setoffset} % Compute offset for \gls{dynamic} "#1". Stores offset value % in "\ff@offset". % \begin{macrocode} \newcommand*{\@df@setoffset}[1]{% \ifthenelse{% \equal{\csname @df@offset@\romannumeral#1\endcsname}% {compute}}{% \setlength{\@ff@offset}{0pt}% \ifthenelse{\boolean{dynamicframe\romannumeral#1}}{% \ifthenelse{% \equal{\csname @df@frametype@\romannumeral#1\endcsname}% {doublebox}}{% \@ff@s@t@doubleboxoffset }{% \ifthenelse{% \equal{\csname @df@frametype@\romannumeral#1\endcsname}% {ovalbox}}{% \@ff@s@t@ovalboxoffset }{% \ifthenelse{% \equal{\csname @df@frametype@\romannumeral#1\endcsname}% {Ovalbox}}{% \@ff@s@t@Ovalboxoffset}{% \@ff@s@t@defaultoffset }}}% }{}% }{% \setlength{\@ff@offset}% {\csname @df@offset@\romannumeral#1\endcsname}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@putmarginbox} % Draw box representing the margin for \gls{flow} "#1". % \begin{macrocode} \newcommand*{\@putmarginbox}[1]{% \@ff@chckifthispg{\c@page}{#1}% \if@notthiscol \else \@killglue \if@twoside \ifodd\c@page \edef\ff@x{\csname col@\romannumeral#1@posx\endcsname}% \edef\ff@y{\csname col@\romannumeral#1@posy\endcsname}% \else \edef\ff@x{\csname col@\romannumeral#1@evenx\endcsname}% \edef\ff@y{\csname col@\romannumeral#1@eveny\endcsname}% \fi \else \edef\ff@x{\csname col@\romannumeral#1@posx\endcsname}% \edef\ff@y{\csname col@\romannumeral#1@posy\endcsname}% \fi \setlength{\@ff@tmp@x}{\ff@x}% \setlength{\@ff@tmp@y}{\ff@y}% \@getmarginpos{\csname @ff@margin@\romannumeral#1\endcsname}% \ifthenelse{\equal{\ff@margin}{left}}{% \addtolength{\@ff@tmp@x}{-\marginparwidth}% \addtolength{\@ff@tmp@x}{-\marginparsep}% \ifthenelse{\boolean{columnframe\romannumeral#1}}{% }{}% }{% \addtolength{\@ff@tmp@x}% {\csname colwidth\romannumeral#1\endcsname}% \addtolength{\@ff@tmp@x}{\marginparsep}% \ifthenelse{\boolean{columnframe\romannumeral#1}}{% }{}% }% \raise\@ff@tmp@y \hb@xt@\z@{% \expandafter\kern\@ff@tmp@x \@fr@meifdraft{\@ff@box{\marginparwidth}% {\csname colheight\romannumeral#1\endcsname}{}}% {M:\number#1}\hss}\fi \ignorespaces} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@drawmargins} % Draw all the margins associated with the \glspl{flow} defined % on the current page. % \begin{macrocode} \newcommand*{\@ff@drawmargins}{% \@colN=0\relax \whiledo{\@colN<\c@maxflow}{% \advance\@colN by 1\relax \makebox[0pt][l]{\@putmarginbox{\@colN}}% }% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@getstaticpos} % Extract the width and height for static or \gls{dynamic} % specified in the form \oarg{c}\oarg{height}\oarg{valign}\marg{width} % \begin{macrocode} \def\@ff@getstaticpos[#1][#2][#3]#4{\@ff@tmp@x=#4\relax \@ff@tmp@y=#2\relax \def\ff@valign{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\@dostaticbox} % Display the savebox associated with \gls{static} "#1" % \begin{macrocode} \newcommand*{\@dostaticbox}[1]{% \edef\ff@frametype{% \csname @sf@frametype@\romannumeral#1\endcsname}% \edef\ff@col{\csname @sf@col@\romannumeral#1\endcsname}% \edef\ff@backcol{\csname @sf@backcol@\romannumeral#1\endcsname}% \@sf@setoffset{#1}% \expandafter\expandafter\expandafter \@ff@getstaticpos\csname @sf@dim@\romannumeral#1\endcsname \rotateframe{\csname @sf@angle@\romannumeral#1\endcsname}{% \ifthenelse{\boolean{staticframe\romannumeral#1}}{% \@ff@fbox{\@ff@tmp@x}{\@ff@tmp@y}{% \expandafter\usebox\csname @staticframe@\romannumeral#1\endcsname} {\csname\ff@frametype\endcsname}% }{% \@ff@box{\@ff@tmp@x}{\@ff@tmp@y}% {\expandafter\usebox\csname @staticframe@\romannumeral#1\endcsname}% }}} % \end{macrocode} %\end{macro} %\begin{macro}{\@dostaticbbox} % Now for the \gls{bbox}: % \begin{macrocode} \newcommand*{\@dostaticbbox}[1]{% \edef\ff@col{}% \@sf@setoffset{#1}% \expandafter\expandafter\expandafter \@ff@getstaticpos\csname @sf@dim@\romannumeral#1\endcsname \@fr@meifdraft{% \@ff@box{\@ff@tmp@x}{\@ff@tmp@y}% {\expandafter\usebox\csname @staticframe@\romannumeral#1\endcsname}% }{S:\number#1;\csname @sf@id@\romannumeral#1\endcsname}} % \end{macrocode} %\end{macro} %\begin{macro}{\@putstaticbox} % Put the static box "#1" at its given position, with its % associated border. % \begin{macrocode} \newcommand*{\@putstaticbox}[1]{% \@sf@chckifthispg{#1}% \if@notthiscol\else \@killglue \if@twoside \ifodd\c@page \expandafter\raise\csname @sf@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname @sf@\romannumeral#1@posx\endcsname \@dostaticbox{#1}\hss}% \else \expandafter\raise\csname @sf@\romannumeral#1@eveny\endcsname \hb@xt@\z@{% \expandafter\kern \csname @sf@\romannumeral#1@evenx\endcsname \@dostaticbox{#1}\hss}% \fi \else \expandafter\raise\csname @sf@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname @sf@\romannumeral#1@posx\endcsname \@dostaticbox{#1}\hss}% \fi \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\@putstaticbbox} % Now for the \gls{bbox}: % \begin{macrocode} \newcommand*{\@putstaticbbox}[1]{% \@sf@chckifthispg{#1}% \if@notthiscol\else \@killglue \if@twoside \ifodd\c@page \expandafter\raise\csname @sf@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname @sf@\romannumeral#1@posx\endcsname \@dostaticbbox{#1}\hss}\ignorespaces \else \expandafter\raise\csname @sf@\romannumeral#1@eveny\endcsname \hb@xt@\z@{% \expandafter\kern \csname @sf@\romannumeral#1@evenx\endcsname \@dostaticbbox{#1}\hss}\ignorespaces \fi \else \expandafter\raise\csname @sf@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname @sf@\romannumeral#1@posx\endcsname \@dostaticbbox{#1}\hss}\ignorespaces \fi \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\@resetst@tics} % Clear the contents of all the \glspl{static} that have % the "clear" option set. % \begin{macrocode} \newcommand*{\@resetst@tics}{% \@colN=0\relax \whiledo{\@colN<\c@maxstatic}{\advance\@colN by 1\relax \ifthenelse{\boolean{@sf@clear@\romannumeral\@colN}}{% \global\sbox{% \csname @staticframe@\romannumeral\@colN\endcsname}{}}{}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@resetdyn@mics} % Clear the contents of the \glspl{dynamic} that have the "clear" option % set. % \begin{macrocode} \newcommand*{\@resetdyn@mics}{% \@colN=0\relax \whiledo{\@colN<\c@maxdynamic}{\advance\@colN by 1\relax \ifthenelse{\boolean{@df@clear@\romannumeral\@colN}}{% \expandafter\global\expandafter \gdef\csname @dynamicframe@\romannumeral\@colN\endcsname{}}{}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@dodfparbox} % Display contents of dynamic box (contents stored in % "\ff@contents", style given by "\ff@style"): % \begin{macrocode} \newcommand*{\@dodfparbox}[1]{% \expandafter\let\expandafter \@ff@parshape\csname @df@shape@\romannumeral#1\endcsname \expandafter\@ff@getshape\@ff@parshape\relax \ifcase\ff@shape % no shape \expandafter\expandafter\expandafter \parbox\csname @df@dim@\romannumeral#1\endcsname {% \setlength\parindent\sdfparindent \csname\ff@style\endcsname{\ff@contents}}% \or % \parshape \expandafter\expandafter\expandafter \parbox\csname @df@dim@\romannumeral#1\endcsname {% \setlength\parindent\sdfparindent \csname\ff@style\endcsname{{% \let\oldpar=\par \let\par=\ffpshpar \@ff@setsecthead \@ff@parshape \ff@contents\oldpar}}}% \or % \shapepar \expandafter\expandafter\expandafter \parbox\csname @df@dim@\romannumeral#1\endcsname {% \setlength\parindent\sdfparindent \csname\ff@style\endcsname{{\@ff@disablesec\@ff@parshape \ff@contents\par}}}% \fi } % \end{macrocode} %\end{macro} %\begin{macro}{\@dodynamicbox} % Typeset the dynamic box with its associated border. % \begin{macrocode} \newcommand*{\@dodynamicbox}[1]{% \edef\ff@frametype{% \csname @df@frametype@\romannumeral#1\endcsname}% \edef\ff@col{\csname @df@col@\romannumeral#1\endcsname}% \edef\ff@txtcol{\csname @df@txtcol@\romannumeral#1\endcsname}% \edef\ff@backcol{\csname @df@backcol@\romannumeral#1\endcsname}% \edef\ff@style{\csname @df@style@\romannumeral#1\endcsname}% \def\ff@contents{\csname @dynamicframe@\romannumeral#1\endcsname}% \@df@setoffset{#1}% \expandafter\expandafter\expandafter \@ff@getstaticpos\csname @df@dim@\romannumeral#1\endcsname \rotateframe{\csname @df@angle@\romannumeral#1\endcsname}{% \ifthenelse{\boolean{dynamicframe\romannumeral#1}}{% \@ff@fbox{\@ff@tmp@x}{\@ff@tmp@y}% {\@dodfparbox{#1}}% {\csname\ff@frametype\endcsname}% }{% \@ff@box{\@ff@tmp@x}{\@ff@tmp@y}{% \@dodfparbox{#1}}% }}} % \end{macrocode} %\end{macro} %\begin{macro}{\@dodynamicbbox} % Now for the \gls{bbox}: % \begin{macrocode} \newcommand*{\@dodynamicbbox}[1]{% \edef\ff@col{}% \@df@setoffset{#1}% \expandafter\expandafter\expandafter \@ff@getstaticpos\csname @df@dim@\romannumeral#1\endcsname \@fr@meifdraft{% \@ff@box{\@ff@tmp@x}{\@ff@tmp@y}{% \expandafter\expandafter\expandafter \parbox\csname @df@dim@\romannumeral#1\endcsname {}}% }{D:\number#1;\csname @df@id@\romannumeral#1\endcsname}} % \end{macrocode} %\end{macro} %\begin{macro}{\@putdynamicbox} % Put the \gls{dynamic} "#1" at its given position % \begin{macrocode} \newcommand*{\@putdynamicbox}[1]{% \@df@chckifthispg{#1}% \if@notthiscol\else \@killglue \if@twoside \ifodd\c@page \expandafter\raise\csname @df@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname @df@\romannumeral#1@posx\endcsname \@dodynamicbox{#1}\hss}\ignorespaces \else \expandafter\raise\csname @df@\romannumeral#1@eveny\endcsname \hb@xt@\z@{% \expandafter\kern \csname @df@\romannumeral#1@evenx\endcsname \@dodynamicbox{#1}\hss}\ignorespaces \fi \else \expandafter\raise\csname @df@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname @df@\romannumeral#1@posx\endcsname \@dodynamicbox{#1}\hss}\ignorespaces \fi \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\@putdynamicbbox} % Bounding box: % \begin{macrocode} \newcommand*{\@putdynamicbbox}[1]{% \@df@chckifthispg{#1}% \if@notthiscol\else \@killglue \if@twoside \ifodd\c@page \expandafter\raise\csname @df@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname @df@\romannumeral#1@posx\endcsname \@dodynamicbbox{#1}\hss}\ignorespaces \else \expandafter\raise\csname @df@\romannumeral#1@eveny\endcsname \hb@xt@\z@{% \expandafter\kern \csname @df@\romannumeral#1@evenx\endcsname \@dodynamicbbox{#1}\hss}\ignorespaces \fi \else \expandafter\raise\csname @df@\romannumeral#1@posy\endcsname \hb@xt@\z@{% \expandafter\kern \csname @df@\romannumeral#1@posx\endcsname \@dodynamicbbox{#1}\hss}\ignorespaces \fi \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\@@doheader} % Do standard header in the standard place. % \begin{macrocode} \newcommand*{\@@doheader}{% \setlength\@ff@tmp@y{\textheight}% \addtolength{\@ff@tmp@y}{\headsep}% \def\ff@col{}% \def\ff@txtcol{}% \def\ff@backcol{{none}}% \@ff@box{0pt}{\@ff@tmp@y}{\makebox[0pt][l]{\@dothehead}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@@dofooter} % Do standard footer in the standard place. % \begin{macrocode} \newcommand*{\@@dofooter}{% \setlength\@ff@tmp@y{-\footskip}% \def\ff@col{}% \def\ff@txtcol{}% \def\ff@backcol{{none}}% \@ff@box{0pt}{\@ff@tmp@y}{\makebox[0pt][l]{\@dothefoot}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@s@tfr@mes} % This is a modified version of the way the picture environment % works: % \begin{macrocode} \newcommand{\@s@tfr@mes}[1]{{\@picht\textheight \setbox\@picbox\hb@xt@ \textwidth \bgroup \hbox \bgroup #1\relax \egroup \hss \egroup \ht\@picbox\@picht \dp\@picbox \z@ \mbox{\box \@picbox}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@doallflowframes} % Puts all the \glspl{flow} defined on the current page % \begin{macrocode} \newcommand*{\@ff@doallflowframes}{% \@colN=0\relax \whiledo{\@colN<\c@maxflow}{\advance\@colN by 1\relax \@putcolbox{\@colN}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@doallflowframesbbox} % Flow frame \glspl{bbox}: % \begin{macrocode} \newcommand*{\@ff@doallflowframesbbox}{% \@colN=0\relax \whiledo{\@colN<\c@maxflow}{\advance\@colN by 1\relax \@putcolbbox{\@colN}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@doallstatics} % Puts all \glspl{static} defined on the current page % \begin{macrocode} \newcommand*{\@ff@doallstatics}{% \@colN=0\relax \whiledo{\@colN<\c@maxstatic}{\advance\@colN by 1\relax \@putstaticbox{\@colN}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@doallstaticsbbox} % Static frame \glspl{bbox}: % \begin{macrocode} \newcommand*{\@ff@doallstaticsbbox}{% \@colN=0\relax \whiledo{\@colN<\c@maxstatic}{\advance\@colN by 1\relax \@putstaticbbox{\@colN}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@doalldynamics} % Puts all the \glspl{dynamic} defined on the current page % \begin{macrocode} \newcommand*{\@ff@doalldynamics}{% \@colN=0\relax \whiledo{\@colN<\c@maxdynamic}{\advance\@colN by 1\relax \@putdynamicbox{\@colN}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@doalldynamicsbbox} % Dynamic frame \glspl{bbox}: % \begin{macrocode} \newcommand*{\@ff@doalldynamicsbbox}{% \@colN=0\relax \whiledo{\@colN<\c@maxdynamic}{\advance\@colN by 1\relax \@putdynamicbbox{\@colN}}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@dotypeblock} % Draw \gls{typeblock} frame if draft. % \begin{macrocode} \newcommand*{\@ff@dotypeblock}{% \makebox[0pt][l]{\@fr@meifdraft[\setffdrafttypeblockcolor]{% \vbox to \textheight{\hbox to \textwidth{}}}{}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@ff@do@allframes} % Put all frames defined on the current page. % \begin{macrocode} \newlength\ffevenoffset \newcommand*{\@ff@do@allframes}{% \ffevenoffset=0pt\relax \if@twoside \ifodd\c@page \else \ffevenoffset=-\oddsidemargin\relax \advance\ffevenoffset by \evensidemargin\relax \kern\ffevenoffset\relax \fi \fi \setlength{\@ff@tmp@x}{\textwidth}% \advance\@ff@tmp@x by -\ffevenoffset\relax \makebox[\@ff@tmp@x][l]{% \@s@tfr@mes{% \@ff@doallstatics \@@doheader \@@dofooter \@ff@doallflowframes \@ff@doalldynamics \ifshowtypeblock \@ff@dotypeblock \fi \ifshowframebbox \@ff@doallstaticsbbox \@ff@doallflowframesbbox \@ff@doalldynamicsbbox \fi \ifshowmargins \@ff@drawmargins \fi }}} % \end{macrocode} %\end{macro} %\begin{macro}{\@outputdblcol} % This was modified from the output routine for standard % two column format. After "\@g@tnextcol", the register % "\c@curpg" contains the page that the next \gls{flow} % is on. If "\c@curpg" minus "\c@page" is greater % than 1, then there is at least one page without a \gls{flow}. % These pages will have to be shipped before \TeX\ can % continue with the rest of the document. % \begin{macrocode} \newcount\@nxtcol \def\@outputdblcol{% \@nxtcol=\c@thisframe \c@curpg=\c@page \@g@tnextcol{\@nxtcol}% \if@ff@nwpg % next flow frame starts on new page \global\@firstcolumntrue \@setcolbox\c@thisframe \if@specialpage \global\@specialpagefalse \@nameuse{ps@\@specialstyle}\relax \fi \if@twoside \ifodd\count\z@ \let\@thehead\@oddhead \let\@thefoot\@oddfoot \else \let\@thehead\@evenhead \let\@thefoot\@evenfoot \fi \else \let\@thehead\@oddhead \let\@thefoot\@oddfoot \fi \@begindvi \@dodynamicthehead\@dodynamicthefoot \vbadness=\@M \setbox\@outputbox\vbox{\hbox to \textwidth{\@ff@do@allframes}}% \@combinedblfloats \@outputpage %shipout pages without flow frames \advance\c@curpg by -\c@page\relax \whiledo{\c@curpg>0}{\advance\c@curpg by -1\relax \setbox\@outputbox\vbox{\hbox to \textwidth{\@ff@do@allframes}}% \@outputpage} \begingroup \@dblfloatplacement \@startdblcolumn \@whilesw \if@fcolmade \fi {\@outputpage \@startdblcolumn }\endgroup \@resetst@tics \@resetdyn@mics \else % still on same page, save contents of box255 \global\@firstcolumnfalse \@setcolbox\c@thisframe \fi \global\c@thisframe=\@nxtcol \@setcol{\c@thisframe}\relax \global\@colht\vsize } % \end{macrocode} %\end{macro} %\begin{macro}{\@dblfloatplacement} % Modify "\@dblfloatplacement" replacing "\textheight" % with "\vsize". % \begin{macrocode} \def\@dblfloatplacement{% \global\@dbltopnum\c@dbltopnumber \global\@dbltoproom\dbltopfraction\@colht\@textmin \@colht\advance\@textmin -\@dbltoproom \@fpmin\dblfloatpagefraction\vsize \@fptop \@dblfptop \@fpsep \@dblfpsep \@fpbot \@dblfpbot} % \end{macrocode} %\end{macro} % %\subsection{Static versions of floats} % Floats can not go in saveboxes or minipages, so define % static versions to go in static and \glspl{dynamic}. % These just set "\@captype" so that the "\caption" % command may be used. %\begin{environment}{statictable} % \begin{macrocode} \newenvironment{statictable}{\def\@captype{table}}{} % \end{macrocode} %\end{environment} %\begin{environment}{staticfigure} % \begin{macrocode} \newenvironment{staticfigure}{\def\@captype{figure}}{} % \end{macrocode} %\end{environment} % %\subsection{Standard Layouts} %\subsubsection{Column Styles} % Redefine "\twocolumn" and "\onecolumn" to set up \glspl{flow} from % the dimensions of the \gls{typeblock}. Ignore the optional argument. % The \gls{flow} height will be adjusted to make sure that it % is an integer multiple of "\baselineskip", unless % "\ffvajdustfalse" is used. % \begin{macrocode} \newif\ifffvadjust \ffvadjusttrue % \end{macrocode} %\begin{macro}{\onecolumn} % "\onecolumn" will make a single \gls{flow} that takes % up the entire area of the \gls{typeblock} (adjusted according % to "\ifffvadjust".) Frames should only be created in % the preamble, otherwise the next \gls{flow} may not % be detected by the output routine. The exception to this % is when the output routine can't find any more \glspl{flow} % to use, in which case it creates a single \gls{flow} using % "\@onecolumn". Therefore, make "\onecolumn" use "\@onecolumn", % and then set "\onecolumn" as a preamble command, so it % can't be used in the document, but the output routine can % use "\@onecolumn". Syntax: \cs{onecolumn}\oarg{pages}, % where \meta{pages} is the \gls{pglist} for which the new % \gls{flow} is defined. % \begin{macrocode} \renewcommand*{\onecolumn}{\@onecolumn} % \end{macrocode} %\end{macro} %\begin{macro}{\@onecolumn} % \begin{macrocode} \newcommand*{\@onecolumn}[1][all]{% \@onecolumninarea[#1]{\textwidth}{\textheight}{0pt}{0pt}} % \end{macrocode} %\end{macro} % Need a length to store the height of % the \gls{flow} so that it can be adjusted. % \begin{macrocode} \newlength\columnheight % \end{macrocode} %\begin{macro}{\onecolumninarea} % "\onecolumn" is in fact a special case of "\onecolumninarea" % which sets up one \gls{flow} in the specified area, given % by bottom left corner (\meta{x}, \meta{y}), % relative to the \gls{typeblock}, with width \meta{w} % and height \meta{h}. % The only difference between "\onecolumninarea" and % explicitly creating the \gls{flow} using "\newflowframe" % is the "\onecolumninarea" will adjust the vertical height % the ensure it is a multiple of "\baselineskip". There % is also no starred version, so if you want a border, you % will need to set it explicitly using "\setflowframe". % Syntax:\newline % \cs{onecolumninarea}\oarg{pages}\marg{w}\marg{h}\marg{x}\marg{y}. % \begin{macrocode} \newcommand*{\onecolumninarea}{\@onecolumninarea} \@onlypreamble{\onecolumninarea} % \end{macrocode} %\end{macro} %\begin{macro}{\@onecolumninarea} % \begin{macrocode} \newcommand*{\@onecolumninarea}[5][all]{% \setlength{\columnheight}{#3}% \ifffvadjust\adjustheight{\columnheight}\fi% \@n@wflowframe[#1]{#2}{\columnheight}{#4}{#5}} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumn} % Set up two \glspl{flow} parallel to each other % with a distance of "\columnsep" between them, to % fill the entire \gls{typeblock} (although the frames may % end up marginally shorter than "\textheight" after % they have been adjusted.) Again, these commands may only % be used in the preamble. Note that unlike the standard % "\twocolumn" command, this one has an optional argument % that indicates which pages the two \glspl{flow} should % appear on. Syntax: \cs{twocolumn}\oarg{pages}. % \begin{macrocode} \renewcommand*{\twocolumn}{\@twocolumn} % \end{macrocode} %\end{macro} %\begin{macro}{\@twocolumn} % \begin{macrocode} \newcommand*{\@twocolumn}[1][all]{% \@twocolumninarea[#1]{\textwidth}{\textheight}{0pt}{0pt}} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumninarea} % Again, "\twocolumn" is actually a special case of % "\twocolumninarea". % Syntax:\newline % \cs{twocolumninarea}\oarg{pages}\marg{w}\marg{h}\marg{x}\marg{y}. % \begin{macrocode} \newcommand*{\twocolumninarea}{\@twocolumninarea} \@onlypreamble{\twocolumninarea} % \end{macrocode} %\end{macro} %\begin{macro}{\@twocolumninarea} % \begin{macrocode} \newcommand*{\@twocolumninarea}[5][all]{% \setlength{\columnheight}{#3}% \ifffvadjust\adjustheight{\columnheight}\fi% \setlength{\columnwidth}{#2}% \addtolength{\columnwidth}{-\columnsep}% \divide\columnwidth by 2\relax \setlength{\@ff@tmp@x}{#4}% \addtolength{\@ff@tmp@x}{\columnwidth}% \addtolength{\@ff@tmp@x}{\columnsep}% \@n@wflowframe[#1]{\columnwidth}{\columnheight}{#4}{#5}% \setflowframe{\c@maxflow}{margin=left}% \@n@wflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{#5}% \setflowframe{\c@maxflow}{margin=right}% } % \end{macrocode} %\end{macro} %\begin{macro}{\Ncolumn} % Again for an aribtrary number of columns (\meta{n}). Syntax: % \cs{Ncolumn}\oarg{pages}\marg{n}. % \begin{macrocode} \newcommand*{\Ncolumn}[2][all]{% \Ncolumninarea[#1]{#2}{\textwidth}{\textheight}{0pt}{0pt}} \@onlypreamble{\Ncolumn} % \end{macrocode} %\end{macro} %\begin{macro}{\Ncolumninarea} % Check the number of \glspl{flow} requested, and do one % of the special cases if available. % Syntax:\newline % \cs{Ncolumninarea}\oarg{pages}\marg{n}\marg{w}\marg{h}\marg{x}\marg{y}. % \begin{macrocode} \newcommand*{\Ncolumninarea}[6][all]{% \ifnum#2>2\relax \@Ncolumninarea[#1]{#2}{#3}{#4}{#5}{#6}% \else \ifcase#2\relax \PackageError{flowfram}{% You have requested 0 flowframes!}{% It does not make much sense to ask to create 0 flow frames}% \or \onecolumninarea[#1]{#3}{#4}{#5}{#6}% \or \twocolumninarea[#1]{#3}{#4}{#5}{#6}% \else \PackageError{flowfram}{% Can't create a negative number of flow frames!}{% You have asked for \number#2 \space flow frames which really doesn't make sense}% \fi \fi } \@onlypreamble{\Ncolumninarea} % \end{macrocode} %\end{macro} %\begin{macro}{\@Ncolumninarea} % Set up \meta{n} columns in the area specified. % There is a horizontal distance of "\columnsep" % between them all. % \begin{macrocode} \newcommand*{\@Ncolumninarea}[6][all]{% \@colN=#2\relax \advance\@colN by -1\relax \setlength{\columnwidth}{#3}% \addtolength{\columnwidth}{-\@colN\columnsep}% \divide\columnwidth by #2\relax \setlength{\@ff@tmp@x}{#5}% \setlength{\columnheight}{#4}% \ifffvadjust\adjustheight{\columnheight}\fi% \@colN=0\relax \loop \advance\@colN by 1\relax \newflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{#6}% \addtolength{\@ff@tmp@x}{\columnwidth}% \addtolength{\@ff@tmp@x}{\columnsep}% \ifnum\@colN<#2 \repeat } % \end{macrocode} %\end{macro} % % Set up something similar but have another frame (of type % \meta{type}) at the top of the other frames. %\begin{macro}{\vcolumnsep} % The vertical distance between the top frames and column flow % frames when created using "\Ncolumnhead" etc is given by: % \begin{macrocode} \newlength{\vcolumnsep} \setlength{\vcolumnsep}{\columnsep} % \end{macrocode} %\end{macro} %\begin{macro}{\onecolumntop} % "\onecolumntop" makes one \gls{flow}, and one \meta{type} % frame in the area specified, where the \meta{type} frame is % \meta{H} high. % The distance between the top frame and the column \gls{flow} % will be approximately "\vcolumnsep". (The height of \gls{flow} % may be adjusted to make it an integer multiple of % "\baselineskip".) % % First the special case where the area is the \gls{typeblock}. % Syntax:\newline % \cs{onecolumntop}\oarg{pages}\marg{type}\marg{H} % \begin{macrocode} \newcommand*{\onecolumntop}[3][all]{% \onecolumntopinarea[#1]{#2}{#3}{\textwidth}{\textheight}{0pt}{0pt}} \@onlypreamble{\onecolumntop} % \end{macrocode} %\end{macro} %\begin{macro}{\onecolumnStop} % Special case for \gls{static}. % Syntax: \cs{onecolumnStop}\oarg{pages}\marg{H} % \begin{macrocode} \newcommand*{\onecolumnStop}[2][all]{% \onecolumntopinarea[#1]{static}{#2}{\textwidth}{\textheight}{0pt}{0pt}} % \end{macrocode} %\end{macro} %\begin{macro}{\onecolumnDtop} % Special case for \gls{dynamic}. % Syntax: \cs{onecolumnDtop}\oarg{pages}\marg{H} % \begin{macrocode} \newcommand*{\onecolumnDtop}[2][all]{% \onecolumntopinarea[#1]{dynamic}{#2}{\textwidth}{\textheight}{0pt}{0pt}} % \end{macrocode} %\end{macro} %\begin{macro}{\newframe} % Create a frame of given type. % Syntax:\newline % \cs{newframe}\oarg{pages}\marg{type}\marg{w}\marg{h}\marg{x}\marg{y}. % \begin{macrocode} \newcommand*{\newframe}[6][all]{% \ifthenelse{\equal{#2}{flow}}{% \@n@wflowframe[#1]{#3}{#4}{#5}{#6}% }{% \ifthenelse{\equal{#2}{dynamic}}{% \@n@wdynamicframe[#1]{#3}{#4}{#5}{#6}}{% \ifthenelse{\equal{#2}{static}}{% \@n@wstaticframe[#1]{#3}{#4}{#5}{#6}}{% \PackageError{flowfram}{Unknown frame type '#2'}{% Available frame types are: 'flow', 'static' and 'dynamic'}}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\onecolumntopinarea} % Now for a specified area. % Syntax:\newline % \cs{onecolumntopinarea}\oarg{pages}\marg{type}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}. % \begin{macrocode} \newlength\@ff@staticH \newcommand*{\onecolumntopinarea}[7][all]{% \setlength{\@ff@staticH}{#3}% \setlength{\@ff@tmp@y}{#5}% \addtolength{\@ff@tmp@y}{-\@ff@staticH}% \setlength{\columnheight}{\@ff@tmp@y}% \addtolength{\columnheight}{-\vcolumnsep}% \ifffvadjust\adjustheight{\columnheight}\fi% \addtolength{\@ff@tmp@y}{#7}% \newframe[#1]{#2}{#4}{\@ff@staticH}{#6}{\@ff@tmp@y}% \@n@wflowframe[#1]{#4}{\columnheight}{#6}{#7}% } \@onlypreamble{\onecolumntopinarea} % \end{macrocode} %\end{macro} %\begin{macro}{\onecolumnStopinarea} % Special case for \gls{static}. % Syntax:\newline % \cs{onecolumnStopinarea}\oarg{pages}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}. % \begin{macrocode} \newcommand*{\onecolumnStopinarea}[6][all]{% \onecolumntopinarea[#1]{static}{#2}{#3}{#4}{#5}{#6}} % \end{macrocode} %\end{macro} %\begin{macro}{\onecolumnDtopinarea} % Special case for \gls{dynamic}. % Syntax:\newline % \cs{onecolumnDtopinarea}\oarg{pages}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}. % \begin{macrocode} \newcommand*{\onecolumnDtopinarea}[6][all]{% \onecolumntopinarea[#1]{dynamic}{#2}{#3}{#4}{#5}{#6}} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumntop} % Now for two \glspl{flow}, with a single \meta{type} frame % above both of them. % Syntax:\newline % \cs{twocolumntop}\oarg{pages}\marg{type}\marg{H} % % First the special case where the area is the entire % \gls{typeblock}: % \begin{macrocode} \newcommand*{\twocolumntop}[3][all]{% \twocolumntopinarea[#1]{#2}{#3}{\textwidth}{\textheight}{0pt}{0pt}} \@onlypreamble{\twocolumntop} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumnStop} % Special case for \gls{static}. % \begin{macrocode} \newcommand*{\twocolumnStop}[2][all]{% \@twocolumntopinarea[#1]{static}{#2}{\textwidth}{\textheight}{0pt}{0pt}} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumnDtop} % Special case for \gls{dynamic}. % \begin{macrocode} \newcommand*{\twocolumnDtop}[2][all]{% \twocolumntop[#1]{dynamic}{#2}} % \end{macrocode} %\end{macro} % % Now for a general area. %\begin{macro}{\twocolumntopinarea} % Syntax:\newline % \cs{twocolumntopinarea}\oarg{pages}\marg{type}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}. % \begin{macrocode} \newcommand*{\twocolumntopinarea}{\@twocolumntopinarea} \newcommand*{\@twocolumntopinarea}[7][all]{% \setlength{\@ff@staticH}{#3}% % work out where to put the static frame \setlength{\@ff@tmp@y}{#5}% \addtolength{\@ff@tmp@y}{-\@ff@staticH}% \setlength{\columnheight}{\@ff@tmp@y}% \addtolength{\@ff@tmp@y}{#7}% \newframe[#1]{#2}{#4}{\@ff@staticH}{#6}{\@ff@tmp@y}% % work out height of the flow frames \addtolength{\columnheight}{-\vcolumnsep}% \ifffvadjust\adjustheight{\columnheight}\fi% % work out the widths of the flow frames \setlength{\columnwidth}{#4}% \addtolength{\columnwidth}{-\columnsep}% \divide\columnwidth by 2\relax % work out the offset of the second column \setlength{\@ff@tmp@x}{\columnwidth}% \addtolength{\@ff@tmp@x}{\columnsep}% \addtolength{\@ff@tmp@x}{#6}% \@n@wflowframe[#1]{\columnwidth}{\columnheight}{#6}{#7}% \setflowframe{\c@maxflow}{margin=left}% \@n@wflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{#7}% \setflowframe{\c@maxflow}{margin=right}% } \@onlypreamble{\twocolumntopinarea} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumnStopinarea} % Special case for \gls{static}. % \begin{macrocode} \newcommand*{\twocolumnStopinarea}[6][all]{% \twocolumntopinarea[#1]{static}{#2}{#3}{#4}{#5}{#6}} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumnDtopinarea} % Special case for \gls{dynamic}. % \begin{macrocode} \newcommand*{\twocolumnDtopinarea}[6][all]{% \twocolumntopinarea[#1]{dynamic}{#2}{#3}{#4}{#5}{#6}} % \end{macrocode} %\end{macro} %\begin{macro}{\Ncolumntop} % Similarly for an arbitrary number of \glspl{flow}. % Special case where the area is the \gls{typeblock}. % % Syntax:\newline % \cs{Ncolumntop}\oarg{pages}\marg{type}\marg{n}\marg{H} % \begin{macrocode} \newcommand*{\Ncolumntop}[4][all]{% \Ncolumntopinarea[#1]{#2}{#3}{#4}{\textwidth}{\textheight}{0pt}{0pt}} \@onlypreamble{\Ncolumntop} % \end{macrocode} %\end{macro} %\begin{macro}{\NcolumnStop} % Special case for \gls{static}. % \begin{macrocode} \newcommand*{\NcolumnStop}[3][all]{% \Ncolumntop[#1]{static}{#2}{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\NcolumnDtop} % Special case for \gls{dynamic}. % \begin{macrocode} \newcommand*{\NcolumnDtop}[3][all]{% \Ncolumntop[#1]{dynamic}{#2}{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\Ncolumntopinarea} % Again test to make sure the user requested a sensible % number. % \begin{macrocode} \newcommand*{\Ncolumntopinarea}[8][all]{% \ifnum#3>2\relax \@Ncolumntopinarea[#1]{#2}{#3}{#4}{#5}{#6}{#7}{#8}% \else \ifcase#3\relax \PackageError{flowfram}{% You have requested 0 flowframes!}{% It does not make much sense to ask to create 0 flow frames} \or \onecolumntopinarea[#1]{#2}{#4}{#5}{#6}{#7}{#8}% \or \twocolumntopinarea[#1]{#2}{#4}{#5}{#6}{#7}{#8}% \else \PackageError{flowfram}{% Can't create a negative number of flow frames!}{% You have asked for \number#3 \space flow frames which really doesn't make sense}% \fi \fi } \@onlypreamble{\Ncolumntopinarea} % \end{macrocode} %\end{macro} %\begin{macro}{\@Ncolumntopinarea} % Fit the frames into specified area. % Syntax:\newline % \cs{Ncolumntopinarea}\oarg{pages}\marg{type}\marg{n}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}. % \begin{macrocode} \newcommand*{\@Ncolumntopinarea}[8][all]{% \setlength{\@ff@staticH}{#4}% % \end{macrocode} % work out where to put the static frame % \begin{macrocode} \setlength{\@ff@tmp@y}{#6}% \addtolength{\@ff@tmp@y}{-\@ff@staticH}% \setlength{\columnheight}{\@ff@tmp@y}% \addtolength{\@ff@tmp@y}{#8}% \newframe[#1]{#2}{#5}{\@ff@staticH}{#7}{\@ff@tmp@y}% % \end{macrocode} % work out height of the flow frames % \begin{macrocode} \addtolength{\columnheight}{-\vcolumnsep}% % \end{macrocode} % adjust the flow frame height so that it is a multiple of % \cs{baselineskip} % \begin{macrocode} \ifffvadjust\adjustheight{\columnheight}\fi% % \end{macrocode} % work out the widths of the flow frames % \begin{macrocode} \@colN=#3\relax \advance\@colN by -1\relax \setlength{\columnwidth}{#5}% \addtolength{\columnwidth}{-\@colN\columnsep}% \divide\columnwidth by #3\relax \setlength{\@ff@tmp@x}{#7}% \@colN=0\relax \loop \advance\@colN by 1\relax \newflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{#8}% % work out the offset for the next column \addtolength{\@ff@tmp@x}{\columnwidth}% \addtolength{\@ff@tmp@x}{\columnsep}% \ifnum\@colN<#3 \repeat } % \end{macrocode} %\end{macro} %\begin{macro}{\NcolumnStopinarea} % Specific case for \gls{static}. % \begin{macrocode} \newcommand*{\NcolumnStopinarea}[7][all]{% \Ncolumntopinarea[#1]{static}{#2}{#3}{#4}{#5}{#6}{#7}} % \end{macrocode} %\end{macro} %\begin{macro}{\NcolumnDtopinarea} % Specific case for \gls{dynamic}. % \begin{macrocode} \newcommand*{\NcolumnDtopinarea}[7][all]{% \Ncolumntopinarea[#1]{dynamic}{#2}{#3}{#4}{#5}{#6}{#7}} % \end{macrocode} %\end{macro} % Now the same kind of thing but with the \meta{type} frame at the % bottom. Firstly, a single \gls{flow} with a \meta{type} % frame below it. % %\begin{macro}{\onecolumnbottom} % Syntax:\newline % \cs{onecolumnbottom}\oarg{pages}\marg{type}\marg{H} % \begin{macrocode} \newcommand*{\onecolumnbottom}[3][all]{% \onecolumnSbottominarea[#1]{#2}{#3}{\textwidth}{\textheight}{0pt}{0pt}} % \end{macrocode} %\end{macro} % This command may only be used in the preamble. % \begin{macrocode} \@onlypreamble{\onecolumnbottom} % \end{macrocode} %\begin{macro}{\onecolumnSbottom} % Special case for \gls{static}. % \begin{macrocode} \newcommand*{\onecolumnSbottom}[2][all]{% \onecolumnbottom[#1]{static}{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\onecolumnDbottom} % Special case for \gls{dynamic}. % \begin{macrocode} \newcommand*{\onecolumnDbottom}[2][all]{% \onecolumnbottom[#1]{dynamic}{#2}} % \end{macrocode} %\end{macro} % % General case of the above, but fit in specified area. %\begin{macro}{\onecolumnbottominarea} % Syntax:\newline % \cs{onecolumnbottominarea}\oarg{pages}\marg{type}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y},\newline % where \meta{H} is the \meta{type} frame's height. % The area is defined by bottom % left co-ordinates (\meta{x}, \meta{y}) width \meta{w}, and % height \meta{h}. % \begin{macrocode} \newcommand*{\onecolumnbottominarea}[7][all]{% \setlength{\@ff@staticH}{#3}% \setlength{\columnheight}{#5}% \addtolength{\columnheight}{-\@ff@staticH}% \addtolength{\columnheight}{-\vcolumnsep}% \ifffvadjust\adjustheight{\columnheight}\fi% \setlength{\@ff@tmp@y}{#5}% \addtolength{\@ff@tmp@y}{-\columnheight}% \addtolength{\@ff@tmp@y}{#7}% \newframe[#1]{#2}{#4}{\@ff@staticH}{#6}{#7}% \newflowframe[#1]{#4}{\columnheight}{#6}{\@ff@tmp@y}% } % \end{macrocode} %\end{macro} % Again, this command may only be used in the preamble. % \begin{macrocode} \@onlypreamble{\onecolumnbottominarea} % \end{macrocode} %\begin{macro}{\onecolumnSbottominarea} % Special case for \gls{static}. % \begin{macrocode} \newcommand*{\onecolumnSbottominarea}[6][all]{% \onecolumnbottominarea[#1]{static}{#2}{#3}{#4}{#5}{#6}} % \end{macrocode} %\end{macro} %\begin{macro}{\onecolumnDbottominarea} % Special case for \gls{dynamic}. % \begin{macrocode} \newcommand*{\onecolumnDbottominarea}[6][all]{% \onecolumnbottominarea[#1]{dynamic}{#2}{#3}{#4}{#5}{#6}} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumnbottom} % Now for two \glspl{flow} side by side with a static % frame underneath both of them. Firstly, the specific % case where the area is the entire \gls{typeblock}. % Syntax:\newline % \cs{twocolumnbottom}\oarg{pages}\marg{type}\marg{H}. % \begin{macrocode} \newcommand*{\twocolumnbottom}[3][all]{% \twocolumnSbottominarea[#1]{#2}{#3}{\textwidth}{\textheight}{0pt}{0pt}} \@onlypreamble{\twocolumnbottom} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumnSbottom} % Special case for \gls{static}. % \begin{macrocode} \newcommand*{\twocolumnSbottom}[2][all]{% \twocolumnbottom[#1]{static}{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumnDbottom} % Special case for \gls{dynamic}. % \begin{macrocode} \newcommand*{\twocolumnDbottom}[2][all]{% \twocolumnbottom[#1]{dynamic}{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumnbottominarea} % Now for a general area. % Syntax:\newline % \cs{twocolumnbottominarea}\oarg{pages}\marg{type}\marg{H}\marg{w}\marg{h}\marg{x}\marg{y}. % \begin{macrocode} \newcommand*{\twocolumnbottominarea}[7][all]{% \setlength{\@ff@staticW}{#4}% \setlength{\@ff@staticH}{#3}% % \end{macrocode} % work out height of the flow frames % \begin{macrocode} \setlength{\columnheight}{#5}% \addtolength{\columnheight}{-\@ff@staticH}% \addtolength{\columnheight}{-\vcolumnsep}% \ifffvadjust\adjustheight{\columnheight}\fi% \newframe[#1]{#2}{\@ff@staticW}{\@ff@staticH}{#6}{#7}% % \end{macrocode} % work out the $y$ position of the flow frames % \begin{macrocode} \setlength{\@ff@tmp@y}{#5}% \addtolength{\@ff@tmp@y}{-\columnheight}% \addtolength{\@ff@tmp@y}{#7}% % \end{macrocode} % work out the widths of the flow frames % \begin{macrocode} \setlength{\columnwidth}{\@ff@staticW}% \addtolength{\columnwidth}{-\columnsep}% \divide\columnwidth by 2\relax % \end{macrocode} % work out the $x$ offset of the second column % \begin{macrocode} \setlength{\@ff@tmp@x}{\columnwidth}% \addtolength{\@ff@tmp@x}{\columnsep}% \addtolength{\@ff@tmp@x}{#6}% \newflowframe[#1]{\columnwidth}{\columnheight}{#6}{\@ff@tmp@y}% \setflowframe{\c@maxflow}{margin=left}% \newflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{\@ff@tmp@y}% \setflowframe{\c@maxflow}{margin=right}% } \@onlypreamble{\twocolumnbottominarea} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumnSbottominarea} % Special case for \gls{static}. % \begin{macrocode} \newcommand*{\twocolumnSbottominarea}[6][all]{% \twocolumnbottominarea[#1]{static}{#2}{#3}{#4}{#5}{#6}} % \end{macrocode} %\end{macro} %\begin{macro}{\twocolumnDbottominarea} % Special case for \gls{dynamic}. % \begin{macrocode} \newcommand*{\twocolumnDbottominarea}[6][all]{% \twocolumnbottominarea[#1]{dynamic}{#2}{#3}{#4}{#5}{#6}} % \end{macrocode} %\end{macro} % Now for an arbitrary number of parallel \glspl{flow} % with a \gls{static} beneath all of them. % %\begin{macro}{\Ncolumnbottom} % First make them fill the entire \gls{typeblock}. % Syntax:\newline % \cs{Ncolumnbottom}\oarg{pages}\marg{type}\marg{H}. % \begin{macrocode} \newcommand*{\Ncolumnbottom}[4][all]{% \Ncolumnbottominarea[#1]{#2}{#3}{#4}{\textwidth}{\textheight}{0pt}{0pt}} \@onlypreamble{\Ncolumnbottom} % \end{macrocode} %\end{macro} %\begin{macro}{\NcolumnSbottom} % Special case for \gls{static}. % \begin{macrocode} \newcommand*{\NcolumnSbottom}[3][all]{% \Ncolumnbottom[#1]{static}{#2}{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\NcolumnDbottom} % Special case for \gls{dynamic}. % \begin{macrocode} \newcommand*{\NcolumnDbottom}[3][all]{% \Ncolumnbottom[#1]{dynamic}{#2}{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\Ncolumnbottominarea} % Again check the user has requested a sensible number. % \begin{macrocode} \newcommand*{\Ncolumnbottominarea}[8][all]{% \ifnum#3>2\relax \@Ncolumnbottominarea[#1]{#2}{#3}{#4}{#5}{#6}{#7}{#8}% \else \ifcase#3\relax \PackageError{flowfram}{% You have requested 0 flowframes!}{% It does not make much sense to ask to create 0 flow frames} \or \onecolumnbottominarea[#1]{#2}{#4}{#5}{#6}{#7}{#8}% \or \twocolumnbottominarea[#1]{#2}{#4}{#5}{#6}{#7}{#8}% \else \PackageError{flowfram}{% Can't create a negative number of flow frames!}{% You have asked for \number#3 \space flow frames which really doesn't make sense}% \fi \fi } \@onlypreamble{\Ncolumnbottominarea} % \end{macrocode} %\end{macro} %\begin{macro}{\@NcolumnSbottominarea} % An arbitrary number of columns with a \gls{static} % underneath them all, filling the specified area. % \begin{macrocode} \newcommand*{\@NcolumnSbottominarea}[8][all]{% \setlength{\@ff@staticH}{#4}% % \end{macrocode} % work out height of the flow frames % \begin{macrocode} \setlength{\columnheight}{#6}% \addtolength{\columnheight}{-\@ff@staticH}% \addtolength{\columnheight}{-\vcolumnsep}% % \end{macrocode} % adjust the flow frame height so that it is a multiple of % \cs{baselineskip} % \begin{macrocode} \ifffvadjust\adjustheight{\columnheight}\fi \newframe[#1]{#2}{#5}{\@ff@staticH}{#7}{#8}% % \end{macrocode} % work out the $y$ offset of the flow frames % \begin{macrocode} \setlength{\@ff@tmp@y}{#6}% \addtolength{\@ff@tmp@y}{-\columnheight}% \addtolength{\@ff@tmp@y}{#8}% % \end{macrocode} % work out the widths of the flow frames % \begin{macrocode} \@colN=#3\relax \advance\@colN by -1\relax \setlength{\columnwidth}{#5}% \addtolength{\columnwidth}{-\@colN\columnsep}% \divide\columnwidth by #3\relax \setlength{\@ff@tmp@x}{#7}% \@colN=0\relax \loop \advance\@colN by 1\relax \newflowframe[#1]{\columnwidth}{\columnheight}{\@ff@tmp@x}{\@ff@tmp@y}% % \end{macrocode} % work out the offset for the next column % \begin{macrocode} \addtolength{\@ff@tmp@x}{\columnwidth}% \addtolength{\@ff@tmp@x}{\columnsep}% \ifnum\@colN<#3 \repeat } % \end{macrocode} %\end{macro} %\begin{macro}{\NcolumnSbottominarea} % Specific case for \gls{static}. % \begin{macrocode} \newcommand*{\NcolumnSbottominarea}[1][all]{% \Ncolumnbottominarea[#1]{static}} % \end{macrocode} %\end{macro} %\begin{macro}{\NcolumnDbottominarea} % Specific case for \gls{dynamic}. % \begin{macrocode} \newcommand*{\NcolumnDbottominarea}[1][all]{% \Ncolumnbottominarea[#1]{dynamic}} % \end{macrocode} %\end{macro} %\begin{macro}{\adjustheight} % Given a height "#1" (a length), adjust it so that it is a multiple of "\baselineskip". % \begin{macrocode} \newcount\@ff@adjh \newcommand*{\adjustheight}[1]{% % \end{macrocode} % convert to an integer % \begin{macrocode} \@ff@adjh=#1\relax \divide\@ff@adjh by \baselineskip\relax #1=\baselineskip\relax \multiply#1 by \@ff@adjh\relax } % \end{macrocode} %\end{macro} %\begin{macro}{\adjustcolsep} % Adjust the value of "\columnsep" so that the margins will fit between columns. % \begin{macrocode} \newcommand*{\adjustcolsep}{% \multiply\columnsep by 2\relax \addtolength{\columnsep}{\marginparwidth}} % \end{macrocode} %\end{macro} % %\subsubsection{Backdrop Effects} % Set up some commands to make \glspl{static} for different styles % of backdrop. %\begin{macro}{\vtwotone} % Syntax:\newline % \cs{vtwotone}\oarg{pages}\oarg{xoffset}\marg{W1}\marg{C1}\marg{L1}\marg{W2}\marg{C2}\marg{L2} %\newline where the first frame % has width \meta{W1} with background colour \meta{C1} and label \meta{L1}. % The second frame has width \meta{W2} with background colour \meta{C2} % and label \meta{L2}. Unlike earlier commands, the $x$-offset is % relative to the left page edge \emph{not} the \gls{typeblock}. % This is because they are designed for backdrops, which % tend to span the entire page. % Note that the colour specs must be % completely enclosed in braces. e.g.\ "{[gray]{0.5}}" \emph{not} "[gray]{0.5}". % % Need a length to store the width of the \gls{static}. % \begin{macrocode} \newlength\@ff@staticW % \end{macrocode} % Vertical two tone effect where the height of the static % frames is equal to the paper height. % \begin{macrocode} \newcommand*{\vtwotone}[1][all]{% \def\ff@pages{#1}\@vtwotone} \newcommand*{\@vtwotone}[1][0pt]{\@@vtwotonebottom{#1}{\paperheight}} % \end{macrocode} %\end{macro} %\begin{macro}{\vtwotonebottom} % Vertical two tone effect along the bottom of the page, of % height \meta{H}. % Syntax:\newline % \cs{vtwotonebottom}\oarg{pages}\oarg{xoffset}\marg{H}\marg{W1}\marg{C1}\marg{L1}\marg{W2}\marg{C2}\marg{L2} % where the first frame starts at \meta{xoffset}. % \begin{macrocode} \newcommand*{\@@vtwotonebottom}[8]{% \computeleftedgeodd{\@ff@tmp@x}% \if@twoside \computeleftedgeeven{\@ff@tmp@x@even}% \else \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}% \fi \computebottomedge{\@ff@tmp@y}% \addtolength{\@ff@tmp@x}{#1}% \addtolength{\@ff@tmp@x@even}{#1}% \@nextvband{\ff@pages}{#2}{#3}{#4}{#5}% \@nextvband{\ff@pages}{#2}{#6}{#7}{#8}% } \@onlypreamble{\vtwotone} % \end{macrocode} %\end{macro} %\begin{macro}{\vtwotonebottom} % Border strip along the bottom of the page % \begin{macrocode} \newcommand*{\vtwotonebottom}[1][all]{% \def\ff@pages{#1}\@vtwotonebottom} \@onlypreamble{\vtwotonebottom} \newcommand*{\@vtwotonebottom}[2][0pt]{\@@vtwotonebottom{#1}{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\vtwotonetop} % Border strip along the top of the page % \begin{macrocode} \newcommand*{\vtwotonetop}[1][all]{% \def\ff@pages{#1}\@vtwotonetop} \newcommand*{\@vtwotonetop}[2][0pt]{\@@vtwotonetop{#1}{#2}} \newcommand*{\@@vtwotonetop}[8]{% \computeleftedgeodd{\@ff@tmp@x}% \if@twoside \computeleftedgeeven{\@ff@tmp@x@even}% \else \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}% \fi \computetopedge{\@ff@tmp@y}% \addtolength{\@ff@tmp@y}{-#2}% \addtolength{\@ff@tmp@x}{#1}% \addtolength{\@ff@tmp@x@even}{#1}% \@nextvband{\ff@pages}{#2}{#3}{#4}{#5}% \@nextvband{\ff@pages}{#2}{#6}{#7}{#8}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@nextvband} % Make next \gls{static}. Syntax:\newline % \cs{@nextvband}\marg{pages}\marg{height}\marg{width}\marg{colour specs}\marg{label}\newline % $x$ and $y$ offsets are given by "\@ff@tmp@x" and "\@ff@tmp@y". % On exit, "\@ff@tmp@x" is set to the right border. % \begin{macrocode} \newcommand*{\@nextvband}[5]{% \setlength{\@ff@staticW}{#3}% \ifthenelse{\equal{#5}{}}{% \newstaticframe[#1]{\@ff@staticW}{#2}{\@ff@tmp@x}{\@ff@tmp@y}}% {\newstaticframe[#1]{\@ff@staticW}{#2}{\@ff@tmp@x}{\@ff@tmp@y}[#5]}% \expandafter\global\expandafter\setlength \csname @sf@\romannumeral\c@maxstatic @evenx\endcsname{% \@ff@tmp@x@even}% \@setframecol#4\end{\c@maxstatic}{backcol}{sf}% \addtolength{\@ff@tmp@x}{\@ff@staticW}% \addtolength{\@ff@tmp@x@even}{\@ff@staticW}% } % \end{macrocode} %\end{macro} %\begin{macro}{\vNtone} % Similarly for N colours. Syntax:\newline % \cs{vNtone}\oarg{pages}\oarg{xoffset}\marg{n}\marg{W1}\marg{C1}\marg{L1}\ldots\marg{Wn}\marg{Cn}\marg{Ln}\newline % where the first frame has width \meta{W1} with background % colour \meta{C1} and label \meta{L1} all the way up to % the \meta{n}th frame which has width \meta{Wn}, background % colour \meta{Cn} and \gls{idl} \meta{Ln}. % % Keep track of which strip we are doing. % \begin{macrocode} \newcount\@thisstrip % \end{macrocode} % This command needs two optional arguments, so store % first optional argument, and look for the next. % \begin{macrocode} \newcommand*{\vNtone}[1][all]{% \def\ff@pages{#1}\@vNtone} % \end{macrocode} %\end{macro} %\begin{macro}{\@vNtone} % Got the first argument, now get the next. % \begin{macrocode} \newcommand*{\@vNtone}[2][0pt]{% \@@vNtone{#1}{#2}{\paperheight}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@vNtone} % Vertical \meta{n} tone aligned along the % bottom of the page with height "#3". % \begin{macrocode} \newcommand*{\@@vNtone}[3]{% \computeleftedgeodd{\@ff@tmp@x}% \if@twoside \computeleftedgeeven{\@ff@tmp@x@even}% \else \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}% \fi \computebottomedge{\@ff@tmp@y}% \addtolength{\@ff@tmp@x}{#1}% \addtolength{\@ff@tmp@x@even}{#1}% \@thisstrip=#2\relax \setlength{\@ff@staticH}{#3}% \@nextvNband% } % \end{macrocode} %\end{macro} %\begin{macro}{\@nextvNband} % Recursively do the next strip. % \begin{macrocode} \newcommand*{\@nextvNband}{% \ifnum\@thisstrip>0\relax \let\flf@next\@@nextvNband \else \let\flf@next\relax \fi \advance\@thisstrip by -1\relax \flf@next} % \end{macrocode} %\end{macro} %\begin{macro}{\@@nextvNband} % Do current strip, and go on to next one. % \begin{macrocode} \newcommand*{\@@nextvNband}[3]{% \@nextvband{\ff@pages}{\@ff@staticH}{#1}{#2}{#3}\@nextvNband} \@onlypreamble{\vNtone} % \end{macrocode} %\end{macro} %\begin{macro}{\vNtonebottom} % Border strip along the bottom of the page. Same as above % but user specifies the height. % \begin{macrocode} \newcommand*{\vNtonebottom}[1][all]{% \def\ff@pages{#1}\@vNtonebottom} \@onlypreamble{\vNtonebottom} % \end{macrocode} %\end{macro} %\begin{macro}{\@vNtonebottom} % \begin{macrocode} \newcommand*{\@vNtonebottom}[3][0pt]{% \@@vNtone{#1}{#2}{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\vNtonetop} % Border strip along the top of the page. Again two % optional arguments are required. Get first optional % argument. % \begin{macrocode} \newcommand*{\vNtonetop}[1][all]{% \def\ff@pages{#1}\@vNtonetop} \@onlypreamble{\vNtonetop} % \end{macrocode} %\end{macro} %\begin{macro}{\@vNtonetop} % Get next optional argument. % \begin{macrocode} \newcommand*{\@vNtonetop}[3][0pt]{% \@@vNtonetop{#1}{#2}{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@vNtonetop} % Now get on with it. Again, it has to be done % recursively. % \begin{macrocode} \newcommand*{\@@vNtonetop}[3]{% \computeleftedgeodd{\@ff@tmp@x}% \if@twoside \computeleftedgeeven{\@ff@tmp@x@even}% \else \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}% \fi \computetopedge{\@ff@tmp@y}% \addtolength{\@ff@tmp@y}{-#3}% \addtolength{\@ff@tmp@x}{#1}% \addtolength{\@ff@tmp@x@even}{#1}% \@thisstrip=#2\relax \setlength{\@ff@staticH}{#3}% \@nextvNband% } % \end{macrocode} %\end{macro} %\begin{macro}{\htwotone} % Now do horizontal strips. Syntax:\newline % \cs{htwotone}\oarg{pages}\oarg{y offset}\marg{H1}\marg{C1}\marg{L1}\marg{H2}\marg{C2}\marg{L2} % \begin{macrocode} \newcommand*{\htwotone}[1][all]{% \def\ff@pages{#1}\@htwotone} % \end{macrocode} %\end{macro} %\begin{macro}{\@htwotone} % \begin{macrocode} \newcommand*{\@htwotone}[1][0pt]{\@@htwotoneleft{#1}{\paperwidth}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@htwotoneleft} % This is all done in much the same way as the vertical % strips. % \begin{macrocode} \newcommand*{\@@htwotoneleft}[8]{% \computeleftedgeodd{\@ff@tmp@x}% \if@twoside \computeleftedgeeven{\@ff@tmp@x@even}% \else \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}% \fi \computebottomedge{\@ff@tmp@y}% \addtolength{\@ff@tmp@y}{#1}% \@nexthband{\ff@pages}{#2}{#3}{#4}{#5}% \@nexthband{\ff@pages}{#2}{#6}{#7}{#8}% } \@onlypreamble{\htwotone} % \end{macrocode} %\end{macro} %\begin{macro}{\htwotoneleft} % Two tone horizontal strips along left border % Syntax: \cs{htwotoneleft}\oarg{pages}\oarg{y offset}\marg{width}\marg{H1}\marg{C1}\marg{L1}\marg{H2}\marg{C2}\marg{L2} % \begin{macrocode} \newcommand*{\htwotoneleft}[1][all]{% \def\ff@pages{#1}\@htwotoneleft} \@onlypreamble{\htwotoneleft} % \end{macrocode} %\end{macro} %\begin{macro}{\@htwotoneleft} % \begin{macrocode} \newcommand*{\@htwotoneleft}[2][0pt]{\@@htwotoneleft{#1}{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\htwotoneright} % Two tone horizontal strips along right border % \begin{macrocode} \newcommand*{\htwotoneright}[1][all]{% \def\ff@pages{#1}\@htwotoneright} \@onlypreamble{\htwotoneright} % \end{macrocode} %\end{macro} %\begin{macro}{\@htwotoneright} % \begin{macrocode} \newcommand*{\@htwotoneright}[2][0pt]{\@@htwotoneright{#1}{#2}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@htwotoneright} % \begin{macrocode} \newcommand*{\@@htwotoneright}[8]{% \computerightedgeodd{\@ff@tmp@x}% \if@twoside \computerightedgeeven{\@ff@tmp@x@even}% \else \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}% \fi \computebottomedge{\@ff@tmp@y}% \addtolength{\@ff@tmp@y}{#1}% \addtolength{\@ff@tmp@x}{-#2}% \addtolength{\@ff@tmp@x@even}{-#2}% \@nexthband{\ff@pages}{#2}{#3}{#4}{#5}% \@nexthband{\ff@pages}{#2}{#6}{#7}{#8}% } % \end{macrocode} %\end{macro} %\begin{macro}{\hNtone} % Now for \meta{N} coloured horizontal strips % \begin{macrocode} \newcommand*{\hNtone}[1][all]{% \def\ff@pages{#1}\@hNtone} \@onlypreamble{\hNtone} % \end{macrocode} %\end{macro} %\begin{macro}{\@hNtone} % \begin{macrocode} \newcommand*{\@hNtone}[2][0pt]{% \@@hNtone{#1}{#2}{\paperwidth}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@hNtone} % \begin{macrocode} \newcommand*{\@@hNtone}[3]{% \computeleftedgeodd{\@ff@tmp@x}% \if@twoside \computeleftedgeeven{\@ff@tmp@x@even}% \else \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}% \fi \computebottomedge{\@ff@tmp@y}% \addtolength{\@ff@tmp@y}{#1}% \@thisstrip=#2\relax \setlength{\@ff@staticW}{#3}% \@nexthNband% } % \end{macrocode} %\end{macro} %\begin{macro}{\hNtoneleft} % Now for the N tone strips along the left border % \begin{macrocode} \newcommand*{\hNtoneleft}[1][all]{% \def\ff@pages{#1}\@hNtoneleft} \@onlypreamble{\hNtoneleft} % \end{macrocode} %\end{macro} %\begin{macro}{\@hNtoneleft} % \begin{macrocode} \newcommand*{\@hNtoneleft}[3][0pt]{% \@@hNtone{#1}{#2}{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\hNtoneright} % Border strip along the right border % \begin{macrocode} \newcommand*{\hNtoneright}[1][all]{% \def\ff@pages{#1}\@hNtoneright} \@onlypreamble{\hNtoneright} % \end{macrocode} %\end{macro} %\begin{macro}{\@hNtoneright} % \begin{macrocode} \newcommand*{\@hNtoneright}[3][0pt]{% \@@hNtoneright{#1}{#2}{#3}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@hNtoneright} % \begin{macrocode} \newcommand*{\@@hNtoneright}[3]{% \computerightedgeodd{\@ff@tmp@x}% \if@twoside \computerightedgeeven{\@ff@tmp@x@even}% \else \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}% \fi \computebottomedge{\@ff@tmp@y}% \addtolength{\@ff@tmp@y}{#1}% \addtolength{\@ff@tmp@x}{-#3}% \addtolength{\@ff@tmp@x@even}{-#3}% \@thisstrip=#2\relax \setlength{\@ff@staticW}{#3}% \@nexthNband% } % \end{macrocode} %\end{macro} %\begin{macro}{\@nexthband} % Make next \gls{static}. Syntax:\newline % \cs{@nexthband}\marg{pages}\marg{width}\marg{height}\marg{colour specs}\marg{label}\newline % $x$ and $y$ offsets are given by "\@ff@tmp@x" and "\@ff@tmp@y". % On exit, "\@ff@tmp@y" is set to the top border. % \begin{macrocode} \newcommand*{\@nexthband}[5]{% \setlength{\@ff@staticH}{#3}% \ifthenelse{\equal{#5}{}}{% \newstaticframe[#1]{#2}{\@ff@staticH}{\@ff@tmp@x}{\@ff@tmp@y}}% {\newstaticframe[#1]{#2}{\@ff@staticH}{\@ff@tmp@x}{\@ff@tmp@y}[#5]}% \expandafter\global\expandafter \setlength\csname @sf@\romannumeral\c@maxstatic @evenx\endcsname{% \@ff@tmp@x@even}% \@setframecol#4\end{\c@maxstatic}{backcol}{sf}% \addtolength{\@ff@tmp@y}{\@ff@staticH}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@nexthNband} % Get next horizontal strip recursively. % \begin{macrocode} \newcommand*{\@nexthNband}{% \ifnum\@thisstrip>0\relax \let\flf@next\@@nexthNband% \else \let\flf@next\relax% \fi \advance\@thisstrip by -1\relax \flf@next} % \end{macrocode} %\end{macro} %\begin{macro}{\@@nexthNband} % \begin{macrocode} \newcommand*{\@@nexthNband}[3]{% \@nexthband{\ff@pages}{\@ff@staticW}{#1}{#2}{#3}\@nexthNband} % \end{macrocode} %\end{macro} %\begin{macro}{\makebackgroundframe} % Make one big \gls{static} that covers the entire page. % This command should come before all other commands that create % \glspl{static}, otherwise it will obscure all the ones defined % before it. Syntax:\newline % \cs{makebackgroundframe}\oarg{pages}\oarg{label}. % \begin{macrocode} \newcommand*{\makebackgroundframe}[1][all]{% \ifnum\c@maxstatic>0\relax \PackageWarning{flowfram}{Background frame is not first static frame to be defined. All previously defined static frames may be obscured.}% \fi \computeleftedgeodd{\@ff@tmp@x}% \if@twoside \computeleftedgeeven{\@ff@tmp@x@even}% \else \setlength{\@ff@tmp@x@even}{\@ff@tmp@x}% \fi \computebottomedge{\@ff@tmp@y}% \newstaticframe[#1]{\paperwidth}{\paperheight}{\@ff@tmp@x}% {\@ff@tmp@y}% \expandafter\global\expandafter \setlength\csname @sf@\romannumeral\c@maxstatic @evenx\endcsname {\@ff@tmp@x@even}} % \end{macrocode} %\end{macro} % %\subsubsection{Lines Between Frames} %\DescribeMacro{\insertvrule} % Insert a \gls{static} between two frames with a vertical % rule that goes from the maximum height of the highest % to the minimum height of the lowest, equidistant from % both frames. Syntax:\newline % \cs{insertvrule}\oarg{y top}\oarg{y bottom}\marg{frame1 type}\marg{IDN2}\marg{frame2 type}\meta{IDN2}. % The starred version uses \glspl{idl} instead of \glspl{idn}. % The optional arguments indicate to continue above the highest % point by \meta{y top} or continue below the lowest point % by \meta{y bottom}. % %\begin{macro}{\ffcolumnseprule} % This has changed in v1.09. Define "\ffcolumnseprule" and use % instead of "\columnseprule" % \begin{macrocode} \newlength\ffcolumnseprule \setlength{\ffcolumnseprule}{2pt} % \end{macrocode} %\end{macro} %\begin{macro}{\insertvrule} % Determine whether or not the starred version is being % used. % \begin{macrocode} \newcommand*{\insertvrule}{\@ifstar\@sinsertvrule\@insertvrule} % \end{macrocode} %\end{macro} %\begin{macro}{\@insertvrule} % Two optional arguments required. % \begin{macrocode} \newcommand*{\@insertvrule}[1][0pt]{% \@ifnextchar[{\@@insertvrule[#1]}{\@@insertvrule[#1][0pt]}} % \end{macrocode} %\end{macro} % Need some lengths: % \begin{macrocode} \newlength\@ff@left@x \newlength\@ff@left@y \newlength\@ff@left@evenx \newlength\@ff@left@eveny \newlength\@ff@left@width \newlength\@ff@left@height % \end{macrocode} %\begin{macro}{\@@insertvrule} % Arguments all accounted for. Convert the frame type % into a number to make life easier % \begin{macrocode} \def\@@insertvrule[#1][#2]#3#4#5#6{% \ifthenelse{\equal{#3}{flow}}{% \def\@ff@type@i{1}}{\ifthenelse{\equal{#3}{static}}{% \def\@ff@type@i{2}}{\ifthenelse{\equal{#3}{dynamic}}{% \def\@ff@type@i{3}}{\PackageError{flowfram}{Unknown frame type '#3'}{Available frame types are: 'flow', 'static' or 'dynamic'}}}}% \ifthenelse{\equal{#5}{flow}}{% \def\@ff@type@ii{1}}{\ifthenelse{\equal{#5}{static}}{% \def\@ff@type@ii{2}}{\ifthenelse{\equal{#5}{dynamic}}{% \def\@ff@type@ii{3}}{\PackageError{flowfram}{Unknown frame type '#5'}{Available frame types are: 'flow', 'static' or 'dynamic'}}}}% \@@insert@vrule{#1}{#2}{\@ff@type@i}{#4}{\@ff@type@ii}{#6}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@@insert@vrule} % Insert a new \gls{static} between the two specified frames. % Check to make sure which one is on the left and which one % is on the right. % Syntax:\newline %\cs{@@insert@vrule}\marg{y top}\marg{y bottom}\marg{type ID}\marg{IDN}\marg{type ID}\marg{IDN}. % \begin{macrocode} \newcommand*{\@@insert@vrule}[6]{% \@ff@getdim{#3}{#4}% \setlength{\@ff@left@x}{\ffareax}% \setlength{\@ff@left@y}{\ffareay}% \setlength{\@ff@left@width}{\ffareawidth}% \setlength{\@ff@left@height}{\ffareaheight}% \@ff@getdim{#5}{#6}% \ifnum\@ff@left@x>\ffareax\relax \@ff@swaplen{\@ff@left@x}{\ffareax}% \@ff@swaplen{\@ff@left@y}{\ffareax}% \@ff@swaplen{\@ff@left@evenx}{\ffareaevenx}% \@ff@swaplen{\@ff@left@eveny}{\ffareaevenx}% \@ff@swaplen{\@ff@left@width}{\ffareawidth}% \@ff@swaplen{\@ff@left@height}{\ffareaheight}% \fi \setlength{\@ff@tmp@x}{\@ff@left@x} \addtolength{\@ff@tmp@x}{\@ff@left@width}% \setlength{\@ff@staticW}{\ffareax}% \addtolength{\@ff@staticW}{-\@ff@tmp@x}% \setlength{\@ff@staticH}{\@ff@left@y}% \addtolength{\@ff@staticH}{\@ff@left@height}% \setlength{\@ff@tmp@y}{\ffareay}% \addtolength{\@ff@tmp@y}{\ffareaheight}% \ifnum\@ff@tmp@y>\@ff@staticH \setlength{\@ff@staticH}{\@ff@tmp@y}% \fi \ifnum\@ff@left@y<\ffareay\relax \setlength{\@ff@tmp@y}{\@ff@left@y}% \else \setlength{\@ff@tmp@y}{\ffareay}% \fi \addtolength{\@ff@staticH}{-\@ff@tmp@y}% \newstaticframe{\@ff@staticW}{\@ff@staticH}% {\@ff@tmp@x}{\@ff@tmp@y}% \addtolength{\@ff@staticH}{#1}% \addtolength{\@ff@staticH}{#2}% \setstaticcontents{\c@maxstatic}{\hfill \rule[-#2]{\ffcolumnseprule}{\@ff@staticH}\hfill\mbox{}}% \ifcase#3\relax \or \edef\@ff@pages{\csname @ff@pages@\romannumeral#4\endcsname}% \or \edef\@ff@pages{\csname @sf@pages@\romannumeral#4\endcsname}% \or \edef\@ff@pages{\csname @df@pages@\romannumeral#4\endcsname}% \fi \setstaticframe{\c@maxstatic}{pages=\@ff@pages}% % \end{macrocode} % check the difference between odd and even page co-ordinates % and shift new frame in same direction. (Assumes the two % original frames stay in the same relative position.) % \begin{macrocode} \addtolength{\@ff@tmp@x}{\@ff@left@evenx}% \addtolength{\@ff@tmp@x}{-\@ff@left@x}% \addtolength{\@ff@tmp@y}{\@ff@left@eveny}% \addtolength{\@ff@tmp@y}{-\@ff@left@y}% \setstaticframe{\c@maxstatic}{evenx=\@ff@tmp@x,eveny=\@ff@tmp@y}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@sinsertvrule} % Starred version. Two optional arguments required. % \begin{macrocode} \newcommand*{\@sinsertvrule}[1][0pt]{% \@ifnextchar[{\@@sinsertvrule[#1]}{\@@sinsertvrule[#1][0pt]}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@sinsertvrule} % Find out the frame types and their \gls{idn}. % \begin{macrocode} \def\@@sinsertvrule[#1][#2]#3#4#5#6{% \ifthenelse{\equal{#3}{flow}}{% \def\@ff@type@i{1}\@flowframeid{#4}\@ff@tmpN=\ff@id}{% \ifthenelse{\equal{#3}{static}}{% \def\@ff@type@i{2}\@staticframeid{#4}\@ff@tmpN=\ff@id}{% \ifthenelse{\equal{#3}{dynamic}}{% \def\@ff@type@i{3}\@dynamicframeid{#4}\@ff@tmpN=\ff@id}{% \PackageError{flowfram}{Unknown frame type '#3'}{Available frame types are: 'flow', 'static' or 'dynamic'}}}}% \ifthenelse{\equal{#5}{flow}}{% \def\@ff@type@ii{1}\@flowframeid{#6}}{% \ifthenelse{\equal{#5}{static}}{% \def\@ff@type@ii{2}\@staticframeid{#6}}{% \ifthenelse{\equal{#5}{dynamic}}{% \def\@ff@type@ii{3}\@dynamicframeid{#6}}{% \PackageError{flowfram}{Unknown frame type '#5'}{Available frame types are: 'flow', 'static' or 'dynamic'}}}}% \@@insert@vrule{#1}{#2}{\@ff@type@i}{\@ff@tmpN}% {\@ff@type@ii}{\ff@id}% } % \end{macrocode} %\end{macro} %\begin{macro}{\inserthrule} % Now for a horizontal rule. Syntax similar to "\insertvrule". % Determine whether or not the starred version is being % used. % \begin{macrocode} \newcommand*{\inserthrule}{\@ifstar\@sinserthrule\@inserthrule} % \end{macrocode} %\end{macro} %\begin{macro}{\@inserthrule} % Two optional arguments required. % \begin{macrocode} \newcommand*{\@inserthrule}[1][0pt]{% \@ifnextchar[{\@@inserthrule[#1]}{\@@inserthrule[#1][0pt]}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@inserthrule} % Arguments all accounted for. Convert the frame type % into a number to make life easier % \begin{macrocode} \def\@@inserthrule[#1][#2]#3#4#5#6{% \ifthenelse{\equal{#3}{flow}}{% \def\@ff@type@i{1}}{\ifthenelse{\equal{#3}{static}}{% \def\@ff@type@i{2}}{\ifthenelse{\equal{#3}{dynamic}}{% \def\@ff@type@i{3}}{\PackageError{flowfram}{Unknown frame type '#3'}{Available frame types are: 'flow', 'static' or 'dynamic'}}}}% \ifthenelse{\equal{#5}{flow}}{% \def\@ff@type@ii{1}}{\ifthenelse{\equal{#5}{static}}{% \def\@ff@type@ii{2}}{\ifthenelse{\equal{#5}{dynamic}}{% \def\@ff@type@ii{3}}{\PackageError{flowfram}{Unknown frame type '#5'}{Available frame types are: 'flow', 'static' or 'dynamic'}}}}% \@@insert@hrule{#1}{#2}{\@ff@type@i}{#4}{\@ff@type@ii}{#6}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@@insert@hrule} % Insert a new \gls{static} between the two specified frames. % Check to make sure which one is on the top and which one % is on the bottom. % Syntax:\newline %\cs{@@insert@hrule}\marg{x left}\marg{x right}\marg{type ID}\marg{IDN}\marg{type ID}\marg{IDN}. % \begin{macrocode} \newcommand*{\@@insert@hrule}[6]{% \@ff@getdim{#3}{#4}% \setlength{\@ff@left@x}{\ffareax}% \setlength{\@ff@left@y}{\ffareay}% \setlength{\@ff@left@width}{\ffareawidth}% \setlength{\@ff@left@height}{\ffareaheight}% \@ff@getdim{#5}{#6}% \ifnum\@ff@left@y>\ffareay\relax \@ff@swaplen{\@ff@left@x}{\ffareax}% \@ff@swaplen{\@ff@left@y}{\ffareay}% \@ff@swaplen{\@ff@left@width}{\ffareawidth}% \@ff@swaplen{\@ff@left@height}{\ffareaheight}% \fi \setlength{\@ff@tmp@y}{\@ff@left@y}% \addtolength{\@ff@tmp@y}{\@ff@left@height}% \setlength{\@ff@staticH}{\ffareay}% \addtolength{\@ff@staticH}{-\@ff@tmp@y}% \setlength{\@ff@staticW}{\@ff@left@x}% \addtolength{\@ff@staticW}{\@ff@left@width}% \setlength{\@ff@tmp@x}{\ffareax}% \addtolength{\@ff@tmp@x}{\ffareawidth}% \ifnum\@ff@tmp@x>\@ff@staticW\relax \setlength{\@ff@staticW}{\@ff@tmp@x}% \fi \ifnum\@ff@left@x<\ffareax\relax \setlength{\@ff@tmp@x}{\@ff@left@x}% \else \setlength{\@ff@tmp@x}{\ffareax}% \fi \addtolength{\@ff@staticW}{-\@ff@tmp@x}% \newstaticframe{\@ff@staticW}{\@ff@staticH}% {\@ff@tmp@x}{\@ff@tmp@y}% \addtolength{\@ff@staticW}{#1}% \addtolength{\@ff@staticW}{#2}% \setstaticcontents{\c@maxstatic}{% \hspace*{-#1}\rule{\@ff@staticW}{\ffcolumnseprule}}% \ifcase#3\relax \or \edef\@ff@pages{\csname @ff@pages@\romannumeral#4\endcsname}% \or \edef\@ff@pages{\csname @sf@pages@\romannumeral#4\endcsname}% \or \edef\@ff@pages{\csname @df@pages@\romannumeral#4\endcsname}% \fi \setstaticframe{\c@maxstatic}{pages=\@ff@pages}% \addtolength{\@ff@tmp@x}{\@ff@left@evenx}% \addtolength{\@ff@tmp@x}{-\@ff@left@x}% \addtolength{\@ff@tmp@y}{\@ff@left@eveny}% \addtolength{\@ff@tmp@y}{-\@ff@left@y}% \setstaticframe{\c@maxstatic}{evenx=\@ff@tmp@x,eveny=\@ff@tmp@y}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@sinserthrule} % Starred version. Two optional arguments required. % \begin{macrocode} \newcommand*{\@sinserthrule}[1][0pt]{% \@ifnextchar[{\@@sinserthrule[#1]}{\@@sinserthrule[#1][0pt]}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@sinserthrule} % Find out the frame types and their \gls{idn}. % \begin{macrocode} \def\@@sinserthrule[#1][#2]#3#4#5#6{% \ifthenelse{\equal{#3}{flow}}{% \def\@ff@type@i{1}\@flowframeid{#4}\@ff@tmpN=\ff@id}{% \ifthenelse{\equal{#3}{static}}{% \def\@ff@type@i{2}\@staticframeid{#4}\@ff@tmpN=\ff@id}{% \ifthenelse{\equal{#3}{dynamic}}{% \def\@ff@type@i{3}\@dynamicframeid{#4}\@ff@tmpN=\ff@id}{% \PackageError{flowfram}{Unknown frame type '#3'}{Available frame types are: 'flow', 'static' or 'dynamic'}}}}% \ifthenelse{\equal{#5}{flow}}{% \def\@ff@type@ii{1}\@flowframeid{#6}}{% \ifthenelse{\equal{#5}{static}}{% \def\@ff@type@ii{2}\@staticframeid{#6}}{% \ifthenelse{\equal{#5}{dynamic}}{% \def\@ff@type@ii{3}\@dynamicframeid{#6}}{% \PackageError{flowfram}{Unknown frame type '#5'}{Available frame types are: 'flow', 'static' or 'dynamic'}}}}% \@@insert@hrule{#1}{#2}{\@ff@type@i}{\@ff@tmpN}% {\@ff@type@ii}{\ff@id}% } % \end{macrocode} %\end{macro} % % \subsection{Putting Chapter Headings in Dynamic Frames} %\begin{macro}{\dfchaphead} % Provide facility to make chapter headings appear % in specified \gls{dynamic}. % I originally called this macro "\putchapterheadingsindynamicframe" % which was descriptive, but overly long, so I changed it % to the rather more cryptic name "\dfchaphead". % If the starred form is used, the frame is identified by \gls{idl}, % the unstarred form identifies the frame \gls{idn}. % \begin{macrocode} \newcommand*{\dfchaphead}{% \@ifstar\@sdynamicchap\@dynamicchap} % \end{macrocode} %\end{macro} % Define style for the chapter heading. These commands % are should only be used when "\dfchaphead" has been used. %\begin{macro}{\DFchapterstyle} % \begin{macrocode} \newcommand{\DFchapterstyle}[1]{#1} % \end{macrocode} %\end{macro} %\begin{macro}{\DFschapterstyle} % \begin{macrocode} \newcommand{\DFschapterstyle}[1]{#1} % \end{macrocode} %\end{macro} %\begin{macro}{\@dynamicchap} % Unstarred version. % \begin{macrocode} \newcommand{\@dynamicchap}[1]{% \@ifundefined{chapter}{\PackageError{flowfram}{Chapters aren't defined}{The document class you are using does not define chapters}}{% \let\@ff@OLDmakechapterhead\@makechapterhead \let\@ff@OLDmakeschapterhead\@makeschapterhead \renewcommand{\DFchapterstyle}[1]{\@ff@OLDmakechapterhead{##1}}% \renewcommand{\DFschapterstyle}[1]{\@ff@OLDmakeschapterhead{##1}}% % \xdef\@makechapterhead##1{% \noexpand\@setdynamiccontents{\number#1}{% \noexpand\DFchapterstyle{##1}}}% \xdef\@makeschapterhead##1{% \noexpand\@setdynamiccontents{\number#1}{% \noexpand\DFschapterstyle{##1}}}% }} % \end{macrocode} %\end{macro} %\begin{macro}{\@sdynamicchap} % Starred form. % \begin{macrocode} \newcommand{\@sdynamicchap}[1]{% \@dynamicframeid{#1}\@dynamicchap{\ff@id}} % \end{macrocode} %\end{macro} % There is no facility for placing other sectional types % in \glspl{dynamic}. This is because, either (1) the sectioning % command does not start a new page, in which case there % is no way of telling where exactly the new section will start, % and having a section title in some other location on the % page is ambiguous, and would really confuse the reader, or % (2) in the case of "\part" in report or book class files, the % title appears on a page of its own, so where is the point in % putting it in a \gls{dynamic}? % %\subsection{Thumbtabs} % Define counter to keep track of total number of % thumbtabs. % \begin{macrocode} \newcounter{maxthumbtabs} % \end{macrocode} %\begin{macro}{\defaultthumbtabtype} % Check to see if chapters are defined, if they are make % thumbtabs correspond to chapters, otherwise make % thumbtabs correspond to sections. % \begin{macrocode} \@ifundefined{chapter}{% \newcommand*{\defaultthumbtabtype}{section}}{ \newcommand*{\defaultthumbtabtype}{chapter} } % \end{macrocode} %\end{macro} %\begin{macro}{\@ttb@type} % Section type to assign to thumbtabs. % \begin{macrocode} \newcommand*{\@ttb@type}{\defaultthumbtabtype} % \end{macrocode} %\end{macro} %\begin{macro}{\makethumbtabs} % Make the thumbtabs. Read in information from ".ttb" % file, and open it for output. % Syntax:\newline % \cs{makethumbtabs}\oarg{y offset}\marg{height}\oarg{sec type}. % % First check to see if there is a second optional argument. % \begin{macrocode} \newcommand*{\makethumbtabs}[2][0pt]{% \@ifnextchar[{\@makethumbtabs[#1]{#2}}{% \@makethumbtabs[#1]{#2}[\defaultthumbtabtype]}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@makethumbtabs} % Now all arguments are known, first redefine the % appropriate sectioning command, then input the ttb file, % and create the thumbtabs. % \begin{macrocode} \def\@makethumbtabs[#1]#2[#3]{% \@ifundefined{#3}{\PackageError{flowfram}{% Unknown section type '#3'}{}}{% \renewcommand{\@ttb@type}{#3}% \ifthenelse{\equal{#3}{chapter}}{\@makethumbchapter}{% \ifthenelse{\equal{#3}{part}}{\@makethumbpart}{% \@makethumbsection{#3}}}} \@starttoc{ttb}% \@dothumbtabs{#1}{#2}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@makethumbchapter} % If thumbtabs correspond to chapters, redefine "\@chapter" % so that each unstarred chapter writes an entry to the % ".ttb" file. % \begin{macrocode} \newcommand{\@makethumbchapter}{ \let\@ttb@old@chapter\@chapter \def\@chapter[##1]##2{% \@ttb@old@chapter[##1]{##2}% \addtocontents{ttb}{\protect\thumbtab {\thepage}{\thechapter}{##1}{chapter.\thechapter}}% \@afterheading }} % \end{macrocode} %\end{macro} %\begin{macro}{\@makethumbpart} % For parts in books or reports, the thumbtab needs to be % saved after the part counter has been incremented, but % before the page break so that the page number and part % numbers are correct. If "\@endpart" is not defined, then % the document class probably does not start a new page after % "\part". (This can't be guaranteed for non standard class % files, but there's nothing that can be done about that.) % If this happens, just redefine "\@part", and hope for the % best. % \begin{macrocode} \newcommand{\@makethumbpart}{ \let\@ttb@old@part\@part \@ifundefined{@endpart}{% \def\@part[##1]##2{\@ttb@old@part[##1]{##2}% \addtocontents{ttb}{\protect\thumbtab {\thepage}{\thepart}{##1}{part.\thepage}}% \@afterheading}}{% \let\@ttb@old@endpart\@endpart \def\@part[##1]##2{% \def\@parttitle{##1}% \@ttb@old@part[##1]{##2}% }% \def\@endpart{% \addtocontents{ttb}{% \protect\thumbtab{\thepage}% {\thepart}{\@parttitle}{part.\thepage}}% \@ttb@old@endpart }}} % \end{macrocode} %\end{macro} %\begin{macro}{\@makethumbsection} % Thumbtabs defined for one of the remaining standard % sectioning commands. Since these commands use % "\@startsection", it is necessary to redefine % "\@sect" to add the thumbtab information to the .ttb file. % \begin{macrocode} \newcommand*{\@makethumbsection}[1]{% \let\@ttb@old@sect=\@sect \def\@sect##1##2##3##4##5##6[##7]##8{% \@ttb@old@sect{##1}{##2}{##3}{##4}{##5}{##6}[##7]{##8}% \ifthenelse{\equal{##1}{#1}}{% \addtocontents{ttb}{% \protect\thumbtab{\thepage}{\csname the#1\endcsname}% {##7}{#1.\csname the#1\endcsname}}% \@afterheading}{}% }} % \end{macrocode} %\end{macro} %\begin{macro}{\thumbtab} % The thumbtab file, ".ttb", will have a series of "\thumbtab" % commands, when this file is read in, just store the % information for now. % \begin{macrocode} \newcommand{\thumbtab}[4]{% \stepcounter{maxthumbtabs}% \expandafter \gdef\csname thumbtab@pages@\romannumeral\c@maxthumbtabs\endcsname {#1}% \expandafter \gdef\csname thumbtab@num@\romannumeral\c@maxthumbtabs\endcsname {#2}% \expandafter \gdef\csname thumbtab@title@\romannumeral\c@maxthumbtabs\endcsname {#3}% \expandafter \gdef\csname thumbtab@link@\romannumeral\c@maxthumbtabs\endcsname {#4}} % \end{macrocode} %\end{macro} %\begin{macro}{\@dothumbtabs} % Once the thumbtab information has been read in and stored % in the thumbtab macros, create the thumbtabs using this % information. First need to work out the \glspl{pgrange} between % each thumbtab. If the following thumbtab starts on the % same page as the previous one, leave the page varable % as a single number (this may happen if the thumbtabs % correspond to sections rather than chapters). If the % following thumbtab starts on a different page to the % one before it, the preceding thumbtab page variable so % be a range from its own initial page up to the page before % the next thumbtab starts. The final thumbtab has an open % ended range. This final thumbtab will continue to be displayed % until cancelled by "\disablethumbtabs". % % Syntax: \cs{@dothumbtabs}\marg{y offset}\marg{height}. % \begin{macrocode} \newcommand*{\@dothumbtabs}[2]{% \@colN=0\relax \whiledo{\@colN<\c@maxthumbtabs}{% \advance\@colN by 1\relax \edef\ff@pages{% \csname thumbtab@pages@\romannumeral\@colN\endcsname}% \ifnum\@colN=\c@maxthumbtabs \expandafter \xdef\csname thumbtab@pages@\romannumeral\@colN\endcsname{% \ff@pages,>\ff@pages}% \else \advance\@colN by 1\relax \edef\ff@endpage{% \csname thumbtab@pages@\romannumeral\@colN\endcsname}% \advance\@colN by -1\relax \@ff@tmpN=\ff@endpage\relax \advance\@ff@tmpN by -1\relax \ifnum\@ff@tmpN>\ff@pages \expandafter \xdef\csname thumbtab@pages@\romannumeral\@colN\endcsname{% \ff@pages-\number\@ff@tmpN}% \fi \fi }% \@@dothumbtabs{#1}{#2}% } % \end{macrocode} %\end{macro} %\begin{macro}{\thumbtabwidth} % Default thumbtab width. % \begin{macrocode} \newlength{\thumbtabwidth} \setlength{\thumbtabwidth}{1cm} % \end{macrocode} %\end{macro} %\begin{macro}{\thumbtabindexformat} % Thumbtab format. If hyperlinks have been defined, % use a hyperlink in the thumbtab index. % Syntax: \cs{thumbtabindexformat}\marg{link}\marg{text}\marg{height} % \begin{macrocode} \@ifundefined{hyperlink}{% \newcommand{\thumbtabindexformat}[3]{% \thumbtabformat{#2}{#3}}}{% \newcommand{\thumbtabindexformat}[3]{% \hyperlink{#1}{\thumbtabformat{#2}{#3}}} } % \end{macrocode} %\end{macro} %\begin{macro}{\thumbtabformat} % Individual thumbtab format. If rotating has % been disabled, stack the letters vertically (this % doesn't look very good). % Syntax: \cs{thumbtabformat}\marg{text}\marg{height} % \begin{macrocode} \newcommand{\thumbtabformat}[2]{% \if@ttb@rotate \rotatebox{-90}{\parbox[c][\thumbtabwidth]{#2}{% \centering#1}}% \else \parbox[c][#2]{\thumbtabwidth}{% \centering\@ttb@stack{#1}}% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\@flf@subsp} % Substitute spaces for \cs{space}. Stores resulting text in % \cs{@flf@subsptext} which should be set to empty before use. %\changes{1.10}{2007/08/21}{new} % \begin{macrocode} \def\@flf@subsp#1 #2{% \expandafter\flf@ta\expandafter{\@flf@subsptext}% \flf@tb{#1}% \edef\@flf@subsptext{\the\flf@ta\the\flf@tb}% \def\@flf@tmp{#2}% \ifx\@flf@tmp\@nnil \let\@flf@donextsubsp=\@gobble \else \expandafter\flf@ta\expandafter{\@flf@subsptext}% \edef\@flf@subsptext{\the\flf@ta\noexpand\space}% \let\@flf@donextsubsp=\@flf@subsp \fi \@flf@donextsubsp{#2}% } % \end{macrocode} %\end{macro} %\begin{macro}{\@ttb@stack} % Stack letters vertically. % Any spaces first need to be substituted % with \cs{space}, otherwise they will be ignored. %\changes{1.10}{2007/08/21}{spaces now replaced with \cs{space}} % \begin{macrocode} \newcommand{\@ttb@stack}[1]{% \def\@flf@subsptext{}% \expandafter\@flf@subsp#1 \@nil\relax \begin{tabular}{l}% \expandafter\@@ttb@stack\@flf@subsptext\@nil\relax \end{tabular}} % \end{macrocode} %\end{macro} %\begin{macro}{\@@ttb@stack} %\changes{1.10}{2007/08/21}{now uses \cs{mbox}} % \begin{macrocode} \def\@@ttb@stack#1#2{% \def\@flf@tmp{#1}% \ifx\@flf@tmp\@nnil \let\flf@next\relax \else #1\\% \def\@flf@tmp{#2}% \ifx\@nnil#2\relax \let\flf@next\@gobble \else \let\flf@next\@@ttb@stack \fi \fi \flf@next{#2}} % \end{macrocode} %\end{macro} % %\begin{macro}{\@greyscale} % Count register to compute the grey scale. % \begin{macrocode} \newcount\@greyscale % \end{macrocode} %\end{macro} %\begin{macro}{\@@dothumbtabs} % Once the \gls{pgrange} have been sorted, create the % \glspl{dynamic} associated with each thumbtab. % Thumbtabs will initially have a grey background, but % this can be changed by the user. Each thumbtab is given % an \gls{idl} "thumbtab"\meta{n} where \meta{n} is the index of % the thumbtab (starting from 1 for the topmost thumbtab.) % Each frame in the thumbtab index is given an \gls{idl} % "thumbtabindex"\meta{n}, where \meta{n} is as before. % \begin{macrocode} \newcommand{\@@dothumbtabs}[2]{% \setlength{\@ff@tmp@y}{\textheight}% \addtolength{\@ff@tmp@y}{-#2}% \addtolength{\@ff@tmp@y}{-#1}% \computerightedgeodd{\@ff@tmp@x}% \addtolength{\@ff@tmp@x}{-\thumbtabwidth}% \computeleftedgeeven{\@ff@tmp@x@even}% \@ff@tmpN=0\relax \whiledo{\@ff@tmpN<\c@maxthumbtabs}{% \advance\@ff@tmpN by 1\relax \@greyscale=\@ff@tmpN\relax \multiply\@greyscale by 60\relax \divide\@greyscale by \c@maxthumbtabs \advance\@greyscale by 25\relax \edef\@ff@greyscale{0.\number\@greyscale}% % \end{macrocode} % Thumbtab % \begin{macrocode} \newdynamicframe[none]{\thumbtabwidth}{#2}% {\@ff@tmp@x}{\@ff@tmp@y}[thumbtab\number\@ff@tmpN]% \expandafter\global\expandafter \setlength\csname @df@\romannumeral\c@maxdynamic @evenx\endcsname {\@ff@tmp@x@even}% % \end{macrocode} % set the contents of the dynamic frame % \begin{macrocode} \ifthenelse{\boolean{@ttb@title}\and\boolean{@ttb@num}}{% \expandafter \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{% \noexpand\thumbtabformat{% \csname thumbtab@num@\romannumeral\@ff@tmpN\endcsname\ \csname thumbtab@title@\romannumeral\@ff@tmpN\endcsname }{#2}}% }{% \if@ttb@title \expandafter \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{% \noexpand\thumbtabformat{% \csname thumbtab@title@\romannumeral\@ff@tmpN\endcsname }{#2}}% \fi \if@ttb@num \expandafter \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{% \noexpand\thumbtabformat{% \csname thumbtab@num@\romannumeral\@ff@tmpN\endcsname }{#2}}% \fi }% \expandafter \xdef\csname @df@backcol@\romannumeral\c@maxdynamic\endcsname {[gray]{\@ff@greyscale}} % \end{macrocode} % Thumbtab index % \begin{macrocode} \newdynamicframe[none]{\thumbtabwidth}{#2}% {\@ff@tmp@x}{\@ff@tmp@y}[thumbtabindex\number\@ff@tmpN]% \expandafter\global\expandafter \setlength\csname @df@\romannumeral\c@maxdynamic @evenx\endcsname {\@ff@tmp@x@even}% \expandafter % \end{macrocode} % set the contents of the dynamic frame % \begin{macrocode} \ifthenelse{\boolean{@ttb@title}\and\boolean{@ttb@num}}{% \expandafter \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{% \noexpand\thumbtabindexformat{% \csname thumbtab@link@\romannumeral\@ff@tmpN\endcsname}{% \csname thumbtab@num@\romannumeral\@ff@tmpN\endcsname\ \csname thumbtab@title@\romannumeral\@ff@tmpN\endcsname }{#2}}% }{% \if@ttb@title \expandafter \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{% \noexpand\thumbtabindexformat{% \csname thumbtab@link@\romannumeral\@ff@tmpN\endcsname}{% \csname thumbtab@title@\romannumeral\@ff@tmpN\endcsname }{#2}}% \fi \if@ttb@num \expandafter \xdef\csname @dynamicframe@\romannumeral\c@maxdynamic\endcsname{% \noexpand\thumbtabindexformat{% \csname thumbtab@link@\romannumeral\@ff@tmpN\endcsname}{% \csname thumbtab@num@\romannumeral\@ff@tmpN\endcsname }{#2}}% \fi }% \expandafter \xdef\csname @df@backcol@\romannumeral\c@maxdynamic\endcsname {[gray]{\@ff@greyscale}} \addtolength{\@ff@tmp@y}{-#2}% }% }% % \end{macrocode} %\end{macro} %\begin{macro}{\enablethumbtabs} % Enable thumbtabs. Once the \gls{idn} is obtained for the % first thumbtab, the rest can be found by incrementing the % number by 2 (the frames in between correspond to the % thumbtab index.) % \begin{macrocode} \newcommand*{\enablethumbtabs}{% \ifnum\c@maxthumbtabs>0 \@ff@tmpN=0\relax \@dynamicframeid{thumbtab1}% \whiledo{\@ff@tmpN<\c@maxthumbtabs}{% \advance\@ff@tmpN by 1\relax % \end{macrocode} % thumbtab % \begin{macrocode} \edef\@ff@pages{\csname thumbtab@pages@\romannumeral\@ff@tmpN\endcsname}% \@@setdynamicframe{\ff@id}{pages=\@ff@pages}% \advance\ff@id by 2\relax }% \else\PackageWarning{flowfram}{No thumb tabs defined}\fi} % \end{macrocode} %\end{macro} %\begin{macro}{\disablethumbtabs} % Disable all thumbtabs. % \begin{macrocode} \newcommand*{\disablethumbtabs}{% \ifnum\c@maxthumbtabs>0 \@ff@tmpN=0\relax \@dynamicframeid{thumbtab1}% \whiledo{\@ff@tmpN<\c@maxthumbtabs}{% \advance\@ff@tmpN by 1\relax % \end{macrocode} %thumbtab % \begin{macrocode} \expandafter\xdef\csname @df@pages@\romannumeral\ff@id\endcsname {none}% \advance\ff@id by 1\relax % \end{macrocode} %thumbtab index % \begin{macrocode} \expandafter\xdef\csname @df@pages@\romannumeral\ff@id\endcsname {none}% \advance\ff@id by 1\relax }\fi} % \end{macrocode} %\end{macro} %\begin{macro}{\thumbtabindex} % Show thumbtab index on current page. % The "\@ff@doafter" bit circumvents the problem of duplicate page % numbers, as the table of contents % is quite frequently on page i while the first chapter starts on page 1. % \begin{macrocode} \newcommand*{\thumbtabindex}{% \ifnum\c@maxthumbtabs>0\relax \@ff@tmpN=0\relax \@dynamicframeid{thumbtabindex1}% \whiledo{\@ff@tmpN<\c@maxthumbtabs}{% \advance\@ff@tmpN by 1\relax \expandafter \xdef\csname @df@pages@\romannumeral\ff@id\endcsname{\c@page}% \edef\@ff@doafter{% \noexpand\afterpage{% \noexpand\setdynamicframe{\number\ff@id}{pages=none}}} \@ff@doafter \advance\ff@id by 2\relax }\fi} % \end{macrocode} %\end{macro} %\begin{macro}{\setthumbtab} % Modify the settings for all the thumbtabs (including thumbtab % index). Since the thumbtabs are \glspl{dynamic} % you could just use "\setdynamicframe", however, the thumbtabs % will not be generated on the first run, as there will be no % information in the ttb file, so "\setdynamicframe" would % generate an error. "\setthumbtab" will only give % a warning message if it can not find the thumbtab. % The argument "#1" is the index of the thumbtab (starting % from 1), the second argument "#2" is the % frame settings. % \begin{macrocode} \newcommand{\setthumbtab}[2]{% \ifthenelse{\equal{#1}{all}}{% \@ff@tmpN=0\relax \whiledo{\@ff@tmpN<\c@maxthumbtabs}{% \advance\@ff@tmpN by 1\relax \@setthumbtab{\@ff@tmpN}{#2}}}{% \@for\@ttb@id:=#1\do{\@setthumbtab{\@ttb@id}{#2}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@setthumbtab} % Set individual thumbtab and its index tab. % \begin{macrocode} \newcommand{\@setthumbtab}[2]{% % check if this thumbtab exists \ifthenelse{\(\c@maxthumbtabs<#1\) \or \(#1<1\)}{% \PackageWarning{flowfram}{Can't find thumbtab number '#1', ttb file may not be up-to-date}}{% \@dynamicframeid{thumbtab\number#1}% \@@setdynamicframe{\ff@id}{#2}% \@dynamicframeid{thumbtabindex\number#1}% \@@setdynamicframe{\ff@id}{#2}}} % \end{macrocode} %\end{macro} %\begin{macro}{\setthumbtabindex} % Only change settings for the thumbtab index. This can % take a comma-separated number list. % \begin{macrocode} \newcommand{\setthumbtabindex}[2]{% \ifthenelse{\equal{#1}{all}}{% \@ff@tmpN=0\relax \whiledo{\@ff@tmpN<\c@maxthumbtabs}{% \advance\@ff@tmpN by 1\relax \@setthumbtabindex{\@ff@tmpN}{#2}}}{% \@for\@ttb@id:=#1\do{\@setthumbtabindex{\@ttb@id}{#2}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@setthumbtabindex} % Change setting for individual thumbtab index entry. % \begin{macrocode} \newcommand{\@setthumbtabindex}[2]{% % check if this thumbtab exists \ifthenelse{\(\c@maxthumbtabs<#1\) \or \(#1<1\)}{% \PackageWarning{flowfram}{Can't find thumbtab number `\number#1', ttb file may not be up-to-date}}{% \@dynamicframeid{thumbtabindex\number#1}% \@@setdynamicframe{\ff@id}{#2}}} % \end{macrocode} %\end{macro} %\begin{macro}{\tocandhumbtabindex} % Do both the table of contents and the thumbtab index % \begin{macrocode} \newcommand*{\tocandthumbtabindex}{% \aligntoctrue \tableofcontents \thumbtabindex \aligntocfalse } % \end{macrocode} %\end{macro} % % \subsection{Minitocs} %\begin{macro}{\@ttb@minitoctype} % Sectioning type for the minitoc, by default it is the % same as the thumbtabs % \begin{macrocode} \newcommand*{\@ttb@minitoctype}{\@ttb@type} % \end{macrocode} %\end{macro} %\begin{macro}{\@starttoc} % In order to align the table of contents with the thumbtabs, % or to use minitocs, the toc information must be stored, % rather than simply input. % Therefore, modify "\@starttoc" so that it can store the contents % of the file. "\if@storetoc" is used to determine whether % to store the contents, or act as normal. % \begin{macrocode} \let\@ttb@old@starttoc\@starttoc \newif\if@storetoc \@storetocfalse \renewcommand*{\@starttoc}[1]{% \if@storetoc \@ttb@storetoc{#1}% \else \@ttb@old@starttoc{#1}% \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\@ttb@storetoc} % store the contents of the file with the given extension % \begin{macrocode} \newcommand*{\@ttb@storetoc}[1]{% \begingroup \makeatletter \@storefileconts{\jobname.#1}% \if@filesw \expandafter\newwrite\csname tf@#1\endcsname \immediate\openout\csname tf@#1\endcsname\jobname.#1\relax \fi \@nobreakfalse \endgroup} % \end{macrocode} %\end{macro} %\begin{macro}{\@storefileconts} % store the contents of named file, if it exists. %\changes{1.10}{2007/08/21}{uses \cs{PackageInfo} instead of % \cs{typeout}} % \begin{macrocode} \newcommand*{\@storefileconts}[1]{\IfFileExists{#1}{% \@@storefileconts\@filef@und}{% \PackageInfo{flowfram}{No file #1.}}} % \end{macrocode} %\end{macro} % store the number of units corresponding to the % thumbtab type, and minitoc units. These will usually % have the same value, but this is not always % guaranteed. %\begin{macro}{\c@maxtocunits} % Total number of toc units % \begin{macrocode} \newcount\c@maxtocunits % \end{macrocode} %\end{macro} %\begin{macro}{\c@maxminitoc} % Total number of minitoc units % \begin{macrocode} \newcount\c@maxminitoc % \end{macrocode} %\end{macro} %\begin{macro}{\@@storefileconts} % Read each line in from the file, and add to the contents % list. % \begin{macrocode} \newcommand{\@@storefileconts}[1]{% \@ifundefined{\@ttb@minitoctype}{\@ttb@minitoclevel=6\relax}{% \expandafter\@ttb@minitoclevel\expandafter =\csname @ttb@\@ttb@minitoctype @level\endcsname}% \newread\@ttb@toc \openin\@ttb@toc=#1\relax \c@maxtocunits=0\relax \c@maxminitoc=0\relax \whiledo{\not\boolean{eof}\@ttb@toc}{% \read\@ttb@toc to\tocline \@addtotoclist{\tocline}{\c@maxtocunits}% }% \closein\@ttb@toc} % \end{macrocode} %\end{macro} %\begin{macro}{\@addtotoclist} % Before each line is added to the contents list, it is % first checked to see whether the line starts with % "\contentsline". If it does, then check to see if the % sectioning type corresponds to the thumbtab level. If % it does, then start a new list. There will be "\c@maxtocunits" % lists, each one corresponding to each thumbtab group. % In addition, each contents line needs to be added to % the minitoclists, but only if the sectioning type level % is greater than "\@ttb@minitoctype". The number of minitoc % lists is given by "\c@maxminitoc". % \begin{macrocode} \newif\if@contsline \newcount\@ttb@level \newcount\@ttb@minitoclevel \newcommand{\@addtotoclist}[2]{% \expandafter\@checkcontentsline#1\end \if@contsline \expandafter\@gettype#1\end \ifthenelse{\equal{\@ttb@contstype}{\@ttb@type}}{% \global\advance#2 by 1\relax }{% }% \fi \@ifundefined{@toc@\romannumeral#2}{% \flf@ta=\expandafter{#1}% \expandafter\xdef\csname @toc@\romannumeral#2\endcsname{\the\flf@ta}}{% \flf@ta=\expandafter{#1}% \flf@tb=\expandafter\expandafter\expandafter{\csname @toc@\romannumeral#2\endcsname}% \expandafter\xdef\csname @toc@\romannumeral#2\endcsname{\the\flf@tb\the\flf@ta}}% % \end{macrocode} % now do minitoc stuff. If the sectioning type is unknown, % assume it comes last % \begin{macrocode} \if@minitoc \if@contsline \@ifundefined{\@ttb@contstype}{\@ttb@level=6}{% \@ttb@level=\csname @ttb@\@ttb@contstype @level\endcsname}% \relax \ifnum\@ttb@level=\@ttb@minitoclevel \global\advance\c@maxminitoc by 1\relax \expandafter \gdef\csname @minitoc@\romannumeral\c@maxminitoc\endcsname{}% \else \ifnum\@ttb@level>\@ttb@minitoclevel \flf@ta=\expandafter{#1}\relax \flf@tb=\expandafter\expandafter\expandafter {\csname @minitoc@\romannumeral\c@maxminitoc\endcsname}\relax \expandafter \xdef\csname @minitoc@\romannumeral\c@maxminitoc\endcsname{% \the\flf@tb\the\flf@ta} \fi \fi \fi \fi } % \end{macrocode} %\end{macro} % Is there already a way of determining the sectioning % level from its name? % \begin{macrocode} \def\@ttb@part@level{-1} \def\@ttb@chapter@level{0} \def\@ttb@section@level{1} \def\@ttb@subsection@level{2} \def\@ttb@subsubsection@level{3} \def\@ttb@paragraph@level{4} \def\@ttb@subparagraph@level{5} % \end{macrocode} %\begin{macro}{\@checkcontentsline} % Check to see if line starts with "\contentsline" % \begin{macrocode} \long\def\@checkcontentsline#1#2\end{% \ifx#1\contentsline \@contslinetrue \else \@contslinefalse \fi} % \end{macrocode} %\end{macro} %\begin{macro}{\@gettype} % Given that the line starts with "\contentsline", extract % the first argument of "\contentsline" to get the sectioning % type. % \begin{macrocode} \def\@gettype\contentsline#1#2\end{% \def\@ttb@contstype{#1}} % \end{macrocode} %\end{macro} %\begin{macro}{\tableofcontents} % Modify "\tableofcontents". It first stores the contents % of the toc file, and then, either simply prints it on the % page (so it appears no different to the standard % "\tableofcontents"), or it prints it out so that each % thumbtab unit has the same height as the thumbtabs. % Note: this assumes that the actual table of contents % starts at the same height as the thumbtabs. The thumbtab % vertical position may need to be adjusted to compensate % for space taken up by the contents title. % \begin{macrocode} \newif\ifaligntoc \aligntocfalse \let\@ttb@old@tableofcontents\tableofcontents \renewcommand{\tableofcontents}{% \@storetoctrue \@ttb@old@tableofcontents \ifaligntoc \@printalignedtoc \else \@printtoc \fi \@storetocfalse \global\c@minitoc=0\relax} % \end{macrocode} %\end{macro} %\begin{macro}{\beforeminitocskip} % Vertical space to add before minitoc. % \begin{macrocode} \newlength\beforeminitocskip \setlength{\beforeminitocskip}{0pt} % \end{macrocode} %\end{macro} %\begin{macro}{\afterminitocskip} % Vertical space to add after minitoc. % \begin{macrocode} \newlength\afterminitocskip \setlength{\afterminitocskip}{\baselineskip} % \end{macrocode} %\end{macro} %\begin{macro}{\dominitoc} % Do the minitoc for unit "#1". Check first that % minitocs have been enabled. % \begin{macrocode} \newcommand*{\dominitoc}[1]{% \if@minitoc \@dominitoc{#1}\fi} \newcommand*{\@dominitoc}[1]{\@@dominitoc{#1}} % \end{macrocode} %\end{macro} %\begin{macro}{\minitocstyle} % Style in which to display the minitoc. % \begin{macrocode} \newcommand{\minitocstyle}[1]{\normalfont\normalsize\normalcolor #1} % \end{macrocode} %\end{macro} %\begin{macro}{\@@dominitoc} % Now do the actual minitoc for unit "#1". % \begin{macrocode} \newcommand*{\@@dominitoc}[1]{% {\minitocstyle{% \vskip\beforeminitocskip \csname @minitoc@\romannumeral#1\endcsname}} \vskip\afterminitocskip} % \end{macrocode} %\end{macro} % %\begin{macro}{\appenddfminitoc} % Modify "\dominitoc" so that the minitoc is appended % to specified \gls{dynamic}. Starred version uses % \gls{dynamic} \gls{idl}, unstarred version uses \gls{dynamic} % \gls{idn}. I originally called this macro "\appendminitoctodynamicframe" % but decided it was too long, for I've opted instead % for a slightly more cryptic name. % \begin{macrocode} \newcommand*{\appenddfminitoc}{% \renewcommand{\beforeminitocskip}{\baselineskip}% \@ifstar\@sappendminitocdf\@appendminitocdf} % \end{macrocode} %\end{macro} %\begin{macro}{\@sappendminitocdf} % Starred version % \begin{macrocode} \newcommand*{\@sappendminitocdf}[1]{% \renewcommand{\@dominitoc}[1]{% \@sappenddynamic{#1}{\@@dominitoc{##1}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@appendminitocdf} % Unstarred version % \begin{macrocode} \newcommand*{\@appendminitocdf}[1]{% \renewcommand{\@dominitoc}[1]{% \@appenddynamic{#1}{\@@dominitoc{##1}}}} % \end{macrocode} %\end{macro} %\begin{macro}{\@printtoc} % Do the table of contents, which has been stored % in "\c@maxtocunits" macros. (or possibly % "\c@maxtocunits + 1", if information was added % before the first group---which corresponds to % "\@colN=0".) % \begin{macrocode} \newcommand*{\@printtoc}{% \@colN=0\relax \csname @toc@\romannumeral\@colN\endcsname \whiledo{\@colN<\c@maxtocunits}{% \advance\@colN by 1\relax \csname @toc@\romannumeral\@colN\endcsname}} % \end{macrocode} %\end{macro} %\begin{macro}{\@printalignedtoc} % Print the table of contents so that each unit is % has vertical height the same as the height of the % thumbtabs. Note that you may have to adjust the % vertical offset of the thumbtabs (in "\makethumbtabs") % in order to make them correctly aligned. % \begin{macrocode} \newcommand{\@printalignedtoc}{% \@ff@tmpN=0\relax \@ifundefined{@toc@\romannumeral\@ff@tmpN}{% }{% \csname @toc@\romannumeral\@ff@tmpN\endcsname \par\noindent\hrulefill }% \whiledo{\@ff@tmpN<\c@maxtocunits}{% \advance\@ff@tmpN by 1\relax \ifnum\@ff@tmpN>\c@maxthumbtabs \csname @toc@\romannumeral\@ff@tmpN\endcsname \else \@dynamicframeid{thumbtabindex\number\@ff@tmpN}% \expandafter\expandafter\expandafter \@ff@getstaticpos\csname @df@dim@\romannumeral\ff@id\endcsname \vbox to \@ff@tmp@y{% \noindent\parbox{\linewidth}{% \csname @toc@\romannumeral\@ff@tmpN\endcsname}% \vfill \par\noindent\hrulefill }% \fi}} % \end{macrocode} %\end{macro} %\begin{macro}{\enableminitoc} % Make mini tocs appear at the start of given sectional unit. % \begin{macrocode} \newcounter{minitoc} \newif\if@minitoc \@minitocfalse \newcommand*{\enableminitoc}[1][\@ttb@type]{% \@minitoctrue \setcounter{minitoc}{0}% \@ifundefined{#1}{% \PackageError{flowfram}{Sectioning type `#1' not defined}{}}{% \renewcommand{\@ttb@minitoctype}{#1}% \ifthenelse{\equal{#1}{chapter}}{\@makeminitocchapter}{% \ifthenelse{\equal{#1}{part}}{\@makeminitocpart}{% \@makeminitocsection{#1}}}}% } % \end{macrocode} %\end{macro} % This command should only appear in the preamble. (This % ensures that it is used before "\tableofcontents". % \begin{macrocode} \@onlypreamble{\enableminitoc} % \end{macrocode} %\begin{macro}{\@makeminitocchapter} % If minitocs are associated with chapters, redefine % "\@chapter" so that the minitoc appears after the % chapter heading. % \begin{macrocode} \newcommand{\@makeminitocchapter}{ \let\@mtoc@old@chapter\@chapter \def\@chapter[##1]##2{% \@mtoc@old@chapter[##1]{##2}% \stepcounter{minitoc}% \dominitoc{\c@minitoc}% \@afterheading }} % \end{macrocode} %\end{macro} %\begin{macro}{\@makeminitocpart} % Again, for parts. As before, need to redefine % "\@endpart" if it exists, otherwise redefine % "\@part". % \begin{macrocode} \newcommand{\@makeminitocpart}{ \@ifundefined{@endpart}{% \let\@mtoc@old@part\@part \def\@part[##1]##2{% \@mtoc@old@part[##1]{##2}% \stepcounter{minitoc}% \dominitoc{\c@minitoc}% \@afterheading }}{% \let\@mtoc@old@endpart\@endpart \def\@endpart{% \stepcounter{minitoc}% \dominitoc{\c@minitoc}% \@mtoc@old@endpart }}} % \end{macrocode} %\end{macro} %\begin{macro}{\@makeminitocsection} % Now for the remaining sectional units. % \begin{macrocode} \newcommand{\@makeminitocsection}[1]{% \let\@mtoc@old@sect=\@sect \def\@sect##1##2##3##4##5##6[##7]##8{% \@mtoc@old@sect{##1}{##2}{##3}{##4}{##5}{##6}[##7]{##8}% \ifthenelse{\equal{##1}{#1}}{% \stepcounter{minitoc}% \dominitoc{\c@minitoc}\@afterheading}{}% }} % \end{macrocode} %\end{macro} %\iffalse % \begin{macrocode} % % \end{macrocode} %\fi %\Finale \endinput