You are on page 1of 8

The fnbreak package

Harald Harders harald.harders@gmx.de Version v1.30, 2012/01/01, Printed January 1, 2012


Abstract This package detects footnotes that are split over several pages. It writes a warning into the log le.

Contents
1 The user interface 2 The implementation 1 3

Copyright
Copyright 2003, 2004, 2006, 2010, 2012 Harald Harders. This program can be redistributed and/or modied 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.

The user interface

To use this package place


\usepackage{fnbreak}

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:
Package fnbreak Warning: Footnote number 1 (fnbreak) (label a) (fnbreak) has been split over different pages: (fnbreak) page 1 to page 2.

Sometimes, complicated footnote labels are used (for example, when using symbols):
Package fnbreak Warning: Footnote number 1 (fnbreak) (label \ensuremath {*}) (fnbreak) has been split over different pages: (fnbreak) page 1 to page 2.

In some cases may complex footnote labels may prevent fnbreak from functioning.
nolabel label

To avoid these problems, you may give the package option nolabel:
\usepackage[nolabel]{fnbreak}

Then the label is omitted in the warning:


Package fnbreak Warning: Footnote number 1 (fnbreak) has been split over different pages: (fnbreak) page 1 to page 2. \fnbreaknolabel \fnbreaklabel

You may switsch on and o printing of the footnote label in the warnings also by using the macros \fnbreaknolabel and \fnbreaklabel. If the document is set two-sided, fnbreak tries to determine whether the footnote spans over a double page or ipsides. The result is shown in the warning:
Package fnbreak Warning: Footnote number 1 (fnbreak) has been split over different pages (flipsides): (fnbreak) page 1 to page 2.

or:
Package fnbreak Warning: Footnote number 1 (fnbreak) has been split over different pages (double page): (fnbreak) page 2 to page 3.

This only works if the page numbers are (arabic) numerical.


verbose nonverbose

When using the package option verbose the fnbreak package writes a message for every footnote, even if it is completely on one page:
\usepackage[verbose]{fnbreak}

The output looks as follows:


Package fnbreak Note: (fnbreak) (fnbreak) \fnbreaknonverbose \fnbreakverbose Footnote number 2 (label 2) completely on page 3.

You may switsch on and o printing footnote information for non-split footnotes using the macros \fnbreaknonverbose and \fnbreakverbose.

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 le. Then, it is tested if both pages are the same for each footnote. Heading of the package:
1 2 3 4

package \ProvidesPackage{fnbreak} version \ProvidesFile{fnbreak-v.tex} package | version [2012/01/01 v1.30 package \RequirePackage{ifthen}

Warning for pagebreak in footnote (HH)]

Declare an option to show not only the footnote number but also the label.
5

Declare an option to show not only the footnote number but also the label.
\newif\iffnb@showlabel \newif\iffnb@verbose 8 \DeclareOption{label}{\fnb@showlabeltrue} 9 \DeclareOption{nolabel}{\fnb@showlabelfalse} 10 \DeclareOption{verbose}{\fnb@verbosetrue} 11 \DeclareOption{nonverbose}{\fnb@verbosefalse} 12 \ExecuteOptions{label,nonverbose} 13 \ProcessOptions\relax
6 7

\fnbreakverbose \fnbreaknonverbose

Switch on or o verbose printing of footnotes.


14 15

\newcommand*\fnbreakverbose{\fnb@verbosetrue} \newcommand*\fnbreaknonverbose{\fnb@verbosefalse}

\fnbreaklabel \fnbreaknolabel

Switch on or o printing of footnote labels in the warnings.


16 17

\newcommand*\fnbreaklabel{\fnb@showlabeltrue} \newcommand*\fnbreaknolabel{\fnb@showlabelfalse}

Dene new counter and boolean for determining whether a split footnote spans ofer a double page or ipsides.
18 19

\newcounter{fnb@@numberpages} \newif\iffnb@@isdoublepage \xdef\fnb@@footnotestartnum{0} \xdef\fnb@@footnotestartpage{0} \def\fnb@footnotestart#1#2#3{} \def\fnb@footnoteend#1#2#3{}

Dene default values in order to avoid possible problems:


20 21

