|
From: <mi...@us...> - 2025-03-30 20:13:45
|
Revision: 10063
http://sourceforge.net/p/docutils/code/10063
Author: milde
Date: 2025-03-30 20:13:30 +0000 (Sun, 30 Mar 2025)
Log Message:
-----------
LaTeX writer: Fix formatting of "authors" bibinfo field.
Collect author names from "author" fields nested in "authors".
With "--use-docutils-docinfo", use one "authors" entry instead of separate
"author" entries for the individual author names.
With "--use-latex-docinfo", print author names as one block
to ensure a common author affiliation is centered under all
author names, not just the last (cf. https://tex.stackexchange.com/a/11656/288060).
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docs/user/latex.rst
trunk/docutils/docutils/writers/latex2e/__init__.py
trunk/docutils/test/functional/expected/latex_leavevmode.tex
trunk/docutils/test/functional/expected/latex_memoir.tex
trunk/docutils/test/functional/expected/standalone_rst_latex.tex
trunk/docutils/test/functional/expected/standalone_rst_xetex.tex
trunk/docutils/test/test_writers/test_latex2e_parts.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2025-03-30 20:13:14 UTC (rev 10062)
+++ trunk/docutils/HISTORY.rst 2025-03-30 20:13:30 UTC (rev 10063)
@@ -189,7 +189,7 @@
and`LaTeXTranslator.fallbacks`.
- Use <document> "title" attribute in pdfinfo.
- Encode <meta> element content in pdfinfo.
- - Improve docinfo handling with "use_latex_docinfo".
+ - Improve formatting of docinfo fields.
- `LaTeXTranslator.pop_output_collector()` now returns the popped list.
.. _reference-label: docs/user/config.html#reference-label
Modified: trunk/docutils/docs/user/latex.rst
===================================================================
--- trunk/docutils/docs/user/latex.rst 2025-03-30 20:13:14 UTC (rev 10062)
+++ trunk/docutils/docs/user/latex.rst 2025-03-30 20:13:30 UTC (rev 10063)
@@ -662,6 +662,32 @@
See section Templates_ and the `TeX FAQ`_ on how to customize the
`style of document titles`_.
+Example:
+ With `use-latex-docinfo`_, author information and date are typeset
+ as part of the document title instead of the `document info`_ table.
+
+ Paper by three authors, two of them from the same organisation::
+
+ Shop Sketches
+ =============
+
+ :authors: * Mr. Mousebender
+ * Mr. Arthur Wensleydale
+ :organization: Ye National Cheese Emporium
+
+ :author: Hr. Hallmackenreuther
+ :organization: Bettengeschäft
+
+ With ``--use-latex-docinfo``, authors and their affiliations are
+ typeset below the title using the standard LaTeX command ``\author``
+ with a `simple hack for the common affiliation`__. [#]_
+
+.. [#] Unfortunately, author names don't wrap if there are more
+ authors than fit on one line in one "authors" field.
+
+__ https://tex.stackexchange.com/a/11656/288060from
+
+
.. _section structure: rst/quickref.html#section-structure
.. _doctitle_xform: config.html#doctitle-xform
.. _TeX FAQ: https://texfaq.org/
Modified: trunk/docutils/docutils/writers/latex2e/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/latex2e/__init__.py 2025-03-30 20:13:14 UTC (rev 10062)
+++ trunk/docutils/docutils/writers/latex2e/__init__.py 2025-03-30 20:13:30 UTC (rev 10063)
@@ -1728,17 +1728,24 @@
def visit_author(self, node) -> None:
self.pdfauthor.append(self.attval(node.astext()))
- self.visit_docinfo_item(node)
+ if isinstance(node.parent, nodes.authors):
+ # ensure output is one item per <author> element (see depart…)
+ self.push_output_collector([])
+ else:
+ self.visit_docinfo_item(node)
def depart_author(self, node) -> None:
- self.depart_docinfo_item(node)
+ if isinstance(node.parent, nodes.authors):
+ author_name = self.pop_output_collector()
+ self.out.append(''.join(author_name))
+ else:
+ self.depart_docinfo_item(node)
def visit_authors(self, node) -> None:
- # not used: visit_author is called anyway for each author.
- pass
+ self.visit_docinfo_item(node)
def depart_authors(self, node) -> None:
- pass
+ self.depart_docinfo_item(node)
def visit_block_quote(self, node) -> None:
self.duclass_open(node)
@@ -1973,16 +1980,33 @@
self.out.append('\n ')
else:
self.out.append(' ')
+ if isinstance(node, nodes.authors):
+ self.push_output_collector([]) # collect author names
def depart_docinfo_item(self, node) -> None:
if self.use_latex_docinfo and isinstance(node, self.TITLEDATA_NODES):
- # Collect date and author info for use in `self.make_title()`:
- text = ''.join(self.pop_output_collector())
+ # Prepare data for use in `self.make_title()`
+ if isinstance(node, nodes.authors):
+ # join author names with "\and" or,
+ # if there is shared author info, with "\quad"
+ # (cf. https://tex.stackexchange.com/a/11656/288060)
+ s = r' \and '
+ for nn in node.findall(include_self=False, descend=False,
+ siblings=True):
+ if isinstance(nn, (nodes.author, nodes.authors)):
+ break
+ if isinstance(nn, (nodes.address, nodes.contact,
+ nodes.organization)):
+ s = r' \quad '
+ else:
+ s = ''
+ text = s.join(self.pop_output_collector())
+
if isinstance(node, nodes.date):
self.date.append(text)
- elif isinstance(node, nodes.author):
- # Insert author name as first item of an "author info" list.
- # If author name already set, start a new list.
+ elif isinstance(node, (nodes.author, nodes.authors)):
+ # Insert author name(s) as first item of an "author info" list,
+ # starting a new list if author name already set:
if self.author_stack[-1][0]:
self.author_stack.append([text])
else:
@@ -1993,6 +2017,13 @@
else:
if isinstance(node, nodes.address):
self.out.append('}')
+ elif isinstance(node, nodes.authors):
+ author_names = self.pop_output_collector()
+ # get last "author separator" that is not in any author name
+ for sep in reversed(self.language_module.author_separators):
+ if not any(sep in name for name in author_names):
+ break
+ self.out.append((sep+' ').join(author_names))
self.out.append(' \\\\\n')
def visit_doctest_block(self, node) -> None:
Modified: trunk/docutils/test/functional/expected/latex_leavevmode.tex
===================================================================
--- trunk/docutils/test/functional/expected/latex_leavevmode.tex 2025-03-30 20:13:14 UTC (rev 10062)
+++ trunk/docutils/test/functional/expected/latex_leavevmode.tex 2025-03-30 20:13:30 UTC (rev 10063)
@@ -162,8 +162,7 @@
% Docinfo
\begin{center}
\begin{tabularx}{\DUdocinfowidth}{lX}
-\textbf{Author}: & Hänsel \\
-\textbf{Author}: & Gretel \\
+\textbf{Authors}: & Hänsel, Gretel \\
\textbf{Address}: & {\raggedright
123 Example Street\\
Example, EX Canada} \\
Modified: trunk/docutils/test/functional/expected/latex_memoir.tex
===================================================================
--- trunk/docutils/test/functional/expected/latex_memoir.tex 2025-03-30 20:13:14 UTC (rev 10062)
+++ trunk/docutils/test/functional/expected/latex_memoir.tex 2025-03-30 20:13:30 UTC (rev 10063)
@@ -206,9 +206,7 @@
Example, EX Canada\\
A1B 2C3\\
\href{mailto:go...@py...}{go...@py...} \and
-Me \and
-Myself \and
-I\\
+Me \quad Myself \quad I\\
humankind}
\date{Now, or yesterday. Or maybe even \emph{before} yesterday.}
Modified: trunk/docutils/test/functional/expected/standalone_rst_latex.tex
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_latex.tex 2025-03-30 20:13:14 UTC (rev 10062)
+++ trunk/docutils/test/functional/expected/standalone_rst_latex.tex 2025-03-30 20:13:30 UTC (rev 10063)
@@ -215,9 +215,7 @@
Example, EX Canada\\
A1B 2C3} \\
\textbf{Contact}: & \href{mailto:go...@py...}{go...@py...} \\
-\textbf{Author}: & Me \\
-\textbf{Author}: & Myself \\
-\textbf{Author}: & I \\
+\textbf{Authors}: & Me, Myself, I \\
\textbf{Organization}: & humankind \\
\textbf{Date}: & Now, or yesterday. Or maybe even \emph{before} yesterday. \\
\textbf{Status}: & This is a “work in progress” \\
Modified: trunk/docutils/test/functional/expected/standalone_rst_xetex.tex
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_xetex.tex 2025-03-30 20:13:14 UTC (rev 10062)
+++ trunk/docutils/test/functional/expected/standalone_rst_xetex.tex 2025-03-30 20:13:30 UTC (rev 10063)
@@ -82,9 +82,7 @@
Example, EX Canada\\
A1B 2C3} \\
\textbf{Contact}: & \href{mailto:go...@py...}{go...@py...} \\
-\textbf{Author}: & Me \\
-\textbf{Author}: & Myself \\
-\textbf{Author}: & I \\
+\textbf{Authors}: & Me, Myself, I \\
\textbf{Organization}: & humankind \\
\textbf{Date}: & Now, or yesterday. Or maybe even \emph{before} yesterday. \\
\textbf{Status}: & This is a “work in progress” \\
Modified: trunk/docutils/test/test_writers/test_latex2e_parts.py
===================================================================
--- trunk/docutils/test/test_writers/test_latex2e_parts.py 2025-03-30 20:13:14 UTC (rev 10062)
+++ trunk/docutils/test/test_writers/test_latex2e_parts.py 2025-03-30 20:13:30 UTC (rev 10063)
@@ -733,6 +733,41 @@
\end{center}
""",
}],
+["""
+:authors: * \\A. *Smith*
+ * \\B. Miller
+:organization: Example & Cie.
+:author: C. Baker
+:organization: Another Example
+""",
+ {'requirements': '\\usepackage[T1]{fontenc}\n'
+ '\\usepackage{tabularx}\n',
+ 'fallbacks': r"""
+% Provide a length variable and set default, if it is new
+\providecommand*{\DUprovidelength}[2]{%
+ \ifdefined#1
+ \else
+ \newlength{#1}\setlength{#1}{#2}%
+ \fi
+}
+
+% width of docinfo table
+\DUprovidelength{\DUdocinfowidth}{0.9\linewidth}
+""",
+ 'pdfsetup': DEFAULT_PARTS['pdfsetup']
+ + '\\hypersetup{\n pdfauthor={A. Smith; B. Miller; C. Baker}\n}\n',
+ 'docinfo': r"""
+% Docinfo
+\begin{center}
+\begin{tabularx}{\DUdocinfowidth}{lX}
+\textbf{Authors}: & A. \emph{Smith}, B. Miller \\
+\textbf{Organization}: & Example \& Cie. \\
+\textbf{Author}: & C. Baker \\
+\textbf{Organization}: & Another Example \\
+\end{tabularx}
+\end{center}
+""",
+ }],
])
samples['book'] = ({'documentclass': 'book'}, [
@@ -1002,8 +1037,25 @@
""",
'body_pre_docinfo': '\\maketitle\n',
}],
-# bibliographic fields
["""
+:authors: * \\A. *Smith*
+ * \\B. Miller
+:organization: Example & Cie.
+:author: C. Baker
+:organization: Another Example
+""",
+ {'pdfsetup': DEFAULT_PARTS['pdfsetup']
+ + '\\hypersetup{\n pdfauthor={A. Smith; B. Miller; C. Baker}\n}\n',
+ 'titledata': r"""\title{}
+\author{A. \emph{Smith} \quad B. Miller\\
+Example \& Cie. \and
+C. Baker\\
+Another Example}
+\date{}
+""",
+ 'body_pre_docinfo': '\\maketitle\n',
+ }],
+["""
:keywords: custom, docinfo, field
""",
{'requirements': '\\usepackage[T1]{fontenc}\n'
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|