Skip to content

Commit

Permalink
Allow hyperlinked footnotes in tables and topics of pdf output
Browse files Browse the repository at this point in the history
Using an updated footnote.sty package, it is possible to have
footnotes in tables (be it tabular, tabulary, threeparttable,
or longtable) without \footnotemark/\footnotetext which anyhow
do not create working hyper-footnotes.

This partially reverts commit 9b958b6 (Fix sphinx-doc#2291). The fixes to
footnote.sty to make it hyperref aware are in the small shipped
"footnotehyper-sphinx" package.
  • Loading branch information
jfbu committed Apr 21, 2016
1 parent becc547 commit ea954b1
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 31 deletions.
67 changes: 67 additions & 0 deletions sphinx/texinputs/footnotehyper-sphinx.sty
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{footnotehyper-sphinx}%
[2016/04/22 v0.9d-sphinx hyperref aware footnote.sty (JFB)]
\DeclareOption*{}%
\ProcessOptions\relax
%%
%% Package: footnotehyper-sphinx
%% Version: 0.9d-sphinx (2016/04/22)
%% License: LPPL 1.3c (http://www.latex-project.org/lppl/lppl-1-3c.txt)
%% Copyright (C) 2016 Jean-Francois Burnol <jfbu at free dot fr>.
%%
%% Trimmed variant of footnotehyper v0.9d (2016/04/21)
%% Sphinx does not use the `footnote` environment defined by footnote.sty. The
%% loading of footnote.sty may crash if the user has other footnote related
%% packages loaded first. Thus to make sure no such crash can happen, we
%% deactivate this construction of footnote environment and take care only
%% of \footnote command.
\let\FNHS@@makefntext\@makefntext\let\@makefntext\@firstofone
\let\FNHS@endfootnote\endfootnote % probably \undefined
\let\FNHS@endfootnotetext\endfootnotetext
\RequirePackage{footnote}\relax
\let\@makefntext\FNHS@@makefntext
\let\footnote \fn@latex@@footnote
\let\footnotetext\fn@latex@@footnotetext
\let\endfootnote \FNHS@endfootnote
\let\endfootnotetext\FNHS@endfootnotetext
\def\fn@fntext {\ifx\ifmeasuring@\undefined\expandafter\@secondoftwo
\else\expandafter\@firstofone\fi
{\ifmeasuring@\expandafter\@gobbletwo\fi}%
\FNHS@fn@fntext }%
\long\def\FNHS@fn@fntext #1{\global\setbox\fn@notes\vbox
{\unvbox\fn@notes
\fn@startnote
\@makefntext
{\rule\z@\footnotesep\ignorespaces
\ifHy@nesting\expandafter\ltx@firstoftwo
\else\expandafter\ltx@secondoftwo
\fi
{\expandafter\hyper@@anchor\expandafter{\Hy@footnote@currentHref}{#1}}%
{\Hy@raisedlink
{\expandafter\hyper@@anchor\expandafter{\Hy@footnote@currentHref}%
{\relax}}%
\let\@currentHref\Hy@footnote@currentHref
\let\@currentlabelname\@empty
#1}%
\@finalstrut\strutbox }%
\fn@endnote }%
}%
\def\spewnotes {\endgroup
\if@savingnotes\else\ifvoid\fn@notes\else
\begingroup\let\@makefntext\@empty
\let\@finalstrut\@gobble
\let\rule\@gobbletwo
\H@@footnotetext{\unvbox\fn@notes}%
\endgroup\fi\fi
}%
\let\endsavenotes\spewnotes
\def\fn@endnote {\color@endgroup}%
\AtBeginDocument {%
\let\fn@latex@@footnote \footnote
\let\fn@latex@@footnotetext\footnotetext
\let\footnote \FNHS@fn@footnote
\let\footnotetext\FNHS@fn@footnotetext
}%
\endinput
%%
%% End of file `footnotehyper-sphinx.sty'.
37 changes: 17 additions & 20 deletions sphinx/texinputs/sphinx.sty
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@
\RequirePackage{fancyvrb}
% For table captions.
\RequirePackage{threeparttable}
% Handle footnotes in tables.
\RequirePackage{footnote}
% Handle footnotes in tables; also for topic and warning blocks.
\RequirePackage{footnotehyper-sphinx}
% longtable is already able to handle footnotes in a hyperref compatible way
\makesavenoteenv{tabulary}
\makesavenoteenv{tabular}
\makesavenoteenv{threeparttable}
% For floating figures in the text.
\RequirePackage{wrapfig}
% Separate paragraphs by space by default.
Expand Down Expand Up @@ -313,9 +316,12 @@
% imitate closely the layout from Sphinx <= 1.4.1; the \FrameHeightAdjust
% will put top part of frame on this baseline.
\def\FrameHeightAdjust {\baselineskip}%
% use package footnote to handle footnotes
\savenotes
\trivlist\item\noindent
% use a minipage if we are already inside a framed environment
\ifSphinx@inframed\begin{minipage}{\linewidth}\fi
% use minipage* for global footnotes
\ifSphinx@inframed\begin{minipage*}{\linewidth}\fi
\MakeFramed {\Sphinx@inframedtrue
% framed.sty puts into "\width" the added width (=2shadowsep+2shadowrule)
% adjust \hsize to what the contents must use
Expand All @@ -326,24 +332,19 @@
% itemize/enumerate are therein typeset more tightly, we want to keep
% that). We copy-paste from LaTeX source code but don't do a real minipage.
\@pboxswfalse
% for footnotes, but Sphinx inactivates footnotes in topics
\def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@
\let\@footnotetext\@mpfootnotetext
\let\@listdepth\@mplistdepth \@mplistdepth\z@
\@minipagerestore
\@setminipage
}%
}%
{% insert the "endminipage" code
\par\unskip
% handle (currently non existing) minipage style footnotes
\ifvoid\@mpfootins\else
\vskip\skip\@mpfootins\normalcolor\footnoterule\unvbox\@mpfootins
\fi
\@minipagefalse
\endMakeFramed
\ifSphinx@inframed\end{minipage}\fi
\ifSphinx@inframed\end{minipage*}\fi
\endtrivlist
% output the stored footnotes
\spewnotes
}

% \moduleauthor{name}{email}
Expand Down Expand Up @@ -423,31 +424,27 @@
\def\FrameCommand##1{\hskip\@totalleftmargin
\fboxsep\FrameSep \fboxrule\FrameRule\fbox{##1}%
\hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
\savenotes
% use a minipage if we are already inside a framed environment
\ifSphinx@inframed
\noindent\begin{minipage}{\linewidth}
\noindent\begin{minipage*}{\linewidth}
\else
\vspace{\parskip}
\fi
\MakeFramed {\Sphinx@inframedtrue
\advance\hsize-\width \@totalleftmargin\z@ \linewidth\hsize
% minipage initialization copied from LaTeX source code.
\@pboxswfalse
% for footnotes
\def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@
\let\@footnotetext\@mpfootnotetext
\let\@listdepth\@mplistdepth \@mplistdepth\z@
\@minipagerestore
\@setminipage }%
}
\newcommand{\py@endheavybox}{%
\par\unskip
% handles footnotes
\ifvoid\@mpfootins\else
\vskip\skip\@mpfootins\normalcolor\footnoterule\unvbox\@mpfootins
\fi
\@minipagefalse\endMakeFramed
\ifSphinx@inframed\end{minipage}\fi
\ifSphinx@inframed\end{minipage*}\fi
% set footnotes at bottom of page
\spewnotes
% arrange for similar spacing below frame as for "light" boxes.
\vskip .4\baselineskip
}
Expand Down
16 changes: 5 additions & 11 deletions sphinx/writers/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,11 @@ def expand_show_urls(self):
if node.astext() != uri:
index = node.parent.index(node)
if show_urls == 'footnote':
if list(traverse_parent(node, nodes.topic)):
# should not expand references in topics
pass
else:
footnote_nodes = self.create_footnote(uri)
for i, fn in enumerate(footnote_nodes):
node.parent.insert(index + i + 1, fn)

self.expanded = True
footnote_nodes = self.create_footnote(uri)
for i, fn in enumerate(footnote_nodes):
node.parent.insert(index + i + 1, fn)

self.expanded = True
else: # all other true values (b/w compat)
textnode = nodes.Text(" (%s)" % uri)
node.parent.insert(index + 1, textnode)
Expand Down Expand Up @@ -964,7 +960,6 @@ def visit_table(self, node):
self.tableheaders = []
# Redirect body output until table is finished.
self.pushbody(self.tablebody)
self.restrict_footnote(node)

def depart_table(self, node):
if self.table.rowcount > 30:
Expand Down Expand Up @@ -1036,7 +1031,6 @@ def depart_table(self, node):
self.body.append(endmacro)
if not self.table.longtable and self.table.caption is not None:
self.body.append('\\end{threeparttable}\n\n')
self.unrestrict_footnote(node)
self.table = None
self.tablebody = None

Expand Down

0 comments on commit ea954b1

Please sign in to comment.