When the aux le is read the rst time (before \begin{document}, do nothing:
22 23

Dene the working commands at \begin{document} in order to activate them when the aux le is read at the end of the document:
24

\AtBeginDocument{%

If the start of a footnote has been found, just dene commands containing the footnote number (only for debugging) and the start page:
25 26 27 28

\def\fnb@footnotestart#1#2#3{% \xdef\fnb@@footnotestartnum{#1}% \gdef\fnb@@footnotestartpage{#3}% }%

If the end of a footnote has been found, test wheather the footnote numbers t and wheather the start and end pages are the same. If one of the tests fails, generate a warning:1
29 30 31

\def\fnb@footnoteend#1#2#3{% \xdef\fnb@@footnoteendnum{#1}% \def\fnb@@footnoteendpage{#3}% \ifx\fnb@@footnotestartnum\fnb@@footnoteendnum \ifthenelse{\equal{\fnb@@footnotestartpage}{\fnb@@footnoteendpage}}{%

Test if start and end refer to the same footnote.


32

Test if the footnote ends on the same page it has started.


33

Yes, the footnote is completely on one page. Print a message if verbose mode is requested. Simulate a variant of \PackageInfo which is also written to the output rather than only to the log le.
34 35 36 37 38 39 40 41 42 43 44 45

\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 }{%

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 ipside.2 fnb@@numberpages = 0 is used if the code cannot nd out whether a footnote spans over a double page (i. e., for non-integer page numbers or single-side documents).
46

\setcounter{fnb@@numberpages}{0}%

Do the eort only if the document is two-sided. This code requised the boolean \if@twoside to be dened. If this is not the case please report to the author including a minimal example le.
47
1 Thanks 2 Thanks

\if@twoside
to Bastien Roucaries for pointing at a problem with symbol footnote marks. to Martin M unch for the idea of determining double pages.

We can nd double pages only if the start page as well as the end page are numbers.
48 49

\ifnum\number0<0\fnb@@footnoteendpage{}% \ifnum\number0<0\fnb@@footnotestartpage{}%

Calculate the number of pages covered by the footnote. If it is more than two, a ipside occurs anyways.
50 51 52

\setcounter{fnb@@numberpages}{\fnb@@footnoteendpage}% \addtocounter{fnb@@numberpages}{-\fnb@@footnotestartpage}% \addtocounter{fnb@@numberpages}{1}% \ifodd \fnb@@footnotestartpage{}% \fnb@@isdoublepagefalse

If the footnote starts on an odd page, ipside occurs in any case.


53 54

If the footnote starts on an odd page, a double page is found if the number of pages equals two.
55 56 57

\else \ifnum \thefnb@@numberpages=2{}% \fnb@@isdoublepagetrue \else \fnb@@isdoublepagefalse \fi \fi \fi \fi \fi

If the number of pages is larger, ipside.


58 59 60 61 62 63 64

Print a warning. If not determined whether a double page occurs:


65 66 67 68 69 70

\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}% \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}% \else \PackageWarningNoLine{fnbreak}{Footnote number #1 \iffnb@showlabel\MessageBreak (label #2)\fi \MessageBreak

For a double page:


71 72 73 74 75 76 77

For a ipside:
78 79 80 81

82 83 84 85

has been split over different pages (flipside):\MessageBreak page \fnb@@footnotestartpage\space to page #3}% \fi \fi \def\fnb@globalwarning{% \PackageWarningNoLine{fnbreak}{There are footnotes with a pagebreak.\MessageBreak Check if they are acceptable}% }% }% \else

Redene the \fnb@globalwarning to print a warning at the end of the log le.
86 87 88 89 90 91 92

This macro trys to handle dierent footnotes. This may not happen and is an internal error.
93 94 95 96 97 98 99 100 101 102

\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 }% } \def\fnb@fnstart{\@bsphack \protected@write\@auxout{}{% \string\fnb@footnotestart{\the\c@footnote}{\thefootnote}{\thepage}% }% \@esphack } \def\fnb@fnend{\@bsphack \protected@write\@auxout{}{% \string\fnb@footnoteend{\the\c@footnote}{\thefootnote}{\thepage}% }% \@esphack }

Dene command that writes the footnote start marker to the aux le:
103 104 105 106 107 108

Dene command that writes the footnote end marker to the aux le:
109 110 111 112 113 114

Redene \@footnotetext by patching the calls \fnb@fnstart and \fnb@fnend after all other packages have been loaded.3
\AtBeginDocument{% \newcommand\fnb@orig@footnotetext{}% 117 \let\fnb@orig@footnotetext\@footnotetext 118 \long\def\@footnotetext#1{\fnb@orig@footnotetext{\fnb@fnstart#1\fnb@fnend}}%
115 116
3 Thanks

to Bastien Roucaries for that patch

Append \fnb@globalwarning to \@dofilelist in order to print the global warning \fnb@globalwarning after all other messages, e.g., the \listfiles list.
119 120 121 122

\newcommand\fnb@dofilelist{}% \let\fnb@dofilelist\@dofilelist \def\@dofilelist{\fnb@dofilelist\fnb@globalwarning}% }

