Fix #4850: latex: footnote inside footnote was not rendered

This commit is contained in:
Takeshi KOMIYA
2018-04-20 21:21:46 +09:00
parent 89d68d9ac3
commit 6977270b66
4 changed files with 49 additions and 31 deletions

View File

@@ -67,6 +67,7 @@ Bugs fixed
----------
* i18n: message catalogs were reset on each initialization
* #4850: latex: footnote inside footnote was not rendered
Testing
--------

View File

@@ -438,6 +438,14 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
self.table_footnotes = []
def visit_footnote(self, node):
# type: (nodes.Node) -> None
self.restrict(node)
def depart_footnote(self, node):
# type: (nodes.Node) -> None
self.unrestrict(node)
def visit_footnote_reference(self, node):
# type: (nodes.Node) -> None
number = node.astext().strip()
@@ -455,6 +463,7 @@ class LaTeXFootnoteVisitor(nodes.NodeVisitor):
footnote = self.get_footnote_by_reference(node)
self.footnotes.remove(footnote)
node.replace_self(footnote)
footnote.walkabout(self)
self.appeared.add((docname, number))
raise nodes.SkipNode

View File

@@ -39,7 +39,8 @@ The section with a reference to [AuthorYear]_
.. [AuthorYear] Author, Title, Year
.. [1] Second
.. [#] Third
.. [#] Third [#]_
.. [#] Footnote inside footnote
The section with a reference to [#]_
=====================================

View File

@@ -583,27 +583,27 @@ def test_reference_in_caption_and_codeblock_in_footnote(app, status, warning):
assert ('\\sphinxcaption{The table title with a reference'
' to {[}AuthorYear{]}}' in result)
assert '\\paragraph{The rubric title with a reference to {[}AuthorYear{]}}' in result
assert ('\\chapter{The section with a reference to \\sphinxfootnotemark[4]}\n'
assert ('\\chapter{The section with a reference to \\sphinxfootnotemark[5]}\n'
'\\label{\\detokenize{index:the-section-with-a-reference-to}}'
'%\n\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n'
'%\n\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n'
'Footnote in section\n%\n\\end{footnotetext}') in result
assert ('\\caption{This is the figure caption with a footnote to '
'\\sphinxfootnotemark[6].}\\label{\\detokenize{index:id27}}\\end{figure}\n'
'%\n\\begin{footnotetext}[6]\\sphinxAtStartFootnote\n'
'\\sphinxfootnotemark[7].}\\label{\\detokenize{index:id29}}\\end{figure}\n'
'%\n\\begin{footnotetext}[7]\\sphinxAtStartFootnote\n'
'Footnote in caption\n%\n\\end{footnotetext}')in result
assert ('\\sphinxcaption{footnote \\sphinxfootnotemark[7] in '
'caption of normal table}\\label{\\detokenize{index:id28}}') in result
assert ('\\caption{footnote \\sphinxfootnotemark[8] '
'in caption \\sphinxfootnotemark[9] of longtable\\strut}') in result
assert ('\\endlastfoot\n%\n\\begin{footnotetext}[8]\\sphinxAtStartFootnote\n'
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'
'Foot note in longtable\n%\n\\end{footnotetext}\\ignorespaces %\n'
'\\begin{footnotetext}[9]\\sphinxAtStartFootnote\n'
'\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n'
'Second footnote in caption of longtable\n') in result
assert ('This is a reference to the code-block in the footnote:\n'
'{\\hyperref[\\detokenize{index:codeblockinfootnote}]'
'{\\sphinxcrossref{\\DUrole{std,std-ref}{I am in a footnote}}}}') in result
assert ('&\nThis is one more footnote with some code in it %\n'
'\\begin{footnote}[10]\\sphinxAtStartFootnote\n'
'\\begin{footnote}[11]\\sphinxAtStartFootnote\n'
'Third footnote in longtable\n') in result
assert ('\\end{sphinxVerbatim}\n%\n\\end{footnote}.\n') in result
assert '\\begin{sphinxVerbatim}[commandchars=\\\\\\{\\}]' in result
@@ -622,14 +622,14 @@ def test_latex_show_urls_is_inline(app, status, warning):
'footnote in bar\n%\n\\end{footnote} in bar.rst') in result
assert ('Auto footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n'
'footnote in baz\n%\n\\end{footnote} in baz.rst') in result
assert ('\\phantomsection\\label{\\detokenize{index:id30}}'
assert ('\\phantomsection\\label{\\detokenize{index:id32}}'
'{\\hyperref[\\detokenize{index:the-section'
'-with-a-reference-to-authoryear}]'
'{\\sphinxcrossref{The section with a reference to '
'\\phantomsection\\label{\\detokenize{index:id1}}'
'{\\hyperref[\\detokenize{index:authoryear}]'
'{\\sphinxcrossref{{[}AuthorYear{]}}}}}}}') in result
assert ('\\phantomsection\\label{\\detokenize{index:id31}}'
assert ('\\phantomsection\\label{\\detokenize{index:id33}}'
'{\\hyperref[\\detokenize{index:the-section-with-a-reference-to}]'
'{\\sphinxcrossref{The section with a reference to }}}' in result)
assert ('First footnote: %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n'
@@ -638,13 +638,15 @@ def test_latex_show_urls_is_inline(app, status, warning):
'Second\n%\n\\end{footnote}') in result
assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx} (http://sphinx-doc.org/)' in result
assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'Third\n%\n\\end{footnote}') in result
'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[4]\\sphinxAtStartFootnote\n'
'Footnote inside footnote\n%\n\\end{footnotetext}\\ignorespaces') in result
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde} '
'(http://sphinx-doc.org/\\textasciitilde{}test/)') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{URL in term} '
'(http://sphinx-doc.org/)}] \\leavevmode\nDescription' in result)
assert ('\\item[{Footnote in term \\sphinxfootnotemark[5]}] '
'\\leavevmode%\n\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n'
assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] '
'\\leavevmode%\n\\begin{footnotetext}[6]\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces \n'
'Description') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist} '
@@ -667,13 +669,13 @@ def test_latex_show_urls_is_footnote(app, status, warning):
'footnote in bar\n%\n\\end{footnote} in bar.rst') in result
assert ('Auto footnote number %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n'
'footnote in baz\n%\n\\end{footnote} in baz.rst') in result
assert ('\\phantomsection\\label{\\detokenize{index:id30}}'
assert ('\\phantomsection\\label{\\detokenize{index:id32}}'
'{\\hyperref[\\detokenize{index:the-section-with-a-reference-to-authoryear}]'
'{\\sphinxcrossref{The section with a reference '
'to \\phantomsection\\label{\\detokenize{index:id1}}'
'{\\hyperref[\\detokenize{index:authoryear}]'
'{\\sphinxcrossref{{[}AuthorYear{]}}}}}}}') in result
assert ('\\phantomsection\\label{\\detokenize{index:id31}}'
assert ('\\phantomsection\\label{\\detokenize{index:id33}}'
'{\\hyperref[\\detokenize{index:the-section-with-a-reference-to}]'
'{\\sphinxcrossref{The section with a reference to }}}') in result
assert ('First footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
@@ -684,22 +686,25 @@ def test_latex_show_urls_is_footnote(app, status, warning):
'%\n\\begin{footnote}[4]\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n\\end{footnote}') in result
assert ('Third footnote: %\n\\begin{footnote}[6]\\sphinxAtStartFootnote\n'
'Third\n%\n\\end{footnote}') in result
'Third \\sphinxfootnotemark[7]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[7]\\sphinxAtStartFootnote\n'
'Footnote inside footnote\n%\n'
'\\end{footnotetext}\\ignorespaces') in result
assert ('\\sphinxhref{http://sphinx-doc.org/~test/}{URL including tilde}'
'%\n\\begin{footnote}[5]\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/~test/}\n%\n\\end{footnote}') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}'
'{URL in term}\\sphinxfootnotemark[8]}] '
'\\leavevmode%\n\\begin{footnotetext}[8]\\sphinxAtStartFootnote\n'
'{URL in term}\\sphinxfootnotemark[9]}] '
'\\leavevmode%\n\\begin{footnotetext}[9]\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n'
'\\end{footnotetext}\\ignorespaces \nDescription') in result
assert ('\\item[{Footnote in term \\sphinxfootnotemark[10]}] '
'\\leavevmode%\n\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n'
assert ('\\item[{Footnote in term \\sphinxfootnotemark[11]}] '
'\\leavevmode%\n\\begin{footnotetext}[11]\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces \n'
'Description') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}'
'\\sphinxfootnotemark[9]}] '
'\\leavevmode%\n\\begin{footnotetext}[9]\\sphinxAtStartFootnote\n'
'\\sphinxfootnotemark[10]}] '
'\\leavevmode%\n\\begin{footnotetext}[10]\\sphinxAtStartFootnote\n'
'\\sphinxnolinkurl{http://sphinx-doc.org/}\n%\n'
'\\end{footnotetext}\\ignorespaces \nDescription') in result
assert ('\\sphinxurl{https://github.com/sphinx-doc/sphinx}\n' in result)
@@ -720,13 +725,13 @@ def test_latex_show_urls_is_no(app, status, warning):
'footnote in bar\n%\n\\end{footnote} in bar.rst') in result
assert ('Auto footnote number %\n\\begin{footnote}[1]\\sphinxAtStartFootnote\n'
'footnote in baz\n%\n\\end{footnote} in baz.rst') in result
assert ('\\phantomsection\\label{\\detokenize{index:id30}}'
assert ('\\phantomsection\\label{\\detokenize{index:id32}}'
'{\\hyperref[\\detokenize{index:the-section-with-a-reference-to-authoryear}]'
'{\\sphinxcrossref{The section with a reference '
'to \\phantomsection\\label{\\detokenize{index:id1}}'
'{\\hyperref[\\detokenize{index:authoryear}]'
'{\\sphinxcrossref{{[}AuthorYear{]}}}}}}}') in result
assert ('\\phantomsection\\label{\\detokenize{index:id31}}'
assert ('\\phantomsection\\label{\\detokenize{index:id33}}'
'{\\hyperref[\\detokenize{index:the-section-with-a-reference-to}]'
'{\\sphinxcrossref{The section with a reference to }}}' in result)
assert ('First footnote: %\n\\begin{footnote}[2]\\sphinxAtStartFootnote\n'
@@ -735,12 +740,14 @@ def test_latex_show_urls_is_no(app, status, warning):
'Second\n%\n\\end{footnote}') in result
assert '\\sphinxhref{http://sphinx-doc.org/}{Sphinx}' in result
assert ('Third footnote: %\n\\begin{footnote}[3]\\sphinxAtStartFootnote\n'
'Third\n%\n\\end{footnote}') in result
'Third \\sphinxfootnotemark[4]\n%\n\\end{footnote}%\n'
'\\begin{footnotetext}[4]\\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\nDescription') in result
assert ('\\item[{Footnote in term \\sphinxfootnotemark[5]}] '
'\\leavevmode%\n\\begin{footnotetext}[5]\\sphinxAtStartFootnote\n'
assert ('\\item[{Footnote in term \\sphinxfootnotemark[6]}] '
'\\leavevmode%\n\\begin{footnotetext}[6]\\sphinxAtStartFootnote\n'
'Footnote in term\n%\n\\end{footnotetext}\\ignorespaces \n'
'Description') in result
assert ('\\item[{\\sphinxhref{http://sphinx-doc.org/}{Term in deflist}}] '