% \iffalse
%%
%% File: manyfoot.dtx Copyright (C) 1998 Alexander Rozhenko
%%
%<package>\NeedsTeXFormat{LaTeX2e}[1993/12/01]
%<package>\ProvidesPackage{manyfoot}
%<package>      [1998/12/19 v1.4 Many Footnote Levels Package (NCC)]
%
% \changes{v1.0}{1998/11/09}{Initial version}
% \changes{v1.1}{1998/11/13}{Compartibility problems solved}
% \changes{v1.2}{1998/11/15}{Such footnotes may now appear in minipages!}
% \changes{v1.3}{1998/11/23}{Floating support bug fixed}
% \changes{v1.4}{1998/12/19}{Hand footnotes are moved to nccfoots package}
% \changes{v1.4}{1998/12/19}{Options |ruled| and |para*| added}
%
%<*driver>
\documentclass{ltxdoc}
\usepackage[para]{manyfoot}
\newfootnote{A}
\newfootnote[para]{B}
\newcounter{footnoteA}
\newcommand{\footnoteA}{%
   \stepcounter{footnoteA}%
   \Footnotemark\thefootnoteA\FootnotetextA{}}
\newcounter{footnoteB}
\newcommand{\footnoteB}{%
   \stepcounter{footnoteB}%
   \Footnotemark\thefootnoteB\FootnotetextB\thefootnoteB}
\renewcommand{\thefootnoteB}{\roman{footnoteB}}
\GetFileInfo{manyfoot.sty}
\begin{document}
\title{The \textsf{manyfoot} package\thanks{This file
        has version number \fileversion, last
        revised \filedate.}}
