10

The motivation is presumably that footnotes are formatted immediately and inside a parbox \hsize does not equal \textwidth (although, unlike a minipage, \textwidth doesn't change). The mechanism is presumably simply using local rather than global definitions. Looking through source2e I couldn't find the source for \@makefntext. I was hoping to be able to fix the problem directly.

Anyway, here is a sort of MWE:

\documentclass{article}

\newcount\savefnused
\newcount\savefndone

\newcommand{\savefootnote}[2][\empty]% #1=number (optional), #2=text
{\ifx\empty#1\footnotemark\else\footnotemark[#1]\fi
 \global\advance\savefnused by 1
 \expandafter\xdef\csname savefnmark\the\savefnused\endcsname{\thefootnote}%
 \expandafter\xdef\csname savefntext\the\savefnused\endcsname{#2}%
}
\newcommand{\flushfootnote}{\loop\ifnum\savefndone<\savefnused
  \global\advance\savefndone by 1
  \footnotetext[\csname savefnmark\the\savefndone\endcsname]%
    {\csname savefntext\the\savefndone\endcsname}%
  \global\expandafter\let\csname savefnmark\the\savefndone\endcsname\relax
  \global\expandafter\let\csname savefntext\the\savefndone\endcsname\relax
\repeat}

\begin{document}
normal\footnote{normal}

\parbox{1in}{parbox\savefootnote{parbox}}
\flushfootnote

check counter\footnote{after}

\end{document}
6
  • You'll fine \@makefntext in the respective class files. See article.cls, book.cls and report.cls, for example.
    – Werner
    Jun 12, 2016 at 14:20
  • 2
    To me the answer here is that minipage was designed to handle \footnotes and it makes specific preparation during \begin{minipage} and releasing any footnotes as part of an "insert" during \end{minipage}. \parbox doesn't do this.
    – Werner
    Jun 12, 2016 at 14:26
  • I know that someone with a lot more knowledge than myself will step in here to fully explain this. From what I can tell \parbox has a rather complex underlying macro \@iiiparbox, which as part of its definition puts the textual materials in a \vtop box. Since footnotes cannot be read from a \vtop box they cannot be used within \parbox. So I would think the problem is in using \parbox.
    – A Feldman
    Jun 12, 2016 at 14:58
  • @AFeldman - I don't think that's it. I often use \setbox inside a \parbox. Jun 13, 2016 at 2:10
  • You probably know better then. All I did was use latexdef to take a look at the definition of \parbox then to take a look at \@iiiparbox which seemed to involve \vtop boxes, which I know will not allow for footnotes.
    – A Feldman
    Jun 13, 2016 at 3:32

1 Answer 1

6

My understanding now is that \insert\footins{...} will cause anything written inside the group to wind up in \box\footins but only AFTER the page is output. Also, \global\insert is not allowed.

The macro \global@insert doesn't precisely mimic the \insert "migration" in that the contents show up immediately, but it seems to work good enough for footnotes.

\documentclass{article}
\usepackage{blindtext}

\makeatletter
\newcommand{\global@insert}[2]% #1=box number, #2=vertical list
{\bgroup
  \setbox\@tempboxa=\box#1
  \global\setbox#1=\vbox{\unvbox\@tempboxa #2}
\egroup}

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

\begin{document}
normal\footnote{normal}

\begin{enumerate}
\item\parbox{1in}{parbox\footnote{parbox - \blindtext}}
\item test
\end{enumerate}

check counter\footnote{after}

\end{document}

This approach uses normal footnotes outside the \parbox, but requires a bit more work. Basically it works like \footnotemark and \footnotetext except that you don't have to keep track of which mark goes with which text.

Inside the \parbox you need to add \globalfootnotestrue to switch modes. After the parbox you need to add \copyinserts to move the footnotes from \parboxins to \footins. Since \parbox is unbreakable, you don't have to worry about winding up on the wrong page.

\documentclass{article}
\usepackage{blindtext}

\makeatletter
\newsavebox{\parboxins}
\newif\ifglobalfootnotes

\newcommand{\copyinserts}{\insert\footins{\unvbox\parboxins}%
  \globalfootnotesfalse}% should be redundant

\newcommand{\global@insert}[2]% #1=box number, #2=vertical list
{\bgroup
  \setbox\@tempboxa=\box#1
  \global\setbox#1=\vbox{\unvbox\@tempboxa #2}
\egroup}

\long\def\@footnotetext#1{%
 \protected@edef\@currentlabel{\csname p@footnote\endcsname\@thefnmark}%
 \ifglobalfootnotes \global@insert\parboxins{\@@footnotetext{#1}}%
 \else \insert\footins{\@@footnotetext{#1}}%
 \fi}

\long\def\@@footnotetext#1{%
 \color@begingroup
 \reset@font\footnotesize
 \interlinepenalty\interfootnotelinepenalty
 \splittopskip\footnotesep
 \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
 \hsize\columnwidth \@parboxrestore
 \@makefntext{\rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
 \color@endgroup}
\makeatother

\begin{document}
normal\footnote{normal}

\begin{enumerate}
\item \parbox[t]{\linewidth}{\globalfootnotestrue
  parbox\footnote{parbox - \blindtext}}%
\copyinserts
\item test
\end{enumerate}

check counter\footnote{after}

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .