Merge pull request #8832 from jfbu/latex_hyperlinked_caption_footnotes_on_3.x

Latex hyperlinked caption footnotes on 3.x
This commit is contained in:
Jean-François B 2021-02-09 17:45:41 +01:00 committed by GitHub
commit a164d4c12c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 147 additions and 24 deletions

View File

@ -118,6 +118,9 @@ Bugs fixed
* #8683: :confval:`html_last_updated_fmt` generates wrong time zone for %Z * #8683: :confval:`html_last_updated_fmt` generates wrong time zone for %Z
* #1112: ``download`` role creates duplicated copies when relative path is * #1112: ``download`` role creates duplicated copies when relative path is
specified specified
* #2616 (fifth item): LaTeX: footnotes from captions are not clickable,
and for manually numbered footnotes only first one with same number is
an hyperlink
* #7576: LaTeX with French babel and memoir crash: "Illegal parameter number * #7576: LaTeX with French babel and memoir crash: "Illegal parameter number
in definition of ``\FNH@prefntext``" in definition of ``\FNH@prefntext``"
* #8055: LaTeX (docs): A potential display bug with the LaTeX generation step * #8055: LaTeX (docs): A potential display bug with the LaTeX generation step

View File

@ -325,8 +325,58 @@
% some extras for Sphinx : % some extras for Sphinx :
% \sphinxfootnotemark: usable in section titles and silently removed from TOCs. % \sphinxfootnotemark: usable in section titles and silently removed from TOCs.
\def\sphinxfootnotemark [#1]% \def\sphinxfootnotemark [#1]%
{\ifx\thepage\relax\else\protect\spx@opt@BeforeFootnote {\ifx\thepage\relax\else\sphinxfootref{#1}\fi}%
\protect\footnotemark[#1]\fi}% % \sphinxfootref:
% - \spx@opt@BeforeFootnote is from BeforeFootnote sphinxsetup option
% - \ref:
% the latex.py writer inserts a \phantomsection\label{<scope>.<num>}
% whenever
% - the footnote was explicitly numbered in sources,
% - or it was in restrained context and is rendered using footnotetext
%
% These are the two types of footnotes that \sphinxfootnotemark must
% handle. But for explicitly numbered footnotes the same number
% can be found in document. So a secondary part in <scope> is updated
% at each novel such footnote to know what is the target from then on
% for \sphinxfootnotemark and already encountered [1], or [2],...
%
% LaTeX package varioref is not supported by hyperref (from its doc: "There
% are too many problems with varioref. Nobody has time to sort them out.
% Therefore this package is now unsupported.") So we will simply use our own
% macros to access the page number of footnote text and decide whether to print
% it. \pagename is internationalized by latex-babel.
\def\spx@thefnmark#1#2{%
% #1=label for reference, #2=page where footnote was printed
\ifx\spx@tempa\spx@tempb
% same page
#1%
\else
\sphinxthefootnotemark{#1}{#2}%
\fi
}%
\def\sphinxfootref@get #1#2#3#4#5\relax{%
\def\sphinxfootref@label{#1}%
\def\sphinxfootref@page {#2}%
\def\sphinxfootref@Href {#4}%
}%
\protected\def\sphinxfootref#1{% #1 always explicit number in Sphinx usage
\spx@opt@BeforeFootnote
\ltx@ifundefined{r@\thesphinxscope.#1}%
{\gdef\@thefnmark{?}\H@@footnotemark}%
{\expandafter\expandafter\expandafter\sphinxfootref@get
\csname r@\thesphinxscope.#1\endcsname\relax
\edef\spx@tempa{\thepage}\edef\spx@tempb{\sphinxfootref@page}%
\protected@xdef\@thefnmark{\spx@thefnmark{\sphinxfootref@label}{\sphinxfootref@page}}%
\let\spx@@makefnmark\@makefnmark
\def\@makefnmark{%
\hyper@linkstart{link}{\sphinxfootref@Href}%
\spx@@makefnmark
\hyper@linkend
}%
\H@@footnotemark
\let\@makefnmark\spx@@makefnmark
}%
}%
\AtBeginDocument{% \AtBeginDocument{%
% let hyperref less complain % let hyperref less complain
\pdfstringdefDisableCommands{\def\sphinxfootnotemark [#1]{}}% \pdfstringdefDisableCommands{\def\sphinxfootnotemark [#1]{}}%

View File

@ -847,6 +847,28 @@
%% FOOTNOTES %% FOOTNOTES
% %
% Support scopes for footnote numbering
\newcounter{sphinxscope}
\newcommand{\sphinxstepscope}{\stepcounter{sphinxscope}}
% Explictly numbered footnotes may be referred to, and for this to be
% clickable we need to have only one target. So we will step this at each
% explicit footnote and let \thesphinxscope take it into account
\newcounter{sphinxexplicit}
\newcommand{\sphinxstepexplicit}{\stepcounter{sphinxexplicit}}
% Some babel/polyglossia languages fiddle with \@arabic, so let's be extra
% cautious and redefine \thesphinxscope with \number not \@arabic.
% Memo: we expect some subtle redefinition of \thesphinxscope to be a part of page
% scoping for footnotes, when we shall implement it.
\renewcommand{\thesphinxscope}{\number\value{sphinxscope}.\number\value{sphinxexplicit}}
\newcommand\sphinxthefootnotemark[2]{%
% this is used to make reference to an explicitly numbered footnote not on same page
% #1=label of footnote text, #2=page number where footnote text was printed
\ifdefined\pagename
\pagename\space#2, % <- space
\else
p. #2, % <- space
\fi #1% no space
}
% Support large numbered footnotes in minipage % Support large numbered footnotes in minipage
% But now obsolete due to systematic use of \savenotes/\spewnotes % But now obsolete due to systematic use of \savenotes/\spewnotes
% when minipages are in use in the various macro definitions next. % when minipages are in use in the various macro definitions next.

View File

@ -846,11 +846,16 @@ class LaTeXTranslator(SphinxTranslator):
def visit_footnote(self, node: Element) -> None: def visit_footnote(self, node: Element) -> None:
self.in_footnote += 1 self.in_footnote += 1
label = cast(nodes.label, node[0]) label = cast(nodes.label, node[0])
if 'auto' not in node.attributes:
self.body.append('\\sphinxstepexplicit ')
if self.in_parsed_literal: if self.in_parsed_literal:
self.body.append('\\begin{footnote}[%s]' % label.astext()) self.body.append('\\begin{footnote}[%s]' % label.astext())
else: else:
self.body.append('%\n') self.body.append('%\n')
self.body.append('\\begin{footnote}[%s]' % label.astext()) self.body.append('\\begin{footnote}[%s]' % label.astext())
if 'auto' not in node:
self.body.append('\\phantomsection'
'\\label{\\thesphinxscope.%s}%%\n' % label.astext())
self.body.append('\\sphinxAtStartFootnote\n') self.body.append('\\sphinxAtStartFootnote\n')
def depart_footnote(self, node: Element) -> None: def depart_footnote(self, node: Element) -> None:
@ -1749,7 +1754,9 @@ class LaTeXTranslator(SphinxTranslator):
label = cast(nodes.label, node[0]) label = cast(nodes.label, node[0])
self.body.append('%\n') self.body.append('%\n')
self.body.append('\\begin{footnotetext}[%s]' self.body.append('\\begin{footnotetext}[%s]'
'\\sphinxAtStartFootnote\n' % label.astext()) '\\phantomsection\\label{\\thesphinxscope.%s}%%\n'
% (label.astext(), label.astext()))
self.body.append('\\sphinxAtStartFootnote\n')
def depart_footnotetext(self, node: Element) -> None: def depart_footnotetext(self, node: Element) -> None:
# the \ignorespaces in particular for after table header use # the \ignorespaces in particular for after table header use

View File

@ -724,7 +724,8 @@ def test_footnote(app, status, warning):
print(result) print(result)
print(status.getvalue()) print(status.getvalue())
print(warning.getvalue()) print(warning.getvalue())
assert ('\\begin{footnote}[1]\\sphinxAtStartFootnote\nnumbered\n%\n' assert ('\\sphinxstepexplicit %\n\\begin{footnote}[1]\\phantomsection'
'\\label{\\thesphinxscope.1}%\n\\sphinxAtStartFootnote\nnumbered\n%\n'
'\\end{footnote}') in result '\\end{footnote}') in result
assert ('\\begin{footnote}[2]\\sphinxAtStartFootnote\nauto numbered\n%\n' assert ('\\begin{footnote}[2]\\sphinxAtStartFootnote\nauto numbered\n%\n'
'\\end{footnote}') in result '\\end{footnote}') in result
@ -732,9 +733,13 @@ def test_footnote(app, status, warning):
assert '\\sphinxcite{footnote:bar}' in result assert '\\sphinxcite{footnote:bar}' in result
assert ('\\bibitem[bar]{footnote:bar}\n\\sphinxAtStartPar\ncite\n') in result assert ('\\bibitem[bar]{footnote:bar}\n\\sphinxAtStartPar\ncite\n') in result
assert '\\sphinxcaption{Table caption \\sphinxfootnotemark[4]' 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{\\thesphinxscope.4}%\n'
'\\sphinxAtStartFootnote\n'
'footnote in table caption\n%\n\\end{footnotetext}\\ignorespaces %\n' 'footnote in table caption\n%\n\\end{footnotetext}\\ignorespaces %\n'
'\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n' '\\begin{footnotetext}[5]'
'\\phantomsection\\label{\\thesphinxscope.5}%\n'
'\\sphinxAtStartFootnote\n'
'footnote in table header\n%\n\\end{footnotetext}\\ignorespaces ' 'footnote in table header\n%\n\\end{footnotetext}\\ignorespaces '
'\n\\sphinxAtStartPar\n' '\n\\sphinxAtStartPar\n'
'VIDIOC\\_CROPCAP\n&\n\\sphinxAtStartPar\n') in result 'VIDIOC\\_CROPCAP\n&\n\\sphinxAtStartPar\n') in result
@ -760,19 +765,27 @@ 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 '\\subsubsection*{The rubric title with a reference to {[}AuthorYear{]}}' in result
assert ('\\chapter{The section with a reference to \\sphinxfootnotemark[5]}\n' assert ('\\chapter{The section with a reference to \\sphinxfootnotemark[5]}\n'
'\\label{\\detokenize{index:the-section-with-a-reference-to}}' '\\label{\\detokenize{index:the-section-with-a-reference-to}}'
'%\n\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n' '%\n\\begin{footnotetext}[5]'
'\\phantomsection\\label{\\thesphinxscope.5}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in section\n%\n\\end{footnotetext}') in result 'Footnote in section\n%\n\\end{footnotetext}') in result
assert ('\\caption{This is the figure caption with a footnote to ' assert ('\\caption{This is the figure caption with a footnote to '
'\\sphinxfootnotemark[7].}\\label{\\detokenize{index:id29}}\\end{figure}\n' '\\sphinxfootnotemark[7].}\\label{\\detokenize{index:id29}}\\end{figure}\n'
'%\n\\begin{footnotetext}[7]\\sphinxAtStartFootnote\n' '%\n\\begin{footnotetext}[7]'
'\\phantomsection\\label{\\thesphinxscope.7}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in caption\n%\n\\end{footnotetext}') in result 'Footnote in caption\n%\n\\end{footnotetext}') in result
assert ('\\sphinxcaption{footnote \\sphinxfootnotemark[8] in ' assert ('\\sphinxcaption{footnote \\sphinxfootnotemark[8] in '
'caption of normal table}\\label{\\detokenize{index:id30}}') in result 'caption of normal table}\\label{\\detokenize{index:id30}}') in result
assert ('\\caption{footnote \\sphinxfootnotemark[9] ' assert ('\\caption{footnote \\sphinxfootnotemark[9] '
'in caption \\sphinxfootnotemark[10] of longtable\\strut}') in result '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{\\thesphinxscope.9}%\n'
'\\sphinxAtStartFootnote\n'
'Foot note in longtable\n%\n\\end{footnotetext}\\ignorespaces %\n' 'Foot note in longtable\n%\n\\end{footnotetext}\\ignorespaces %\n'
'\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n' '\\begin{footnotetext}[10]'
'\\phantomsection\\label{\\thesphinxscope.10}%\n'
'\\sphinxAtStartFootnote\n'
'Second footnote in caption of longtable\n') in result 'Second footnote in caption of longtable\n') in result
assert ('This is a reference to the code\\sphinxhyphen{}block in the footnote:\n' assert ('This is a reference to the code\\sphinxhyphen{}block in the footnote:\n'
'{\\hyperref[\\detokenize{index:codeblockinfootnote}]' '{\\hyperref[\\detokenize{index:codeblockinfootnote}]'
@ -793,7 +806,9 @@ def test_latex_show_urls_is_inline(app, status, warning):
print(result) print(result)
print(status.getvalue()) print(status.getvalue())
print(warning.getvalue()) print(warning.getvalue())
assert ('Same footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n' assert ('Same footnote number \\sphinxstepexplicit %\n'
'\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n'
'\\sphinxAtStartFootnote\n'
'footnote in bar\n%\n\\end{footnote} in bar.rst') in result 'footnote in bar\n%\n\\end{footnote} in bar.rst') in result
assert ('Auto footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n' assert ('Auto footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n'
'footnote in baz\n%\n\\end{footnote} in baz.rst') in result 'footnote in baz\n%\n\\end{footnote} in baz.rst') in result
@ -807,12 +822,16 @@ def test_latex_show_urls_is_inline(app, status, warning):
'{\\sphinxcrossref{The section with a reference to }}}' in result) '{\\sphinxcrossref{The section with a reference to }}}' in result)
assert ('First footnote: %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n' assert ('First footnote: %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n'
'First\n%\n\\end{footnote}') in result 'First\n%\n\\end{footnote}') in result
assert ('Second footnote: %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n' assert ('Second footnote: \\sphinxstepexplicit %\n'
'\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n'
'\\sphinxAtStartFootnote\n'
'Second\n%\n\\end{footnote}') in result 'Second\n%\n\\end{footnote}') in result
assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx} (http://sphinx\\sphinxhyphen{}doc.org/)' in result assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx} (http://sphinx\\sphinxhyphen{}doc.org/)' in result
assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n' assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n' 'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n' '\\begin{footnotetext}[4]'
'\\phantomsection\\label{\\thesphinxscope.4}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result 'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde} ' assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde} '
'(http://sphinx\\sphinxhyphen{}doc.org/\\textasciitilde{}test/)') in result '(http://sphinx\\sphinxhyphen{}doc.org/\\textasciitilde{}test/)') in result
@ -820,7 +839,9 @@ def test_latex_show_urls_is_inline(app, status, warning):
'(http://sphinx\\sphinxhyphen{}doc.org/)}] ' '(http://sphinx\\sphinxhyphen{}doc.org/)}] '
'\\leavevmode\n\\sphinxAtStartPar\nDescription' in result) '\\leavevmode\n\\sphinxAtStartPar\nDescription' in result)
assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] ' assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] '
'\\leavevmode%\n\\begin{footnotetext}[6]\\sphinxAtStartFootnote\n' '\\leavevmode%\n\\begin{footnotetext}[6]'
'\\phantomsection\\label{\\thesphinxscope.6}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces ' 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces '
'\n\\sphinxAtStartPar\nDescription') in result '\n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist} ' assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist} '
@ -841,7 +862,9 @@ def test_latex_show_urls_is_footnote(app, status, warning):
print(result) print(result)
print(status.getvalue()) print(status.getvalue())
print(warning.getvalue()) print(warning.getvalue())
assert ('Same footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n' assert ('Same footnote number \\sphinxstepexplicit %\n'
'\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n'
'\\sphinxAtStartFootnote\n'
'footnote in bar\n%\n\\end{footnote} in bar.rst') in result 'footnote in bar\n%\n\\end{footnote} in bar.rst') in result
assert ('Auto footnote number %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n' assert ('Auto footnote number %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n'
'footnote in baz\n%\n\\end{footnote} in baz.rst') in result 'footnote in baz\n%\n\\end{footnote} in baz.rst') in result
@ -854,14 +877,18 @@ def test_latex_show_urls_is_footnote(app, status, warning):
'{\\sphinxcrossref{The section with a reference to }}}') in result '{\\sphinxcrossref{The section with a reference to }}}') in result
assert ('First footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n' assert ('First footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'First\n%\n\\end{footnote}') in result 'First\n%\n\\end{footnote}') in result
assert ('Second footnote: %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n' assert ('Second footnote: \\sphinxstepexplicit %\n'
'\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n'
'\\sphinxAtStartFootnote\n'
'Second\n%\n\\end{footnote}') in result 'Second\n%\n\\end{footnote}') in result
assert ('\\sphinxhref{http://sphinx-doc.org/}{Sphinx}' assert ('\\sphinxhref{http://sphinx-doc.org/}{Sphinx}'
'%\n\\begin{footnote}[4]\\sphinxAtStartFootnote\n' '%\n\\begin{footnote}[4]\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n\\end{footnote}') in result '\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n\\end{footnote}') in result
assert ('Third footnote: %\n\\begin{footnote}[6]\\sphinxAtStartFootnote\n' assert ('Third footnote: %\n\\begin{footnote}[6]\\sphinxAtStartFootnote\n'
'Third \\sphinxfootnotemark[7]\n%\n\\end{footnote}%\n' 'Third \\sphinxfootnotemark[7]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[7]\\sphinxAtStartFootnote\n' '\\begin{footnotetext}[7]'
'\\phantomsection\\label{\\thesphinxscope.7}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote inside footnote\n%\n' 'Footnote inside footnote\n%\n'
'\\end{footnotetext}\\ignorespaces') in result '\\end{footnotetext}\\ignorespaces') in result
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}' assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}'
@ -869,16 +896,22 @@ def test_latex_show_urls_is_footnote(app, status, warning):
'\\sphinxnolinkurl{http://sphinx-doc.org/~test/}\n%\n\\end{footnote}') in result '\\sphinxnolinkurl{http://sphinx-doc.org/~test/}\n%\n\\end{footnote}') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}' assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}'
'{URL in term}\\sphinxfootnotemark[9]}] ' '{URL in term}\\sphinxfootnotemark[9]}] '
'\\leavevmode%\n\\begin{footnotetext}[9]\\sphinxAtStartFootnote\n' '\\leavevmode%\n\\begin{footnotetext}[9]'
'\\phantomsection\\label{\\thesphinxscope.9}%\n'
'\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n' '\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n'
'\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result '\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{Footnote in term \\sphinxfootnotemark[11]}] ' assert ('\\item[{Footnote in term \\sphinxfootnotemark[11]}] '
'\\leavevmode%\n\\begin{footnotetext}[11]\\sphinxAtStartFootnote\n' '\\leavevmode%\n\\begin{footnotetext}[11]'
'\\phantomsection\\label{\\thesphinxscope.11}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces ' 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces '
'\n\\sphinxAtStartPar\nDescription') in result '\n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}' assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}'
'\\sphinxfootnotemark[10]}] ' '\\sphinxfootnotemark[10]}] '
'\\leavevmode%\n\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n' '\\leavevmode%\n\\begin{footnotetext}[10]'
'\\phantomsection\\label{\\thesphinxscope.10}%\n'
'\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n' '\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n'
'\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result '\\end{footnotetext}\\ignorespaces \n\\sphinxAtStartPar\nDescription') in result
assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result) assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result)
@ -896,7 +929,9 @@ def test_latex_show_urls_is_no(app, status, warning):
print(result) print(result)
print(status.getvalue()) print(status.getvalue())
print(warning.getvalue()) print(warning.getvalue())
assert ('Same footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n' assert ('Same footnote number \\sphinxstepexplicit %\n'
'\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n'
'\\sphinxAtStartFootnote\n'
'footnote in bar\n%\n\\end{footnote} in bar.rst') in result 'footnote in bar\n%\n\\end{footnote} in bar.rst') in result
assert ('Auto footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n' assert ('Auto footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n'
'footnote in baz\n%\n\\end{footnote} in baz.rst') in result 'footnote in baz\n%\n\\end{footnote} in baz.rst') in result
@ -909,18 +944,24 @@ def test_latex_show_urls_is_no(app, status, warning):
'{\\sphinxcrossref{The section with a reference to }}}' in result) '{\\sphinxcrossref{The section with a reference to }}}' in result)
assert ('First footnote: %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n' assert ('First footnote: %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n'
'First\n%\n\\end{footnote}') in result 'First\n%\n\\end{footnote}') in result
assert ('Second footnote: %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n' assert ('Second footnote: \\sphinxstepexplicit %\n'
'\\begin{footnote}[1]\\phantomsection\\label{\\thesphinxscope.1}%\n'
'\\sphinxAtStartFootnote\n'
'Second\n%\n\\end{footnote}') in result 'Second\n%\n\\end{footnote}') in result
assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx}' in result assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx}' in result
assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n' assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n' 'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n' '\\begin{footnotetext}[4]'
'\\phantomsection\\label{\\thesphinxscope.4}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result 'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result
assert '\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}' in result assert '\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}' in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term}}] ' assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term}}] '
'\\leavevmode\n\\sphinxAtStartPar\nDescription') in result '\\leavevmode\n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] ' assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] '
'\\leavevmode%\n\\begin{footnotetext}[6]\\sphinxAtStartFootnote\n' '\\leavevmode%\n\\begin{footnotetext}[6]'
'\\phantomsection\\label{\\thesphinxscope.6}%\n'
'\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces ' 'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces '
'\n\\sphinxAtStartPar\nDescription') in result '\n\\sphinxAtStartPar\nDescription') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}}] ' assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}}] '