diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/mparhack/mparhack.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/mparhack/mparhack.dtx | 838 |
1 files changed, 838 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/mparhack/mparhack.dtx b/Master/texmf-dist/source/latex/mparhack/mparhack.dtx new file mode 100644 index 00000000000..7c390633be1 --- /dev/null +++ b/Master/texmf-dist/source/latex/mparhack/mparhack.dtx @@ -0,0 +1,838 @@ +% \iffalse meta-comment +% +% 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +% +% \fi +% +% \DoNotIndex{\#,\$,\%,\&,\@,\\,\{,\},\^,\_,\~,\ } +% \DoNotIndex{\def,\long,\edef,\xdef,\gdef,\let,\global} +% \DoNotIndex{\if,\ifnum,\ifdim,\ifcat,\ifmmode,\ifvmode,\ifhmode,% +% \iftrue,\iffalse,\ifvoid,\ifx,\ifeof,\ifcase,\else,\or,\fi,\loop,\do} +% \DoNotIndex{\box,\copy,\setbox,\unvbox,\unhbox,\hbox,% +% \vbox,\vtop,\vcenter} +% \DoNotIndex{\@empty,\immediate,\write} +% \DoNotIndex{\egroup,\bgroup,\expandafter,\begingroup,\endgroup} +% \DoNotIndex{\divide,\advance,\multiply,\count,\dimen} +% \DoNotIndex{\relax,\space,\string} +% \DoNotIndex{\csname,\endcsname,\@spaces,\openin,\openout,% +% \closein,\closeout} +% \DoNotIndex{\catcode,\endinput} +% \DoNotIndex{\jobname,\message,\read,\the,\noexpand} +% \DoNotIndex{\hsize,\vsize,\hskip,\vskip,\kern,\hfil,\hfill,\hss} +% \DoNotIndex{\m@ne,\z@,\@m,\z@skip,\@ne,\tw@,\p@} +% \DoNotIndex{\DeclareRobustCommand,\DeclareOption,\newcommand,\newcommand*} +% \DoNotIndex{\newcount,\newif,\newlinechar,\newread,\newtoks,\newwrite} +% \DoNotIndex{\dp,\wd,\ht,\vss,\unskip} +% +% \CheckSum{405} +% +% \MakeShortVerb\| +% +% \iffalse +% \begin{macrocode} +%<*driver> +\documentclass{ltxdoc} +\RequirePackage{url}% +\IfFileExists{hyperref.sty}{\RequirePackage{hyperref}}{% +%%% alternative definitions if hyperref is not available + \newcommand\href[2]{#2}% + \newcommand\url{\texttt}% +} +\EnableCrossrefs + %\DisableCrossrefs % Say \DisableCrossrefs if index is ready +\CodelineIndex +\RecordChanges +\setcounter{IndexColumns}{2} % make a twocolumn index +\setlength{\columnseprule}{0pt} % no rules between columns ... +\setlength{\columnsep}{2em} % ... but more spacing instead. +\setcounter{unbalance}{4} +\setlength{\IndexMin}{100pt} +\OnlyDescription +\setlength\hfuzz{3pt} +%\hbadness=7000 +\frenchspacing +\begin{document} + \DocInput{mparhack.dtx} + \raggedright +\end{document} +%</driver> +% \end{macrocode} +% ^^A See CTAN:tools/filehdr/filehdr.dvi for an explanation for the following stuff +% +% =================================================================== +% @LaTeX-package-file{ +% version = "1.3a", +% date = "2003/05/22", +% filename = "mparhack.sty", +% author-1 = "Tom Sgouros", +% email-1 = "tomfool@top.gso.uri.edu", +% author-2 = "Stefan Ulrich", +% email-2 = "stefanulrich@users.sourceforge.net", +% codetable = "ISO/ASCII", +% keywords = "marginpar, marginpars, marginal notes, wrong margin" +% supported = "yes", +% docstring = "User manual and documented source code and for the +% LaTeX package mparhack.sty" +% } +% =================================================================== +% \fi +% \newcommand*\Com[1]{\texttt{\char`\\#1}} +% \newcommand*\File[1]{\texttt{#1}} +% \newcommand*\Explanation[1]{\noindent +% \rule[.5ex]{.4\linewidth}{.6pt}\kern1em +% ^^A$\bullet\bullet\bullet$ +% {\itshape\small #1}^^A +% }^^A\kern1em\rule[.5ex]{6em}{.6pt}} +% \newenvironment{Addition}{\par\noindent\Explanation{begin addition}\par\noindent\ignorespaces}^^A +% {\Explanation{end addition}} +% \newenvironment{Replacement}{\par\noindent\Explanation{begin replacement:}\par\noindent\ignorespaces}^^A +% {\Explanation{end replacement}} +% \newcommand*\ReplacedBy{\par\noindent\Explanation{by:}\par\noindent\ignorespaces} +% \newcommand*\PackageNameNoExt{mparhack} +% \newcommand*\PackageName{\texttt{\PackageNameNoExt.sty}} +% \def\AfterElseFi#1\else#2\fi{\else#2\fi#1} +% \GetFileInfo{mparhack.sty} +% \title{\PackageName} +% \author{Tom Sgouros\\ {\small\texttt{tomfool@top.gso.uri.edu}} \and +% Stefan Ulrich\\ {\small\href{mailto:stefanulrich@users.sourceforge.net}{\texttt{stefanulrich@users.sourceforge.net}}}} +% \date{v1.3a 2003/05/22\\[1ex] {\footnotesize CTAN: +% \href{http://www.ucc.ie/cgi-bin/ctan?server=ftp.dante.de%2Ftex-archive&term=mparhack} +% {\texttt{macros/latex/contrib/supported/mparhack/}}}} +% \maketitle +% +% \begin{abstract} +% This package implements a workaround for the \LaTeX\ bug +% that marginpars sometimes show up on the wrong margin. +% \end{abstract} +% +% \changes{1.0}{1999/03/02}{Created} +% \changes{1.1}{1999/09/23}{Rewrite to use only one label per page, and to implement +% `twocolumn' document option.} +% \changes{v1.2}{2000/02/29}{Small documentation changes} +% \changes{1.2a}{2000/03/14}{Fixed the \Com{NeedsTeXFormat} to use 1997/04/14} +% \changes{1.2c}{2001/02/07}{Small documentation changes} +% \changes{1.3}{2001/02/07}{Use \Com{mph@tempa} instead of \Com{@tempa} to avoid possible clashes with other classes (e.g. scrpage2)} +% +% +% {\parskip 0pt \tableofcontents } +% +% ^^A -------------------------------------------------- +% \section{Introduction} +% ^^A -------------------------------------------------- +% +% A persistent problem with the |\marginpar| command is that the +% marginalia produced often show up on the wrong margin. This has +% been noted in the \LaTeX\ bugs database.^^A +% \footnote{See \url{http://www.Uni-Mainz.DE/cgi-bin/ltxbugs2html}: +% \href{http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=latex/2361}{latex/2361}, +% \href{http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=latex/2484}{latex/2484}, +% \href{http://www.latex-project.org/cgi-bin/ltxbugs2html?pr=latex/2617}{latex/2617}.} +% +% +% The problem occurs most likely when a marginpar appears near +% the top of a page. The problem is exacerbated when +% the page break penalties are adjusted so that the page look is +% quite ragged. In cases like this, if there is a deal of white +% space on a page, the marginpars on the next page will be on the +% wrong side for the same length of the page. +% The reason for this is that the \LaTeX\ output routine is not +% in complete synchronization with the \TeX\ page breaker, so that +% sometimes +% material might still move to a later page \emph{after} \LaTeX's +% marginpar algorithm has determined a page number for the marginpar. +% +% The fix suggested in the bugs database is to insert |\pagebreak| +% commands at the places where the page breaks naturally fall; +% then the marginpars will appear on the correct side. However, this is +% awkward and unpleasant work for a document that changes +% regularly, and seems to fly against the spirit of \LaTeX. +% +% A different approach was suggested by D. E. Knuth in his +% \emph{Macros for Jill}\footnote{Originally published in TUGboat +% \textbf{8}, pp.~309--314, reprinted in his \emph{Digital +% Typography} pp.~185--193.}: make two |.dvi| files, one with all +% notes in the left margin, the other one with all notes in the +% right margin. Then print the odd pages from one file, and the +% even pages from the other file; merge them by hand. +% +% However, Knuth also mentions the possibility to use an auxiliar +% file to save the page information for each marginpar and use this +% information to position it correctly in a second \TeX\ run; and +% this is the strategy adopted by \PackageName. +% Each marginpar is assigned a unique number; the output routine +% writes the number of the last marginpar of each page\slash column +% to the |.aux| file, and this information is used in +% |\@addmarginpar| to position the current marginpar on the correct +% margin. +% +% +% ^^A -------------------------------------------------- +% \section{Usage} +% ^^A -------------------------------------------------- +% Just insert |\usepackage{mparhack}| into your document preamble. +% After the first run, you'll probably get the warning message +% `\texttt{Marginpars may have changed. Rerun to get them right}'. +% This is similar to \LaTeX's warning `\texttt{Label(s) may have +% changed}'; it indicates that the |.aux| file doesn't contain the +% information needed to position the marginpars correctly, due to +% some changes in the document since the last run. The warning +% should go away after running \LaTeX\ again (eventually several +% times if there's also a table of contents etc.). +% +% \DescribeMacro{debug}^^A +% If you think something is going wrong, the package also has a +% \texttt{debug} option; this will output a lot of tracing +% information and will add numbers to the marginpars in the |.dvi| +% file for reference. +% +% +% ^^A -------------------------------------------------- +% \section{Bugs\slash Restrictions} +% ^^A -------------------------------------------------- +% \begin{itemize} +% \item +% The package works with the |twocolumn| document option, but not +% with the |multicol| package (you can't use marginpars inside +% the |multicols| environment). +% \item +% The package uses one command sequence per page, and the total number +% of command sequences available is limited on most \TeX\ systems. +% Note however that most current \TeX\ implementations +% can allocate more than several thousand command names, and some can +% be configured to allocate more than the default during run-time, +% so this shouldn't be a problem for moderately sized documents. +% \item +% The package has to hook into three commands of the \LaTeX2e\ output +% routine (by redefining some command), so it requires at least +% \LaTeX\ version 1997/04/14 and might break with future \LaTeX\ +% versions that change these commands. +% We try to detect this by requiring a version newer than 1997/04/14 +% and using some heuristics to check if the redefinitions have worked. +% You should watch out for this warning message:\par +% {\ttfamily\footnotesize\begin{tabular}{@{}l@{}l@{}} +%LaTeX Warning:&\ You have requested release `1997/04/14' of LaTeX,\\ +% &\ but only release `...' is available. +% \end{tabular}}\par\noindent +% It might be that the package also works with older versions of \LaTeX, +% but this hasn't been tested. If one of the heuristics detects an incompatible +% change, it will raise an error:\par +% {\ttfamily\footnotesize\begin{tabular}{@{}l@{}} +%Package mparhack Error: Couldn't hook into command `xyz'. +% \end{tabular}}\par\noindent +% \vskip-\lastskip\noindent +% It might also happen that the heuristics don't detect a change +% properly. If the package simply seems to fail, this could be a reason. +% In both cases, please send a bug report to +% \href{mailto:stefanulrich@users.sourceforge.net}{\texttt{stefanulrich@users.sourceforge.net}} +% (if neccessary including the +% |.log| file of your \LaTeX\ run with the \texttt{debug} +% package option enabled). Suggestions/improvements are also welcome, +% of course. +% \end{itemize} +% +% ^^A -------------------------------------------------- +% \section{Acknowledgements} +% ^^A -------------------------------------------------- +% Thanks to Donald Arseneau and Robin Fairbairns for providing +% detailed hints\footnote{in \texttt{<23AUG199920123097@erich.triumf.ca>} and +% \texttt{<7prb8s\$dpr\$1@pegasus.csx.cam.ac.uk>}, respectively.} +% on how to implement the page referencing mechanism using only one +% label per page (instead of one label each marginpar, as in a +% previous version). +% +% ^^A -------------------------------------------------- +% ^^A Place to stop if implementation shouldn't be printed +% ^^A -------------------------------------------------- +% +% \typein[\answer]% +% {^^JPrint an annotated listing of the macro definitions (y/n)? [n]} +% \def\next{y}^^A +% \ifx\answer\next +% \AfterElseFi\AlsoImplementation +% \else +% \typeout{(not printing macro definitions.)}^^A +% \expandafter\endinput +% \fi +% \StopEventually{\relax} +% ^^A -------------------------------------------------- +% \section{Implementation} +% ^^A -------------------------------------------------- +% +% ^^A -------------------------------------------------- +% \subsection{Overview}\label{implementation} +% ^^A -------------------------------------------------- +% Here's the algorithm for recording the positioning information for +% marginpars in more detail: Every marginpar has a unique number $n$ and +% writes to the |.aux| file a string like\par\medskip +% ^^A +% \begin{tabular}{@{}l} +% |\def\mph@nr{|$n$|}|. +% \end{tabular}\par\medskip +% +% The commands shipping out the columns and pages write to the +% |.aux| file strings like:\par\medskip +% ^^A +% \begin{tabular}{@{}l} +% |\mph@setcol{|$x{\texttt{:}}$|\thepage}{\mph@nr}|, +% \end{tabular}\par\medskip\noindent +% ^^A +% with $x = \mbox{i}$ for the first column and $x = \mbox{ii}$ +% otherwise. Then when reading the |.aux| +% file at the begin of the \LaTeX\ run, |\mph@nr| will be substitued +% by the number of the last marginpar (the value of the |\mph@nr| command +% read before that), +% and |\mph@setcol| will assign that number to the command sequence |\csname| +% |mph@last@|$x{\texttt{:}}$|\thepage\endcsname|; so this will contain +% the number of the last marginpar on column\slash page $x{\texttt{:}}$|\thepage|. +% +% Later on, in the document itself, |\@addmarginpar| will be able to check the value of +% |\csname| |mph@last@|$x{\texttt{:}}$\Com{thepage}\Com{end\-csname}, +% using the current values for $x$ and |\thepage|. Then there are two +% cases: +% +% (a) |\csname| |mph@last@|$x{\texttt{:}}$|\thepage\endcsname| is +% undefined, which means that there has been no |.aux| file +% previously, or that there are more pages\slash marginpars than in +% the previous run; in this case, |\@addmarginpar| will fall back to using +% the value of |\c@page| to determine the current page number (yielding the +% same result as without this package), or +% +% (b) |\csname| |mph@last@|$x{\texttt{:}}$|\thepage\endcsname| is defined as +% an integer $z$, the number of the last marginpar on |\thepage|. +% Then $z \leq n$, the number of the current marginpar.^^A +% \footnote{$z$ cannot be greater than $n$: this would +% mean that \TeX\ had shifted some material (including a marginpar) +% from later pages to earlier pages, which AFAIK cannot happen.} +% While $z < n$, the page counter will be incremented (inside a group) +% until |\csname| |mph@last@|$x{\texttt{:}}$|\thepage\endcsname| for +% that new page is $\geq n$, or until +% we end up in case (a). The incremented value for the page counter +% now represents the actual page number of the current marginpar, +% and it will be used instead of the original page counter in the +% check for even-\slash oddness. +% +% ^^A -------------------------------------------------- +% \subsection{Code} +% ^^A -------------------------------------------------- +% +% We need at least \LaTeX\ version 1997/04/14 which introduced +% |\normalsfcodes| into |\@outputdblcol|. +% \begin{macrocode} +%<*sty> +\NeedsTeXFormat{LaTeX2e}[1997/04/14] +\ProvidesPackage{mparhack} + [2003/05/22 v1.3a (T. Sgouros and S. Ulrich)] +% \end{macrocode} +% ^^A -------------------------------------------------- +% \subsubsection{Booleans, Options, etc.} +% ^^A -------------------------------------------------- +% Some boolean switches which we will be using: +% |\if@mph@firstcol@| indicates that the current column is the +% first column, |\if@mph@warning@| toggles the warning message +% about changed marginpars, and |\if@debug@| toggles printing (lots +% of) debugging messages. +% \begin{macrocode} +\newif\if@mph@firstcol@ +\newif\if@mph@warning@ +\newif\if@debug@ +% \end{macrocode} +% \begin{macro}{\mph@debug} +% This command will print the debugging messages if |@debug@| is |true|: +% \begin{macrocode} +\newcommand*\mph@debug[2][]{% + \if@debug@ + \typeout{DBG: #2}% + \else + \ifx#1\@empty\else + \typeout{DBG (#1): #2}% + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% The |debug| package option sets |@debug@| to true and adds +% numbers to each marginpar by redefining \Com{@xmpar} and +% \Com{@ympar}. The numbers are put into boxes of dimension +% zero so that they don't alter the spacing. +% \begin{macrocode} + +\DeclareOption{debug}{% + \newcommand\mph@info{% + \@tempcnta=\mph@cnt + \advance\@tempcnta1 + \raisebox{0pt}[0pt][0pt]{\makebox[0pt][r]{\tiny\the\@tempcnta}}% + }% + \long\def\@xmpar[#1]#2{% + \@savemarbox\@marbox{\mph@info#1}% + \@savemarbox\@currbox{\mph@info#2}% + \@xympar + }% + \long\def\@ympar#1{% + \@savemarbox\@marbox{\mph@info#1}% + \global\setbox\@currbox\copy\@marbox + \@xympar + }% + \global\@debug@true +}% +\ProcessOptions* +% \end{macrocode} +% ^^A -------------------------------------------------- +% \subsubsection{Commands} +% ^^A -------------------------------------------------- +% \begin{macro}{\mph@nr} +% A command sequence containing the current marginpar number (which +% will be written to the |.aux| file). +% \begin{macrocode} +\newcommand*\mph@nr{0} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\mph@pg@new} +% A command sequence for saving the newly determined value of |\thepage| for later use. +% \begin{macrocode} +\newcommand*\mph@pg@new{0} +\newcommand*\mph@lastpage{0} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mph@cnt} +% Emulate a counter with a command name to save one count +% register. Oh well~\dots \texttt{;-)} +% \begin{macrocode} +\newcommand*\mph@cnt{0} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\mph@step@cnt} +% Use this instead of |\stepcounter| to increment the `counter' +% passed as the argument. +% \begin{macrocode} +\newcommand*\mph@step@cnt[1]{% + \begingroup + \@tempcnta#1 + \advance\@tempcnta\@ne + \protected@xdef#1{\the\@tempcnta}% + \endgroup +} + +% \end{macrocode} +% \end{macro} +% \begin{macro}{\mph@setcol} +% The command sequence written to the |.aux| file that will save +% the column number\slash page number of the last marginpar on the +% column\slash page.^^A The additional |ignore@warn#1| macro is used +% ^^A in the |\mph@check| macro. +% \begin{macrocode} +\newcommand*\mph@setcol[2]{% +% \@ifundefined{mph@last@#1}{% +% \relax +% }{% +% \expandafter\xdef\csname ignore@warn#1\endcsname{x}% +% }% + \expandafter\xdef\csname mph@last@#1\endcsname{#2}% +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\mph@check} +% Similar to \LaTeX's |\@testdef| for labels, this will be called +% at the end of the \LaTeX\ run to check if the meaning of |#2| is +% still equal to |mph@last@#1| or if it has changed since the last +% run. +% \begin{macrocode} +\newcommand*\mph@tempa{} +\newcommand*\mph@check[2]{% + \protected@edef\mph@tempa{#2}% + \expandafter\ifx\csname mph@last@#1\endcsname\mph@tempa + \mph@debug{\csname mph@last@#1\endcsname\space == \mph@tempa}% + \else + \mph@debug{\csname mph@last@#1\endcsname\space != \mph@tempa!}% + \global\@mph@warning@true + \fi +} +\newcommand*\mph@do@warn{% + \if@mph@warning@ + \PackageWarningNoLine{mparhack}{Marginpars may have + changed.\MessageBreak Rerun to get them right% + }% + \fi +} +% \end{macrocode} +% \end{macro} +% To avoid warnings about undefined commands when someone stops using +% this package, we |\providecommand| the |\mph@setcol| command that +% we're going to write to the |.aux| file. +% \begin{macrocode} +\AtBeginDocument{% + \protected@write\@auxout{}{% + \string\providecommand\string\mph@setcol[2]{}% + }% +} +% \end{macrocode} +% Add the needed checks to |\@enddocumenthook|. Again, use +% |\csname| ... |\endcsname| to avoid warnings about undefined +% commands. +% \changes{v1.2}{2000/02/29}{% +% Use \Com{csname...} when writing commands to \texttt{.aux} file +% }% +% \begin{macrocode} +\AtEndDocument{% + \let\mph@setcol\mph@check + \clearpage + \immediate\write\@auxout{% + \string\gdef\string\mph@lastpage{\the\c@page}^^J% + \string\csname\space mph@do@warn\string\endcsname + }% +} +% \end{macrocode} +% +% \begin{macro}{\mph@ifundef@or@smaller} +% A helper macro that checks if the command sequence in |#1| is +% undefined or if its value is smaller than |\mph@cnt| (it assumes +% that |#1| is never empty). If one of these conditions is true, +% the second argument is evaluated, else the third argument is +% evaluated (similar to \LaTeX's |\@ifundefined|). This macro +% will be used to shorten the body of the next macro definition. +% \changes{v1.2}{2000/02/29}{% +% Renamed this command, and updated the documentation +% }% +% \begin{macrocode} +\newcommand*\mph@ifundef@or@smaller[1]{% + \expandafter\ifx#1\relax + \let\mph@tempa\@firstoftwo + \else + \ifnum#1<\mph@cnt\relax + \let\mph@tempa\@firstoftwo + \else + \let\mph@tempa\@secondoftwo + \fi + \fi + \mph@tempa +} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mph@pg@orig} +% \changes{v1.2}{2000/02/29}{% +% Added the \Com{mph@pg@orig} macro +% }% +% The macro |\mph@pg@orig| is used to +% save the original value of |\c@page| which is used in case the |.aux| +% file information is not up-to date and we can't determine the +% correct value; this should give the same results as if \PackageName\ +% hadn't been used. +% \begin{macrocode} +\newcommand*\mph@pg@orig{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\mph@get@margin} +% This macro does most of the work described in +% section~\ref{implementation}. +% \changes{v1.2}{2000/02/29}{% +% Use \Com{c@page} instead of \Com{thepage} as value in \Com{mph@pg@new} +% }% +% \begin{macrocode} +\newcommand*\mph@get@margin{% + \begingroup + \edef\mph@pg@orig{\the\c@page} + \loop +% \end{macrocode} +% This loop will be controlled by |\@tempswa|; all changes to that +% and to |\thepage| will be local to the current group. +% \begin{macrocode} + \@tempswafalse + \mph@debug{--- checking marginpar \mph@cnt}% + \if@twocolumn +% \end{macrocode} +% When we are in twocolumn mode, first check if the current +% marginpar number is greater than the last marginpar in the first +% column. If it isn't, we're in the first column. If it is, do the +% check for the last marginpar of the entire page. If this returns +% false, we're in the second column. Else, advance the page number +% and try again. +% \begin{macrocode} + \mph@debug{last on page \thepage: + \csname mph@last@i:\thepage\endcsname(i) + \csname mph@last@ii:\thepage\endcsname(ii), + }% + \mph@ifundef@or@smaller{% + \csname mph@last@i:\thepage\endcsname + }{% + \mph@ifundef@or@smaller{% + \csname mph@last@ii:\thepage\endcsname + }{% + \global\@mph@firstcol@true + \@tempswatrue + \advance\c@page by 1 + \mph@debug{\mph@cnt\space > + \csname mph@last@ii:\thepage\endcsname, + incrementing \thepage, set col to i + }% + }{% + \global\@mph@firstcol@false + \@tempswafalse + \mph@debug{\mph@cnt\space <= + \csname mph@last@ii:\thepage\endcsname, + exiting loop + }% + }% + }{% + \@tempswafalse + \global\@mph@firstcol@true + \mph@debug{exiting loop}% + }% + \else +% \end{macrocode} +% Not in twocolumn mode, we need only check for |mph@last@ii|: +% \begin{macrocode} + \mph@debug{last on page \thepage\space is + \csname mph@last@ii:\thepage\endcsname + }% + \mph@ifundef@or@smaller{% + \csname mph@last@ii:\thepage\endcsname + }{% + \@tempswatrue + \advance\c@page by 1 + \mph@debug{\mph@cnt\space > + \csname mph@last@ii:\thepage\endcsname, + incrementing page number + }% + }{% + \@tempswafalse + \mph@debug{\mph@cnt\space <= + \csname mph@last@ii:\thepage\endcsname, + exiting loop + }% + }% + \fi +% \end{macrocode} +% Now we have either found the correct page, or reached the end of the document +% without finding the appropriate page (e.\,g., if the |.aux| file hasn't existed +% before, or if the document has grown a lot since the last run). +% In this case we reset |\c@page| and |\if@mph@firstcol@| to their original values +% and jump out of the loop. +% \changes{v1.2}{2000/02/29}{% +% Use original values for page and column number by default% +% }% +% \begin{macrocode} + \ifnum\mph@lastpage>\c@page + \else + \@tempswafalse + \mph@debug{\c@page >= \mph@lastpage!}% + \c@page=\mph@pg@orig + \if@firstcolumn + \global\@mph@firstcol@true + \else + \global\@mph@firstcol@false + \fi + \mph@debug{using original value: \c@page for + \string\c@page and exiting loop. + }% + \fi + \if@tempswa + \mph@debug{iterating ...}% + \repeat +% \end{macrocode} +% After having finished the loop, we save the current (eventually modified) +% value of |\c@page| to |\mph@pg@new|: +% \begin{macrocode} + \mph@debug{=== marginpar \mph@cnt\space is on page \thepage% + \if@twocolumn, col \if@mph@firstcol@ 1 \else 2 \fi\fi + }% + \protected@xdef\mph@pg@new{\the\c@page}% + \endgroup +} + +% \end{macrocode} +% \end{macro} +% +% ^^A -------------------------------------------------- +% \subsubsection{Patching the output routine} +% ^^A -------------------------------------------------- +% We have to hook into 3 commands that are part of \LaTeX's output routine: +% |\@addmarginpar|, |\@outputdblcol| and |\@outputpage|. For the latter, we can use the default +% \LaTeX\ mechanism |\g@addto@macro|. For the others, this is more difficult, +% since the changes need to go somewhere `in between'. +% +% One could use hard redefinitions (plus +% \Com{CheckCommand*} to verify that the correct version of +% the command was being defined); but this soon gets too bothersome +% with new \LaTeX2e\ versions introducing minor changes that don't +% affect the stuff which we are concerned, but that nevertheless +% would require multiplying the redefinitions for the various versions. +% +% So instead, we locally redefine some +% commands to hook into the existing definitions. As a heuristic of +% detecting whether we change the appropriate commands, we check +% the values of some special counters \Com{mph@chk@xyz} that get +% incremented by some of the `hooks'. +% +% \changes{v1.3a}{2003/05/22}{% +% Use \Com{g@addto@macro} for \Com{@outputpage} to +% improve compatibility with e.g. the memoir class +% }% +% \changes{v1.2}{2000/02/29}{% +% Added \Com{CheckCommand*} for \Com{@addmarginpar}, \Com{@outputpage} +% and \Com{@outputdblcol} +% }% +% \changes{v1.2b}{2000/09/01}{% +% Replaced \Com{CheckCommand*} and the full redefinitions of +% \Com{@addmarginpar}, \Com{@outputpage} and \Com{@outputdblcol} +% by hooking into certain commands inside them +% }% +% +% \begin{macro}{\mph@error} +% Error message if something suspicious happened with the redefintions: +% \begin{macrocode} +\newcommand\mph@error[1]{% + \PackageError{mparhack}{% + Couldn't hook into command `#1' + }{% + This means that a LaTeX version incompatible with + mparhack.sty^^J% + has been used. See also the section on `Bugs/Restrictions'^^J% + in mparhack.dvi. Please send an email about this bug to^^J% + <stefanulrich@users.sourceforge.net>, along with the file `\jobname.log'. + }% +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@addmarginpar} +% This command adds the marginpar box to the current page. +% We change the \Com{c@page} counter and the \Com{if@firstcolumn} switch +% to the values that have been set correctly by the \Com{mph@get@margin} +% command. There's no further error checking done here. +% +% \begin{macrocode} +\newcommand\mph@orig@c@page{} +\newcommand\mph@orig@addmarginpar{} +\let\mph@orig@addmarginpar\@addmarginpar + +\renewcommand\@addmarginpar{% + \mph@step@cnt\mph@cnt + \protected@write\@auxout{}% + {\string\def\string\mph@nr{\mph@cnt}}% + \mph@get@margin + \def\mph@orig@c@page{\c@page} + \c@page=\mph@pg@new + \if@mph@firstcol@ + \@firstcolumntrue + \else + \@firstcolumnfalse + \fi + \mph@orig@addmarginpar + \c@page=\mph@orig@c@page +} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@outputpage} +% Add the |\mph@outputpage@hook| hook to |\@outputpage|. +% We need to decrement |\c@page|, since |\@outputpage| will +% have incremented it after dumping the page contents. +% The group in |\mph@outputpage@hook| is to keep this change local. +% \begin{macrocode} +\newcommand*\mph@outputpage@hook{% + \bgroup + \advance\c@page\m@ne + \immediate\write\@auxout{% + \string\mph@setcol{ii:\thepage}{\string\mph@nr}% + }% + \egroup +} +\g@addto@macro{\@outputpage}{\mph@outputpage@hook} + +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@outputdblcol} +% In case an entire twocolumn page is finished, this command calls +% \Com{hb@xt@} with the boxes for the two columns inside, and each +% one needs to set a marker with the current column number. So +% we hook into \Com{hb@xt@} and check if its first argument equals +% \Com{columnwidth} (\Com{hb@xt@} is also called for the entire page, +% but in this case the first argument is \Com{textwidth}). +% +% The current column number is represented by \Com{mph@chk@dcl}, and at +% the end we check if this number equals 0 (in which case the +% page hadn't been fininshed yet, and we didn't need to do anything) +% or 2 (the `interesting' case); else we signal an error. +% +% \begin{macrocode} +\newcommand\mph@orig@hb@xt@{} +\newcommand\mph@orig@outputdblcol{} +\newcommand\mph@chk@dcl{0}% +\let\mph@orig@hb@xt@\hb@xt@ +\let\mph@orig@outputdblcol\@outputdblcol + +\renewcommand\@outputdblcol{% + \def\mph@chk@dcl{0}% + \def\hb@xt@##1##2{% + \ifx##1\columnwidth + \mph@step@cnt\mph@chk@dcl + \protected@edef\mph@tempa{% + \noexpand\write\noexpand\@auxout{% + \noexpand\string\noexpand\mph@setcol{% + \romannumeral\mph@chk@dcl:\noexpand\thepage% + }{% + \noexpand\string\noexpand\mph@nr% + }% + }% + }% + \else + \def\mph@tempa{}% + \fi + \mph@orig@hb@xt@##1{##2\mph@tempa}% + }% + \mph@orig@outputdblcol + \def\hb@xt@{\mph@orig@hb@xt@}% + \ifnum\mph@chk@dcl=0\relax + \else + \ifnum\mph@chk@dcl=2\relax + \else + \mph@error{\string\@outputdblcol}% + \fi + \fi +} + +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</sty> +% \end{macrocode} +% ^^A\typeout{End of package documentation.} +% \typein[\answer]% +% {^^JPrint an index of command names (y/n)? [n]^^J^^A +% -- Note: this requires a previous run of:^^J^^A +% \space\space\space makeindex -s gind.ist \PackageNameNoExt^^J} +% \def\next{y}^^A +% \ifx\answer\next +% \AfterElseFi\PrintIndex +% \else +% \typeout{(not printing index.)}^^A +% \fi +% \typein[\answer]% +% {^^JPrint a history of changes (y/n)? [n]^^J^^A +% -- Note: this requires a previous run of:^^J^^A +% \space\space\space makeindex -s gglo.ist -o \PackageNameNoExt.gls \PackageNameNoExt.glo^^J} +% \def\next{y}^^A +% \ifx\answer\next +% \AfterElseFi\PrintChanges +% \else +% \typeout{(not printing history of changes.)}^^A +% \fi +% \Finale |