9

How can I replace footnotes for non-floating marginal notes?

I have tried to replace my footnotes for sidenotes with footmisc package's side option, but they continue to be floats, like every \marginpar. I don't want them to float around an anchor: I want these marginal notes flowing from the top of the page to the bottom, and with the capacity of being splitted between pages when needed (because some of them might be too long, or there might be too many of them).

henrique
  • 6,616

1 Answers1

9

EDIT Original version using a newly allocated box register is at the end. This version uses the \footins insertion register to take advantage of the primitive insert capability to pick up the correct notes for each page.

enter image description here

\documentclass[twoside]{article}
\newcounter{f}
\addtolength\textheight{-20\baselineskip}
\def\z{\stepcounter{f}\Roman{f}
\roman{f} \alph{f} \roman{f} \roman{f} \roman{f}
\roman{f} \roman{f} \alph{f} \roman{f} \roman{f}
\roman{f} \roman{f} \roman{f} \alph{f} \roman{f}
\roman{f} \roman{f} \roman{f} \roman{f} \alph{f}}

\def\a{One two three.}
\def\b{\a\ \a\ Four five. \a}
\def\c{\b\ \b\ Red green blue. \b\footnote{\z} \a}
\def\d{\c\ \c\ \c\ \c}


\makeatletter
\skip\footins\z@
\count\footins\z@
\dimen\footins\textheight

\long\def\@footnotetext#1{%
  \insert\footins{%
    \reset@font\footnotesize
    \interlinepenalty\interfootnotelinepenalty
    \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
    \hsize\marginparwidth \@parboxrestore
    \protected@edef\@currentlabel{%
       \csname p@footnote\endcsname\@thefnmark
    }%
    \color@begingroup
      \@makefntext{%
        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
    \color@endgroup}}%

\gdef \@makecol {%
   \ifvoid\footins
     \setbox\@outputbox \box\@cclv
   \else
     \setbox\@outputbox \vbox {%
\hbox{\color@begingroup
  \if@twoside\ifodd\c@page
     \box\@cclv\rlap{\kern\marginparsep\vbox to \textheight{\unvbox\footins}}
  \else
    \llap{\vbox to \textheight{\unvbox\footins}\kern\marginparsep}\box\@cclv
   \fi
\color@endgroup}}%
   \let\@elt\relax
   \xdef\@freelist{\@freelist\@midlist}%
   \global \let \@midlist \@empty
   \@combinefloats
   \ifvbox\@kludgeins
     \@makespecialcolbox
   \else
     \setbox\@outputbox \vbox to\@colht {%
       \@texttop
       \dimen@ \dp\@outputbox
       \unvbox \@outputbox
       \vskip -\dimen@
       \@textbottom
       }%
   \fi
   \global \maxdepth \@maxdepth
}

\makeatother

\begin{document}


\d\ Nine ten. \d

Five four three two one. \d\ \d

Red blue green. \d\ Yellow blue. \d
\end{document}

I think something like this (updated for twoside) ....

enter image description here

\documentclass[twoside]{article}
\newcounter{f}
\addtolength\textheight{-20\baselineskip}
\def\z{\stepcounter{f}\Roman{f}
\roman{f} \alph{f} \roman{f} \roman{f} \roman{f}
\roman{f} \roman{f} \alph{f} \roman{f} \roman{f}
\roman{f} \roman{f} \roman{f} \alph{f} \roman{f}
\roman{f} \roman{f} \roman{f} \roman{f} \alph{f}}

\def\a{One two three.}
\def\b{\a\ \a\ Four five. \a}
\def\c{\b\ \b\ Red green blue. \b\footnote{\z} \a}
\def\d{\c\ \c\ \c\ \c}

\newbox\ftbox
\setbox\ftbox\vbox{}

\makeatletter
\long\def\@footnotetext#1{%
  \global\setbox\ftbox\vbox{%
    \unvbox\ftbox    
    \reset@font\footnotesize
    \interlinepenalty\interfootnotelinepenalty
    \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
    \hsize\marginparwidth \@parboxrestore
    \protected@edef\@currentlabel{%
       \csname p@footnote\endcsname\@thefnmark
    }%
    \color@begingroup
      \@makefntext{%
        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
    \color@endgroup}}%

\gdef \@makecol {%
   \ifvoid\footins
     \setbox\@outputbox \box\@cclv
   \else
     \setbox\@outputbox \vbox {%
       \boxmaxdepth \@maxdepth
       \unvbox \@cclv
       \vskip \skip\footins
       \color@begingroup
         \normalcolor
         \footnoterule
         \unvbox \footins
       \color@endgroup
       }%
   \fi
   \global\setbox\@ne\vsplit\ftbox to \textheight
  \if@twoside\ifodd\c@page
     \setbox\@outputbox\vbox{\hbox{\box\@outputbox\rlap{\kern\marginparsep\box\@ne}}}%
  \else
     \setbox\@outputbox\vbox{\hbox{\llap{\box\@ne\kern\marginparsep}\box\@outputbox}}%
   \fi
  \else
     \setbox\@outputbox\vbox{\hbox{\box\@outputbox\rlap{\kern\marginparsep\box\@ne}}}%
  \fi
   \let\@elt\relax
   \xdef\@freelist{\@freelist\@midlist}%
   \global \let \@midlist \@empty
   \@combinefloats
   \ifvbox\@kludgeins
     \@makespecialcolbox
   \else
     \setbox\@outputbox \vbox to\@colht {%
       \@texttop
       \dimen@ \dp\@outputbox
       \unvbox \@outputbox
       \vskip -\dimen@
       \@textbottom
       }%
   \fi
   \global \maxdepth \@maxdepth
}

