|
From: Matěj C. <mc...@ce...> - 2025-07-22 00:16:16
|
---
docutils/docutils/writers/latex2e/__init__.py | 4 +-
docutils/test/data/help/rst2latex.rst | 3 +-
docutils/test/test_writers/test_latex2e.py | 350 ++++++++++++++----
3 files changed, 280 insertions(+), 77 deletions(-)
diff --git a/docutils/docutils/writers/latex2e/__init__.py b/docutils/docutils/writers/latex2e/__init__.py
index 1dcf13466..4b6b0b431 100644
--- a/docutils/docutils/writers/latex2e/__init__.py
+++ b/docutils/docutils/writers/latex2e/__init__.py
@@ -232,13 +232,13 @@ class Writer(writers.Writer):
{'default': True,
'action': 'store_true',
'validator': frontend.validate_boolean}),
- ),
('Footnotes with numbers by LaTeX.',
['--latex-footnotes'],
{'dest': 'docutils_footnotes',
'action': 'store_false',
- 'validator': frontend.validate_boolean}),
+ 'validator': frontend.validate_boolean})
)
+ )
relative_path_settings = ('template',)
settings_defaults = {}
diff --git a/docutils/test/data/help/rst2latex.rst b/docutils/test/data/help/rst2latex.rst
index d0ede4c63..8e7e702f4 100644
--- a/docutils/test/data/help/rst2latex.rst
+++ b/docutils/test/data/help/rst2latex.rst
@@ -256,5 +256,4 @@ LaTeX-Specific Options
--new-column-widths Use new algorithm to determine table column widths.
(future default)
--docutils-footnotes Footnotes with numbers/symbols by Docutils. (default)
- (The alternative, --latex-footnotes, is not
- implemented yet.)
+--latex-footnotes Footnotes with numbers by LaTeX.
diff --git a/docutils/test/test_writers/test_latex2e.py b/docutils/test/test_writers/test_latex2e.py
index 434786690..acb9dd6ed 100755
--- a/docutils/test/test_writers/test_latex2e.py
+++ b/docutils/test/test_writers/test_latex2e.py
@@ -47,7 +47,7 @@ def test_body(self):
self.assertEqual(expected, output)
-samples = {}
+samples = {} # type: ignore
samples['default'] = ({}, [
@@ -500,98 +500,256 @@ def test_body(self):
])
-totest_latex_footnotes['simple'] = [
-# input
-["""\
-Paragraphs contain text and may contain footnote references (manually
-numbered [1]_, anonymous auto-numbered [#]_, labeled auto-numbered
-[#label]_, or symbolic [*]_).
+class FootnoteTestCase(unittest.TestCase):
-.. [1] A footnote contains body elements, consistently indented by at
- least 3 spaces.
+ maxDiff = None
+ settings = {
+ '_disable_config': True,
+ 'strict_visitor': True,
+ 'output_encoding': 'unicode',
+ 'stylesheet': '',
+ 'language_code': 'en',
+ 'use_latex_toc': False,
+ 'use_latex_citations': False,
+ 'legacy_column_widths': True,
+ }
- This is the footnote's second paragraph.
+ def test_footnotes(self):
+ for name, (settings_overrides, cases) in footnote_samples.items():
+ for casenum, (rst_input, expected) in enumerate(cases):
+ with self.subTest(id=f'footnote_samples[{name!r}][{casenum}]'):
+ output = publish_parts(
+ source=rst_input,
+ writer=latex2e.Writer(),
+ settings_overrides=self.settings | settings_overrides
+ )['whole']
+ self.assertEqual(expected, output)
-.. [#label] Footnotes may be numbered, either manually or
- automatically using a "#"-prefixed label. This footnote has a
- label so it can be referred to from multiple places, both as a
- footnote reference and as a hyperlink reference.
-.. [#] This footnote is numbered automatically and anonymously using a
- label of "#" only.
+footnote_samples = {
+ 'simple': ({}, [
+ [r"""
+ Paragraphs contain text and may contain footnote references (manually
+ numbered [1]_, anonymous auto-numbered [#]_, labeled auto-numbered
+ [#label]_, or symbolic [*]_).
+
+ .. [1] A footnote contains body elements, consistently indented by at
+ least 3 spaces.
+
+ This is the footnote's second paragraph.
+
+ .. [#label] Footnotes may be numbered, either manually or
+ automatically using a "#"-prefixed label. This footnote has a
+ label so it can be referred to from multiple places, both as a
+ footnote reference and as a hyperlink reference.
+
+ .. [#] This footnote is numbered automatically and anonymously using a
+ label of "#" only.
+
+ .. [*] Footnotes may also use symbols, specified with a "*" label.
+ """,
+ r"""\documentclass[a4paper]{article}
+% generated by Docutils <https://docutils.sourceforge.io/>
+\usepackage{cmap} % fix search and cut-and-paste in Acrobat
+\usepackage[T1]{fontenc}
+
+%%% Custom LaTeX preamble
+% PDF Standard Fonts
+\usepackage{mathptmx} % Times
+\usepackage[scaled=.90]{helvet}
+\usepackage{courier}
+
+%%% User specified packages and stylesheets
+
+%%% Fallback definitions for Docutils-specific commands
+
+% numerical or symbol footnotes with hyperlinks and backlinks
+\providecommand*{\DUfootnotemark}[3]{%
+ \raisebox{1em}{\hypertarget{#1}{}}%
+ \hyperlink{#2}{\textsuperscript{#3}}%
+}
+\providecommand{\DUfootnotetext}[4]{%
+ \begingroup%
+ \renewcommand{\thefootnote}{%
+ \protect\raisebox{1em}{\protect\hypertarget{#1}{}}%
+ \protect\hyperlink{#2}{#3}}%
+ \footnotetext{#4}%
+ \endgroup%
+}
-.. [*] Footnotes may also use symbols, specified with a "*" label.
-""",
-## # expected output
-head_template.substitute(dict(parts)) + r"""
+% hyperlinks:
+\ifdefined\hypersetup
+\else
+ \usepackage[hyperfootnotes=false,
+ colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
+ \usepackage{bookmark}
+ \urlstyle{same} % normal text font (alternatives: tt, rm, sf)
+\fi
+
+%%% Body
+\begin{document}
+
+\begin{quote}
Paragraphs contain text and may contain footnote references (manually
-numbered\footnote{%
+numbered\DUfootnotemark{footnote-reference-1}{footnote-1}{1}, anonymous auto-numbered\DUfootnotemark{footnote-reference-2}{footnote-2}{3}, labeled auto-numbered\DUfootnotemark{footnote-reference-3}{label}{2}, or symbolic\DUfootnotemark{footnote-reference-4}{footnote-3}{*}).
+%
+\DUfootnotetext{footnote-1}{footnote-reference-1}{1}{%
A footnote contains body elements, consistently indented by at
least 3 spaces.
This is the footnote's second paragraph.
-}, anonymous auto-numbered\footnote{%
-This footnote is numbered automatically and anonymously using a
-label of \textquotedbl{}\#\textquotedbl{} only.
-}, labeled auto-numbered\footnote{%
+}
+%
+\DUfootnotetext{label}{footnote-reference-3}{2}{\phantomsection\label{label}%
Footnotes may be numbered, either manually or
automatically using a \textquotedbl{}\#\textquotedbl{}-prefixed label. This footnote has a
label so it can be referred to from multiple places, both as a
footnote reference and as a hyperlink reference.
-}, or symbolic\footnote{%
+}
+%
+\DUfootnotetext{footnote-2}{footnote-reference-2}{3}{%
+This footnote is numbered automatically and anonymously using a
+label of \textquotedbl{}\#\textquotedbl{} only.
+}
+%
+\DUfootnotetext{footnote-3}{footnote-reference-4}{*}{%
Footnotes may also use symbols, specified with a \textquotedbl{}*\textquotedbl{} label.
-}).
+}
+\end{quote}
\end{document}
-"""],
-]
+"""]]),
+ 'nested': ({}, [
+ [r"""
+ It's possible to produce nested footnotes in LaTeX. [#]_
+
+ .. [#] It takes some work, though. [#]_
+ .. [#] And don't even get me started on how tricky recursive footnotes would be.
+ """,
+ r"""\documentclass[a4paper]{article}
+% generated by Docutils <https://docutils.sourceforge.io/>
+\usepackage{cmap} % fix search and cut-and-paste in Acrobat
+\usepackage[T1]{fontenc}
+
+%%% Custom LaTeX preamble
+% PDF Standard Fonts
+\usepackage{mathptmx} % Times
+\usepackage[scaled=.90]{helvet}
+\usepackage{courier}
+
+%%% User specified packages and stylesheets
+
+%%% Fallback definitions for Docutils-specific commands
+
+% numerical or symbol footnotes with hyperlinks and backlinks
+\providecommand*{\DUfootnotemark}[3]{%
+ \raisebox{1em}{\hypertarget{#1}{}}%
+ \hyperlink{#2}{\textsuperscript{#3}}%
+}
+\providecommand{\DUfootnotetext}[4]{%
+ \begingroup%
+ \renewcommand{\thefootnote}{%
+ \protect\raisebox{1em}{\protect\hypertarget{#1}{}}%
+ \protect\hyperlink{#2}{#3}}%
+ \footnotetext{#4}%
+ \endgroup%
+}
-totest_latex_footnotes['nested'] = [
-# input
-["""\
-It's possible to produce nested footnotes in LaTeX. [#]_
+% hyperlinks:
+\ifdefined\hypersetup
+\else
+ \usepackage[hyperfootnotes=false,
+ colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
+ \usepackage{bookmark}
+ \urlstyle{same} % normal text font (alternatives: tt, rm, sf)
+\fi
-.. [#] It takes some work, though. [#]_
-.. [#] And don't even get me started on how tricky recursive footnotes would be.
-""",
-## # expected output
-head_template.substitute(dict(parts)) + r"""
-It's possible to produce nested footnotes in LaTeX.\footnote{%
-It takes some work, though.\footnotemark{}
-}\footnotetext{%
+%%% Body
+\begin{document}
+
+\begin{quote}
+It's possible to produce nested footnotes in LaTeX.\DUfootnotemark{footnote-reference-1}{footnote-1}{1}
+%
+\DUfootnotetext{footnote-1}{footnote-reference-1}{1}{%
+It takes some work, though.\DUfootnotemark{footnote-reference-2}{footnote-2}{2}
+}
+%
+\DUfootnotetext{footnote-2}{footnote-reference-2}{2}{%
And don't even get me started on how tricky recursive footnotes would be.
}
+\end{quote}
\end{document}
-"""],
-]
+"""]]),
+ 'chained': ({}, [
+ [r"""
+ It's possible to produce chained footnotes in LaTeX. [#]_
+
+ .. [#] They're just a special case of nested footnotes. [#]_
+ .. [#] A nested footnote is a footnote on a footnote. [#]_
+ .. [#] This is a footnote on a footnote on a footnote.
+ """,
+ r"""\documentclass[a4paper]{article}
+% generated by Docutils <https://docutils.sourceforge.io/>
+\usepackage{cmap} % fix search and cut-and-paste in Acrobat
+\usepackage[T1]{fontenc}
+
+%%% Custom LaTeX preamble
+% PDF Standard Fonts
+\usepackage{mathptmx} % Times
+\usepackage[scaled=.90]{helvet}
+\usepackage{courier}
+
+%%% User specified packages and stylesheets
+
+%%% Fallback definitions for Docutils-specific commands
+
+% numerical or symbol footnotes with hyperlinks and backlinks
+\providecommand*{\DUfootnotemark}[3]{%
+ \raisebox{1em}{\hypertarget{#1}{}}%
+ \hyperlink{#2}{\textsuperscript{#3}}%
+}
+\providecommand{\DUfootnotetext}[4]{%
+ \begingroup%
+ \renewcommand{\thefootnote}{%
+ \protect\raisebox{1em}{\protect\hypertarget{#1}{}}%
+ \protect\hyperlink{#2}{#3}}%
+ \footnotetext{#4}%
+ \endgroup%
+}
-totest_latex_footnotes['chained'] = [
-# input
-["""\
-It's possible to produce chained footnotes in LaTeX. [#]_
+% hyperlinks:
+\ifdefined\hypersetup
+\else
+ \usepackage[hyperfootnotes=false,
+ colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
+ \usepackage{bookmark}
+ \urlstyle{same} % normal text font (alternatives: tt, rm, sf)
+\fi
-.. [#] They're just a special case of nested footnotes. [#]_
-.. [#] A nested footnote is a footnote on a footnote. [#]_
-.. [#] This is a footnote on a footnote on a footnote.
-""",
-## # expected output
-head_template.substitute(dict(parts)) + r"""
-It's possible to produce chained footnotes in LaTeX.\footnote{%
-They're just a special case of nested footnotes.\footnotemark{}
-}\footnotetext{%
-A nested footnote is a footnote on a footnote.\footnotemark{}
-}\footnotetext{%
+%%% Body
+\begin{document}
+
+\begin{quote}
+It's possible to produce chained footnotes in LaTeX.\DUfootnotemark{footnote-reference-1}{footnote-1}{1}
+%
+\DUfootnotetext{footnote-1}{footnote-reference-1}{1}{%
+They're just a special case of nested footnotes.\DUfootnotemark{footnote-reference-2}{footnote-2}{2}
+}
+%
+\DUfootnotetext{footnote-2}{footnote-reference-2}{2}{%
+A nested footnote is a footnote on a footnote.\DUfootnotemark{footnote-reference-3}{footnote-3}{3}
+}
+%
+\DUfootnotetext{footnote-3}{footnote-reference-3}{3}{%
This is a footnote on a footnote on a footnote.
}
+\end{quote}
\end{document}
-"""],
-]
-
-totest_latex_footnotes['multinested'] = [
-# input
-["""\
+"""]]),
+ 'multinested': ({}, [
+ [r"""
LaTeX isn't the best at nested footnote support. [#]_
.. [#] Specifically, it gets the numbers wrong [#]_ for "multinested"
@@ -600,21 +758,67 @@ def test_body(self):
show up as footnote 3.
.. [#] That's a footnote that contains more than one footnote of its own.
""",
-## # expected output
-head_template.substitute(dict(parts)) + r"""
-LaTeX isn't the best at nested footnote support.\footnote{%
-Specifically, it gets the numbers wrong\footnotemark{} for \textquotedbl{}multinested\textquotedbl{}
-footnotes.\footnotemark{}
-}\footnotetext{%
+r"""\documentclass[a4paper]{article}
+% generated by Docutils <https://docutils.sourceforge.io/>
+\usepackage{cmap} % fix search and cut-and-paste in Acrobat
+\usepackage[T1]{fontenc}
+
+%%% Custom LaTeX preamble
+% PDF Standard Fonts
+\usepackage{mathptmx} % Times
+\usepackage[scaled=.90]{helvet}
+\usepackage{courier}
+
+%%% User specified packages and stylesheets
+
+%%% Fallback definitions for Docutils-specific commands
+
+% numerical or symbol footnotes with hyperlinks and backlinks
+\providecommand*{\DUfootnotemark}[3]{%
+ \raisebox{1em}{\hypertarget{#1}{}}%
+ \hyperlink{#2}{\textsuperscript{#3}}%
+}
+\providecommand{\DUfootnotetext}[4]{%
+ \begingroup%
+ \renewcommand{\thefootnote}{%
+ \protect\raisebox{1em}{\protect\hypertarget{#1}{}}%
+ \protect\hyperlink{#2}{#3}}%
+ \footnotetext{#4}%
+ \endgroup%
+}
+
+% hyperlinks:
+\ifdefined\hypersetup
+\else
+ \usepackage[hyperfootnotes=false,
+ colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
+ \usepackage{bookmark}
+ \urlstyle{same} % normal text font (alternatives: tt, rm, sf)
+\fi
+
+%%% Body
+\begin{document}
+
+LaTeX isn't the best at nested footnote support.\DUfootnotemark{footnote-reference-1}{footnote-1}{1}
+%
+\DUfootnotetext{footnote-1}{footnote-reference-1}{1}{%
+Specifically, it gets the numbers wrong\DUfootnotemark{footnote-reference-2}{footnote-2}{2} for \textquotedbl{}multinested\textquotedbl{}
+footnotes.\DUfootnotemark{footnote-reference-3}{footnote-3}{3}
+}
+%
+\DUfootnotetext{footnote-2}{footnote-reference-2}{2}{%
For example, this should be footnote 2, but both it and the next one
show up as footnote 3.
-}\footnotetext{%
+}
+%
+\DUfootnotetext{footnote-3}{footnote-reference-3}{3}{%
That's a footnote that contains more than one footnote of its own.
}
\end{document}
-"""],
-]
+"""]]),
+}
+
if __name__ == '__main__':
unittest.main()
--
2.50.1
|