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 |