\author{Alexander Rozhenko\\rozhenko@oapmg.sscc.ru}
\date{\filedate}
\maketitle
\DocInput{manyfoot.dtx}
\end{document}
%</driver>
% \fi
%
% This package implements a command, |\newfootnote|, that adds
% footnote levels to the standard \LaTeX's footnote mechanism. Footnotes
% of every additional level are automatically grouped together
% on a \LaTeXe{} output page and are separated from another levels
% by the special vertical space and rule.
% The command |\newfootnote| allows customisation of the
% way foonotes of additional level are represented in \LaTeXe{}
% documents. Two
% customisation styles are available now: the |plain| style is the
% ordinary \LaTeX's style of footnote representation; the |para| style
% causes footnotes to be typeset as a run-in paragraph (derived from
% Donald Knuth's \TeX book and from anouther sources such as the package
% |fnpara| by Dominik Wujastyk and Chris Rowley and the package
% |footmisc| by Robin Fairbairns).
%
% \section{User Interface}
%
% \DescribeMacro\extrafootnoterule
% Footnotes of different levels are separated at the output page
% by the special footnote
% rule, |\extrafootnoterule|. By the default this command is empty. If
% you want to separate footnotes by a rule you may redefine it
% or call the package with |ruled| option:
% \begin{quote}
%   |\usepackage[ruled]{manyfoot}|
% \end{quote}
% In the last case |\extrafootnoterule| receives the value of the
% |\footnoterule| command.
%
% The style |para| of footnotes typesetting is rarely useful. To save
% space we implement options |para| and |para*|.
% If you are going to use run-in paragraph footnotes typesetted with
% the same indentation as ordinary footnotes call the package with
% |para| option:
% \begin{quote}
%   |\usepackage[para]{manyfoot}|
% \end{quote}
% To suppress indentation call it with |para*| option:
% \begin{quote}
%   |\usepackage[para*]{manyfoot}|
% \end{quote}
% Note, that these options only \emph{allows} you to generate
% additional footnote levels in |para| style.
% But what style you prefer for every footnote level is your choise. For
% example, let as generate two footnote levels: the first---in ordinary
% style and the second---in |para| style. To do this we have to write
% the following code in the preamble of the document:
% \begin{quote}
%     |\usepackage[para]{manyfoot}|\\
%     |\newfootnote{A}|\\
%     |\newfootnote[para]{B}|
% \end{quote}
% \DescribeMacro\newfootnote
% The |\newfootnote| mandatory parameter \emph{suffix} will be added
% to the end of command names generated by |\newfootnote| command.
% The optional parameter is a customisation
% style for generated footnote level (two styles now implemented, named
% |plain| and |para|; the default is |plain|).
%
% This code generates
% two commands, |\FootnotetextA| and |\FootnotetextB|, for insertion of
% a text into corresponding footnote levels. Their syntax
% is the following:
% \begin{quote}
%     |\Footnotetext|\meta{suffix}\marg{marker}\marg{inserted
%     text}
% \end{quote}
% They put the \meta{inserted text} marked with \meta{marker} into
% \TeX's insert register |\footins|\meta{suffix} (this insert is also
% generated by |\newfootnote| command). We use \emph{the hand} style of
% footnote marking, because the choise of how such footnotes have to be
% marked is user's one. Such a way simplifies the syntax of new commands
% and minimize a number of additional commands needed.
%
% \DescribeMacro\Footnotemark
% \DescribeMacro\Footnotetext
% \DescribeMacro\Footnote
% It is clear that acompany to |\Footnotetext|\meta{suffix} must
% present something like \emph{the hand footnote mark} command. Such
% commands are provided by |nccfoots| package which is automatically
% called in this package. Their syntax is the following:
% \begin{quote}
%     |\Footnotemark|\marg{marker}\\
%     |\Footnotetext|\marg{marker}\marg{inserted text}\\
%     |\Footnote|\marg{marker}\marg{inserted text}
% \end{quote}
% The first command is useful for all footnote levels. Two last commands
% are the hand companions for \LaTeX's |\footnote...| commands.
%
% The question is what these commands have to do when \meta{marker} is
% empty? In such a case we leave the current marker unchanged.
% Therefore, |\Footnote| command is equal to
% \begin{quote}
%     |\Footnotemark|\marg{marker}|\Footnotetext{}|\marg{inserted text}
% \end{quote}
% The same rule is useful for |\Footnotetext|\meta{suffix} commands in
% |plain| style. For |para| style the empty \meta{marker} means
% the footnote without marker (this is the special case useful for
% splitting of long footnotes in |para| style; see below).
%
% Finally, we explain\footnoteA{This is the first A-level footnote.}
% on the previous example\footnoteB{This is the first B-level
% footnote.} how to automate\footnoteA{The second
% A-footnote.} enumeration of the
% additional\footnoteB{The second B-footnote.}
% footnote\footnoteA{The third A-footnote.}
% levels\footnoteB{The third very very very very very very very very very
% long B-footnote.} (we have used in this
% sentence a number of level's |A| and |B| footnotes to show how this
% package works). Let us enumerate the footnotes of |A|~level by arabic
% numbers and the footnotes of |B|~level by roman numbers. We allocate
% two new counters named |footnoteA| and |footnoteB| and define the
% corresponding |\footnote...| commands with automatic enumeration. The
% corresponding code is the following
% \begin{quote}
%     |\newcounter{footnoteA}|\\
%     |\newcommand{\footnoteA}{%|\\
%     |   \stepcounter{footnoteA}%|\\
%     |   \Footnotemark\thefootnoteA \FootnotetextA{}}|\\
%     |\newcounter{footnoteB}|\\
%     |\newcommand{\footnoteB}{%|\\
%     |   \stepcounter{footnoteB}%|\\
%     |   \Footnotemark\thefootnoteB \FootnotetextB\thefootnoteB}|\\
%     |\renewcommand{\thefootnoteB}{\roman{footnoteB}}|
% \end{quote}
% To produce footnotes presented here we have done the following
% \begin{verbatim}
%     Finally, we explain\footnoteA{This is the first A-level
%     footnote.} on the previous example\footnoteB{This is the first
%     B-level footnote.} how to automate\footnoteA{The second
%     A-footnote.} enumeration of the additional\footnoteB{The second
%     B-footnote.} footnote\footnoteA{The third A-footnote.}
%     levels\footnoteB{The third very very very very very very very
%     very very long B-footnote.}\end{verbatim}
%
% \section{Splitting of \texttt{para} Footnotes}
%
% The algorithm proposed by Donald Knuth for processing of run-in
% paragraph footnotes has some shortages. Namely, small overfulls of
% output page frequently arise and the automatical splitting of long
% footnotes is impossible. First bug is corrected here (look at the
% implementation section below), but the second one couldn't be easily
% eliminated.
%
% \DescribeMacro\SplitNote
% To split a long footnote near the end of the output page we propose
% the following method. You should decide where the splitting have to be
% done. Then you split footnote ``by hands" into two parts. You leave
% \emph{the first part} at the same position in the text and comlete its
% text by the command |\SplitNote|. You move \emph{the second part} down
% in the source file and attach it to any text corresponding to the next
% page via the |\Footnotetext...| command with \emph{the empty marker}.
% E.g. you source text will look as follows:
% \begin{verbatim}
%     This text goes on the current
%     page\footnotemarkB{This is the beginning of the long
%     footnote ... the splitting must be here\SplitNote}
%         ...
%     This text goes on the next
%     page\FootnotetextB{}{and the end of the splitted
%     footnote is here ...}\end{verbatim}
% If both parts of splitted footnote get into the same output page the
% splitting is ignored.
%
% \section{Footnotes within Minipages and Multicolumns}
%
% If you attach an additional level footnote to some text inside a
% minipage, it will appear at the bottom of the page nor the minipage.
%
% The package correctly works together with |multicol| package and
% gives good results when switching between one and two columns by
% \LaTeX's commands |\twocolumn| and |\onecolumn|.
%
% You can use |footmisc| package without |para| option together with
% this package.
%
% \StopEventually{}
%
% \section{The Implementation}
%
% First we load |nccfoots| package, containing hand footnote mark
% commands and the command |\NCC@makemark|\marg{marker} which
% generates marker in |\@thefnmark| command.
%    \begin{macrocode}
%<*package>
\RequirePackage{nccfoots}
%    \end{macrocode}
%
% \begin{macro}{\extrafootnoterule}
% Then we define the empty |\extrafootnoterule| command and implement
% |ruled| option.
%    \begin{macrocode}
\newcommand{\extrafootnoterule}{}
\DeclareOption{ruled}{\def\extrafootnoterule{\footnoterule}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@columnwidth}
% \begin{macro}{\MFL@floathook}
% We use the dimen |\MFL@columnwidth| instead of |\columnwidth| while
% producing the footnote for insertion. We set this dimen to be equal
% to |\columnwidth| at the beginning of document and within the
% |\@floatplacement| command. The command |\MFL@floathook| does this
% job. Later, in |para| option, we'll add to this hook the resetting of
% the fudge factor.
%    \begin{macrocode}
\newdimen\MFL@columnwidth
\def\MFL@floathook{\MFL@columnwidth\columnwidth}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\MFL@insert}
% The command |\MFL@insert|\marg{insert register}\marg{text}
% inserts the text to the insert register and sets the standard
% splitting parameters. We let this command to be equal |\MFL@mpinsert|
% when go into a minipage. To use this command after a minipage we save
% its value in |\MFL@realinsert| command.
%    \begin{macrocode}
\long\def\MFL@insert#1#2{%
  \insert#1{\splittopskip\footnotesep \splitmaxdepth \dp\strutbox
    \floatingpenalty\@MM #2%
  }%
}
\let\MFL@realinsert\MFL@insert
%    \end{macrocode}
% \end{macro}
%
% \subsection{Footnote Styles Support}
%
% \DescribeMacro{\MFL@start...}
% Every additional footnote level has deal with its own
% \emph{insert register}
% which is allocated by |\newfootnote| command. This insert register is
% automatically initialized by the same values as the |\footins|
% register. You can modify its parameters and do something more by
% the command
% \begin{quote}
%     |\MFL@start|\meta{style}\marg{insert register}
% \end{quote}
% You must do all modifications globally, because this command is called
% within the group. It is called at the beginning of the document for
% every
% footnote of such style and is needed in the preamble only.
%
% \DescribeMacro{\MFL@fnote...}
% To put footnote into the insert register the command
% \begin{quote}
%     |\MFL@fnote|\meta{style}\marg{insert
%     register}\marg{marker}\marg{inserted text}
% \end{quote}
% is used. Note that you have to define it with |\long| modifier if you
% allow footnotes consisting of a number of paragraphs. You have to use
% the macros |\MFL@insert| and |\MFL@columnwidth| instead of |\insert|
% and |\columnwidth|.
%
% \DescribeMacro{\MFL@process...}
% And the last style customisation command
% \begin{quote}
%     |\MFL@process|\meta{style}\marg{insert register}
% \end{quote}
% is called within the output routine to prepare the box of the
% \meta{insert register} for joining it with anouther footnote inserts.
%
% Do some comments on joining algorithm. It joins together all nonempty
% footnote insert boxes and puts the result into |\footins| box. Special
% vertical space and |\extrafootnoterule| are added between every
% two neighboring nonempty inserts. This space
% is defined by the skip of the second neighbor. In other words the skip
% of the \meta{insert register} is the vertical space to be added
% between
% this insert and any nonempty footnote insert coming before it in the
% \emph{list of footnote inserts}. Note that this skip may be
% modified while processing of the document (the |multicol| package
% multiplies |\skip| and |\count| of |\footins| to the number of columns
% when goes into multicolumns mode; we do the same with these parameters
% of all another footnote inserts to provide the compartibility with
% |multicol| package).
%
% \DescribeMacro{\MFL@skip}
% The command to add the vertical space before the processed insert
% is saved in the command |\MFL@skip| exactly before the call of
% |\MFL@process...| command. The value of this space is also calculated
% in |\@tempskipa|. Using this skip register you can redefine the
% command |\MFL@skip| if nesessary. Note that this command is inserted
% \emph{between} vertical boxes in joining procedure. If processed box
% is the first nonempty footnote box (|\footins| register and all
% registers going in footins list before the processed insert are
% empty) the command |\MFL@skip| is ignored.
%
% \subsection{Plain Footnote Style}
%
% \begin{macro}{\MFL@startplain}
% \begin{macro}{\MFL@fnoteplain}
% \begin{macro}{\MFL@processplain}
% It is very simple. The commands
% |\MFL@startplain| and |\MFL@processplain| do nothing
%    \begin{macrocode}
\let\MFL@startplain\@gobble
\@onlypreamble\MFL@startplain
\let\MFL@processplain\@gobble
%    \end{macrocode}
% and the command |\MFL@fnoteplain| does near the same as the usual
% \@footnotetext command.
%    \begin{macrocode}
\long\def\MFL@fnoteplain#1#2#3{\NCC@makemark{#2}%
  \MFL@insert#1{\reset@font\footnotesize
    \interlinepenalty\interfootnotelinepenalty
    \hsize\MFL@columnwidth \@parboxrestore
    \protected@edef\@currentlabel{\@thefnmark}%
    \color@begingroup
      \@makefntext{%
        \rule\z@\footnotesep\ignorespaces#3\@finalstrut\strutbox}%
    \color@endgroup
  }%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{Para Footnote Style}