\makeatother

\begin{document}


\d\ Nine ten. \d

Five four three two one. \d\ \d

Red blue green. \d\ Yellow blue. \d
\end{document}
David Carlisle
  • 757,742
  • Thank you! The only problem I've seen so far is that some notes are being placed in the page prior to the footnote marker (although there's enough space for it in the current page)... – henrique Sep 06 '12 at 13:58
  • yes that's a bug really (no time to fix today) tex reads at least a paragraph at a time before deciding where the page breaks and any footnotes seen in the part that is not placed on the shipped out page will be grabbed early. – David Carlisle Sep 06 '12 at 14:39
  • The edited version gives the following error at \end{document}: ! Extra \else. <output> ...utpenalty <-\@M \@specialoutput \else \@makecol \@opcol \@startc..., an error that, if ignored, will result in an emergency stop: ! Incomplete \ifvoid; all text was ignored after line 65. [where the \end{document} is --henrique] <inserted text> \fi. – henrique Sep 18 '12 at 13:14
  • I just copied the file back from this web page and re-ran and it runs without error and makes a three page pdf however it warns (\end occurred when \ifvoid on line 75 was incomplete) which is clearly a bug so I'll update in a bit. – David Carlisle Sep 18 '12 at 13:19
  • yes. Sorry, I forgot to mention that your MWE isn't affected by that error, but one based on blindtext was. – henrique Sep 18 '12 at 13:22
  • Yes the code's wrong: if it warns about unfinished if (which it does on my example) then that's an accident waiting to happen. I need to do the day job now though so it will be later. – David Carlisle Sep 18 '12 at 14:54
  • I think the unfinished if it the \ifvoid\footins. Curiously, the error is intermittent (it appears in pagebreaks when using blindtext, but not with regular text?). Besides, long footnotes increase \parskip up to the footnote end. – henrique Sep 18 '12 at 23:30
  • yes sorry been busy:-) reusing footins is probably the right way but it might be safer to allocate a new insertion register that way I wouldn't have to check everyplace that the current output routine checks footins. sorry I ran out of your bounty time, just need to find a spare hour to dissect the output routine:-) – David Carlisle Sep 18 '12 at 23:37
  • Thank you very much David, I'm looking foward to it! I thought we still had some hours and I was going to bounty it the way it is, but the bounty button is gone... :( – henrique Sep 18 '12 at 23:47
  • don't worry about it, I'm not desperately short of points:-) – David Carlisle Sep 18 '12 at 23:54
  • This is exactly what I've been looking for! But I want a singles-sided letterpaper article-class document, with the notes in the right hand margin. When I run the code above as-is, it works, but when I change twoside to letterpaper, it no longer works. Is there way to make it work? – Mårten Apr 23 '13 at 20:35
  • @Mårten what goes wrong, you mean literally taking the code above and removing twoside? – David Carlisle Apr 23 '13 at 20:48
  • Yes, replacing twoside with letterpaper. xelatex says: ! You can't use `\end' in internal vertical mode. \enddocument ... \endgroup \deadcycles \z@ @@end

    l.71 \end{document}

    – Mårten Apr 23 '13 at 21:19
  • @Mårten I get no error in pdflatex or xelatex if I change twoside to letterpaper (texlive 2012) (lots of underful box warnings) – David Carlisle Apr 23 '13 at 21:34
  • I don't know what I did before, it works beautifully now! Now I thought of a potential problem though. Is is possible to make the right margin elastic to accommodate large footnotes, like the bottom margin does on a "normal" page? – Mårten Apr 24 '13 at 02:50
  • Hmm I also noted that even though I enlarge the size of the margin, the footnote area remains the same, and the footnotes have become double spaced like the text, which they weren't before. – Mårten Apr 24 '13 at 02:57
  • 1
    @Mårten the width is the standard LaTeX \marginparwidth length which you can set as usual. The code does `@parboxrestore, I'd have thought any code inflicting double spacing on the main document would have added single spacing to that so parboxes are not spaced out, anyway you could add single spacing to the code just after the call to that (of course the correct fix is not to double space the main text) – David Carlisle Apr 24 '13 at 08:10
  • @David, sorry it took me so long to reactivate this question (I just read http://meta.tex.stackexchange.com/q/3640 and remembered this :)). The footins-enabled version has one drawback: It adds a lot of whitespace after paragraphs in order to keep the footnotes near their marks. (iiuc, it also has two missing \fis that should follow \color@endgroup}}); the former version halts at the the main text's end, and will not add new pages for the completion of footnotes. I believe something from \footins could fix the first version but that's way beyond my knowledge... – henrique Jul 12 '13 at 15:02
  • @henrique I can't remember what this was doing:-) I'll have a look at the weekend if I get time:-) – David Carlisle Jul 12 '13 at 15:04