summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/bigfoot/perpage.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-07-17 22:56:22 +0000
committerKarl Berry <karl@freefriends.org>2006-07-17 22:56:22 +0000
commitd9fe66749d8072f377522910c593df4705a9dc66 (patch)
treeca9258ad5cb90a44ec3c024220a97b98572b214a /Master/texmf-dist/source/latex/bigfoot/perpage.dtx
parent037d0c8b95024ed72ea62802db4f25231049bb7d (diff)
bigfoot update (18jul06)
git-svn-id: svn://tug.org/texlive/trunk@1872 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/bigfoot/perpage.dtx')
-rw-r--r--Master/texmf-dist/source/latex/bigfoot/perpage.dtx483
1 files changed, 483 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/bigfoot/perpage.dtx b/Master/texmf-dist/source/latex/bigfoot/perpage.dtx
new file mode 100644
index 00000000000..0209aa9e5d2
--- /dev/null
+++ b/Master/texmf-dist/source/latex/bigfoot/perpage.dtx
@@ -0,0 +1,483 @@
+% \iffalse
+%%
+%% perpage is part of the bigfoot bundle for critical typesetting
+%% Copyright 2002, 03, 04, 05, 06 David Kastrup <dak@gnu.org>
+%%
+% This program is free software; you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation; either version 2 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program; if not, write to the Free Software
+% Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+% \fi
+% \CheckSum{363}
+% \GetFileInfo{perpage.sty}
+% \date{\filedate}
+% \author{David Kastrup\thanks{\texttt{dak@gnu.org}}}
+% \title{The \texttt{perpage} package\\Version \fileversion}
+% \maketitle
+% \section{Description}
+%
+% The \texttt{perpage} package adds the ability to reset counters per
+% page and/or keep their occurences sorted in order of appearance on
+% the page.
+%
+% It works by attaching itself to the code for \cmd{\stepcounter} and
+% will then modify the given counter according to information written
+% to the |.aux| file, which means that multiple passes may be needed.
+% Since it uses the internals of the \cmd{\label} mechanism, the need
+% for additional passes will get announced by \LaTeX\ as ``labels may
+% have changed''.
+%
+% \DescribeMacro{\MakePerPage}
+% \begin{quote}
+% |\MakePerPage[2]{footnote}|
+% \end{quote}
+% will start footnote numbers with~2 on each page (the optional
+% argument defaults to~1). 2~might be a strange number, unless you
+% have used something like
+% \begin{quote}
+% |\renewcommand\thefootnote{\fnsymbol{footnote}}|
+% \end{quote}
+% and want to start off with a dagger. The starting value must not be
+% less than~1 so that the counter logic can detect the reset of a
+% counter
+% reliably.\footnote{This unfortunately means that you can't just use
+% \cmd{\alph} in order to get figures on page~10 numbered as ``10'',
+% ``10a'', ``10b''.}
+% It could be a good idea to redefine |\@cnterr| if you use a format
+% with limited range: at the first pass, footnotes are not reset
+% across pages and things like |\fnsymbol| will quickly run out of
+% characters to use.
+%
+% \DescribeMacro{\theperpage}
+% If you want to label things also on a per page base, for example
+% with
+% \begin{quote}
+% |\renewcommand{\thefigure}{\thepage-\arabic{figure}}|
+% \end{quote}
+% you'll have the problem that \thepage is updated asynchronously with
+% the real page, since \TeX\ does not know which page the figure will
+% end up. If you have used the |perpage| package for modifying the
+% figure counter, however, at the point where the counter is
+% incremented, the macro \cmd{\theperpage} will be set to the correct
+% value corresponding to the actual page location. Note that this
+% macro is shared between all counters, so advancing a different
+% counter under control of |perpage| will render \cmd{\thefigure}
+% incorrect.
+%
+% \DescribeMacro{\MakeSorted}
+% \begin{quote}
+% |\MakeSorted{figure}|
+% \end{quote}
+% will make the |figure| counter get `sorted': this means that counter
+% values will be assigned in order of appearance in the output, not in
+% order of appearance in the source code. For example, the order of
+% interspersed one- and two-column figures might get mixed up by
+% \LaTeX\ in the output. Making the counter sorted will fix the order
+% to match the order of appearance. A similar problem is when
+% ordinary footnotes are present in floating material (this does not
+% work in standard \LaTeX, but might do so when using |manyfoot.sty|
+% or |bigfoot.sty|): this might jumble their order in the output, and
+% making their counter sorted will make things appear fine again.
+%
+% While this would not fix the order in the table of figures,
+% fortunately the respective entries actually get written out in order
+% of appearance in the output anyway, so this indeed fixes the
+% problem.
+%
+% Manually setting the counter does not lead to reliable results in
+% general; as a special case, however, resetting it to zero is
+% recognized (this can also happen automatically when the counter is
+% dependent on some other counter). The point where it is reset in
+% the source code separates `count groups': everything in the source
+% before that point is assigned sorted numbers separately from
+% everything appearing behind it, and the sequence numbers start again
+% with~1 with the first item appearing in the output (not the source)
+% from the new count group.
+%
+% \DescribeMacro{\MakeSortedPerPage}
+% \begin{quote}
+% |\MakeSortedPerPage[2]{table}|
+% \end{quote}
+% will make the table numbers restart at 2 on each page \emph{and}
+% will keep them sorted, to boot. Introducing new count groups by
+% resetting the counter to~0 manually will not work, as it is not
+% clear how to handle count groups scattered between pages. You will
+% usually want to use something like
+% \begin{quote}
+% |\renewcommand{\thefigure}{\theperpage-\arabic{figure}}|
+% \end{quote}
+% to go along with a page-wise figure
+% number.\footnote{Note the use of \cmd{\theperpage} here, see above.}
+% Note that it would be quite silly to start the ranges with~2: this
+% is just an example for the optional argument in case that you ever
+% need it.
+%
+% \DescribeMacro{\AddAbsoluteCounter}
+% \begin{quote}
+% |\AddAbsoluteCounter{equation}|
+% \end{quote}
+% will create a counter |absequation| that will advance together with
+% the counter |equation| but will not get reset along with it. This
+% is not sorted into output order, but just runs along with the
+% sequence in the source file. As a special case, the counter
+% |abspage| is created in this manner and \cmd{\theabspage} is defined
+% as an arabic number that works in the same contexts as \cmd{\page}
+% (namely, gets properly deferred by \cmd{\protected@write}).
+%
+% \StopEventually{}
+% \section{The documentation driver}
+% This is the default driver for typesetting the docs. Running it
+% through as a separate file will include the code section. Running
+% the original |.dtx| file through will omit the code.
+% \begin{macrocode}
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{perpage}
+\MakePerPage{footnote}
+\begin{document}
+\OnlyDescription
+%<driver> \AlsoImplementation
+\DocInput{perpage.dtx}
+\end{document}
+%</driver>
+% \end{macrocode}
+%
+% \section{The package interfaces}
+% First identification. We just use date and version from CVS.
+% \begin{macrocode}
+%<*style>
+\NeedsTeXFormat{LaTeX2e}
+\def\next$#1: #2 #3${#2}
+\ProvidesPackage{perpage}[\next$Date: 2006/07/15 21:43:23 $
+ \next$Revision: 1.12 $ Reset/sort counters per page]
+% \end{macrocode}
+% \begin{macro}{\AddAbsoluteCounter}
+% adds a counter with prefix |abs| to a given counter. It typesets as
+% an arabic number and never gets reset. And it is advanced with the
+% unprefixed counter.
+% \begin{macrocode}
+\newcommand\AddAbsoluteCounter[1]
+{\@ifundefined{c@abs#1}{%
+ \expandafter\newcount\csname c@abs#1\endcsname
+ \global\value{abs#1}\@ne
+ \global\expandafter\let\csname cl@abs#1\endcsname\@empty
+ \expandafter\xdef\csname theabs#1\endcsname{%
+ \noexpand\number \csname c@abs#1\endcsname}%
+ \global\@namedef{c@pabs@#1}{\z@=\z@{%
+ \stepcounter{abs#1}%
+ \afterassignment}\count@}%
+ \@addtoreset{pabs@#1}{#1}}{}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\c@perpage}
+% We now create the absolute counter |perpage|:
+% \begin{macrocode}
+\AddAbsoluteCounter{page}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\theabspage}
+% This has to be specially defined so that it will expand as late as
+% \cmd{\thepage} does. Several commands set the latter temporarily
+% to \cmd{\relax} in order to inhibit expansion, and we will more or
+% less imitate its behavior when found set in that manner.
+% \begin{macrocode}
+\def\theabspage{\ifx\thepage\relax
+ \noexpand\theabspage
+ \else
+ \number\c@abspage
+ \fi}
+% \end{macrocode}
+% \end{macro}
+% Here follow the three commands for defining counters per page:
+% \begin{macro}{\MakePerPage}
+% This creates a counter reset per page. An optional second
+% argument specifies the starting point of the sequence.
+% \begin{macrocode}
+\newcommand*\MakePerPage[2][\@ne]{%
+ \pp@makeperpage{#2}\c@pchk@{#1}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MakeSorted}
+% This will create a counter sorted in appearance on the page. No
+% optional argument is given: set the counter to a desired starting
+% value manually if you need to. Resetting it to zero will start a
+% new count group, setting it to other values is probably not reliable.
+% \begin{macrocode}
+\newcommand*\MakeSorted[1]{%
+ \setcounter{#1}{\z@}%
+ \pp@makeperpage{#1}\c@schk@{\@ne}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\MakeSortedPerPage}
+% This will create output in sorted order, reset on each page. Use
+% an optional argument to specify the starting value per page. This
+% must not be~0, unfortunately.
+% \begin{macrocode}
+\newcommand*\MakeSortedPerPage[2][\@ne]{%
+ \pp@makeperpage{#2}\c@spchk@{#1}}
+% \end{macrocode}
+% \end{macro}
+% All of those must only occur in the preamble since we can't do the
+% initialization of the counter values otherwise.
+% \begin{macrocode}
+\@onlypreamble\MakePerPage
+\@onlypreamble\MakeSorted
+\@onlypreamble\MakeSortedPerPage
+% \end{macrocode}
+% \section{Internals}
+%
+% It works in the following manner: The basic work is done through
+% attaching help code to the counter's reset list. Each counter has
+% an associated absolute id that is counted through continuously and
+% is never reset, thus providing a unique frame of reference. Sorted
+% and perpage counters work by writing out information to the
+% |.aux| file.
+%
+% The information we maintain for each counter while processing the
+% source file are:
+% \begin{itemize}
+% \item The absolute counter id.
+% \item The last counter value so that we can check whether the
+% sequence has been interrupted.
+% \item The current scope id.
+% \item Its starting value.
+% \end{itemize}
+%
+% The information written to the file consists of:
+% \begin{itemize}
+% \item The absolute counter id.
+% \item The current scope id.
+% \item The scope's starting value.
+% \item The absolute counter id of a superior counter.
+% \end{itemize}
+%
+% Sorted counters work by writing out the current absolute id and
+% range id into the |.aux| file each time the counter gets incremented.
+% Whenever the counter is changed in a manner different from being
+% incremented, a new counter scope gets started. Each counter scope
+% has its own independently assigned counter numbers and is associated
+% with its absolute id starting value. So as each counter is
+% incremented, we write out the triple of current absolute id, counter
+% scope and initial value for the scope. Scope changes when a value
+% assigned from the file differs from the `natural' value. When the
+% file is read in, counter movements are tracked. Each counter that
+% does not have its `natural' value, is having a counter setting
+% recorded.
+%
+% The stuff works by adding a pseudo-reset counter to the counter's
+% dependent counter list.
+%
+% \begin{macro}{\pp@makeperpage}
+% This does the relevant things for modifying a counter. It defines
+% its reset value, it defines the correspoding absolute counter.
+% The absolute counter serves a double function: it is also used for
+% assigning numbers while reading the |.aux| file. For this purpose
+% it is assigned the initialized values here and in the enddocument
+% hook (which is called before rereading the |.aux| file and
+% checking for changed labels), while the counter is reset to zero
+% at the start of the document.
+% \begin{macrocode}
+\def\pp@makeperpage#1#2#3{%
+ \global\expandafter\mathchardef\csname c@pp@r@#1\endcsname=#3\relax
+ \global\@namedef{c@pchk@#1}{#2{#1}}%
+ \newcounter{pp@a@#1}%
+ \setcounter{pp@a@#1}{#3}%
+ \addtocounter{pp@a@#1}\m@ne
+ \@addtoreset{pchk@#1}{#1}%
+ \AtBeginDocument{\setcounter{pp@a@#1}\z@}%
+ \edef\next{\noexpand\AtEndDocument{\noexpand\setcounter{pp@a@#1}{%
+ \number\value{pp@a@#1}}}}\next}
+\@onlypreamble\pp@makeperpage
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pp@chkvlist}
+% Check for an empty vertical list. If we have one, that is worth
+% warning about.
+% \begin{macrocode}
+\def\pp@chkvlist{%
+ \ifcase
+ \ifvmode
+ \ifx\lastnodetype\@undefined
+ \ifdim-\@m\p@=\prevdepth\ifdim\lastskip=\z@\ifnum\lastpenalty=\z@
+ \@ne
+ \fi\fi\fi
+ \else
+ \ifnum\lastnodetype=\m@ne \@ne \fi
+ \fi
+ \fi \z@
+ \or
+ \PackageWarning{perpage}{\string\stepcounter\space probably at start of
+ vertical list:^^JYou might need to use \string\leavevmode\space
+ before it to avoid vertical shifts}%
+ \fi}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pp@fetchctr}
+% \begin{macro}{\theperpage}
+% This fetches the counter information and puts it into
+% \cmd{\pp@label}, \cmd{\pp@page} and (globally) into
+% \cmd{\theperpage}.
+% \begin{macrocode}
+\def\pp@fetchctr#1{\expandafter\expandafter\expandafter\pp@fetchctrii
+ \csname pp@r@#1@\number\value{pp@a@#1}\endcsname
+ \@empty\@empty}
+
+\global\let\theperpage\@empty
+
+\def\pp@fetchctrii#1#2#3{\edef\pp@label{#1}%
+ \edef\pp@page{#2}%
+ \gdef\theperpage{#3}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% Ok, let's put together all the stuff for the simplest case, counters
+% numbered per page without sorting:
+% \begin{macro}{\c@pchk@}
+% This is the code buried into to the reset list. When the reset
+% list is executed in the context of advancing a counter, we call
+% something like
+% \begin{verbatim}
+%\global\c@pchk@{countername}\z@
+% \end{verbatim}
+% since the reset list expected a counter here instead of some
+% generic command. That is the reason we start off this command by
+% giving \cmd{\global} something to chew on.
+% \begin{macrocode}
+\def\c@pchk@#1{\z@=\z@
+ \begingroup
+% \end{macrocode}
+% Now we fetch the page value corresponding to the not yet adjusted
+% value of the absolute counter to see whether the previous counter
+% advance happened on the same page.
+% \begin{macrocode}
+ \pp@fetchctr{#1}\let\next\pp@page
+ \addtocounter{pp@a@#1}\@ne
+ \pp@fetchctr{#1}%
+% \end{macrocode}
+% We compare the pages for current and last advance of the counter.
+% If they differ, we reset the counter to its starting value. We do
+% the same if the counter has been reset to zero manually, likely by
+% being in the reset list of some other counter.
+% \begin{macrocode}
+ \ifcase\ifx\next\pp@page\else\@ne\fi
+ \ifnum\value{#1}=\z@\@ne\fi\z@
+ \else
+ \setcounter{#1}{\value{pp@r@#1}}%
+ \fi
+ \pp@writectr\pp@pagectr{#1}{\noexpand\theabspage}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pp@writectr}
+% This is the common ending of all pseudo reset counters. It writes
+% out an appropriate command to the |.aux| file with all required
+% information.
+% \begin{macrocode}
+\def\pp@writectr#1#2#3{\edef\next{%
+ \string#1{#2}{\number\value{pp@a@#2}}{#3}{\noexpand\thepage}}%
+ \pp@chkvlist
+ \dimen@=\lastkern
+ \ifdim\dimen@=\z@ \else \unkern\fi
+ \protected@write\@auxout{}{\next}%
+ \ifdim\dimen@=\z@ \nobreak \else \kern\dimen@\fi
+ \afterassignment\endgroup\count@}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pp@pagectr}
+% This is the workhorse for normal per page counters. It is called
+% whenever the |.aux| file is read in and establishes the
+% appropriate information for each counter advancement in a
+% pseudolabel.
+% \begin{macrocode}
+\def\pp@pagectr#1#2#3#4{\@ifundefined{c@pp@a@#1}{}{%
+ \addtocounter{pp@a@#1}\@ne
+ \edef\next{\noexpand
+ \@newl@bel{pp@r@#1}{#2}{{\number\value{pp@a@#1}}{#3}%
+ {#4}}}\next}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\c@schk@}
+% This is called for implementing sorted counters. Sorted counters
+% maintain a ``count group'', and the values in each count group are
+% numbered independently from that of other count groups. Whenever
+% a counter is found to have been reset, it will start a new count
+% group. At the end of document, the count group counters need to
+% get reset, too, so that the check for changed |.aux| files will
+% still work.
+% \begin{macrocode}
+\def\c@schk@#1{\z@=\z@
+ \begingroup
+ \addtocounter{pp@a@#1}\@ne
+ \ifnum\value{#1}=\@ne
+ \expandafter\xdef\csname pp@g@#1\endcsname{\number\value{pp@a@#1}}%
+ \edef\next{\noexpand\AtEndDocument{\global\let
+ \expandafter\noexpand\csname pp@g@#1@\number\value{pp@a@#1}\endcsname
+ \relax}}\next
+ \fi
+ \pp@fetchctr{#1}%
+ \ifx\pp@page\@empty
+ \else \setcounter{#1}{\pp@label}\fi
+ \pp@writectr\pp@spagectr{#1}{\csname pp@g@#1\endcsname}}%
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pp@spagectr}
+% This is the code advancing the respective value of the appropriate
+% count group and assigning the label.
+% \begin{macrocode}
+\def\pp@spagectr#1#2#3#4{\@ifundefined{c@pp@a@#1}{}{%
+ \count@0\csname pp@g@#1@#3\endcsname
+ \advance\count@\@ne
+ \expandafter\xdef\csname pp@g@#1@#3\endcsname{\number\count@}%
+ \edef\next{\noexpand
+ \@newl@bel{pp@r@#1}{#2}{{\number\count@}{#3}%
+ {#4}}}\next}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\c@spchk@}
+% And this finally is the counter advance code for sorted counters
+% per page. Basically, we just use one count group per page.
+% Resetting a counter manually will not introduce a new count group,
+% and it would be hard to decide what to do in case count groups and
+% page positions overlap.
+% \begin{macrocode}
+\def\c@spchk@#1{\z@=\z@
+ \begingroup
+ \addtocounter{pp@a@#1}\@ne
+ \pp@fetchctr{#1}%
+ \ifx\pp@page\@empty
+ \else \setcounter{#1}{\pp@label}\fi
+ \pp@writectr\pp@ppagectr{#1}{\noexpand\theabspage}}
+%</style>
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\pp@ppagectr}
+% \begin{macrocode}
+\def\pp@ppagectr#1#2#3#4{\@ifundefined{c@pp@a@#1}{}{%
+ \def\next{#3}%
+ \expandafter\ifx\csname pp@page@#1\endcsname\next
+ \addtocounter{pp@a@#1}\@ne
+ \else
+ \setcounter{pp@a@#1}{\value{pp@r@#1}}%
+ \fi
+ \global\expandafter\let\csname pp@page@#1\endcsname\next
+ \edef\next{\noexpand
+ \@newl@bel{pp@r@#1}{#2}{{\number\value{pp@a@#1}}{#3}%
+ {#4}}}\next}}
+% \end{macrocode}
+% \end{macro}
+%
+% \Finale{}
+% \endinput
+% Local Variables:
+% mode: doctex
+% TeX-master: "perpage.drv"
+% End:
+