%
% \begin{macro}{\ifMFL@paraindent}
% This style is too complicated and rarely used. We load its
% commands optionally. First we define |\ifMFL@paraindent| command to
% switch between indented and not indented versions of |para| footnotes.
%    \begin{macrocode}
\newif\ifMFL@paraindent \MFL@paraindenttrue
%    \end{macrocode}
% \end{macro}
%
% Now we implement |para| option.
%    \begin{macrocode}
\DeclareOption{para}{%
%    \end{macrocode}
%
% \begin{macro}{\footglue}
% The skip |\footglue| is the horisontal space between footnotes in
% run-in paragraph. It's name goes from \TeX book
% (Appendix D. Dirty Tricks) and we don't rename this
% register. This gives us an additional protection from the usage
% at the document a number of packages providing footnotes in
% |para| style.
%    \begin{macrocode}
  \newskip\footglue
%    \end{macrocode}
% Contrarily to |footmisc| package we initialize this skip in terms of
% the footnote size (nor the normal size).
%    \begin{macrocode}
  {\footnotesize \global\footglue=1em plus.3em minus.3em }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\SplitNote}
% \begin{macro}{\ifMFL@split}
% The switch |MFL@split| provides footnote splitting and
% the command |\SplitNote| simply sets this switch to \emph{true}.
%    \begin{macrocode}
  \newif\ifMFL@split  \MFL@splitfalse
  \newcommand\SplitNote{\MFL@splittrue}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\MFL@startpara}
