% \iffalse meta comment
% File: fnbreak.dtx Copyright (C) 2003, 2004, 2006, 2010, 2012 Harald Harders
% \fi
%
% \iffalse
%
%<*driver>
\documentclass{ltxdoc}
\title{The \texttt{fnbreak} package}
\author{Harald Harders\\\texttt{harald.harders@gmx.de}}
\date{Version \fileversion, \filedate, Printed \today}
\EnableCrossrefs
\CodelineIndex
\DoNotIndex{\def,\edef,\let,\newcommand,\newenvironment,\newcounter}
\DoNotIndex{\setcounter,\space,\ifx,\else,\fi}
\CodelineNumbered
\RecordChanges
\CheckSum{202}
\IfFileExists{fnbreak-v.tex}{%
  \input{fnbreak-v.tex}
  \GetFileInfo{fnbreak-v.tex}
}{%
  \PackageError{fnbreak}{File fnbreak-v.tex not found,
    please\MessageBreak 
    run `latex fnbreak.ins' first}{No additional help}%
  \def\fileversion{\textbf{??}}%
  \def\filedate{\textbf{??}}%
}
\begin{document}
 \DocInput{fnbreak.dtx}
\end{document}
%</driver>
% \fi
%
% \changes{0.01}{2003/04/03}{First version}
%
% \maketitle
% \begin{abstract}
% \noindent This package detects footnotes that are split over several
% pages. It writes a warning into the log file.
% \end{abstract}
%
% \tableofcontents
%
% \section*{Copyright}
% Copyright 2003, 2004, 2006, 2010, 2012 Harald Harders.
%
% This program can be redistributed and/or modified under the terms
% of the LaTeX Project Public License Distributed from CTAN
% archives in directory macros/latex/base/lppl.txt; either
% version 1.3 of the License, or any later version.
%
% \section{The user interface}
%
% To use this package place
%\begin{verbatim}
%\usepackage{fnbreak}
%\end{verbatim}
% in the preamble of your document.
%
% If a footnote is split over a page break, a warning like the
% following is put into the log:
%\begin{verbatim}
%Package fnbreak Warning: Footnote number 1
%(fnbreak)                (label `a')
%(fnbreak)                has been split over different pages:
%(fnbreak)                page 1 to page 2.
%\end{verbatim}
% Sometimes, complicated footnote labels are used (for example, when
% using symbols):
%\begin{verbatim}
%Package fnbreak Warning: Footnote number 1
%(fnbreak)                (label `\ensuremath {*}')
%(fnbreak)                has been split over different pages:
%(fnbreak)                page 1 to page 2.
%\end{verbatim}
% In some cases may complex footnote labels may prevent |fnbreak| from
% functioning.
% \begin{macro}{nolabel}
% \begin{macro}{label}
% To avoid these problems, you may give the package option |nolabel|:
%\begin{verbatim}
%\usepackage[nolabel]{fnbreak}
%\end{verbatim}
% Then the label is omitted in the warning:
%\begin{verbatim}
%Package fnbreak Warning: Footnote number 1 
%(fnbreak)                has been split over different pages:
%(fnbreak)                page 1 to page 2.
%\end{verbatim}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\fnbreaknolabel}
% \begin{macro}{\fnbreaklabel}
% You may switsch on and off printing of the footnote label in the
% warnings also by using the macros \cs{fnbreaknolabel} and \cs{fnbreaklabel}.
% \end{macro}
% \end{macro}
%
% If the document is set two-sided, fnbreak tries to determine whether
% the footnote spans over a double page or flipsides.
% The result is shown in the warning:
%\begin{verbatim}
%Package fnbreak Warning: Footnote number 1 
%(fnbreak)                has been split over different pages (flipsides):
%(fnbreak)                page 1 to page 2.
%\end{verbatim}
% or:
%\begin{verbatim}
%Package fnbreak Warning: Footnote number 1 
%(fnbreak)                has been split over different pages (double page):
%(fnbreak)                page 2 to page 3.
%\end{verbatim}
% This only works if the page numbers are (arabic) numerical.
%
% \begin{macro}{verbose}
% \begin{macro}{nonverbose}
% When using the package option |verbose| the fnbreak package writes a
% message for every footnote, even if it is completely on one page:
%\begin{verbatim}
%\usepackage[verbose]{fnbreak}
%\end{verbatim}
% The output looks as follows:
%\begin{verbatim}
%Package fnbreak Note:    Footnote number 2
%(fnbreak)                (label `2') 
%(fnbreak)                completely on page 3.
%\end{verbatim}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\fnbreaknonverbose}
% \begin{macro}{\fnbreakverbose}
% You may switsch on and off printing footnote information for
% non-split footnotes using the macros \cs{fnbreaknonverbose} and
% \cs{fnbreakverbose}.
% \end{macro}
% \end{macro}
%
%
%
% \StopEventually{\PrintChanges \PrintIndex}
%
% \section{The implementation}
%
% The approach of this package is very simple:
% At the begin and the end of each footnote text, the footnote number
% and current page are written to the aux file. Then, it is tested if
% both pages are the same for each footnote.
%
% Heading of the package:
%    \begin{macrocode}
%<package>\ProvidesPackage{fnbreak}
%<version>\ProvidesFile{fnbreak-v.tex}
%<package|version>  [2012/01/01  v1.30  Warning for pagebreak in footnote (HH)]
%<*package>
%    \end{macrocode}
% Declare an option to show not only the footnote number but also the
% label.
% \changes{1.11}{2006/05/08}{Allow commands in page number}%
%    \begin{macrocode}
\RequirePackage{ifthen}
%    \end{macrocode}
% Declare an option to show not only the footnote number but also the
% label.
% \changes{1.10}{2004/04/06}{Add option `verbose'}%
% \changes{1.30}{2012/01/01}{Add options `nonverbose' and `label'}%
%    \begin{macrocode}
\newif\iffnb@showlabel
\newif\iffnb@verbose
\DeclareOption{label}{\fnb@showlabeltrue}
\DeclareOption{nolabel}{\fnb@showlabelfalse}
\DeclareOption{verbose}{\fnb@verbosetrue}
\DeclareOption{nonverbose}{\fnb@verbosefalse}
\ExecuteOptions{label,nonverbose}
\ProcessOptions\relax
%    \end{macrocode}
% \begin{macro}{\fnbreakverbose}
% \begin{macro}{\fnbreaknonverbose}
% Switch on or off verbose printing of footnotes.
%    \begin{macrocode}
\newcommand*\fnbreakverbose{\fnb@verbosetrue}
\newcommand*\fnbreaknonverbose{\fnb@verbosefalse}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \begin{macro}{\fnbreaklabel}
% \begin{macro}{\fnbreaknolabel}
% Switch on or off printing of footnote labels in the warnings.
%    \begin{macrocode}
\newcommand*\fnbreaklabel{\fnb@showlabeltrue}
\newcommand*\fnbreaknolabel{\fnb@showlabelfalse}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% Define new counter and boolean for determining whether a split
% footnote spans ofer a double page or flipsides.
% \changes{1.20}{2010/08/09}{Distinguish between split over double
%   page or flipsides}%
%    \begin{macrocode}
\newcounter{fnb@@numberpages}
\newif\iffnb@@isdoublepage
%    \end{macrocode}
% Define default values in order to avoid possible problems:
% \changes{1.00}{2004/04/01}{Correct some internal macro names}%
%    \begin{macrocode}
\xdef\fnb@@footnotestartnum{0}
\xdef\fnb@@footnotestartpage{0}
%    \end{macrocode}
% When the aux file is read the first time (before \cs{begin\{document\}},
% do nothing:
%    \begin{macrocode}
\def\fnb@footnotestart#1#2#3{}
\def\fnb@footnoteend#1#2#3{}
%    \end{macrocode}
% Define the working commands at \cs{begin\{document\}} in order to
% activate them when the aux file is read at the end of the document:
%    \begin{macrocode}
\AtBeginDocument{%
%    \end{macrocode}
% If the start of a footnote has been found, just define commands
% containing the footnote number (only for debugging) and the start page:
% \changes{1.11}{2006/05/08}{Allow commands in page number}%
%    \begin{macrocode}
  \def\fnb@footnotestart#1#2#3{%
    \xdef\fnb@@footnotestartnum{#1}%
    \gdef\fnb@@footnotestartpage{#3}%
  }%
%    \end{macrocode}
% \changes{1.00}{2004/04/01}{No need to have numerical page numbers
%   anymore}%
% \changes{1.00}{2004/04/01}{Use the footnote number instead of the
%   label, show both in the warning}%
% If the end of a footnote has been found, test wheather the footnote
% numbers fit and wheather the start and end pages are the same. If
% one of the tests fails, generate a warning:\footnote{Thanks to
%   Bastien Roucaries for pointing at a problem with symbol footnote
%   marks.}
%    \begin{macrocode}
  \def\fnb@footnoteend#1#2#3{%
    \xdef\fnb@@footnoteendnum{#1}%
    \def\fnb@@footnoteendpage{#3}%
%    \end{macrocode}
% Test if start and end refer to the same footnote.
%    \begin{macrocode}
    \ifx\fnb@@footnotestartnum\fnb@@footnoteendnum
%    \end{macrocode}
% Test if the footnote ends on the same page it has started.
% \changes{1.11}{2006/05/08}{Allow commands in page number}%
%    \begin{macrocode}
      \ifthenelse{\equal{\fnb@@footnotestartpage}{\fnb@@footnoteendpage}}{%
%    \end{macrocode}
% Yes, the footnote is completely on one page.
% Print a message if |verbose| mode is requested.
% Simulate a variant of \cs{PackageInfo} which is also written to the
% output rather than only to the log file.
% \changes{1.30}{2012/01/01}{Fix verbose mode for non-numeric labels}
%    \begin{macrocode}
        \iffnb@verbose
          \begingroup
            \def\MessageBreak{^^J(fnbreak)\@spaces\@spaces\@spaces\@spaces}%
            \set@display@protect
            \immediate\write\@unused{^^JPackage fnbreak Note:%
              \space\space\space\space Footnote number #1
            \iffnb@showlabel\MessageBreak (label `#2') \fi
            \MessageBreak
            completely on page #3.^^J}%
          \endgroup
        \fi
      }{%
%    \end{macrocode}
% No, the footnote contains a pagebreak.
%
% If the page labels are plain numbers we can determine whether a
% footnot spans over a double page or a flipside.\footnote{Thanks to
%   Martin M\"unch for the idea of determining double pages.}
% \changes{1.20}{2010/08/09}{Distinguish between split over double
%   page or flipsides}%
% |fnb@@numberpages = 0| is used if the code cannot find out whether a
% footnote spans over a double page (i.\,e., for non-integer page
% numbers or single-side documents).
%    \begin{macrocode}
        \setcounter{fnb@@numberpages}{0}%
%    \end{macrocode}
% Do the effort only if the document is two-sided.
% This code requised the boolean \cs{if@twoside} to be defined.
% If this is not the case please report to the author including a
% minimal example file.
%    \begin{macrocode}
        \if@twoside
%    \end{macrocode}
% We can find double pages only if the start page as well as the end
% page are numbers.
%    \begin{macrocode}
          \ifnum\number0<0\fnb@@footnoteendpage{}%
            \ifnum\number0<0\fnb@@footnotestartpage{}%
%    \end{macrocode}
% Calculate the number of pages covered by the footnote. If it is more
% than two, a flipside occurs anyways.
%    \begin{macrocode}
              \setcounter{fnb@@numberpages}{\fnb@@footnoteendpage}%
              \addtocounter{fnb@@numberpages}{-\fnb@@footnotestartpage}%
              \addtocounter{fnb@@numberpages}{1}%
%    \end{macrocode}
% If the footnote starts on an odd page, flipside occurs in any case.
%    \begin{macrocode}
              \ifodd \fnb@@footnotestartpage{}%
                \fnb@@isdoublepagefalse
%    \end{macrocode}
% If the footnote starts on an odd page, a double page is found if the
% number of pages equals two.
%    \begin{macrocode}
              \else
                \ifnum \thefnb@@numberpages=2{}%
                  \fnb@@isdoublepagetrue
%    \end{macrocode}
% If the number of pages is larger, flipside.
%    \begin{macrocode}
                \else
                  \fnb@@isdoublepagefalse
                \fi
              \fi
            \fi
          \fi
        \fi
%    \end{macrocode}
% Print a warning.
%
% If not determined whether a double page occurs:
%    \begin{macrocode}
        \ifnum\thefnb@@numberpages=0
          \PackageWarningNoLine{fnbreak}{Footnote number #1
            \iffnb@showlabel\MessageBreak (label `#2')\fi
            \MessageBreak
            has been split over different pages:\MessageBreak
            page \fnb@@footnotestartpage\space to page #3}%
%    \end{macrocode}
% For a double page:
%    \begin{macrocode}
        \else
          \iffnb@@isdoublepage
            \PackageWarningNoLine{fnbreak}{Footnote number #1
              \iffnb@showlabel\MessageBreak (label `#2')\fi
              \MessageBreak
              has been split over different pages (double page):\MessageBreak
              page \fnb@@footnotestartpage\space to page #3}%
%    \end{macrocode}
% For a flipside:
%    \begin{macrocode}
          \else
            \PackageWarningNoLine{fnbreak}{Footnote number #1
              \iffnb@showlabel\MessageBreak (label `#2')\fi
              \MessageBreak
              has been split over different pages (flipside):\MessageBreak
              page \fnb@@footnotestartpage\space to page #3}%
          \fi
        \fi
%    \end{macrocode}
% Redefine the \cs{fnb@globalwarning} to print a warning at the end of
% the log file.
%    \begin{macrocode}
        \def\fnb@globalwarning{%
          \PackageWarningNoLine{fnbreak}{There are footnotes with a
            pagebreak.\MessageBreak
            Check if they are acceptable}%
        }%
      }%
    \else
%    \end{macrocode}
% This macro trys to handle different footnotes.
% This may not happen and is an internal error.
%    \begin{macrocode}
      \PackageError{fnbreak}{Internal problem:\MessageBreak
        Start and stop marker of footnote do not fit:\MessageBreak
        start: \fnb@@footnotestartnum, page \fnb@@footnotestartpage,
        end: #1, page #3}{%
        This error may not happen.
        Please try to make a short example which shows this behaviour
        and send a bug report to harald.harders@gmx.de.}%
    \fi
    }%
  }
%    \end{macrocode}
% Define command that writes the footnote start marker to the aux
% file:
%    \begin{macrocode}
  \def\fnb@fnstart{\@bsphack
    \protected@write\@auxout{}{%
      \string\fnb@footnotestart{\the\c@footnote}{\thefootnote}{\thepage}%
    }%
    \@esphack
  }
%    \end{macrocode}
% Define command that writes the footnote end marker to the aux file:
%    \begin{macrocode}
  \def\fnb@fnend{\@bsphack
    \protected@write\@auxout{}{%
      \string\fnb@footnoteend{\the\c@footnote}{\thefootnote}{\thepage}%
    }%
    \@esphack
  }
%    \end{macrocode}
% \changes{1.00}{2004/04/01}{Patch \cs{@footnotetext} instead of
%   re-writing it}%
% Redefine \cs{@footnotetext} by patching the calls \cs{fnb@fnstart}
% and \cs{fnb@fnend} after all other packages have been
% loaded.\footnote{Thanks to Bastien Roucaries for that patch}
%    \begin{macrocode}
\AtBeginDocument{%
  \newcommand\fnb@orig@footnotetext{}%
  \let\fnb@orig@footnotetext\@footnotetext
  \long\def\@footnotetext#1{\fnb@orig@footnotetext{\fnb@fnstart#1\fnb@fnend}}%
%    \end{macrocode}
% \changes{1.10}{2004/04/06}{Write a warning at the end of the log
%   file}%
% Append \cs{fnb@globalwarning} to \cs{@dofilelist} in order to print
% the global warning \cs{fnb@globalwarning} after all other messages,
% e.g., the \cs{listfiles} list.
%    \begin{macrocode}
  \newcommand\fnb@dofilelist{}%
  \let\fnb@dofilelist\@dofilelist
  \def\@dofilelist{\fnb@dofilelist\fnb@globalwarning}%
}
%    \end{macrocode}
% Initialise \cs{fnb@globalwarning} to print no warning by default.
%    \begin{macrocode}
\newcommand\fnb@globalwarning{}%
\let\fnb@globalwarning\relax
%</package>
%    \end{macrocode}
%
% \Finale