Initialise \fnb@globalwarning to print no warning by default.


\newcommand\fnb@globalwarning{}% \let\fnb@globalwarning\relax 125 /package
123 124

Change History
0.01 General: First version . . . . . . . . . 1.00 General: Correct some internal macro names . . . . . . . . . . . . . No need to have numerical page numbers anymore . . . . . . . . . . Patch \@footnotetext instead of re-writing it . . . . . . . . . . . . . . Use the footnote number instead of the label, show both in the warning . . . . . . . . . . . . . . . . . 1.10 General: Add option verbose . . . 1 Write a warning at the end of the log le . . . . . . . . . . . . . . . . . . 7 1.11 General: Allow commands in page number . . . . . . . . . . . . . . . 3, 1.20 General: Distinguish between split over double page or ipsides 3, 1.30 General: Add options nonverbose and label . . . . . . . . . . . . . . . Fix verbose mode for nonnumeric labels . . . . . . . . . . . .

3 4 6

4 3

3 4

Index
Numbers written in italic refer to the page where the corresponding entry is described; numbers underlined refer to the code line of the denition; numbers in roman refer to the code lines where the entry is used.
Symbols \@auxout . . . . . 104, \@bsphack . . . . 103, \@dofilelist . . 120, \@esphack . . . . 107, \@footnotetext 117, \@spaces . . . . . . . . . \@unused . . . . . . . . . \AtBeginDocument 24, 115 110 109 121 113 118 36 38 B \begingroup . . . . . . . 35 \equal . . . . . . . . . . . \ExecuteOptions . . . 33 12

C \c@footnote . . . 105, 111 D \DeclareOption . . . 811 E \endgroup . . . . . . . . 43

A \addtocounter . . . 51, 52

F \fnb@@footnoteendnum . . . . . . . . . 30, 32 \fnb@@footnoteendpage . . . . 31, 33, 48, 50 \fnb@@footnotestartnum . . . . 20, 26, 32, 95 \fnb@@footnotestartpage . . . . . . . . . 21,

27, 33, 49, 51, 53, 70, 77, 83, 95 \fnb@@isdoublepagefalse . . . . . . . . . 54, 59 \fnb@@isdoublepagetrue . . . . . . . . . . . . 57 \fnb@dofilelist 119121 \fnb@fnend . . . 109, 118 \fnb@fnstart . . 103, 118 \fnb@footnoteend . . . . . . . . 23, 29, 111 \fnb@footnotestart . . . . . . . 22, 25, 105 \fnb@globalwarning . . 86, 121, 123, 124 \fnb@orig@footnotetext . . . . . . . . 116118 \fnb@showlabelfalse . . . . . . . . . . 9, 17 \fnb@showlabeltrue 8, 16 \fnb@verbosefalse 11, 15 \fnb@verbosetrue 10, 14 \fnbreaklabel . . . . 1, 16 \fnbreaknolabel . . 1, 16 \fnbreaknonverbose 1, 14 \fnbreakverbose . . 1, 14 G \gdef . . . . . . . . . . . .

I \if@twoside . . . . . . . \iffnb@@isdoublepage . . . . . . . . . 19, \iffnb@showlabel . . . . 6, 40, 67, 74, \iffnb@verbose . . . 7, \ifnum . . . 48, 49, 56, \ifodd . . . . . . . . . . . \ifthenelse . . . . . . . \immediate . . . . . . .

47 72 80 34 65 53 33 38

\PackageWarningNoLine . . . . 66, 73, 79, 87 \ProcessOptions . . . 13 \protected@write . . . . . . . . . . 104, 110 \ProvidesFile . . . . . . 2 \ProvidesPackage . . . 1 R \relax . . . . . . . . 13, 124 \RequirePackage . . . . 5 S \set@display@protect 37 \string . . . . . . 105, 111 T \the . . . . . . . . . 105, 111 \thefnb@@numberpages . . . . . . . . . 56, 65 \thefootnote . . 105, 111 \thepage . . . . . 105, 111 V \verbose . . . . . . . . . . 1 W \write . . . . . . . . . . .

L \label . . . . . . . . . . . . 1 \long . . . . . . . . . . . . 118 M \MessageBreak . . . . . . . . 36, 40, 41, 6769, 7476, 8082, 88, 93, 94 N \newif . . . . . . \nolabel . . . . \nonverbose . . \number . . . . .

. . . .

. . . .

6, 7, .... .... . 48,

19 1 1 49

38

27

P \PackageError . . . . .

93

\xdef . . . .

X 20, 21, 26, 30

You might also like