% Now we prepare |para| support routines. The first is the starting
% routine.
%    \begin{macrocode}
  \def\MFL@startpara#1{%
%    \end{macrocode}
% It adds to insert's skip additional space |\MFL@paraskip| (it is
% unstrechable and is calculated at the beginning of the document).
%    \begin{macrocode}
    \global\advance\skip#1\MFL@paraskip
%    \end{macrocode}
% Then we define the command named |\MFL@splitfootins|\meta{suffix}
% which saves the splitting information for the corresponding footnote
% level. While processing the document this command will have the
% empty value or |\noindent| value.
%    \begin{macrocode}
    \MFL@setsplit{#1}{}%
  }
  \@onlypreamble\MFL@startpara
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@fnotepara}
% The next command inserts footnote into \meta{insert register}.
% We use Knuth's trick to inform the output procedure how many
% horisontal space occupy the footnote by modifying its vertical size
% as \emph{fudgefactor}${}\times{}$\emph{footnotebaselineskip} where
% \emph{fudgefactor} is the ratio of \emph{footnotebaselineskip} to
% |\columnwidth|. The real vertical size of such footnote is not needed
% because the footnote is save in |\hbox| nor |\vbox| and
% while processing to the run-in paragraph will be unboxed.
%
% This footnote command is not |\long| because the |\par| command can't
% be used in |\hbox|. At the beginning we make footnote mark and
% set current label only if footnote mark was nonempty. We use below the
% temporary switch |@tempswa| to select the case of nonempty footnote
% mark.
%    \begin{macrocode}
  \def\MFL@fnotepara#1#2#3{\let\@thefnmark\@empty
    \NCC@makemark{#2}%
    \MFL@insert#1{\reset@font\footnotesize
      \ifx\@thefnmark\@empty \@tempswafalse \else
        \@tempswatrue
        \protected@edef\@currentlabel{\@thefnmark}%
      \fi
      \color@begingroup
%    \end{macrocode}
% Now we test the width of the footnote mark and if\/ it less than
% |0.8em| we calculate in |\@tempdima| the difference between |0.8em|
% and the natural width of the marker. This horisontal space is
% inserted before the footnote mark. Why it is needed? While the
% processing of |para| insert we set |\parindent| to |1em|. And taking
% into account that the marker width is at least |0.8em| we obtain the
% distance at least |1.8em| between the footnote text and the left
% margin. It is exactly the same distance as for footnotes in |plain|
% style. Why we add this space using |\hskip|? It should be removed
% when line will be broken at this point.
% We add this space when the switch |MFL@paraindent| is true.
%    \begin{macrocode}
        \if@tempswa
          \setbox\@tempboxa\hbox{\@makefnmark}%
          \ifMFL@paraindent
            \@tempdima.8em \advance\@tempdima-\wd\@tempboxa
            \ifdim \@tempdima<\z@ \@tempdima\z@ \fi
          \else
            \@tempdima\z@
          \fi
        \fi
        \setbox\@tempboxa\hbox{%
          \if@tempswa
            \hskip\@tempdima\unhbox\@tempboxa\nobreak
          \fi
%    \end{macrocode}
% Well. Now we insert the footnote text into hbox and test the
% |MFL@split| switch.
% If it is true (splitting needed) we add at the end of text the special
% small penalty |-1|. It will indicate us where the splitting needed.
% In false case we set penalty |-10| and insert |\footglue| space.
%    \begin{macrocode}
          \ignorespaces#3\unskip\strut
          \ifMFL@split \penalty\m@ne\space \else
            \penalty-10 \hskip\footglue
          \fi
        }%
%    \end{macrocode}
% And finally we use Knuth's trick.
%    \begin{macrocode}
        \dp\@tempboxa\z@ \ht\@tempboxa\MFL@fudgefactor\wd\@tempboxa
        \box\@tempboxa
      \color@endgroup
    }%
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@processpara}
% This is the last procedure of |para| style which is called in the
% output routine. We must reorganize the box of the \meta{insert
% register} which is the ``vbox of hboxes".
%    \begin{macrocode}
  \def\MFL@processpara#1{%
