1

I have this issue with some footnotes in some tcolorboxes. I would like to have footnotes displayed at the bottom of the page where the footnotemark is located. Apparently it is something difficult to obtain when the tcolorbox is very long and splitted over 2 or 3 pages (they are breakable tcolorboxes). The problem is quite similar to

Decorate environment with vertical bars or background but keeping footnote default behavior (ie text on the correct page)

(In first place I wanted to comment on this post but I'm too "newbie" to do that (need some reputation points...)).

Apparently the core of the problem is in the LaTeX algorithm that places floats, and from the following posts one may think that my issue has no solution.

\tcolorbox: footnote on page on which there are

However, some years later I'm wondering if someone could find a kind of TeX patch to make footnotes placement like requested, for instance by making them have a sort of priority over other kind of float objects?

other similar question: footnote in a tcolorbox environment

The tex patch in my preamble was found on this forum (Tcolorbox - footnotes at end of each page) to make footnotes inside the tcolorbox appearing as regular footnotes, that is to say outside of the tcolorbox.

Any idea?

Regards, Eric

\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[ % Define your margins here
    a4paper,
    left=2.5cm,
    right=2.5cm,
    bottom=2.5cm,
    textheight=650pt,
    footskip=50pt
    ]{geometry}

\usepackage{lipsum,changepage}
\usepackage[breakable,hooks]{tcolorbox}

\makeatletter
% restore footnote internals to those in normal page, not minipage
\def\tcb@restore@footnote{%
  \def\@mpfn{footnote}%
  \def\thempfn{\arabic{footnote}}%
  \let\@footnotetext\tcb@footnote@collect
}

% collect footnote text
\long\def\tcb@footnote@collect#1{%
  % expand \@thefnmark before appending before app to \tcb@footnote@acc
  \expandafter\gappto\expandafter\tcb@footnote@acc\expandafter{%
    \expandafter\footnotetext\expandafter[\@thefnmark]{#1}%
  }%
}

\def\tcb@footnote@use{%
  \tcb@footnote@acc
  \global\let\tcb@footnote@acc\@empty
}
\global\let\tcb@footnote@acc\@empty

\tcbset{
  % restore for every box
  every box/.style={
    before upper pre=\tcb@restore@footnote
  },
  % use for layer 1 boxes only
  every box on layer 1/.append style={
    after app=\tcb@footnote@use
  }
}
\makeatother

\begin{document}

\begin{tcolorbox}[breakable,
                  colback=blue!7!white,
                  colframe=blue!75!black,
                  title=Protocole détaillé:
                 ]

\lipsum[1-4]
Nous avons mis en suspension 
   le pellet\footnote{Egalement appelé culot en français, il correspond au fond 
  du tube dans lequel les diatomées se sont agglomérées.} 
  \lipsum[1-1]
 Nous avons ensuite introduit le contenu dans des tubes à cryogénisation pour faire 
 un shock freeze\footnote{Méthode qui consiste à plonger brusquement les tubes 
 dans de l'azote liquide afin de détériorer les membranes.}. 
Nous avons ajouté ensuite du $\beta$-mercaptoéthanol et 
du Tween qui servent à lyser\footnote{Ouvrir, voire détruire les membranes des cellules.} 
\lipsum[1-5]
\end{tcolorbox}

\end{document}
3
  • 1
    I believe the way a breakable tcolorbox works is the entire text is put into one column which is then broken using \vsplit, so there is really no way to figure out what page the footnote is from, Well, you could write them to the aux file, but tcolorbox would need some serious surgery to use them. Aug 19 '21 at 14:18
  • You might be able to put footnotes outside the tcolorbox using everypage (or \AddToHook). Aug 19 '21 at 14:30
  • Hi John, thanks for your comments. I have no clue of how to use this everypage package in fact, Do you have an example? From your explanation I understand that solving this issue may require a rather complex patch to apply to the existing tcolorbox package. Basically one would need to fill an array of the footnotes positions within the box while collecting its content, so that when the box is split one can identify afterwards which footnote is associated to each part of the box. But I'm not a TeX expert at all unfortunately... Aug 19 '21 at 20:19
0

This writes the footnotes to the aux file, so it takes two passes. At the end of every page it checks for any footnotes on the next page and adds them to the queue. They may appear out of order wrt normal footnotes (outside tcolorbox).

Another possible problem is if a footnote is placed near the bottom of the page, in which case the footnote and its mark will cycle, never being on the same page. Use a separate \footnotemark and \footnotetext to force the placement.

\documentclass[12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[ % Define your margins here
    a4paper,
    left=2.5cm,
    right=2.5cm,
    bottom=2.5cm,
    textheight=650pt,
    footskip=50pt
    ]{geometry}

\usepackage{lipsum,changepage}
\usepackage[breakable,hooks]{tcolorbox}

\newif\iffootaux
\newcounter{footaux}% for \csname
\newcounter{auxpage}% to handle frontmatter etc.
\setcounter{auxpage}{1}

\makeatletter
\tcbset{every box/.style={before upper app=\tcb@footnote@setup}}

\def\tcb@footnote@setup{\let\footnotetext=\footaux
  \let\footnote=\footnoteaux}
  
\def\footnoteaux{\@ifnextchar[\@xfootnoteaux{\stepcounter{footnote}%
  \footnotemark[\thefootnote]\@footaux[\thefootnote]}}
  
\def\@xfootnoteaux[#1]{\footnotemark[#1]\@footaux[#1]}

\def\footaux{\@ifnextchar[\@footaux{\@footaux[\thefootnote]}}
\def\@footaux[#1]#2{\protected@write{\@auxout}{\let\theauxpage\relax}{\string\newfootnote{\theauxpage}{#1}{#2}}}

\newcommand{\newfootnote}[3]{% #1 = \theauxpage, #2 = \thefoontnote, #3 = text
  \ifnum#1=1\relax
    \footnotetext[#2]{#3}%
  \else
    \stepcounter{footaux}%
    \expandafter\xdef\csname footauxpage\thefootaux\endcsname{#1}%
    \expandafter\xdef\csname footauxnumber\thefootaux\endcsname{#2}%
    \expandafter\protected@xdef\csname footauxtext\thefootaux\endcsname{#3}%
  \fi}

% to run at the end of every page (debug version)
\newcommand{\addfootaux}{\loop
  \@ifundefined{footauxpage\thefootaux}{\footauxfalse}{%
    \count1=\csname footauxpage\thefootaux\endcsname\relax
    \advance\count1 by -1
    \ifnum\count1=\value{auxpage}%
      \expandafter\let\expandafter\footauxnumber\csname footauxnumber\thefootaux\endcsname
      \expandafter\let\expandafter\footauxtext\csname footauxtext\thefootaux\endcsname
      \footnotetext[\footauxnumber]{\footauxtext}%
      \footauxtrue
    \else
      \footauxfalse
    \fi}
  \iffootaux
    \global\expandafter\let\csname footauxpage\thefootaux\endcsname\relax
    \global\expandafter\let\csname footauxnumber\thefootaux\endcsname\relax
    \global\expandafter\let\csname footauxtext\thefootaux\endcsname\relax
    \stepcounter{footaux}%
  \repeat
\stepcounter{auxpage}}
\makeatother

\AtBeginDocument{\setcounter{footaux}{1}}% reset counter after \newfootnote
\AddToHook{shipout/after}{\addfootaux}

\begin{document}

\begin{tcolorbox}[breakable,
                  colback=blue!7!white,
                  colframe=blue!75!black,
                  title=Protocole détaillé:
                 ]
\let\footnotetext=\footaux
\lipsum[1-4]
Nous avons mis en suspension 
   le pellet\footnote{Egalement appelé culot en français, il correspond au fond 
  du tube dans lequel les diatomées se sont agglomérées.} 
  \lipsum[1-1]
 Nous avons ensuite introduit le contenu dans des tubes à cryogénisation pour faire 
 un shock freeze\footnote{Méthode qui consiste à plonger brusquement les tubes 
 dans de l'azote liquide afin de détériorer les membranes.}. 
Nous avons ajouté ensuite du $\beta$-mercaptoéthanol et 
du Tween qui servent à lyser\footnote{Ouvrir, voire détruire les membranes des cellules.} 
\lipsum[1-5]
\end{tcolorbox}

\end{document}
3
  • John, your solution is wonderfull!! In fact I have to process a document of about 45 pages with many tcolorboxes and footnotes sometimes inside tcoloboxes, sometimes outside. I had to perform several trials before finding the "correct" protocol, which seems to include at first a removal of the existing aux file, and type the \let\footnotetext=\footaux command inside the first tcolorbox encountered (indeed it seems to be sufficient to put this command in the first tcolorbox containing a footnote). In the end all the footnotes are correctly place on the same page as the footnotemark. Thanks!!! Aug 21 '21 at 21:10
  • Just to be complete, on the large document I had to process I had to perform 3 passes to get the correct placement of the last footnotes. But it's not a big deal. Aug 21 '21 at 21:18
  • I just played with the \tcbset until it worked. I have no idea which key would be best (the manual wasn't much help). And yes, adding footnotes in the second pass may move the page on which the footnote occurs. Aug 22 '21 at 0:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.