From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Mon, 2 Sep 2019 13:46:59 +0900
Subject: Initial commit

---
 macros/latex/contrib/marginfix/marginfix.dtx | 1615 ++++++++++++++++++++++++++
 1 file changed, 1615 insertions(+)
 create mode 100644 macros/latex/contrib/marginfix/marginfix.dtx

(limited to 'macros/latex/contrib/marginfix/marginfix.dtx')

diff --git a/macros/latex/contrib/marginfix/marginfix.dtx b/macros/latex/contrib/marginfix/marginfix.dtx
new file mode 100644
index 0000000000..1e7b43ea06
--- /dev/null
+++ b/macros/latex/contrib/marginfix/marginfix.dtx
@@ -0,0 +1,1615 @@
+% \iffalse
+%
+% Copyright 2010 Stephen Hicks, All rights reserved.
+% marginfix.dtx - 29 Jul 2010
+% originally floatprobsbegone, created 21 Mar 2008
+%
+% Run LaTeX on this document to produce documentation.
+% Run LaTeX on marginfix.ins to produce the package.
+%<*driver>
+\ProvidesFile{marginfix.dtx}
+%</driver>
+%
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{marginfix}%
+           [2013/09/08 v1.1 Fix Margin Paragraphs]
+%<*driver>
+\documentclass{ltxdoc}
+\CheckSum{1197}
+%\OnlyDescription % (un)comment this line to show (hide) source code
+\RecordChanges
+\EnableCrossrefs
+\CodelineIndex   % (un)comment this line to index source by page (line)
+\begin{document}
+  \newcommand*\Lopt[1]{\textsf {#1}}
+  \newcommand*\lit[1]{\texttt{\char`#1}} %% literal character (funny catcodes)
+  \parindent0pt
+  \def\*#1{\texttt{\string#1}} %% sdh - |...| doesn't work in headings
+  \makeatletter
+  %
+  \let\pkg\textsf
+  \newcount\mac@depth\mac@depth\z@
+  \newcommand\@macros{}\newcommand\@endmacros{}
+  \catcode`&3  %% we use a funny catcode to ensure never used.
+  \def\@macros#1,{\macro{#1}\global\advance\mac@depth\@ne\relax
+    \@ifnextchar&\@gobble\@macros}
+  \def\@endmacros{\let\mac@next\relax\ifnum\mac@depth>\z@
+    \endmacro\let\mac@next\@endmacros
+    \global\advance\mac@depth\m@ne\fi\mac@next}
+  \newenvironment{macros}[1]{\@macros#1,&}{\@endmacros}
+  \catcode`&4  %% put it back 
+  \makeatother %% must be balanced for character table to work properly
+  %
+  \DocInput{marginfix.dtx}
+  \setcounter{IndexColumns}{2}
+  \PrintIndex
+  \PrintChanges
+\end{document}
+%</driver>
+% \fi
+% \changes{v0.0}{2008/03/21}
+%       {(SDH) Initial version of floatprobsbegone.}
+% \changes{v0.9}{2010/08/18}
+%       {(SDH) Initial CTAN version.}
+% \changes{v0.9.1}{2010/08/28}
+%       {(SDH) Fix bug where we alternated sides in article.}
+% \changes{v1.0}{2013/09/01}
+%       {(Dario Buttari) Alternate order of \cs{marginpar} arguments to be
+%        consistent with the original macro.}
+% \changes{v1.0}{2013/09/01}
+%       {(Dario Buttari) Fix bug in deferred note spacing.}
+% \changes{v1.0}{2013/09/01}
+%       {(Dario Buttari) Fix issues with \cs{marginheightadjustment} and
+%        \cs{extendmargin} not being applied and reset consistently.}
+% \changes{v1.0}{2013/09/01}
+%       {(SDH) Stop gobbling vertical stretch on page.  Margin notes will
+%        not line up properly if page is stretched.}
+% \changes{v1.0}{2013/09/01}
+%       {(SDH) Add margin phantoms.}
+% \changes{v1.1}{2013/09/08}
+%       {(SDH) Globally calculate margin phantoms over 4 passes.}
+% \changes{v1.1}{2013/09/08}
+%       {(SDH) Add \cs{topskip} to notes at the top of the margin.}
+%
+% \GetFileInfo{marginfix.dtx}
+% \title{\Lopt{marginfix} package documentation}
+% \author{Stephen Hicks\\%
+%    \texttt{sdh33@cornell.edu}\\%
+%    \texttt{http://shicks.github.com/marginfix}}
+% \date{\fileversion{} -- \filedate}
+% \maketitle
+%
+% \part*{Usage}
+% \section{Overview}
+% Authors using \LaTeX\ to typeset books with significant margin material
+% often run into the problem of long notes running off the bottom of the
+% page.  A typical workaround is to insert \cs{vshift}s by hand, but
+% this is a tedious process that is invalidated when pagination changes.
+% Another workaround is \pkg{memoir}'s \cs{sidebar} function, but this can be
+% unsatisfying for short textual notes, and standard marginpars cannot
+% be mixed with sidebars.  This package implements a solution to
+% make marginpars "just work" by keeping a list of floating inserts and
+% arranging them intelligently in the output routine.  The credit for the
+% concept behind this algorithm goes to Prof. Andy Ruina, who employed me
+% to work on some of his textbook macros in 2007--9.
+%
+% \section{Options}
+% There are currently no options that do anything yet.
+%
+% \section{Commands}
+% For the most part, this is a drop-in replacement.  Simply include
+% a call to |\usepackage{marginfix}| to the preamble, use \cs{marginpar}
+% normally and hope for the best.
+% In the event, however, that it doesn't work exactly as hoped,
+% there are a number of tweaks that the user can apply.
+%
+% \DescribeMacro{\marginskip}
+% Calling \cs{marginskip}\marg{length} will insert an incompressible
+% skip in the margin.  These skips will force neighboring notes on
+% the same page to be separated, but will disappear at the top or
+% bottom of a margin.
+%
+% \DescribeMacro{\clearmargin}\DescribeMacro{\softclearmargin}
+% In an analog to \cs{clearpage}, \cs{clearmargin} prevents any further
+% material from being added to the current margin.  These calls are
+% cumulative, so that two \cs{clearmargin}s in a row will produce a
+% completely empty margin on the next page as well.  If this is not
+% the desired effect, use \cs{softclearmargin}, which is effectively
+% idempotent: multiple calls have the same effect as one call to
+% end the current margin.
+%
+% \DescribeMacro{\extendmargin}
+% If a page has too much margin material to fit and an important note
+% is floating to the next page, \cs{extendmargin}\marg{length} will
+% extend the margin (for the current page only) by the given length.
+% If the length is negative, the margin will shrink.  Multiple calls
+% on the same page are cumulative.
+%
+% \DescribeMacro{\mparshift}
+% To adjust the position of a single note, use \cs{mparshift}\marg{length}
+% before a call to \cs{marginpar}.  Positive lengths move it down the page.
+% This essentially shifts the call-out location, so the actual position of
+% the note might not change if the margin is sufficiently crowded.
+% Multiple calls before the same note are cumulative.
+%
+% \DescribeMacro{\marginheightadjustment}
+% If all the margins are the wrong size, the height of the margin on every
+% page can be adjusted by assigning a non-zero value to the dimension
+% register \cs{marginheightadjustment} (as in 
+% \cs{marginheightadjustment}\texttt{=}$\langle$\emph{length}$\rangle$).
+% This is effectively the same as a call to
+% \cs{extendmargin} on every page.
+%
+% \DescribeMacro{\marginposadjustment}
+% Similarly, if all the margin notes are in the wrong place, the callout
+% positions can be adjusted globally by assigning a non-zero value to the
+% dimension register \cs{marginposadjustment}.  This is effectively the same
+% as a call to \cs{mparshift} before every note.  This is particularly useful
+% at present because the height of the line on which the margin note is called
+% is currently only estimated, and appears to be off by a point or two.
+% This may get fixed in the future, but until then, the adjustment is
+% possibly the easiest workaround.
+%
+% \DescribeMacro{\blockmargin}\DescribeMacro{\unblockmargin}
+% As of version 1.0, we now support ``margin phantoms'': sections of the
+% margin in which no notes will be placed, which can be useful for large
+% figures that jut into the margin (note: margins already move out of the
+% way of floats, regardless of whether or not they extend into the margin;
+% this is mainly for in-place figures or equations).  The easiest way to
+% block off part of the margin is to call \cs{blockmargin} before the
+% extended content and \cs{unblockmargin} afterwards.  No margin notes
+% will be placed between these two points (though one must be careful:
+% if one of these is called in horizontal mode, the toggle will occur at
+% the \emph{top} of the current line).  Each of these commands takes an
+% optional argument: \cs{blockmargin}\oarg{pos} will begin the margin
+% block at a position \emph{pos} below the current position (or above
+% if \emph{pos} is negative), and \cs{unblockmargin}\oarg{pos} will
+% likewise end the block at a position \emph{pos} below the current
+% position.
+%
+% \DescribeMacro{\marginphantom}
+% Margin phantoms may also be called out in place with a known size
+% using \cs{marginphantom}\oarg{pos}\marg{size}, which is essentially
+% equivalent to \cs{blockmargin}\oarg{pos}\cs{unblockmargin}\oarg{pos$+$size}.
+% Either argument may be negative to refer upward rather than downward.
+%
+% \section{Interaction with other packages}
+% \subsection{memoir}
+% There are no known issues with \Lopt{memoir} at present, provided that
+% \cs{sidebar} is not used.
+%
+% \subsection{mparhack}
+% \Lopt{mparhack} was designed to deal with the problem of margin notes
+% showing up in the wrong margin because the left/right was decided before
+% it was known exactly which page the note would be on.  Because we defer
+% this decision to shipout time in this package, we are not susceptible
+% to this problem, so \Lopt{mparhack} is no longer needed and should not
+% be included (though I'm unaware whether it causes any actual problems).
+%
+% \subsection{Multiple columns}
+% There is currently no support for multiple columns.
+%
+% \section{Coming attractions and known issues}
+% Here is a list of things to possibly look forward to in a future version.
+% If any of them are particularly important, please let me know.
+% \begin{itemize}
+% \item Use of pdf\TeX's \cs{pdfsavepos} and \cs{pdflastypos} for more
+%   accurate margin placement.
+% \item \cs{vadjust} to correct inconsistencies with \cs{@pageht}.
+% \item Margin note placement is irrespective of vertical stretch.
+%   Previously we gobbled any vertical stretch, but now that we have
+%   fixed that bug, there's the possibility of wrong alignment since
+%   we don't know where the positions will ultimately end up.  This
+%   may be fixed by \cs{pdfsavepos} as well.
+% \item Better interaction with floats.
+%   (We can set a default one way
+%   or the other and then allow a macro to override it (presumably with a
+%   CS defined in terms of the box name/meaning, so as not to get in the
+%   way of \LaTeX's use of the insert registers).  We would then add or
+%   not add phantoms in the right spots.  We'd also need to shift all the
+%   callout points by the size of the top figures (unless we're using
+%   \cs{pdfsavepos}).)
+% \end{itemize}
+%
+% \StopEventually{}
+%
+% \makeatletter
+% \part*{Implementation}
+% \section{Initial Setup}
+% Make the |@|-sign into a letter for use in macro names.
+%    \begin{macrocode}
+%<*package>
+\makeatletter
+%    \end{macrocode}
+%
+% \begin{macros}{\MFX@debug}
+% We have some optionally-included code for debugging.  \cs{MFX@debug}
+% prints a new line followed by ``|MFX: |'' and then the message.
+% The newline can be suppressed with a |*|.  We'll also ask for more
+% error context in the debug mode.
+%    \begin{macrocode}
+%<*debug>
+\def\MFX@debug{\message{^^JMFX:}\message}
+\errorcontextlines=20
+\def\MFX@mac#1{\expandafter\MFX@@mac\meaning#1>>>}
+\def\MFX@@mac#1->{<<<}
+\def\MFX@htdp#1{\ht#1=\the\ht#1, \dp#1=\the\dp#1}
+\showboxbreadth=100
+\showboxdepth=10
+%</debug>
+%    \end{macrocode}
+% \end{macros}
+%
+% The reader might begin to note at this point a convention we
+% adopt throughout this package.  While we strive to avoid introducing
+% new names as much as possible (with clever usages of \cs{expandafter}),
+% any new names we do introduce will be prefixed
+% by |\MFX@|, |\Mfx@|, or |\mfx@|, depending on the type of name.
+% The all-capitol |\MFX@| is used for fully-constant macros.  The
+% initial-caps |\Mfx@| is used for control sequences that are
+% technically constant, but that refer to things that change, such
+% as counters, token lists, dimension registers, etc.  Finally,
+% the lowercase |\mfx@| is used for control sequences whose meaning
+% changes dynamically (i.e. variable macros).
+%
+% \section{Options}
+% Here we define the various package options.
+% \iffalse - CURRENTLY UNIMPLEMENTED
+% \begin{macros}{\ifmfx@ypos}
+% The \Lopt{ypos} option signifies that we should use the pdf{\TeX}
+% primitives \cs{pdfsavepos} and \cs{pdflastypos} to improve positioning
+% of margin notes relative to their callouts.  This requires two
+% passes to work, and the first time through, the margin notes
+% will be positioned very na\"ively.
+%    \begin{macrocode}
+\newif\ifmfx@ypos
+\DeclareOption{ypos}{\mfx@ypostrue}
+%    \end{macrocode}
+% \end{macros}
+% END IFFALSE - \else There are no options yet. \fi
+%
+% Now we actually process the options.
+%    \begin{macrocode}
+\ProcessOptions\relax
+%    \end{macrocode}
+%
+% \section{Variables}
+% \begin{macros}{\mfx@marginlist}
+% We need a place to store our list of marginal material.  We
+% store material in this variable using insert registers and
+% a variety of macros, to be explained later.
+%    \begin{macrocode}
+\let\mfx@marginlist\@empty
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\mfx@inject,\Mfx@inject@insert}
+% These are used to hijack \cs{marginpar} to inject arbitrary code
+% into the output routine, rather than actually set a note.  To
+% inject code, we unshift two copies of this dummy insert onto
+% \cs{@freelist} for \cs{marginpar} to pull off.  We append
+% whatever code we want to inject into \cs{mfx@inject} and then
+% call \cs{marginpar}.  Then our custom \cs{@addmarginpar} will
+% recognize the dummy inserts and run the code instead of setting
+% a margin note.
+%    \begin{macrocode}
+\let\mfx@injected\@empty
+\newinsert\Mfx@inject@insert
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\Mfx@marginbox}
+% While we're building the margin, we need to put it in a box
+% before we can attach it to the main columm.
+%    \begin{macrocode}
+\newbox\Mfx@marginbox
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\Mfx@marginpos@min,\Mfx@marginpos@max,\Mfx@marginspace}
+% While we build up the margin piece boxes, we need to keep track of the
+% possible range of positions.  The pair \cs{Mfx@marginpos@min} and
+% \cs{Mfx@marginpos@max} are used to accumulate how much material has
+% been added so far, with the difference that \cs{Mfx@marginpos@min} doesn't
+% take into account compressible space, while \cs{Mfx@marginpos@max} does.
+% Finally, \cs{Mfx@marginspace} is the amount of (incompressible) space
+% since the last note, which allows skips to span margin phantoms.
+%    \begin{macrocode}
+\newdimen\Mfx@marginpos@min
+\newdimen\Mfx@marginpos@max
+\newdimen\Mfx@marginspace
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\Mfx@marginheight}
+% Because the margin height can be altered by, \cs{extendmargin},
+% we must maintain a dimension for the height of the current margin.
+% This dimension is reused in several different ways in the shipout-time
+% margin building routines, keeping track of how much much space is left
+% in (for the global passes) and the end position of the end of (for the
+% piecewise passes) the current piece.
+%    \begin{macrocode}
+\newdimen\Mfx@marginheight
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\mfx@marginstart,\mfx@marginpieces,
+%     \Mfx@piece@content,\Mfx@piece@count,\ifmfx@in@phantom}
+% These control sequences keep track of the margin phantoms.  When the
+% margin is unblocked then \cs{mfx@marginstart} is not \cs{relax}.  When
+% a phantom begins, the current \cs{mfx@marginstart} and page position
+% are stored as a pair in \cs{mfx@marginpieces}, which is iterated over
+% while building individual pieces of the margin.  We also define a box
+% to keep the content of each margin piece, and a counter to keep track
+% of how many pieces we have.  Finally, we define a switch for use in
+% the second pass to indicate that we're inside a phantom.
+%    \begin{macrocode}
+\def\mfx@marginstart{0pt}
+\let\mfx@marginpieces\@empty
+\newbox\Mfx@piece@content
+\newcount\Mfx@piece@count
+\newif\ifmfx@in@phantom
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\Mfx@mparshift}
+% We store the current shift in a dimension register.
+%    \begin{macrocode}
+\newdimen\Mfx@mparshift
+%    \end{macrocode}
+% \end{macros}
+%
+% \section{User-configurable dimensions}
+% We export a few dimensions that the user can redefine to tweak behavior.
+% \begin{macros}{\marginheightadjustment}
+% This length will be added to the total margin height of each page
+% (the default is zero).
+%    \begin{macrocode}
+\newdimen\marginheightadjustment
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\marginposadjustment}
+% We will offset each margin note from its callout location by this length
+% (the default is zero).
+%    \begin{macrocode}
+\newdimen\marginposadjustment
+%    \end{macrocode}
+% \end{macros}
+%
+% \section{Plan of attack}
+% \subsection{\cs{marginpar}}
+% The default sequence of events for a \cs{marginpar} is roughly the following
+% (assuming no errors):
+% \begin{verbatim}
+% \marginpar:
+%   let \@floatpenalty := (horizontal ? -10002 : -10003)
+%   allocate inserts \@currbox and \@marbox from \@freelist
+%   let \count\@marbox := -1 % signifies marginpar (not float)
+%   if optional argument then \@xmpar else \@ympar
+% \@xmpar:
+%   \@savemarbox \@currbox := required argument
+%   \@savemarbox \@marbox := optional argument
+%   \@xympar
+% \@ympar:
+%   \@savemarbox \@currbox := required argument
+%   copy \@marbox := \@currbox
+%   \@xympar
+% \@xympar:
+%   append \@marbox to \@currlist
+%   \end@float
+% \end@float:
+%   append \@currbox to \@currlist
+%   if horizontal then following two lines are in \vadjust:
+%     \penalty -10004
+%     \penalty \@floatpenalty
+% \end{verbatim}
+%
+% To get the rest of the picture, we need to peek into the
+% output routine.  The pertinent parts are as follows (in
+% vanilla \LaTeX):
+% \begin{verbatim}
+% \output:
+%   if \outputpenalty < -10000 then
+%     \@specialoutput
+%   else
+%     do regular output...
+%   details for dealing with footnotes...
+% \@specialoutput:
+%   switch \outputpenalty:
+%    case -10001: \@doclearpage
+%    case -10004: set box \@holdpg := \vbox{\unvbox255}
+%    case -10002 or -10003:
+%     set box \@holdpg := \vbox{\unvbox\@holdpg \unvbox255}
+%     let \@pageht := \ht\@holdpg, \@pagedp := \dp\@holdpg
+%     \unvbox\@holdpg
+%     pop \@currbox off of \@currlist
+%     \@addmarginpar (assuming \count\@currbox <= 0)
+% \@addmarginpar:
+%   pop \@marbox off of \@currlist
+%   free \@currbox and \@marbox back to \@freelist
+%   if left-hand margin then let \@marbox := \@currbox
+%   let \@tempdima := \@mparbottom - \@pageht + \ht\@marbox
+%   if \@tempdima < 0 then let \@tempdima := 0
+%   let \@mparbottom := \@pageht + \@tempdima + \dp\@marbox + \marginparpush
+%   decrement \@tempdima := \@tempdima - \ht\@marbox
+%   prepend \vskip\@tempdima to \@marbox
+%   let \ht\@marbox := \dp\@marbox := 0
+%   \kern -\@pagedp, \nointerlineskip
+%   set an \hbox to \columnwidth (zero height/depth):
+%     attach \@marbox to correct margin
+%   set a \vbox with height 0 and depth \@pagedp
+% \end{verbatim}
+%
+% We see from here that \cs{@addmarginpar} is the place where {\LaTeX}
+% does the work of calculating the current page position and where the
+% next note should go, and then actually puts it there.  We will need
+% to completely replace this routine, but can leave everything else
+% as is.
+%
+% \subsection{\cs{output}}
+% While \LaTeX's margin routines end with \cs{@addmarginpar}, we must
+% dig even deeper to apply our patch, since we need to insert some
+% code to run during the \emph{main} output routine that ships out
+% each page.  Thus, we'll expand ``\texttt{do regular output...}''
+% from the previous \cs{output} listing.
+% \begin{verbatim}
+% do regular output...:
+%   \@makecol
+%   do { \@opcol \@startcolumn } while @fcolmade
+% \@makecol:
+%   set box \@outputbox := box255 (plus any footnotes)
+%   let \@freelist := \@freelist + \@midlist, \@midlist := \@empty
+%   \@combinefloats
+%   add \@texttop and \@textbottom to \@outputbox (default no-op)
+% \@opcol:
+%   \@outputpage (or \@outputdblcol in twocolumn mode)
+%   let \@mparbottom := \@textfloatsheight := 0
+%   \@floatplacement
+% \@startcolumn:
+%   try to make a float column from \@deferlist, setting @fcolmade
+%   if !@fcolmade then add floats from \@deferlist to next column
+% \@combinefloats:
+%   aggregate \@toplist floats into a box and prepend to \@outputbox
+%   aggregate \@botlist floats into a box and append to \@coutputbox
+%   free inserts from \@toplist and \@botlist
+% \@outputpage:
+%   ship out the page
+%   reset a bunch of stuff
+%   let \@colht := \textheight (in \@outputpage)
+% \end{verbatim}
+%
+% We've seen two main times when action occurs: callout time and
+% shipout time.  We proceed chronologically with our patches.
+%
+% \section{Callout-time patches}
+% \begin{macros}{\@addmarginpar}
+% The first thing we must modify is that at callout time, we need to
+% get the inserts into \cs{mfx@marginlist}.  This should happen in the
+% output routine so that we can get ahold of the current page
+% position.  Even if we have a better idea of the page position
+% (e.g. from pdf\TeX), we still might as well do this in the OR.
+% In addition to actually setting the margin note, we also use this
+% routine to inject arbitrary code into the OR (see \cs{MFX@inject}).
+%    \begin{macrocode}
+\def\@addmarginpar{%
+  \@next\@marbox\@currlist{}\MFX@AssertionError
+%<debug>\MFX@debug{addmarginpar (running insert) \@marbox/ \@currbox at
+%<debug>    \the\c@page:\the\@pageht, marginlist=\MFX@mac\mfx@marginlist}%
+%<debug>\MFX@debug{addmarginpar outputpenalty=\the\outputpenalty}%
+  \MFX@getypos
+  \expandafter\ifx\@marbox\Mfx@inject@insert
+    \mfx@injected\global\let\mfx@injected\@empty
+  \else
+    \MFX@cons\mfx@marginlist{%
+      \noexpand\mfx@build@note\@currbox\@marbox{\mfx@ypos}%
+      \noexpand\mfx@build@skip{\the\marginparpush}%
+    }%
+  \fi
+%<debug>\MFX@debug{addmarginpar (exit): marginlist=\MFX@mac\mfx@marginlist}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@cons,\MFX@snoc,\MFX@run@clear}
+% In passing we'll define the cons macro, which fully-expands
+% its second argument, but makes sure to only expand the first
+% one once, so that any fragile control sequences in it are
+% corectly protected.  We also define snoc, which prepends.
+% Note that we could put the \cs{temp@} definition into a group
+% if it was really gonna matter\ldots
+%    \begin{macrocode}
+\def\MFX@cons#1#2{%
+  \edef\temp@{#2}%
+  \expandafter\expandafter\expandafter\gdef
+  \expandafter\expandafter\expandafter#1%
+  \expandafter\expandafter\expandafter{\expandafter#1\temp@}%
+}
+
+\def\MFX@snoc#1#2{%
+  \edef\temp@{#2}%
+  \expandafter\expandafter\expandafter\gdef
+  \expandafter\expandafter\expandafter#1%
+  \expandafter\expandafter\expandafter{\expandafter\temp@#1}%
+}
+%    \end{macrocode}
+% Finally, \cs{MFX@run@clear} is a quick trick to expand the
+% contents of a macro and then clear it (to \cs{@empty}) before
+% any of its tokens are consumed.
+%     \begin{macrocode}
+\def\MFX@run@clear#1{%
+  \expandafter\global\expandafter\let\expandafter#1\expandafter\@empty#1%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@inject}
+% As mentioned earlier, \cs{@addmarginpar} is also a hook for injecting
+% arbitrary code into the output routine, i.e. to get a vertical position
+% for blocking the margin.  We define \cs{MFX@inject} to facilitate this.
+%    \begin{macrocode}
+\def\MFX@inject#1{
+  \expandafter\def\expandafter\@freelist\expandafter{%
+    \expandafter\@elt\expandafter\Mfx@inject@insert
+    \expandafter\@elt\expandafter\Mfx@inject@insert
+    \@freelist}%
+  \expandafter\def\expandafter\mfx@injected\expandafter{\mfx@injected#1}%
+  \marginpar{}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@getypos,\mfx@ypos}
+% We now need to settle on a way to determine the vertical position.
+% Someday this may be an option, and will depend on a variety
+% of factors.  But for starters, we define the simplest version.
+% Note the subtraction of \cs{Mfx@strutheight}.  Ideally we would simply
+% grab a copy of \cs{@holdpg} from the middle of \cs{@specialoutput}
+% and then discard the last box to figure out what height we're really
+% at, since \cs{@holdpg} includes the box from the line we're currently
+% on, and we want to be level with the \emph{top} of that box, rather
+% than the baseline.  But since \cs{@holdpg} is accessible only deep
+% within \cs{@specialoutput}, and it's not worth the risky job of
+% performing surgery on it (which is unfortunately brittle if anyone
+% else has a similar idea), we instead resort to this approximation.
+% And since this should ultimately be only a fallback for when
+% \cs{pdflastypos} isn't available, it's good enough.
+% (NOTE: we might be able to use a \cs{vadjust} instead here?)
+%    \begin{macrocode}
+\def\MFX@getypos{%
+  \dimen@\dimexpr\@pageht+\@pagedp+\marginposadjustment+\Mfx@mparshift\relax
+  \ifnum\outputpenalty=-10002\relax
+    \advance\dimen@-\Mfx@strutheight
+  \fi
+  \edef\mfx@ypos{\the\dimen@}%
+  \global\Mfx@mparshift\z@
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\marginpar,\Mfx@strutheight}
+% We need to make sure \cs{Mfx@strutheight} gets defined somewhere,
+% and the best time is probably right before the \cs{marginpar} does
+% its work, since that will most likely ensure we're using the right
+% font for the line.
+%    \begin{macrocode}
+\newdimen\Mfx@strutheight
+\edef\marginpar{%
+  \unexpanded{\setbox\@tempboxa\hbox{\strut}\Mfx@strutheight\ht\@tempboxa}%
+  \expandafter\unexpanded\expandafter{\marginpar}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \section{Shipout-time patches}
+% \begin{macros}{\@combinefloats,\MFX@combinefloats@before}
+% We need to patch in somewhere before \cs{@combinefloats} at the latest,
+% so that any heights calculated from \cs{@pageht} are correct---otherwise
+% the top figures will confuse us.  So we'll start by simply adding our
+% own \cs{MFX@combinefloats@before} at the very beginning of \cs{@combinefloats}
+%    \begin{macrocode}
+\expandafter\def\expandafter\@combinefloats\expandafter{\expandafter
+  \MFX@combinefloats@before\@combinefloats}
+%    \end{macrocode}
+% 
+% \cs{MFX@combinefloats@before} is then responsible for picking the
+% needed notes from \cs{mfx@marginlist}, building them into a box, and
+% attaching that box onto the correct side of \cs{@outputbox}.  We also
+% add any global \cs{marginheightadjustment} to \cs{Mfx@marginheight}
+% before building the margin, and then reset it back to zero at the end.
+% This allows any calls to \cs{extendmargin} during the page itself to
+% work as expected.
+%    \begin{macrocode}
+\def\MFX@combinefloats@before{%
+  \advance\Mfx@marginheight\marginheightadjustment
+  \MFX@buildmargin
+  \MFX@attachmargin
+  \global\Mfx@marginheight\z@
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@attachmargin}
+% We'll start with the second half of \cs{MFX@combinefloats@before},
+% since it's simpler.  We need to do several things here.
+%    \begin{macrocode}
+\def\MFX@attachmargin{%
+%<debug>\MFX@debug{attachmargin}%
+%    \end{macrocode}
+% First, we need to make sure that the boxes we're combining are the
+% same size.
+%    \begin{macrocode}
+%<debug>\MFX@debug{attachmargin: \MFX@htdp\@outputbox, \MFX@htdp\Mfx@marginbox}%
+ %<debug>\showbox\@outputbox
+ %<debug>\showbox\Mfx@marginbox
+  \setbox\Mfx@marginbox\vtop{%
+    \vskip\z@\unvbox\Mfx@marginbox}%
+  %% \ifdim\ht\@outputbox<\ht\Mfx@marginbox
+  %%   \setbox\Mfx@marginbox\vbox to \ht\@outputbox{%
+  %%     \unvbox\Mfx@marginbox
+  %%     \vskip\z@ shrink 1filll\relax
+  %%   }%
+  %% \else
+  %%   \setbox\Mfx@marginbox\vbox to \ht\@outputbox{%
+  %%     \unvbox\Mfx@marginbox
+  %%     \vfill
+  %%   }%
+  %% \fi
+%    \end{macrocode}
+% Next we need to figure out which side of \cs{@outputbox} to attach
+% the \cs{Mfx@marginbox} on.  We now use \cs{columnwidth} instead of
+% \cs{wd}\cs{@outputbox} to set the right-hand margins, since tufte-\LaTeX
+% sometimes makes too-wide output boxes.  If this becomes a problem,
+% we'll need to consider making this configurable elsewhere.  We should
+% also pay attention to whether adding a box at the top of \cs{@outputbox}
+% might have unintended consequences w.r.t. any glue being retained that
+% should have been swallowed.  This will require further investigation.
+%    \begin{macrocode}
+  \setbox\@outputbox\vbox{% to \ht\@outputbox{%
+    \begingroup
+    \setbox\@tempboxa\vbox{% to \ht\@outputbox{%
+      \hbox{% to \wd\@outputbox{%
+        \if\MFX@leftmargin
+          \llap{\box\Mfx@marginbox\hskip\marginparsep}%
+        \else
+          \hskip\columnwidth
+          \rlap{\hskip\marginparsep\box\Mfx@marginbox}%
+        \fi
+      }}%
+    \ht\@tempboxa\z@
+    \dp\@tempboxa\z@
+    \box\@tempboxa
+    \endgroup
+    \unskip
+    \unvbox\@outputbox
+  }%
+ %<debug>\showbox\@outputbox
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@buildmargin}
+% When \cs{MFX@buildmargin} is called, we have a list of tokens in
+% \cs{mfx@marginlist} that need to be processed: combinations of
+% \cs{mfx@build@note}, \cs{mfx@build@skip}, and \cs{mfx@build@clear},
+% with various parameters to indicate what material still needs to be
+% set in the margin.  This macro therefore must pull off the first $n>0$
+% of these commands to set on the current page ($n$ must be positive to
+% prevent infinite loops), and leave the rest to be deferred.  We do not
+% currently support taking notes out of order, though that is a possible
+% feature to allow in the future, on an opt-in basis.  The typeset
+% material will be left in \cs{Mfx@marginbox}, which must have the same
+% height as \cs{@outputbox} (although because we \cs{unvbox}\cs{@outputbox}
+% in \cs{MFX@attachmargin}, we can't guarantee that this will correctly
+% line up the notes with their callouts).  This procedure happens in
+% four passes.  But first, we initialize \cs{Mfx@marginheight} to
+% \cs{@colroom}, which is the height of the page minus any floats that
+% have been added to the top of bottom (these floats may extend into the
+% margins: in the future we may look into detecting this and using the
+% whole page, with overwide floats blocked off as phantoms).  We add
+% \cs{@colroom} rather than assigning it because any global or per-page
+% adjustments have already been added to \cs{Mfx@marginheight}.  We
+% can then close out any still-open margin pieces (this is the typical
+% case, where the margin is not blocked across a page boundary, so that
+% \cs{mfx@marginstart} will hold a position, rather than \cs{relax}).
+% After this, \cs{Mfx@marginheight} is no longer necessary, so we reuse
+% it for keeping track of available space in individual margin pieces.
+%    \begin{macrocode}
+\def\MFX@buildmargin{%
+  \advance\Mfx@marginheight\@colroom
+  \ifx\mfx@marginstart\relax
+  \else
+    \MFX@cons\mfx@marginpieces{%
+      \noexpand\@elt{\mfx@marginstart}{\the\Mfx@marginheight}}%
+    \gdef\mfx@marginstart{0pt}%
+    \global\advance\Mfx@piece@count\@ne
+  \fi
+%<debug>\MFX@debug{buildmargin: marginheight=\the\Mfx@marginheight,
+%<debug>           marginlist=\MFX@mac\mfx@marginlist,
+%<debug>           marginpieces=\MFX@mac\mfx@marginpieces}%
+%    \end{macrocode}
+% We now execute the four passes.  First is a global downward pass,
+% whose purpose is to determine the maximum number of notes (and other
+% material) that can fit in the margin, taking any phantoms into
+% consideration.  Every note identified by \cs{MFX@buildmargin@down}
+% is guaranteed to show up on this page, so we free its inserts back
+% to \cs{@freelist}.  The second pass is the global upward pass, in
+% which we determine the lowest possible margin piece each note may
+% go into without causing lower notes to fall off the bottom.  The
+% third pass is the piecewise downward pass.  For each piece, we
+% figure out where in the piece each note will go by inserting
+% compressible spaces between the notes.  If a note is called out
+% past the end of the piece and does not need to go into the piece
+% (as determined by pass 2), it will be deferred to a later piece.
+% The fourth pass is the piecewise upward pass, in which the compressible
+% spaces are shrunk just enough to fit everything into the piece.  The
+% last two (piecewise) passes both occur in each piece before the next
+% piece is addressed.  The whole process is bypassed if there are
+% no eligible margin pieces.
+%    \begin{macrocode}
+  \ifx\mfx@marginpieces\@empty\else
+    \MFX@buildmargin@down
+    \MFX@buildmargin@up
+    \MFX@buildmargin@pieces
+  \fi
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \subsection{First pass: global downward}
+% \begin{macros}{\MFX@buildmargin@down,\mfx@pieceheights}
+% The first step is the global ``down'' step, in which we move the
+% notes that will fit on the current page into \cs{mfx@marginout} in
+% reverse order (to prepare for the second, upward, pass), and anything
+% that doesn't fit is deferred back into \cs{mfx@marginlist}.  We do
+% this by changing the meaning of \cs{mfx@build@note}, \cs{mfx@build@skip},
+% and \cs{mfx@build@clear}, which delimit the different types of material
+% in \cs{mfx@marginlist}.  Note that as we continue processing, these
+% macros will change from time to time (i.e. changing \cs{mfx@build@skip}
+% to actually doing something once we find a note, rather than gobbling
+% so as to remove skips at page boundaries; or changing them to save
+% material back onto \cs{mfx@marginlist} once the margin fills up).
+% The first thing we need to do is iterate over the piece positions
+% to get the list of heights.
+%    \begin{macrocode}
+\def\MFX@buildmargin@down{%
+  \let\mfx@pieceheights\@empty
+  \def\@elt##1##2{%
+    \MFX@cons\mfx@pieceheights{\noexpand\@elt{\the\dimexpr##2-##1}}}%
+  \mfx@marginpieces
+  \MFX@popdimen\Mfx@marginheight\mfx@pieceheights
+%    \end{macrocode}
+% Now we run forwards over the \cs{mfx@marginlist} to actually
+% operate on each thing in the margin.
+%    \begin{macrocode}
+  \let\mfx@build@note\MFX@margin@note@down
+  \let\mfx@build@skip\@gobble
+  \let\mfx@build@clear\MFX@build@clear@down
+  \let\mfx@marginout\@empty
+  \MFX@run@clear\mfx@marginlist
+%<debug>\MFX@debug{buildmargin@down: RETURN
+%<debug>           marginout=\MFX@mac\mfx@marginout,
+%<debug>           marginlist=\MFX@mac\mfx@marginlist}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@margin@note@down,\MFX@margin@skip@down,
+%                \MFX@margin@clear@down}
+% We now define the various |\MFX@margin@...@down| macros.
+% At this stage in the game, the only difference between  notes
+% and skips is that we ignore skips before any notes by setting
+% \cs{mfx@build@note} initially to \cs{@gobble}.  Once we've
+% seen the first note, skips are treated exactly the same: as
+% fixed-height material.  If there is room in the current piece
+% for the given height, then we prepend it to \cs{mfx@marginout},
+% decrement the remaining height, and arrange for the boxes to
+% be freed.  If not, we unshift the next piece height from
+% \cs{mfx@pieceheights} and try again, until \cs{mfx@pieceheights}
+% is empty and we simply defer everything to later pages.
+%
+% Upon seeing a note, we must do several things:
+% \begin{enumerate}
+% \item determine which box (left or right) is needed for the
+%   current page, by calling \cs{MFX@whichbox}
+% \item if the box fits, free both boxes, prepend \cs{mfx@marginout}
+%   with a call to \cs{mfx@build@note}, and re-enable skips
+% \item otherwise, defer the current note and all future notes
+% \end{enumerate}
+% The latter two steps are taken care of by \cs{MFX@margin@fit},
+% which takes the height and two blocks of material: one to prepend
+% to \cs{mfx@marginout} if it fits, the other to append to
+% \cs{mfx@marginlist} if it doesn't.
+%    \begin{macrocode}
+\def\MFX@margin@note@down#1#2#3{%
+%<debug>\MFX@debug{margin@note@down: ENTRY: #1/ #2 at #3}%
+  \MFX@whichbox\@marbox#1#2%
+  \if\MFX@check@fit{}{\ht\@marbox+\dp\@marbox}%
+    \MFX@snoc\mfx@marginout{%
+      \noexpand\@cons\noexpand\@freelist#1%
+      \noexpand\@cons\noexpand\@freelist#2%
+      \noexpand\mfx@build@note\@marbox{#3}}%
+    \let\mfx@build@skip\MFX@margin@skip@down
+  \else
+    \mfx@build@clear
+    \mfx@build@note{#1}{#2}{#3}%
+  \fi
+}
+%    \end{macrocode}
+%
+% Skips are similar.  A skip needs only to save itself back into
+% \cs{mfx@marginout}, provided it fits.  If not, there is no need
+% to defer it because it will just get gobbled at the top of the
+% next page anyway.
+%    \begin{macrocode}
+\def\MFX@margin@skip@down#1{%
+%<debug>\MFX@debug{margin@skip@down #1}%
+  \if\MFX@check@fit{}{#1}%
+    \MFX@snoc\mfx@marginout{\noexpand\mfx@build@skip{#1}}%
+  \else
+    \mfx@build@clear
+  \fi
+}
+%    \end{macrocode}
+%
+% Finally, \cs{MFX@margin@clear@down} is the only place we actually
+% need to handle full-margin clears, since the downward pass does not
+% ever push \cs{mfx@build@clear} onto \cs{mfx@marginout}.  When we
+% see this, we simply redefine all three commands to append themselves
+% back to \cs{mfx@marginlist}.
+%    \begin{macrocode}
+\def\MFX@build@clear@down{%
+%<debug>\MFX@debug{clear@down}%
+  \def\mfx@build@note##1##2##3{%
+    \MFX@cons\mfx@marginlist{\noexpand\mfx@build@note##1##2{\MFX@minus@inf}}}%
+  \def\mfx@build@skip##1{%
+    \MFX@cons\mfx@marginlist{\noexpand\mfx@build@skip{##1}}}%
+  \def\mfx@build@clear{%
+    \MFX@cons\mfx@marginlist{\noexpand\mfx@build@clear}}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@check@fit,\MFX@popdimen}
+% We factored out some of the common functionality between the
+% note and skip routines, so that must now be defined.  The
+% \cs{MFX@check@fit} macro acts as a conditional and should be
+% used as \cs{if}\cs{MFX@check@fit}\marg{piece-hook}\marg{size}.
+% It takes care of iterating through the list of heights and
+% accumulating the total size of material encountered so far.
+% The \emph{piece-hook} is executed each time a new piece height
+% is popped.
+%    \begin{macrocode}
+\def\MFX@check@fit#1#2{%
+  00\fi % close out the \if
+%<debug>\MFX@debug{check@fit{\unexpanded{#1}}{#2=\the\dimexpr#2} ENTRY:
+%<debug>           marginheight=\the\Mfx@marginheight}%
+  \@tempswafalse
+  \ifdim\dimexpr#2<\Mfx@marginheight % it fits
+    \advance\Mfx@marginheight-\dimexpr#2\relax % deduct the size
+    \@tempswatrue
+  \else % didn't fit: check the next piece
+%<debug>\MFX@debug{check@fit overflow: pieceheights=\MFX@mac\mfx@pieceheights}%
+    \ifx\mfx@pieceheights\@empty\else % make sure there's anything there
+      #1%
+      \MFX@popdimen\Mfx@marginheight\mfx@pieceheights
+      \if\MFX@check@fit{#1}{#2}\fi
+    \fi
+  \fi
+%<debug>\MFX@debug{check@fit RETURN \meaning\if@tempswa:
+%<debug>           marginheight=\the\Mfx@marginheight,}%
+  \if@tempswa % start a new \if
+}
+%    \end{macrocode}
+% Here is a quick convenience routine.  \cs{MFX@popdimen}\marg{dimen}%
+% \marg{list} removes the first dimension from \emph{list} and stores
+% it into \emph{dimen}.
+%    \begin{macrocode}
+\def\MFX@popdimen#1#2{%
+  \def\@elt##1{%
+    #1##1\relax
+    \def\@elt####1{%
+      \MFX@cons#2{\noexpand\@elt{####1}}%
+    }%
+  }%
+  \MFX@run@clear#2%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@whichbox,\MFX@leftmargin}
+% We also need to determine which box should be used, since they
+% may have different heights.  The macro \cs{MFX@whichbox}%
+% \marg{target-box}\marg{left-box}\marg{right-box} checks which margin
+% we're setting and stores the correct box into \emph{target-box}.
+% Note that \emph{target-box} must be a single control sequence.
+%    \begin{macrocode}
+\def\MFX@whichbox#1#2#3{%
+  \if\MFX@leftmargin
+    \def#1{#2}%
+  \else
+    \def#1{#3}%
+  \fi
+%<debug>\MFX@debug{whichbox: \@marbox (\the\dimexpr\ht#1+\dp#1)}%
+}
+%    \end{macrocode}
+%
+% And here is the logic to figure out which margin were in, based
+% on the page number and other flags.  This is another conditional-like
+% macro, and should be used after an \cs{if}, as in
+% \cs{if}\cs{MFX@leftmargin}\ldots\cs{else}\ldots\cs{fi}.
+%
+% This is different from the corresponding code in the {\LaTeX}
+% routines because we don't support double columns.  In addition, we
+% would ideally allow \cs{if@reversemargin} to work on a per-note
+% basis (i.e. at callout time) but we also need something working at
+% shipout time so we can figure out which margin to use.  Thus, until
+% we figure out how to use multiple margins, this will have to do.
+%    \begin{macrocode}
+\def\MFX@leftmargin{%
+  00\fi % close out the \if
+  \@tempcnta\@ne
+  \if@mparswitch
+    \unless\ifodd\c@page
+      \@tempcnta\m@ne
+    \fi
+  \fi
+  \if@reversemargin
+    \@tempcnta-\@tempcnta
+  \fi
+%<debug>\MFX@debug{margin on \ifnum\@tempcnta<\z@ left\else right\fi}%
+  \ifnum\@tempcnta<\z@ % start a new \if
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@minus@inf}
+% Finally, note that when deferring notes to the next page, we
+% adjust their position to the top of the page, rather than the
+% callout position.  This is a large negative dimension (near
+% \TeX's maximum), but we may reconsider making this zero or even
+% a small positive amount, since there seems to be a small amount
+% of space before the first paragraph in normal text, though I'm
+% not sure where that comes from.
+%    \begin{macrocode}
+\def\MFX@minus@inf{-4000\p@}
+%    \end{macrocode}
+% \end{macros}
+%
+% \subsection{Second pass: global upward}
+% \begin{macros}{\MFX@buildmargin@up,\mfx@phantomheights}
+% The next step is the global ``up'' step, in which we figure out the
+% lowest piece a note can possibly occupy (without pushing later notes
+% off the bottom) and add this information to the \cs{mfx@build@note} in
+% \cs{mfx@marginout}.  We start similar to \cs{MFX@buildmargin@down},
+% except we need the list of heights to be backwards.  We also need a
+% list of phantom heights, in order to handle skips properly, which we
+% intersperse as negative heights.
+%    \begin{macrocode}
+\def\MFX@buildmargin@up{%
+%<debug>\MFX@debug{buildmargin@up: ENTRY
+%<debug>           marginpieces=\MFX@mac\mfx@marginpieces,
+%<debug>           marginout=\MFX@mac\mfx@marginout}%
+  \let\mfx@pieceheights\@empty
+  \let\mfx@phantomheights\@empty
+  \let\temp@@\relax
+  \def\@elt##1##2{%
+%<debug>\MFX@debug{  -> piece (##1,##2), temp@@=\meaning\temp@@}%
+    \MFX@snoc\mfx@pieceheights{\noexpand\@elt{\the\dimexpr##2-##1}}%
+    \ifx\temp@@\relax\else
+%<debug>\MFX@debug{  -> phantom (\temp@@,##1)}%
+      \MFX@snoc\mfx@phantomheights{\noexpand\@elt{\the\dimexpr##1-\temp@@}}%
+    \fi
+    \def\temp@@{##2}%
+  }%
+  \mfx@in@phantomfalse
+  \mfx@marginpieces
+%    \end{macrocode}
+% The piece counter, \cs{Mfx@piece@count} has not been touched yet,
+% so now we will start decrementing it for each piece to keep track
+% of where we are.  Note that \cs{mfx@marginout} will never contain
+% \cs{mfx@build@clear} so we don't need to reassign it.  Since we
+% don't do any deferrals here, we don't need to empty out a new target
+% list.  Instead, we operate ``in-place'' in \cs{mfx@marginout}, after
+% popping off the first height.
+%    \begin{macrocode}
+  \MFX@popdimen\Mfx@marginheight\mfx@pieceheights
+  \let\mfx@build@note\MFX@margin@note@up
+  \let\mfx@build@skip\@gobble
+  \MFX@run@clear\mfx@marginout
+%<debug>\MFX@debug{buildmargin@up: RETURN marginout=\MFX@mac\mfx@marginout}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@margin@note@up,\MFX@margin@skip@up}
+% We must again define the specific behavior of each build command.
+% These macros simply reuse \cs{MFX@check@fit}, but ask it to
+% decrement the piece counter when a piece runs out of space.
+% Aside from that, the only thing that actually happens here is
+% that we append the current piece to each note, and also end
+% up reversing the contents by again prepending everything.
+% We are guaranteed that \cs{MFX@check@fit} will never fail.
+% Since we cannot put notes in a phantom, we start by ensuring
+% we're not in one.
+%    \begin{macrocode}
+\def\MFX@margin@note@up#1#2{%
+%<debug>\MFX@debug{margin@note@up: #1at #2, marginheight=\the\Mfx@marginheight}%
+  \ifmfx@in@phantom
+    \MFX@popdimen\Mfx@marginheight\mfx@pieceheights
+    \advance\Mfx@piece@count\m@ne
+    \mfx@in@phantomfalse
+  \fi
+%    \end{macrocode}
+% Now we're guaranteed to be in a piece, rather than a phantom, we
+% look for a piece that can fit this note, making sure to decrement
+% the piece count and pop off a phantom for each new piece we check.
+% Once it's found, we add the note back to \cs{mfx@marginout} with
+% the corect piece.
+%    \begin{macrocode}
+  \if\MFX@check@fit{\advance\Mfx@piece@count\m@ne
+                    \MFX@popdimen\dimen@\mfx@phantomheights}{\ht#1+\dp#1}%
+    \MFX@snoc\mfx@marginout{%
+      \noexpand\mfx@build@note{#1}{#2}{\the\Mfx@piece@count}}%
+    \let\mfx@build@skip\MFX@margin@skip@up
+  \else\MFX@AssertionError\fi
+}
+%    \end{macrocode}
+% Skips are similar, but we have the added complication of handling
+% margin phantoms.  When we cross between phantom and piece, we split
+% the skip so that we can use the simplest recursion possible.
+%    \begin{macrocode}
+\def\MFX@margin@skip@up#1{%
+%<debug>\MFX@debug{margin@skip@up: #1}%
+  \dimen@#1\relax
+  \advance\Mfx@marginheight-\dimen@
+  \ifdim\Mfx@marginheight<\z@
+%    \end{macrocode}
+% This skip was bigger than the piece, so we need to split this skip,
+% adding the overflow back, and try again.  Since we're done with this
+% piece, we'll pop the next one and recurse on whatever's left.  This
+% looks slightly different depending on whether or not we're in a phantom.
+%    \begin{macrocode}
+    \advance\dimen@\Mfx@marginheight
+    \MFX@snoc\mfx@marginout{%
+      \noexpand\mfx@build@skip{\the\dimen@}{\the\Mfx@piece@count}}%
+    \dimen@-\Mfx@marginheight
+    \ifmfx@in@phantom
+      \MFX@popdimen\Mfx@marginheight\mfx@pieceheights
+      \advance\Mfx@piece@count\m@ne
+      \mfx@in@phantomfalse
+    \else
+      \MFX@popdimen\Mfx@marginheight\mfx@phantomheights
+      \mfx@in@phantomtrue
+    \fi
+    \mfx@build@skip\dimen@
+  \else
+%    \end{macrocode}
+% This skip fit entirely within the phantom, so we simply emit it.
+%    \begin{macrocode}
+    \MFX@snoc\mfx@marginout{%
+      \noexpand\mfx@build@skip{\the\dimen@}{\the\Mfx@piece@count}}%
+  \fi
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \subsection{Margin pieces}
+% \begin{macros}{\MFX@buildmargin@pieces,\MFX@buildmargin@piece}
+% Before we can start the third and fourth passes, we need to set up
+% a loop over the pieces so that each piece can do these passes at
+% one time.  In case we didn't use up all the pieces in the second
+% phase, we'll reset \cs{Mfx@piece@count} to zero.  We also reset
+% \cs{Mfx@marginspace} and \cs{Mfx@marginbox}.
+%    \begin{macrocode}
+\def\MFX@buildmargin@pieces{%
+  \Mfx@piece@count\z@
+  \Mfx@marginspace\z@
+  \setbox\Mfx@marginbox\vbox{\vskip\z@}%  TODO - do we need this?
+%    \end{macrocode}
+% Now we run over the individual margin pieces, clearing it out as we
+% build up the contents of \cs{Mfx@marginbox}.  Once we're done with
+% that, we need to do a bit of clean-up before finishing.
+%    \begin{macrocode}
+  \let\@elt\MFX@buildmargin@piece
+  \MFX@run@clear\mfx@marginpieces
+  \let\@elt\relax
+  \Mfx@piece@count\z@
+}
+%    \end{macrocode}
+%
+% The \cs{MFX@buildmargin@piece} macro is called for each piece of
+% the margin, and is passed the top and bottom positions of the piece.
+% Here we need to do a few things.  First, if the output so far is
+% smaller than the top of the piece (this is generally true, except
+% sometimes for the first piece) then we need to insert padding into
+% \cs{Mfx@marginbox} before continuing.  We accumulate this padding
+% into \cs{Mfx@marginspace}, which allows skips to do double-duty
+% across phantoms.
+%    \begin{macrocode}
+\def\MFX@buildmargin@piece#1#2{%
+%<debug>\MFX@debug{buildmargin@piece: ENTRY (#1, #2)}%
+  \ifdim\ht\Mfx@marginbox<#1\relax
+    \dimen@\dimexpr#1-\ht\Mfx@marginbox\relax
+%<debug>\MFX@debug{buildmargin@piece: padding \the\dimen@}%
+    \setbox\Mfx@marginbox\vbox{%
+      \unvbox\Mfx@marginbox
+      \vskip\dimen@
+    }%
+    \advance\Mfx@marginspace\dimen@
+  \fi
+%    \end{macrocode}
+% Now that \cs{Mfx@marginbox} has been padded, we proceed to set
+% things up for our down and up passes, and then run them to build
+% \cs{Mfx@piece@content}.
+%    \begin{macrocode}
+  \Mfx@marginpos@min#1\relax
+  \Mfx@marginpos@max#1\relax
+  \Mfx@marginheight#2\relax
+  \advance\Mfx@piece@count\@ne
+  \MFX@buildpiece@down
+  \MFX@buildpiece@up
+%    \end{macrocode}
+% Once \cs{Mfx@piece@content} has been built, we append it to the
+% \cs{Mfx@marginbox}.
+%    \begin{macrocode}
+  \setbox\Mfx@marginbox\vbox{%
+    \unvbox\Mfx@marginbox
+    \box\Mfx@piece@content
+    \vskip\z@
+  }%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \subsection{Third pass: piecewise downward}
+% \begin{macros}{\MFX@buildpiece@down,\mfx@pieceout}
+% The next pass is another downward pass.  This is very similar
+% to the first (global downward) pass, except we're now moving
+% the first several notes from \cs{mfx@marginout} into
+% \cs{mfx@pieceout} (again, inverting the order) and deferring
+% the rest back into \cs{mfx@marginout}.  
+%    \begin{macrocode}
+\def\MFX@buildpiece@down{%
+%<debug>\MFX@debug{buildpiece@down: ENTRY piece=\the\Mfx@piece@count,
+%<debug>    marginpos=(\the\Mfx@marginpos@min, \the\Mfx@marginpos@max),
+%<debug>    marginspace=\the\Mfx@marginspace,
+%<debug>    marginout=\MFX@mac\mfx@marginout}%
+  \let\mfx@build@note\MFX@piece@note@down
+  \let\mfx@build@skip\MFX@piece@skip@down
+  \let\mfx@pieceout\@empty
+  \MFX@run@clear\mfx@marginout
+%<debug>\MFX@debug{buildpiece@down: RETURN pieceout=\MFX@mac\mfx@pieceout,
+%<debug>    marginout=\MFX@mac\mfx@marginout}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@piece@note@down,\MFX@piece@skip@down,\MFX@piece@clear}
+% We again define each of our building macros.  First, the note builder.
+% When we encounter a note, we first zero out \cs{Mfx@marginspace}.  Then
+% we need to decide whether to put it in the current piece, or whether
+% to defer it to the next piece, based on a few signals.  A note will only
+% be deferred for one of two reasons.  In either case, we store the decision
+% to defer in |@tempswa|, so we'll start by clearing it.
+%    \begin{macrocode}
+\def\MFX@piece@note@down#1#2#3{%
+%<debug>\MFX@debug{piece@note@down: ENTRY: #1at #2, lowest=#3,
+%<debug>           marginpos=(\the\Mfx@marginpos@min,\the\Mfx@marginpos@max,
+%<debug>           marginspace=\the\Mfx@marginspace}%
+  \Mfx@marginspace\z@
+  \@tempswafalse
+%    \end{macrocode}
+% The first reason to defer is if its callout position (|#2|)
+% is beneath the end of the current piece (\cs{Mfx@marginheight}) \emph{and}
+% if its lowest-possible-piece (|#3|, as computed in the second pass) is
+% \emph{after} the current one (\cs{Mfx@piece@count}).
+%    \begin{macrocode}
+  \ifdim#2>\Mfx@marginheight
+    \ifnum#3>\Mfx@piece@count
+      \@tempswatrue
+    \fi
+  \fi
+%    \end{macrocode}
+% The second possibility is that we've run out of room in this piece.
+% In this case, there's no need to check |#3|, since that number was
+% computed assuming everything that fit was as low as possible.
+%    \begin{macrocode}
+  \ifdim\dimexpr\ht#1+\dp#1+\Mfx@marginpos@min>\Mfx@marginheight
+    \@tempswatrue
+  \fi
+%    \end{macrocode}
+% If a note is deferred, then we push it and everything after it
+% back onto \cs{mfx@marginout}.
+%    \begin{macrocode}
+  \if@tempswa
+%<debug>\MFX@debug{piece@note@down: clearing margin}%
+    \MFX@piece@clear
+    \mfx@build@note{#1}{#2}{#3}%
+  \else
+%    \end{macrocode}
+% Otherwise, we have decided the note is going into this piece.  In this
+% case, we now need to check if any compressible space is needed above it.
+% In order to get better alignment for deferred notes, we check for the
+% case that the current position is zero and the note's callout position
+% is \cs{MFX@minus@inf}.  In this case, we change the callout position
+% to instead be the greater of 0 or $\cs{topskip}-\cs{ht}\#1$.
+%    \begin{macrocode}
+    \dimen@#2\relax
+    \ifdim\dimen@=\MFX@minus@inf
+      \ifdim\Mfx@marginpos@max=\z@
+        \dimen@\topskip
+        \advance\dimen@-\ht#1\relax
+        \ifdim\dimen@<\z@ \dimen@\z@ \fi
+      \fi
+    \fi
+    \advance\dimen@-\Mfx@marginpos@max
+    \ifdim\dimen@>\z@
+%<debug>\MFX@debug{piece@note@down: adding compressible \the\dimen@}%
+      \MFX@snoc\mfx@pieceout{\noexpand\mfx@build@compressible{\the\dimen@}}%
+      \advance\Mfx@marginpos@max\dimen@
+    \fi
+%    \end{macrocode}
+% After (maybe) adding the compressible space, we now add the
+% (incompressible) box itself, and accumulate its height in both position
+% registers.  We no longer need the piece index or the position, so we
+% only store the box itself here.
+%    \begin{macrocode}
+    \MFX@snoc\mfx@pieceout{\noexpand\mfx@build@note{#1}}%
+    \advance\Mfx@marginpos@min\dimexpr\ht#1+\dp#1\relax
+    \advance\Mfx@marginpos@max\dimexpr\ht#1+\dp#1\relax
+  \fi    
+}
+%    \end{macrocode}
+%
+% Skips are a bit more complicated now.  We no longer gobble the
+% initial skips (since the skips at the top and bottom of the page
+% have already been eaten).  Instead, we need to look at
+% \cs{Mfx@marginspace}: if it's nonzero, we substract it from the
+% skip length before adding it incompressibly (if there's any left).
+% While we have piece number information here, we just pass it on
+% to the upward pass, which can choose to ``late-defer'' initial
+% (i.e. the bottom-most) skips in a piece.
+%    \begin{macrocode}
+\def\MFX@piece@skip@down#1#2{%
+  \dimen@#1\relax
+  \ifdim\Mfx@marginspace>\z@
+    \advance\dimen@-\Mfx@marginspace
+    \ifdim\dimen@<\z@ \dimen@\z@ \fi
+    \advance\Mfx@marginspace-\dimen@
+  \fi
+%    \end{macrocode}
+% At this point, \cs{dimen@} now stores any further incompressible
+% skip we need to add, which is now relative to the top of this piece.
+% In that case (note that \cs{Mfx@marginspace} is now necessarily zero),
+% we need to check that it actually fits in the current piece, and if
+% not, defer it.
+%    \begin{macrocode}
+  \ifdim\dimen@>\z@
+    \ifdim\dimexpr#1+\Mfx@marginpos@min>\Mfx@marginheight
+      \MFX@piece@clear
+      \mfx@build@skip{\the\dimen@}{#2}%
+    \else
+%    \end{macrocode}
+% If the skip \emph{does} fit, we need to add it to \cs{mfx@pieceout}
+% and advance the position registers.
+%    \begin{macrocode}
+      \MFX@snoc\mfx@pieceout{\noexpand\mfx@build@skip{\the\dimen@}{#2}}%
+      \advance\Mfx@marginpos@min\dimen@
+      \advance\Mfx@marginpos@max\dimen@
+    \fi
+  \fi
+}
+%    \end{macrocode}
+%
+% Finally, we need to handle the case of deferring material.  By
+% analogy with the previous two passes, we'll continue to refer to
+% this as clearing.  In this case, we need to redefine the note and
+% skip macros to save themselves back to \cs{mfx@marginout}.
+%    \begin{macrocode}
+\def\MFX@piece@clear{%
+%<debug>\MFX@debug{piece@clear}%
+  \def\mfx@build@note##1##2##3{%
+    \MFX@cons\mfx@marginout{\noexpand\mfx@build@note##1{##2}{##3}}}%
+  \def\mfx@build@skip##1##2{%
+    \MFX@cons\mfx@marginout{\noexpand\mfx@build@skip{##1}{##2}}}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \subsection{Fourth pass: piecewise upward}
+% \begin{macros}{\MFX@buildpiece@up}
+% We are now ready for the final pass, where we take the reversed
+% list of notes for this piece and stack them up, compressing as much
+% compressible space as necessary to make them all fit.  Since this
+% is the last pass, we can finally prepend all the boxes into
+% \cs{Mfx@piece@content}.  Because it is still possible for pieces
+% to have skips at the bottom, we need to worry about which piece
+% these skips belong in.  Since we've passed forward the lowest-piece
+% information from pass 2, we can choose at the last possible moment
+% to defer the bottom-most skips of a piece to the next piece (by
+% prepending it to \cs{mfx@marginout}.  Note that compressible spaces
+% will \emph{never} be at the beginning of \cs{mfx@pieceout}.  We
+% store the excess space in \cs{Mfx@marginheight}.
+%    \begin{macrocode}
+\def\MFX@buildpiece@up{%
+  \Mfx@marginheight\dimexpr\Mfx@marginpos@max-\Mfx@marginheight\relax
+  \ifdim\Mfx@marginheight<\z@\Mfx@marginheight\z@\fi
+%<debug>\MFX@debug{buildpiece@up: excess=\the\Mfx@marginheight}%
+  \let\mfx@build@note\MFX@piece@note@up
+  \let\mfx@build@compressible\MFX@piece@compressible@up
+  \let\mfx@build@skip\MFX@piece@skip@maybedefer
+  \MFX@run@clear\mfx@pieceout\relax
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@piece@skip@maybedefer}
+% As mentioned earlier, the initial skips in a piece may be deferred
+% to later pieces, provided they can possibly go there.  Here we
+% check the |#2| argument against \cs{Mfx@piece@count} and defer if
+% it is larger.  Otherwise, we switch back to the standard behavior
+% defined in \cs{MFX@piece@skip@up}.  Deferred skips do not need to
+% be subtracted from the excess because they were never compressible
+% in the first place.
+%    \begin{macrocode}
+\def\MFX@piece@skip@maybedefer#1#2{%
+  \ifnum#2>\Mfx@piece@count
+%<debug>\MFX@debug{piece@skip deferring: #1, #2 (\the\Mfx@piece@count)}%
+    \MFX@snoc\mfx@marginout{\noexpand\mfx@build@skip{#1}{#2}}%
+  \else
+    \let\mfx@build@skip\MFX@piece@skip@up
+    \mfx@build@skip{#1}{#2}%
+  \fi
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@piece@note@up,\MFX@piece@skip@up}
+% Now that we've taken care of late deferrals, we can define the
+% standard behavior without worrying as much about that.
+% These macros finally set their contents into \cs{Mfx@piece@content},
+% as well as reset \cs{mfx@build@skip} back to its standard value.
+%    \begin{macrocode}
+\def\MFX@piece@note@up#1{%
+%<debug>\MFX@debug{piece@note@up: #1}%
+  \setbox\Mfx@piece@content\vbox{%
+    \box#1%
+    \unvbox\Mfx@piece@content}%
+  \let\mfx@build@skip\MFX@piece@skip@up
+}
+%    \end{macrocode}
+% Skips are also straightforward.
+%    \begin{macrocode}
+\def\MFX@piece@skip@up#1#2{%
+%<debug>\MFX@debug{skip@up: #1=\the\dimexpr#1\relax (#2)}%
+  \setbox\Mfx@piece@content\vbox{%
+    \vskip#1\relax
+    \unvbox\Mfx@piece@content}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\MFX@piece@compressible@up}
+% Finally we come to the compressible space.  Here, as long as
+% there's excess space (\cs{Mfx@marginheight}) we drop the
+% compressible space.  Once the excess is exhausted, we insert
+% them as normal skips.
+%    \begin{macrocode}
+\def\MFX@piece@compressible@up#1{%
+%<debug>\MFX@debug{compressible@up: #1, excess=\the\Mfx@marginheight}%
+  \advance\Mfx@marginheight-#1\relax
+  \ifdim\Mfx@marginheight<\z@
+    \MFX@piece@skip@up{-\Mfx@marginheight}\relax
+    \Mfx@marginheight\z@
+  \fi
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \section{Cleaning up}
+% We need to worry about a few more things.  First, what happens
+% if we reach the end of the document and there are still deferred
+% margin notes?  We need to be able to dump all the margin notes
+% whenever the user wants (i.e. before a new chapter), so we'll
+% make a macro \cs{dumpmargins} to do this, and then make sure it
+% gets called \cs{AtEndDocument}.  Since we're looping to do this,
+% we need to make darned sure that every \cs{newpage} shrinks the
+% marginlist.
+% \begin{macros}{\dumpmargins}
+%    \begin{macrocode}
+\def\dumpmargins{%
+%<debug>\MFX@debug{dumpmargins}%
+  \loop
+  \unless\ifx\mfx@marginlist\@empty
+%<debug>\MFX@debug{dumpmargins: marginlist=\MFX@mac\mfx@marginlist}%
+    \let\temp@\mfx@marginlist
+    \vbox{}\clearpage
+    \ifx\temp@\mfx@marginlist
+      \PackageError{marginfix}{lost some margin notes%
+      \ifx\mfx@marginstart\relax\ (missing \noexpand\unblockmargin)\fi
+%<debug>: \MFX@mac\mfx@marginlist
+      }\@eha
+      \let\mfx@marginlist\@empty % be nicer by just dropping one?
+      % TODO: also, set an emergency mode to allow oversized notes
+    \fi
+  \repeat
+}
+\AtEndDocument{\dumpmargins}
+%    \end{macrocode}
+% \end{macros}
+%
+% \section{User macros}
+%
+% \begin{macros}{\marginskip}
+% Inserting a skip in the margin list is simple.  We need only
+% append \cs{mfx@build@skip} to \cs{mfx@marginlist}.
+%    \begin{macrocode}
+\def\marginskip#1{%
+  \MFX@cons\mfx@marginlist{\noexpand\mfx@build@skip{#1}}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\clearmargin,\softclearmargin}
+% Likewise, \cs{clearmargin} is easy too.
+%    \begin{macrocode}
+\def\clearmargin{%
+  \MFX@cons\mfx@marginlist{\noexpand\mfx@build@clear}%
+}
+%    \end{macrocode}
+% While we call \cs{softclearmargin} a ``clear margin'', it's
+% actually just a big \cs{marginskip}.  This allows us to stack
+% multiple copies without backing them all up.
+%    \begin{macrocode}
+\def\softclearmargin{%
+  \marginskip{\the\textheight}%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\extendmargin}
+% We overload \cs{Mfx@marginheight} to be the amount of extension
+% at all times except shipout-time.
+%    \begin{macrocode}
+\def\extendmargin#1{%
+  \advance\Mfx@marginheight#1\relax
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\mparshift}
+% This is as simple as setting the dimen register.  We advance so that
+% the shifts are cumulative, but there's not really any point either way.
+%    \begin{macrocode}
+\def\mparshift#1{%
+  \advance\Mfx@mparshift#1\relax
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\blockmargin,\MFX@blockmargin}
+% We need two macros to process the optional bracket argument.
+% Essentially, \cs{blockmargin} just checks that
+% \cs{mfx@marginstart} is defined and then appends a new item to
+% the \cs{mfx@marginpieces} list to indicate a piece that starts
+% at \cs{mfx@marginstart} and ends at the current position, potentially
+% modified by the argument.  It then resets \cs{mfx@marginstart} to
+% \cs{relax} and optionally adds a \cs{softclearmargin} if there was no
+% star, to keep margin material separated on either side of the phantom.
+%    \begin{macrocode}
+\def\blockmargin{%
+  \@ifnextchar[%]
+    \MFX@blockmargin
+    {\MFX@blockmargin[0\p@]}%
+}
+\def\MFX@blockmargin[#1]{%
+  \MFX@inject{%
+    \ifx\mfx@marginstart\relax
+      \PackageError{marginfix}{two \\blockmargin with no \\unblockmargin}\@eha
+    \else
+      \MFX@cons\mfx@marginpieces{\noexpand
+        \@elt{\mfx@marginstart}{\expandafter\dimexpr\mfx@ypos+#1\relax}}%
+      \global\let\mfx@marginstart\relax
+      \global\advance\Mfx@piece@count\@ne
+    \fi
+  }%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\unblockmargin,\MFX@unblockmargin}
+% This is the other half of \cs{blockmargin}.  It ensures that the
+% margin is currently blocked, and if so, sets \cs{mfx@marginstart}
+% back to a real dimension (the current page position, plus the optional
+% modifier).
+%    \begin{macrocode}
+\def\unblockmargin{%
+  \@ifnextchar[%]
+    \MFX@unblockmargin
+    {\MFX@unblockmargin[0\p@]}%
+}
+\def\MFX@unblockmargin[#1]{%
+  \MFX@inject{%
+    \ifx\mfx@marginstart\relax
+      \xdef\mfx@marginstart{\dimexpr\mfx@ypos+#1\relax}%
+    \else
+      \PackageError{marginfix}{\\unblockmargin with no \\blockmargin}\@eha
+    \fi
+  }%
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \begin{macros}{\marginphantom,\MFX@marginphantom}
+% The \cs{marginphantom} command is basically just a concatenation of
+% \cs{blockmargin} and \cs{unblockmargin}.  We reimplement it from the
+% ground up mainly so that the error messages make more sense.
+%    \begin{macrocode}
+\def\marginphantom{%
+  \@ifnextchar[%]
+    \MFX@marginphantom
+    {\MFX@marginphantom[0\p@]}%
+}
+\def\MFX@marginphantom[#1]#2{%
+  \ifdim#2<\z@\MFX@marginphantom[#1+#2]{-#2}\else
+  \MFX@inject{%
+    \ifx\mfx@marginstart\relax
+      \PackageError{marginfix}{\\marginphantom while margin blocked}\@eha
+    \else
+      \MFX@cons\mfx@marginpieces{\noexpand
+        \@elt{\mfx@marginstart}{\expandafter\dimexpr\mfx@ypos+#1\relax}}%
+      \xdef\mfx@marginstart{\dimexpr\mfx@ypos+#1+#2\relax}%
+      \global\advance\Mfx@piece@count\@ne
+    \fi
+  }%
+  \fi
+}
+%    \end{macrocode}
+% \end{macros}
+%
+% \section{Random scribbles}
+%
+% Later we'll get fancier with putting notes next to top/bottom
+% figures but for now, not so much.
+%
+% In the future we will support the use of \cs{pdfsavepos} and
+% \cs{pdflastypos} for more accurately determining where the callouts
+% actually were, which will end up going right around here.  But in
+% order to work with older versions of \LaTeX, we still need to
+% support the old style of using \cs{@pageht} to figure that out, so for
+% now that's all we'll do.
+%
+% \section{Parting words}
+% Finish it up.
+%    \begin{macrocode}
+\makeatother
+%</package>
+%    \end{macrocode}
+% \makeatother
+% \Finale
+%
+%
+% \iffalse
+%
+% The next line of code prevents DocStrip from adding the
+% character table to the generated files(s).
+\endinput
+% \fi
+%
+%% \CharacterTable
+%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+%%   Digits        \0\1\2\3\4\5\6\7\8\9
+%%   Exclamation   \!     Double quote  \"     Hash (number) \#
+%%   Dollar        \$     Percent       \%     Ampersand     \&
+%%   Acute accent  \'     Left paren    \(     Right paren   \)
+%%   Asterisk      \*     Plus          \+     Comma         \,
+%%   Minus         \-     Point         \.     Solidus       \/
+%%   Colon         \:     Semicolon     \;     Less than     \<
+%%   Equals        \=     Greater than  \>     Question mark \?
+%%   Commercial at \@     Left bracket  \[     Backslash     \\
+%%   Right bracket \]     Circumflex    \^     Underscore    \_
+%%   Grave accent  \`     Left brace    \{     Vertical bar  \|
+%%   Right brace   \}     Tilde         \~}
+%%
-- 
cgit v1.2.3