%    \end{macrocode}
% Firstly we redefine |\MFL@skip| command by decreasing its skip by
% |\MFL@paraskip|.
%    \begin{macrocode}
    \advance\@tempskipa -\MFL@paraskip
    \edef\MFL@skip{\vskip\the\@tempskipa\relax}%
    \setbox#1\vbox{%
%    \end{macrocode}
% Now we execute the first step of Knuth's algorithm: convert the ``vbox
% of hboxes" to ``hbox of hboxes".
%    \begin{macrocode}
      \unvbox#1\setbox\@tempboxa\hbox{}\MFL@makehhbox
%    \end{macrocode}
% The second step is unhboxing of all first level hboxes. After that we
% have the normal hbox which may be easily converted to paragraph vbox.
%    \begin{macrocode}
      \setbox\@tempboxa\hbox{\unhbox\@tempboxa\MFL@removehboxes}%
%    \end{macrocode}
% Now we set all needed parameters to prepare run-in paragraph.
%    \begin{macrocode}
      \footnotesize
      \hsize\MFL@columnwidth \@parboxrestore
      \ifMFL@paraindent \parindent\footglue \fi
%    \end{macrocode}
% Then we call |\MFL@splitfootins|\meta{suffix} macro to set |\noindent|
% if\/ it is needed (this case occurs when the footnote was splitted at
% the previous page).
%    \begin{macrocode}
      \csname MFL@split\string#1\endcsname
%    \end{macrocode}
% Here is the right place where |\footnotesep| rule have to be inserted.
%    \begin{macrocode}
      \rule\z@\footnotesep
%    \end{macrocode}
% Finally, we convert prepared hbox to vbox and test the last penalty
% (it is
% the penalty of the last |para| footnote inserted into this vbox). This
% penalty may be |-10| or |-1|. The case |-1| mean that the last
% footnote continues onto the next page (splitting case; see the
% command |\MFL@fnotepara|). In this case we adjust the last line of
% paragraph to the right margin and set |\MFL@splitfootins|\meta{suffix}
% macro to |\noindent|.
%    \begin{macrocode}
      \unhbox\@tempboxa\unskip
      \ifnum\lastpenalty=\m@ne \parfillskip\z@
        \MFL@setsplit{#1}{\noindent}%
      \else
        \MFL@setsplit{#1}{}%
      \fi
    }%
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@makehhbox}
% This procedure converts ``vbox of hboxes" to ``hbox of hboxes".
% Its implementation has minimal distinctions from the original code
% described in \TeX book. We removed from it the initialization of
% the accumulating box (|\@tempboxa|) and added a possibility some boxes
% in the list to be vboxes nor hboxes. Such vboxes arises because
% while processing a minipage we put all internal footnotes
% into vbox to prevent their splitting.
% We use the box 0 as the temporary box here.
%    \begin{macrocode}
  \def\MFL@makehhbox{%
    \loop\setbox\z@\lastbox \ifhbox\z@
      \setbox\@tempboxa\hbox{\box\z@\unhbox\@tempboxa}%
    \repeat
    \ifvbox\z@ \unvbox\z@ \MFL@makehhbox \fi
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@removehboxes}
% This is internal procedure described in \TeX book to unboxing ``hbox
% of hboxes".
%    \begin{macrocode}
  \def\MFL@removehboxes{\setbox\@tempboxa\lastbox
    \ifhbox\@tempboxa{\MFL@removehboxes}\unhbox\@tempboxa\fi
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@setsplit}
% This macro sets the value of |\MFL@splitfootins|\meta{suffix} macro.
%    \begin{macrocode}
  \def\MFL@setsplit#1#2{%
    \expandafter\gdef\csname MFL@split\string#1\endcsname{#2}%
  }
