LaTeX footnotes from caption titles now hyperlinked in PDF

This is fifth item of #2616
This commit is contained in:
jfbu 2021-02-05 14:56:23 +01:00
parent a39b5f08e9
commit a0b0a08e38
3 changed files with 41 additions and 17 deletions

View File

@ -325,8 +325,17 @@
% some extras for Sphinx :
% \sphinxfootnotemark: usable in section titles and silently removed from TOCs.
\def\sphinxfootnotemark [#1]%
{\ifx\thepage\relax\else\protect\spx@opt@BeforeFootnote
\protect\footnotemark[#1]\fi}%
{\ifx\thepage\relax\else\sphinxfootref{#1}\fi}%
% \sphinxfootref: almost same as \footref from footmisc package as
% re-defined by hyperref:
% - \spx@opt@BeforeFootnote is from BeforeFootnote sphinxsetup option
% - 'fn:' prefix is output by LaTeX writer in \label of footnotetext
\protected\def\sphinxfootref#1{\spx@opt@BeforeFootnote
\begingroup
\unrestored@protected@xdef\@thefnmark{\ref{fn:#1}}% #1 = number
\endgroup
\H@@footnotemark
}%
\AtBeginDocument{%
% let hyperref less complain
\pdfstringdefDisableCommands{\def\sphinxfootnotemark [#1]{}}%

View File

@ -1738,7 +1738,8 @@ class LaTeXTranslator(SphinxTranslator):
def visit_footnotetext(self, node: Element) -> None:
label = cast(nodes.label, node[0])
self.body.append('%%\n\\begin{footnotetext}[%s]'
'\\sphinxAtStartFootnote\n' % label.astext())
'\\phantomsection\\label{fn:%s}%%\n'
'\\sphinxAtStartFootnote\n' % (label.astext(), label.astext()))
def depart_footnotetext(self, node: Element) -> None:
# the \ignorespaces in particular for after table header use

View File

@ -732,9 +732,11 @@ def test_footnote(app, status, warning):
assert '\\sphinxcite{footnote:bar}' in result
assert ('\\bibitem[bar]{footnote:bar}\n\\sphinxAtStartPar\ncite\n') in result
assert '\\sphinxcaption{Table caption \\sphinxfootnotemark[4]' in result
assert ('\\hline%\n\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n'
assert ('\\hline%\n\\begin{footnotetext}[4]\\phantomsection\\label{fn:4}%\n'
'\\sphinxAtStartFootnote\n'
'footnote in table caption\n%\n\\end{footnotetext}\\ignorespaces %\n'
'\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n'
'\\begin{footnotetext}[5]\\phantomsection\\label{fn:5}%\n'
'\\sphinxAtStartFootnote\n'
'footnote in table header\n%\n\\end{footnotetext}\\ignorespaces '
'\n\\sphinxAtStartPar\n'
'VIDIOC\\_CROPCAP\n&\n\\sphinxAtStartPar\n') in result
@ -760,19 +762,23 @@ def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning):
assert '\\subsubsection*{The rubric title with a reference to {[}AuthorYear{]}}' in result
assert ('\\chapter{The section with a reference to \\sphinxfootnotemark[5]}\n'
'\\label{\\detokenize{index:the-section-with-a-reference-to}}'
'%\n\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n'
'%\n\\begin{footnotetext}[5]\\phantomsection\\label{fn:5}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in section\n%\n\\end{footnotetext}') in result
assert ('\\caption{This is the figure caption with a footnote to '
'\\sphinxfootnotemark[7].}\\label{\\detokenize{index:id29}}\\end{figure}\n'
'%\n\\begin{footnotetext}[7]\\sphinxAtStartFootnote\n'
'%\n\\begin{footnotetext}[7]\\phantomsection\\label{fn:7}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in caption\n%\n\\end{footnotetext}') in result
assert ('\\sphinxcaption{footnote \\sphinxfootnotemark[8] in '
'caption of normal table}\\label{\\detokenize{index:id30}}') in result
assert ('\\caption{footnote \\sphinxfootnotemark[9] '
'in caption \\sphinxfootnotemark[10] of longtable\\strut}') in result
assert ('\\endlastfoot\n%\n\\begin{footnotetext}[9]\\sphinxAtStartFootnote\n'
assert ('\\endlastfoot\n%\n\\begin{footnotetext}[9]\\phantomsection\\label{fn:9}%\n'
'\\sphinxAtStartFootnote\n'
'Foot note in longtable\n%\n\\end{footnotetext}\\ignorespaces %\n'
'\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n'
'\\begin{footnotetext}[10]\\phantomsection\\label{fn:10}%\n'
'\\sphinxAtStartFootnote\n'
'Second footnote in caption of longtable\n') in result
assert ('This is a reference to the code\\sphinxhyphen{}block in the footnote:\n'
'{\\hyperref[\\detokenize{index:codeblockinfootnote}]'
@ -812,7 +818,8 @@ def test_latex_show_urls_is_inline(app, status, warning):
assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx} (http://sphinx\\sphinxhyphen{}doc.org/)' in result
assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n'
'\\begin{footnotetext}[4]\\phantomsection\\label{fn:4}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde} '
'(http://sphinx\\sphinxhyphen{}doc.org/\\textasciitilde{}test/)') in result
@ -820,7 +827,8 @@ def test_latex_show_urls_is_inline(app, status, warning):
'(http://sphinx\\sphinxhyphen{}doc.org/)}] '
'\\leavevmode\n\\sphinxAtStartPar\nDescription' in result)
assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] '
'\\leavevmode%\n\\begin{footnotetext}[6]\\sphinxAtStartFootnote\n'
'\\leavevmode%\n\\begin{footnotetext}[6]\\phantomsection\\label{fn:6}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces '
'\n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist} '
@ -861,7 +869,8 @@ def test_latex_show_urls_is_footnote(app, status, warning):
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n\\end{footnote}') in result
assert ('Third footnote: %\n\\begin{footnote}[6]\\sphinxAtStartFootnote\n'
'Third \\sphinxfootnotemark[7]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[7]\\sphinxAtStartFootnote\n'
'\\begin{footnotetext}[7]\\phantomsection\\label{fn:7}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote inside footnote\n%\n'
'\\end{footnotetext}\\ignorespaces') in result
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}'
@ -869,16 +878,19 @@ def test_latex_show_urls_is_footnote(app, status, warning):
'\\sphinxnolinkurl{http://sphinx-doc.org/~test/}\n%\n\\end{footnote}') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}'
'{URL in term}\\sphinxfootnotemark[9]}] '
'\\leavevmode%\n\\begin{footnotetext}[9]\\sphinxAtStartFootnote\n'
'\\leavevmode%\n\\begin{footnotetext}[9]\\phantomsection\\label{fn:9}%\n'
'\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n'
'\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{Footnote in term \\sphinxfootnotemark[11]}] '
'\\leavevmode%\n\\begin{footnotetext}[11]\\sphinxAtStartFootnote\n'
'\\leavevmode%\n\\begin{footnotetext}[11]\\phantomsection\\label{fn:11}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces '
'\n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}'
'\\sphinxfootnotemark[10]}] '
'\\leavevmode%\n\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n'
'\\leavevmode%\n\\begin{footnotetext}[10]\\phantomsection\\label{fn:10}%\n'
'\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n'
'\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result
assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result)
@ -914,13 +926,15 @@ def test_latex_show_urls_is_no(app, status, warning):
assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx}' in result
assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n'
'\\begin{footnotetext}[4]\\phantomsection\\label{fn:4}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result
assert '\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}' in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term}}] '
'\\leavevmode\n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] '
'\\leavevmode%\n\\begin{footnotetext}[6]\\sphinxAtStartFootnote\n'
'\\leavevmode%\n\\begin{footnotetext}[6]\\phantomsection\\label{fn:6}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces '
'\n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}}] '