%    \end{macrocode}
% \end{macro}
%
% Finally, we have to prepare something for the work.
% We add to |\MFL@floathook| the calculation of the fudge factor.
% Such a calculation is needed when we switch between one and two
% columns by the standard \LaTeX{} commands.
%    \begin{macrocode}
  \g@addto@macro\MFL@floathook{%
    \begingroup
      \footnotesize \@tempdima\normalbaselineskip
      \multiply\@tempdima 1024
      \divide \@tempdima \columnwidth
      \multiply\@tempdima 64
      \xdef\MFL@fudgefactor{\strip@pt\@tempdima}%
    \endgroup
  }
%    \end{macrocode}
%
% \begin{macro}{\MFL@paraskip}
% The last trick is the calculation of |\MFL@paraskip|~--- the skip
% which have to be added to the skip of all |para| style footnote
% inserts and then ``turned back" while preparing of run-in paragraph.
% Why it is needed? Two reasons. The first, the
% value of |\footnotesep| may be larger than the height of |\strut|.
% And we nowhere take into account this exceeding. The second, the
% total height of |para| footnotes is less then the real height of
% the prepared run-in paragraph by |0.5\baselineskip| on the average.
% So we have to add it to the |\skip| register for the compensation.
% We do this calculation at the beginning of the document.
%    \begin{macrocode}
  \AtBeginDocument{%
    \begingroup
      \footnotesize
      \@tempdima\footnotesep
      \advance\@tempdima -\ht\strutbox
      \ifdim\@tempdima<\z@ \@tempdima\z@ \fi
      \advance\@tempdima.5\normalbaselineskip
      \xdef\MFL@paraskip{\the\@tempdima\space}%
    \endgroup
  }
}
%    \end{macrocode}
% \end{macro}
%
% Finally, we implement |para*| option which suppresses indentation of
% |para| footnotes.
%    \begin{macrocode}
\DeclareOption{para*}{%
  \@ifundefined{MFL@startpara}{\ExecuteOptions{para}}{}%
  \MFL@paraindentfalse
}
%    \end{macrocode}
%
% \subsection{Additional Footnotes Support}
%
% The footnote styles are already designed and we could process the
% package options.
%    \begin{macrocode}
\ProcessOptions\relax
%    \end{macrocode}
%
% \begin{macro}{\MFL@list}
% We initialize the list of all additional footnote levels to be empty.
%    \begin{macrocode}
\def\MFL@list{}
%    \end{macrocode}
% Its items will have the form |\@elt|\marg{style}\meta{insert register}
% \end{macro}
%
% \begin{macro}{\newfootnote}
% Then we implement the basic command which generates additional
% footnote levels.
%    \begin{macrocode}
\newcommand*{\newfootnote}[2][plain]{%
%    \end{macrocode}
% Firstly, we test the \meta{style} to be valid.
%    \begin{macrocode}
  \@ifundefined{MFL@fnote#1}{%
    \PackageError{manyfoot}{Incorrect footnote style #1}{}}{}%
%    \end{macrocode}
% Then we allocate and initialize new insert
%    \begin{macrocode}
  \expandafter\MFL@newinsert\csname footins#2\endcsname
%    \end{macrocode}
% and generate |\Footnotetext|\meta{suffix} command
%    \begin{macrocode}
  \edef\@tempa{\noexpand\newcommand
    \expandafter\noexpand\csname Footnotetext#2\endcsname
      {\expandafter\noexpand\csname MFL@fnote#1\endcsname{%
        \expandafter\noexpand\csname footins#2\endcsname}}}%
  \@tempa
%    \end{macrocode}
% and finally we add the description of this insert to the list of
% additional footnote inserts.
%    \begin{macrocode}
  \@cons\MFL@list{{#1}\csname footins#2\endcsname}%
}
\@onlypreamble\newfootnote
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@newinsert}
% The initialization of new insert.
%    \begin{macrocode}
\def\MFL@newinsert#1{\newinsert#1%
  \skip#1\skip\footins \dimen#1\dimen\footins \count#1\count\footins
}
\@onlypreamble\MFL@newinsert
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@start}
% This command executes the |\MFL@start...| command.
% It works at the preamble of the document only once for every
% additional footnote level.
%    \begin{macrocode}
\def\MFL@start#1{\csname MFL@start#1\endcsname}
\@onlypreamble\MFL@start
%    \end{macrocode}
% \end{macro}
%
% \subsection{The Basic Implementation Part}
%
% Now we have to build into \LaTeXe{} the support of additional
% footnote levels. There are a number of points where the modifications
% should be done. We do all real modifications at the beginning of the
% document. Here we prepare macros needed.
%
% \subsubsection{Modifications of Output Routine}
%
% \begin{macro}{\MFL@joinnotes}
% First point of modifications is the output routine. We choose the
% strategy of joining of the additional footnotes with |\footins|
% at the points where it is really needed. The procedure
% |\MFL@joinnotes| processes this job. It will be added later to the
% beginning of |\@makecol| and |\@doclearpage| macros.\footnote{The
% version 1.2 of this package added this procedure to the beginning of
% \texttt{\bslash @specialoutput} instead of \texttt{\bslash
% @doclearpage}. It was incorrect because
% the special output routine is often called to add the next float to
% the output page without ejecting it. As a result the additional
% footnotes disappeared before floats. Thanks to Fran\c cois Patte who
% found this bug.}
%    \begin{macrocode}
\def\MFL@joinnotes{%
  \let\MFL@elt\@elt
  \let\@elt\MFL@join \MFL@list
  \let\@elt\MFL@elt
}
\def\MFL@join#1#2{%
  \ifvoid#2%
  \else
%    \end{macrocode}
% Well. The current insert is not empty. Firstly, we calculate the skip
% of insert. Within |multicols| environement it has the size multiplied
% in |\col@number| times matching to its natural size. Therefore, we
% have to divide it by |\col@number| in such a case.
%    \begin{macrocode}
    \@tempskipa\skip#2%
    \MFL@ifmcol{\divide\@tempskipa\col@number}{}%
    \edef\MFL@skip{\vskip\the\@tempskipa\relax}%
%    \end{macrocode}
% Now we process the current insert by the style processing driver
%    \begin{macrocode}
    \csname MFL@process#1\endcsname #2%
%    \end{macrocode}
% and finally join it with |\footins| insert.
%    \begin{macrocode}
    \ifvoid\footins \setbox\footins\box#2%
    \else
      \setbox\footins\vbox{%
        \unvbox\footins\MFL@skip\extrafootnoterule\unvbox#2%
      }%
    \fi
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@reinsout}
% When the special output is called to process float insertion, all
% accumulated footnotes should be reinserted after the output box.
% This job carries out |\@reinserts| command. We will add to it
% the reinsertion of all additional footnotes with the help of
% |\MFL@reinsout| macro. Note that |\@reinserts| command is called at
% two points: when the float is the marginal note
% (|\count\@currbox|~=~0) or when it is the real float. At the second
% case we must take into account the height of all additional footnotes
% by adding it to |\@pageht| value.
%    \begin{macrocode}
\def\MFL@reinsout#1#2{\ifvoid#2\else
    \ifnum\count\@currbox>\z@
      \advance\@pageht \ht#2%
      \advance\@pageht \skip#2%
      \advance\@pageht \dp#2%
    \fi
    \insert#2{\unvbox#2}%
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Minipages Support}
%
% \begin{macro}{\MFL@reinsert}
% The command reinserts all additional footins by adding if\/
% nessesary the empty insertion (such a way is used in |multicol|).
% It is used in |minipage| and |multicols| environments.
% The point of using it at a minipage is the beginning of the minipage.
% Using this command we release the additional footnote boxes to
% accumulate footnotes inside the minipage.
%    \begin{macrocode}
\def\MFL@reinsert{{\let\@elt\MFL@reins \MFL@list}}
\def\MFL@reins#1#2{\ifvoid#2\else\insert#2{}\fi}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@mpinsert}
% Here we define the minipage insertion command which manually adds
% vbox to the insertion box. The last footnote within minipage could be
% splitted. So, we specially enclose it into vbox and unvbox the
% previous last footnote.
%    \begin{macrocode}
\long\def\MFL@mpinsert#1#2{%
  \global\setbox#1\vbox{%
    \unvbox#1\setbox\@tempboxa\lastbox
    \ifvbox\@tempboxa \unvbox\@tempboxa \fi
    \vbox{#2}%
  }%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@mpreinsert}
% This macro is useful when we really insert footnotes at the end of the
% minipage. We suppress splitting of all minipage insertions expecting
% the last one. To do this we extract the last box from the insertion
% box, then put anouther footnotes into the insert enclosing them into
% vbox, and then put the last unvboxed footnote.
%    \begin{macrocode}
\def\MFL@mpreinsert#1#2{%
  \ifvoid#2\else
    \setbox\@tempboxa\vbox{\unvbox#2\global\setbox#2\lastbox}%
    \setbox\z@\box#2%
    \ifdim\ht\@tempboxa>\z@ \MFL@realinsert#2{\box\@tempboxa}\fi
    \MFL@realinsert#2{\unvbox\z@}%
  \fi
}
%    \end{macrocode}
% Then we define two hooks which will be added to the beginning and to
% the end of a minipage. We do them in not inner mode only (for
% the first level minipages).
% \end{macro}
%
% \begin{macro}{\MFL@minipage}
% We release all box registers of the additional inserts at the
% beginning of\/ minipage to use
% them inside the minipage to accumulate inner inserts.
%    \begin{macrocode}
\def\MFL@minipage{%
  \ifinner\else
    \MFL@reinsert \let\MFL@insert\MFL@mpinsert
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@endminipage}
% We simply reinsert all footnotes at the end of the first level
% minipage.
%    \begin{macrocode}
\def\MFL@endminipage{%
  \ifinner\else
    {\let\@elt\MFL@mpreinsert \MFL@list}%
  \fi
}
%    \end{macrocode}
% \end{macro}
%
% \subsubsection{Multicol Package Support}
%
% \begin{macro}{\MFL@mult}
% The command modifies parameters of the insert register.
% It is usefull in the scope of |multicol| package only.
%    \begin{macrocode}
\def\MFL@mult#1#2{%
  \multiply\count#2\col@number
  \multiply\skip#2\col@number
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\MFL@ifmcol}
% The next macro tests the multicolumn mode. There are two
% conditions which have to be satisfied if we are in the multicolumn
% mode: the value of |\col@number| should be greater then 1 and the
% value of |\footins| count should be at least 2000.
%    \begin{macrocode}
\def\MFL@ifmcol#1#2{\@tempswafalse
  \ifnum\col@number>\@ne
    \ifnum\count\footins>1999 \@tempswatrue \fi
  \fi
  \if@tempswa #1\else #2\fi
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{What Do We Do at the Beginning of Document?}
%
%    \begin{macrocode}
\AtBeginDocument{%
%    \end{macrocode}
% Firstly, we process starting commands for every level
%    \begin{macrocode}
  {\let\@elt\MFL@start \MFL@list}
%    \end{macrocode}
% Then we modify |\@doclearpage| and |\@makecol| commands by added
% the joining algorithm at their beginning.
%    \begin{macrocode}
  \let\MFL@doclearpage\@doclearpage
  \def\@doclearpage{\MFL@joinnotes\MFL@doclearpage}
  \let\MFL@makecol\@makecol
  \def\@makecol{\MFL@joinnotes\MFL@makecol}
%    \end{macrocode}
% Then we modify |\@reinserts| command of the output routine to
% process reinsertion of all additional footnotes.
%    \begin{macrocode}
  \g@addto@macro\@reinserts{%
    \let\MFL@elt\@elt
    \let\@elt\MFL@reinsout \MFL@list
    \let\@elt\MFL@elt
  }
%    \end{macrocode}
% Then we execute |\MFL@floathook| and add it into |\@floatplacement|
% command which is called when the column mode is
% changed. One important note: in the multicolumn mode of |multicol|
% package the width of footnotes is unchanged. So, we test
% this case by the command |\MFL@ifmcol|.
%    \begin{macrocode}
  \MFL@floathook
  \g@addto@macro\@floatplacement{\MFL@ifmcol{}{\MFL@floathook}}
%    \end{macrocode}
%
% The next is the |minipage| environement. We modify |\@iiiminipage| and
% |\endminipage| adding to them hooks describe earlier.
%    \begin{macrocode}
  \let\MFL@iminipage\@iiiminipage
  \def\@iiiminipage{\MFL@minipage\MFL@iminipage}
  \g@addto@macro\endminipage\MFL@endminipage
%    \end{macrocode}
%
% Finally, we do some tricks to provide the compartibility with
% |multicol| package. If this package is loaded then the command
% |\multi@column@out| should be defined
%    \begin{macrocode}
  \@ifundefined{multi@column@out}
%    \end{macrocode}
% If it is undefined the |multicol| specific commands are not useful.
% So, we delete |\MFL@mult| command and modify |\MFL@ifmcol| command to
% choose the second case everytime.
%    \begin{macrocode}
    {\@onlypreamble\MFL@mult \let\MFL@ifmcol\@secondoftwo}
%    \end{macrocode}
% If |multicol| package presents we add the joining algorithm to the
% beginning of |\multi@column@out| command
%    \begin{macrocode}
    {\let\MFL@mcolout\multi@column@out
      \def\multi@column@out{\MFL@joinnotes\MFL@mcolout}
%    \end{macrocode}
% and add the multiplication of additional footins parameters
% by the number of columns to the end of |\init@mult@footins| command.
% We can't do this globally. So we save the previous value of |\@elt|
% command and then restore it after the calculation.
% We also modify |\reinsert@footnotes| command.
%    \begin{macrocode}
      \g@addto@macro\init@mult@footins{%
        \let\MFL@elt\@elt
        \let\@elt\MFL@mult \MFL@list
        \let\@elt\MFL@elt
      }
      \g@addto@macro\reinsert@footnotes{\MFL@reinsert}
    }
}
%</package>
%    \end{macrocode}
\endinput
