You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
(106) |
May
(215) |
Jun
(104) |
Jul
(290) |
Aug
(351) |
Sep
(245) |
Oct
(289) |
Nov
(184) |
Dec
(113) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(179) |
Feb
(88) |
Mar
(77) |
Apr
(70) |
May
(107) |
Jun
(288) |
Jul
(115) |
Aug
(67) |
Sep
(91) |
Oct
(34) |
Nov
(31) |
Dec
(61) |
| 2004 |
Jan
(54) |
Feb
(17) |
Mar
(102) |
Apr
(152) |
May
(178) |
Jun
(377) |
Jul
(136) |
Aug
(37) |
Sep
(196) |
Oct
(142) |
Nov
(119) |
Dec
(58) |
| 2005 |
Jan
(51) |
Feb
(76) |
Mar
(220) |
Apr
(132) |
May
(134) |
Jun
(230) |
Jul
(142) |
Aug
(58) |
Sep
(71) |
Oct
(76) |
Nov
(129) |
Dec
(117) |
| 2006 |
Jan
(94) |
Feb
(30) |
Mar
(97) |
Apr
(63) |
May
(63) |
Jun
(62) |
Jul
(23) |
Aug
(40) |
Sep
(47) |
Oct
(40) |
Nov
(23) |
Dec
(21) |
| 2007 |
Jan
(57) |
Feb
(65) |
Mar
(77) |
Apr
(23) |
May
(118) |
Jun
(127) |
Jul
(87) |
Aug
(33) |
Sep
(26) |
Oct
(8) |
Nov
(4) |
Dec
(25) |
| 2008 |
Jan
(16) |
Feb
(18) |
Mar
(16) |
Apr
(4) |
May
(22) |
Jun
(20) |
Jul
(38) |
Aug
(14) |
Sep
(18) |
Oct
(68) |
Nov
(16) |
Dec
(95) |
| 2009 |
Jan
(28) |
Feb
(16) |
Mar
(8) |
Apr
(44) |
May
(35) |
Jun
(41) |
Jul
(63) |
Aug
(40) |
Sep
(38) |
Oct
(41) |
Nov
(17) |
Dec
(9) |
| 2010 |
Jan
(9) |
Feb
(3) |
Mar
(71) |
Apr
(20) |
May
(15) |
Jun
(16) |
Jul
(33) |
Aug
(13) |
Sep
(39) |
Oct
(30) |
Nov
(25) |
Dec
(20) |
| 2011 |
Jan
(213) |
Feb
(252) |
Mar
(24) |
Apr
(24) |
May
(20) |
Jun
(21) |
Jul
(37) |
Aug
(18) |
Sep
(28) |
Oct
(65) |
Nov
(22) |
Dec
(48) |
| 2012 |
Jan
(35) |
Feb
(39) |
Mar
(17) |
Apr
(9) |
May
(37) |
Jun
(31) |
Jul
(23) |
Aug
(14) |
Sep
(16) |
Oct
(15) |
Nov
(5) |
Dec
(43) |
| 2013 |
Jan
(15) |
Feb
(19) |
Mar
(26) |
Apr
(13) |
May
(9) |
Jun
(11) |
Jul
(32) |
Aug
(9) |
Sep
(6) |
Oct
|
Nov
(13) |
Dec
(5) |
| 2014 |
Jan
(2) |
Feb
(3) |
Mar
(1) |
Apr
|
May
(2) |
Jun
(4) |
Jul
(18) |
Aug
|
Sep
|
Oct
(3) |
Nov
(4) |
Dec
(2) |
| 2015 |
Jan
(3) |
Feb
(25) |
Mar
(49) |
Apr
(28) |
May
(13) |
Jun
(2) |
Jul
(2) |
Aug
(14) |
Sep
(9) |
Oct
(6) |
Nov
|
Dec
(2) |
| 2016 |
Jan
(2) |
Feb
(1) |
Mar
|
Apr
|
May
(12) |
Jun
|
Jul
(17) |
Aug
(7) |
Sep
(3) |
Oct
(2) |
Nov
(5) |
Dec
(28) |
| 2017 |
Jan
(11) |
Feb
(6) |
Mar
(10) |
Apr
(10) |
May
(34) |
Jun
(32) |
Jul
(15) |
Aug
(28) |
Sep
(8) |
Oct
(10) |
Nov
(14) |
Dec
(2) |
| 2018 |
Jan
(8) |
Feb
|
Mar
|
Apr
|
May
|
Jun
(5) |
Jul
(7) |
Aug
|
Sep
(1) |
Oct
|
Nov
(15) |
Dec
|
| 2019 |
Jan
|
Feb
(7) |
Mar
(2) |
Apr
(2) |
May
(2) |
Jun
(2) |
Jul
(48) |
Aug
(73) |
Sep
(22) |
Oct
(8) |
Nov
(16) |
Dec
(26) |
| 2020 |
Jan
(30) |
Feb
(13) |
Mar
(15) |
Apr
(6) |
May
(1) |
Jun
(3) |
Jul
(12) |
Aug
(18) |
Sep
(18) |
Oct
(5) |
Nov
(9) |
Dec
(16) |
| 2021 |
Jan
(13) |
Feb
(17) |
Mar
(19) |
Apr
(70) |
May
(43) |
Jun
(27) |
Jul
(18) |
Aug
(15) |
Sep
(16) |
Oct
(37) |
Nov
(38) |
Dec
(11) |
| 2022 |
Jan
(73) |
Feb
(18) |
Mar
(36) |
Apr
(6) |
May
(8) |
Jun
(33) |
Jul
(22) |
Aug
|
Sep
(6) |
Oct
(71) |
Nov
(91) |
Dec
(26) |
| 2023 |
Jan
(12) |
Feb
(5) |
Mar
(5) |
Apr
(34) |
May
(29) |
Jun
(27) |
Jul
(3) |
Aug
(17) |
Sep
(11) |
Oct
(4) |
Nov
(34) |
Dec
(7) |
| 2024 |
Jan
(16) |
Feb
(27) |
Mar
(60) |
Apr
(57) |
May
(55) |
Jun
(50) |
Jul
(36) |
Aug
(108) |
Sep
(27) |
Oct
(33) |
Nov
(15) |
Dec
(14) |
| 2025 |
Jan
(2) |
Feb
(7) |
Mar
(49) |
Apr
(51) |
May
(35) |
Jun
(34) |
Jul
(10) |
Aug
(32) |
Sep
(27) |
Oct
(1) |
Nov
(13) |
Dec
(12) |
| 2026 |
Jan
(16) |
Feb
(6) |
Mar
(8) |
Apr
(14) |
May
(19) |
Jun
(36) |
Jul
(14) |
Aug
(6) |
Sep
(1) |
Oct
|
Nov
|
Dec
|
|
From: <mi...@us...> - 2026-09-02 15:46:40
|
Revision: 10398
http://sourceforge.net/p/docutils/code/10398
Author: milde
Date: 2026-09-02 15:46:37 +0000 (Wed, 02 Sep 2026)
Log Message:
-----------
Stop `languages.get_language()` from returning incompatible modules.
`get_language()` now returns ``None`` if the module found is not a
compatible translation definitions module. Fixes [bugs:#522].
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/languages/__init__.py
trunk/docutils/test/test_language.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-08-31 08:26:50 UTC (rev 10397)
+++ trunk/docutils/HISTORY.rst 2026-09-02 15:46:37 UTC (rev 10398)
@@ -49,6 +49,11 @@
- Remove `BinaryFileOutput`. Use `FileOutput`
(works with `bytes` since Docutils 0.20).
+* docutils/languages/__init__.py
+
+ - `get_language()` now returns ``None`` if the module found is not a
+ compatible language definitions module. Fixes bug #522.
+
* docutils/nodes.py
- Remove "name" from `reference.valid_attributes`.
Modified: trunk/docutils/docutils/languages/__init__.py
===================================================================
--- trunk/docutils/docutils/languages/__init__.py 2026-08-31 08:26:50 UTC (rev 10397)
+++ trunk/docutils/docutils/languages/__init__.py 2026-09-02 15:46:37 UTC (rev 10398)
@@ -55,8 +55,8 @@
self.cache: dict[str, LanguageModuleT] = {}
def import_from_packages(self, name: str, reporter: Reporter = None
- ) -> LanguageModuleT:
- """Try loading module `name` from `self.packages`."""
+ ) -> LanguageModuleT|None:
+ """Try loading language module `name` from `self.packages`."""
module = None
for package in self.packages:
try:
@@ -70,6 +70,8 @@
reporter.info(f'Module "{package+name}" not found.')
continue
break
+ else:
+ module = None
return module
@overload
Modified: trunk/docutils/test/test_language.py
===================================================================
--- trunk/docutils/test/test_language.py 2026-08-31 08:26:50 UTC (rev 10397)
+++ trunk/docutils/test/test_language.py 2026-09-02 15:46:37 UTC (rev 10398)
@@ -116,5 +116,27 @@
self.assertIn(name, set(module.roles.values()))
+class LanguageTestCase(unittest.TestCase):
+
+ def test_get_language_fallback(self):
+ # Return fallback (English) for unsupported languages ...
+ module = languages.get_language('xx-xxx')
+ self.assertEqual(module, languages.en)
+ # also, if there is an equally named module in the Python path.
+ module = languages.get_language('re') # the regular expressions module
+ self.assertEqual(module, languages.en)
+
+
+class RstLanguageTestCase(unittest.TestCase):
+
+ def test_get_language_fallback(self):
+ # Return None for unsupported languages ...
+ module = rst_languages.get_language('xx-xxx')
+ self.assertEqual(module, None)
+ # also, if there is an equally named module in the Python path.
+ module = rst_languages.get_language('re') # regular expressions module
+ self.assertEqual(module, None)
+
+
if __name__ == '__main__':
unittest.main()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-08-31 08:26:53
|
Revision: 10397
http://sourceforge.net/p/docutils/code/10397
Author: milde
Date: 2026-08-31 08:26:50 +0000 (Mon, 31 Aug 2026)
Log Message:
-----------
Store the "colwidth" attribute as a `str` variable.
To match the definition as a measure (value + optional unit) in the
"Exchange Table Model", the `"colwidth" attribute`_ is stored as
a `str` value (instead of `int`) in Python element instances.
This opens the way to allow fixed length units in later Docutils versions
and to change the default unit to the Exchange Table Model's "pt".
The "xml" writer adds the "proportional unit" symbol "*" to "colwidth" values.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/ref/doctree.rst
trunk/docutils/docutils/nodes.py
trunk/docutils/docutils/parsers/rst/directives/__init__.py
trunk/docutils/docutils/parsers/rst/directives/tables.py
trunk/docutils/docutils/parsers/rst/states.py
trunk/docutils/docutils/writers/docutils_xml.py
trunk/docutils/test/functional/expected/standalone_rst_docutils_xml.xml
trunk/docutils/test/test_parsers/test_docutils_xml/test_parse_element.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-08-30 19:26:53 UTC (rev 10396)
+++ trunk/docutils/HISTORY.rst 2026-08-31 08:26:50 UTC (rev 10397)
@@ -58,6 +58,7 @@
generate identifiers only if the `legacy_ids`_ setting is True.
- Add `Targetable` to parent classes of `inline` to allow test whether
inline internal targets are referenced.
+ - `validate_colwidth()` now returns a `str`.
* docutils/parsers/__init__.py
@@ -76,6 +77,8 @@
* docutils/parsers/rst/directives/__init__.py
- Remove `length_units` (replaced by the tuple CSS3_LENGTH_UNITS).
+ - New option conversion function `column_widths()` (provisional):
+ ignore "proportional unit symbol" ``*``, return list of strings.
* docutils/parsers/rst/directives/images.py
@@ -95,6 +98,8 @@
arguments has content above and below directive options.
- Ignore the "match_titles" argument of `RSTState.nested_list_parse()`.
- Use <inline> elements in `inline_internal_target()`.
+ - The "colwidth_" attribute of `nodes.colspec` instances
+ is now stored as a `str` (instead of numerical) value .
* docutils/readers/standalone.py
@@ -182,6 +187,8 @@
- Do not activate the "external-general-entities" feature of the
SAX parser used to check raw XML content. Fixes bug #521.
+ - Add the "proportional unit" ``*`` to "colwidth_" attribute values
+ (to comply with with the CALS `Exchange Table Model`).
Release 0.23 (2026-05-27)
@@ -5081,10 +5088,11 @@
.. _length unit:
.. _length units: docs/ref/rst/restructuredtext.html#length-units
-.. _<meta>: docs/ref/doctree.html#meta
+.. _colwidth: docs/ref/doctree.html#colwidth
.. _<image>: docs/ref/doctree.html#image
.. _<inline>: docs/ref/doctree.html#inline
.. _<literal>: docs/ref/doctree.html#literal
+.. _<meta>: docs/ref/doctree.html#meta
.. Emacs settings
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-08-30 19:26:53 UTC (rev 10396)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-08-31 08:26:50 UTC (rev 10397)
@@ -50,10 +50,9 @@
deprecated and will be invalid in Docutils 2.0. (The "rst" parser
uses <inline> elements for `inline targets`_ since Docutils 1.0.)
-* To match the definition in the "Exchange Table Model", the
- `"colwidth" attribute`_ will be stored as a `str` (instead of
- numerical) value in Python element instances in Docutils 1.0.
- Proportional values will be stored with unit "*" in Docutils 2.0.
+* To match the definition in the "Exchange Table Model", values of the
+ `"colwidth" attribute`_ will be stored with the "proportional unit
+ symbol" ``*`` and accept fixed length units in Docutils 2.0.
The default unit will change to "pt" in Docutils 3.0.
* The `\<doctest_block>`_ element will be deprecated in Docutils 1.0.
@@ -217,6 +216,9 @@
to customize the <table> element's attribute list in Docutils 1.0.
- Inline `\<target>`_ elements and <target> elements with content are
deprecated.
+ - The `"colwidth" attribute`_ of `nodes.colspec` instances
+ is now stored as a `str` (instead of `int`) value.
+ The XML writer adds the "proportional unit symbol" ``*``.
Configuration changes:
- `Auto-detection`_ of the input encoding is no longer supported.
Modified: trunk/docutils/docs/ref/doctree.rst
===================================================================
--- trunk/docutils/docs/ref/doctree.rst 2026-08-30 19:26:53 UTC (rev 10396)
+++ trunk/docutils/docs/ref/doctree.rst 2026-08-31 08:26:50 UTC (rev 10397)
@@ -4733,13 +4733,13 @@
(positive number followed by "*", e.g., "5*" for 5 times the
`unit proportion`_ , or just "*" for one unit proportion)
or a *fixed measure* (e.g., 2.5cm).
+
Docutils supports only proportional measures.
.. important::
- Currently, Docutils stores "colwidth" values as numbers and
- interprets unitless values as proportional measures while the
- `Exchange Table Model` uses the default unit "pt".
- This will change__ in future versions of Docutils.
+ Currently, Docutils interprets unitless values as proportional
+ measures while the `Exchange Table Model` uses the default unit "pt".
+ This will change__ in future versions.
__ https://www.oasis-open.org/specs/tm9901.html#AEN530
__ ../../RELEASE-NOTES.html#document-tree-docutils-dtd
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-08-30 19:26:53 UTC (rev 10396)
+++ trunk/docutils/docutils/nodes.py 2026-08-31 08:26:50 UTC (rev 10397)
@@ -2613,9 +2613,19 @@
__ https://docutils.sourceforge.io/docs/ref/doctree.html#colwidth
"""
- # Move current implementation of validate_colwidth() here
- # in Docutils 1.0
- return validate_colwidth(self.get('colwidth', ''))
+ measure = self.get('colwidth', '')
+ if isinstance(measure, (int, float)):
+ value = measure
+ elif measure in ('*', ''): # short for '1*'
+ value = 1
+ else:
+ try:
+ value, _unit = parse_measure(measure, unit_pattern='[*]?')
+ except ValueError:
+ value = -1
+ if value <= 0:
+ raise ValueError(f'"{measure}" is no proportional measure.')
+ return value
class thead(Part, Element):
@@ -3227,29 +3237,27 @@
return f'{value}{unit}'
-def validate_colwidth(measure: str|int|float) -> int|float:
+def validate_colwidth(measure: str|int|float) -> str:
"""Validate the "colwidth__" attribute.
Provisional:
- `measure` must be a `str` and will be returned as normalized `str`
- (with unit "*" for proportional values) in Docutils 1.0.
+ Accept fixed length units in Docutils 2.0.
+ The default unit will change to "pt" in Docutils 3.0.
- The default unit will change to "pt" in Docutils 2.0.
-
__ https://docutils.sourceforge.io/docs/ref/doctree.html#colwidth
"""
if isinstance(measure, (int, float)):
- value = measure
+ value, unit = measure, ''
elif measure in ('*', ''): # short for '1*'
- value = 1
+ value, unit = 1, ''
else:
try:
- value, _unit = parse_measure(measure, unit_pattern='[*]?')
+ value, unit = parse_measure(measure, unit_pattern='[*]?')
except ValueError:
value = -1
if value <= 0:
raise ValueError(f'"{measure}" is no proportional measure.')
- return value
+ return f'{value}{unit}'
def validate_NMTOKEN(value: str) -> str:
Modified: trunk/docutils/docutils/parsers/rst/directives/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/directives/__init__.py 2026-08-30 19:26:53 UTC (rev 10396)
+++ trunk/docutils/docutils/parsers/rst/directives/__init__.py 2026-08-31 08:26:50 UTC (rev 10397)
@@ -399,6 +399,8 @@
(Directive option conversion function.)
Raises ValueError for non-positive-integer values.
+
+ Provisional. May be removed in Docutils 2.0 or later.
"""
if ',' in argument:
entries = argument.split(',')
@@ -482,3 +484,23 @@
return parsers.get_parser_class(argument)
except ImportError as err:
raise ValueError(str(err))
+
+
+def column_widths(argument: str) -> list[str]:
+ """
+ Conversion function for the ``widths`` option of the table directives.
+
+ Converts string with a space- or comma-separated list of proportional
+ width values (with optional unit symbol "*") into a list of values.
+ Raises ValueError for non-positive and non-integer values.
+
+ Provisional.
+ See docs/ref/rst/directives.html#table-options
+ and docs/ref/doctree.html#colwidth.
+ """
+ # remove optional "proportional unit" symbol:
+ argument = argument.replace('*', '')
+ # extract values:
+ widths = positive_int_list(argument)
+ # return list of strings
+ return [f'{width}' for width in widths]
Modified: trunk/docutils/docutils/parsers/rst/directives/tables.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/directives/tables.py 2026-08-30 19:26:53 UTC (rev 10396)
+++ trunk/docutils/docutils/parsers/rst/directives/tables.py 2026-08-31 08:26:50 UTC (rev 10397)
@@ -39,7 +39,7 @@
'align': align,
'width': directives.length_or_percentage_or_unitless,
'widths': directives.value_or(('auto', 'grid'),
- directives.positive_int_list)}
+ directives.column_widths)}
has_content = True
def make_title(self):
@@ -108,7 +108,7 @@
raise SystemMessagePropagation(error)
col_widths = self.widths
elif n_cols:
- col_widths = [100 // n_cols] * n_cols
+ col_widths = [f'{100//n_cols}'] * n_cols
else:
error = self.reporter.error('No table data detected in CSV file.',
nodes.literal_block(self.block_text, self.block_text),
@@ -181,7 +181,7 @@
'header': directives.unchanged,
'width': directives.length_or_percentage_or_unitless,
'widths': directives.value_or(('auto', ),
- directives.positive_int_list),
+ directives.column_widths),
'file': directives.path,
'url': directives.uri,
'encoding': directives.encoding,
@@ -377,7 +377,7 @@
'stub-columns': directives.nonnegative_int,
'width': directives.length_or_percentage_or_unitless,
'widths': directives.value_or(('auto', ),
- directives.positive_int_list),
+ directives.column_widths),
'class': directives.class_option,
'name': directives.unchanged,
'align': align}
Modified: trunk/docutils/docutils/parsers/rst/states.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/states.py 2026-08-30 19:26:53 UTC (rev 10396)
+++ trunk/docutils/docutils/parsers/rst/states.py 2026-08-31 08:26:50 UTC (rev 10397)
@@ -1915,7 +1915,7 @@
tgroup = nodes.tgroup(cols=len(colwidths))
table += tgroup
for colwidth in colwidths:
- colspec = nodes.colspec(colwidth=colwidth)
+ colspec = nodes.colspec(colwidth=str(colwidth))
if stub_columns:
colspec.attributes['stub'] = True
stub_columns -= 1
Modified: trunk/docutils/docutils/writers/docutils_xml.py
===================================================================
--- trunk/docutils/docutils/writers/docutils_xml.py 2026-08-30 19:26:53 UTC (rev 10396)
+++ trunk/docutils/docutils/writers/docutils_xml.py 2026-08-31 08:26:50 UTC (rev 10397)
@@ -157,6 +157,18 @@
def depart_Text(self, node) -> None:
pass
+ def visit_colspec(self, node):
+ # add the "proportional unit" (``*``)
+ # provisional, will be removed in Docutils 2.0
+ cspec = node.copy()
+ cwidth = cspec['colwidth']
+ if cwidth and cwidth[-1].isdigit():
+ cspec['colwidth'] = f"{cwidth}*"
+ self.default_visit(cspec)
+
+ def depart_cospec(self, node):
+ self.default_departure(node)
+
def visit_raw(self, node):
if 'xml' not in node.get('format', '').split():
# skip other raw content?
Modified: trunk/docutils/test/functional/expected/standalone_rst_docutils_xml.xml
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_docutils_xml.xml 2026-08-30 19:26:53 UTC (rev 10396)
+++ trunk/docutils/test/functional/expected/standalone_rst_docutils_xml.xml 2026-08-31 08:26:50 UTC (rev 10397)
@@ -853,8 +853,8 @@
<legend>
<table>
<tgroup cols="2">
- <colspec colwidth="12"></colspec>
- <colspec colwidth="47"></colspec>
+ <colspec colwidth="12*"></colspec>
+ <colspec colwidth="47*"></colspec>
<tbody>
<row>
<entry>
@@ -929,8 +929,8 @@
<table align="left">
<title>left-aligned table</title>
<tgroup cols="2">
- <colspec colwidth="5"></colspec>
- <colspec colwidth="5"></colspec>
+ <colspec colwidth="5*"></colspec>
+ <colspec colwidth="5*"></colspec>
<thead>
<row>
<entry>
@@ -964,8 +964,8 @@
<table align="center">
<title>center-aligned table</title>
<tgroup cols="2">
- <colspec colwidth="5"></colspec>
- <colspec colwidth="5"></colspec>
+ <colspec colwidth="5*"></colspec>
+ <colspec colwidth="5*"></colspec>
<thead>
<row>
<entry>
@@ -999,8 +999,8 @@
<table align="right">
<title>right-aligned table</title>
<tgroup cols="2">
- <colspec colwidth="5"></colspec>
- <colspec colwidth="5"></colspec>
+ <colspec colwidth="5*"></colspec>
+ <colspec colwidth="5*"></colspec>
<thead>
<row>
<entry>
@@ -1038,9 +1038,9 @@
<target refid="target2"></target>
<table classes="colwidths-auto" ids="target2 target1" names="target2 target1">
<tgroup cols="3">
- <colspec colwidth="7"></colspec>
- <colspec colwidth="7"></colspec>
- <colspec colwidth="10"></colspec>
+ <colspec colwidth="7*"></colspec>
+ <colspec colwidth="7*"></colspec>
+ <colspec colwidth="10*"></colspec>
<thead>
<row>
<entry>
@@ -1254,9 +1254,9 @@
elements in one logical paragraph. First a table,</paragraph>
<table>
<tgroup cols="3">
- <colspec colwidth="20"></colspec>
- <colspec colwidth="20"></colspec>
- <colspec colwidth="20"></colspec>
+ <colspec colwidth="20*"></colspec>
+ <colspec colwidth="20*"></colspec>
+ <colspec colwidth="20*"></colspec>
<tbody>
<row>
<entry>
@@ -1424,9 +1424,9 @@
<paragraph>This table has a cell spanning two columns:</paragraph>
<table>
<tgroup cols="3">
- <colspec colwidth="5"></colspec>
- <colspec colwidth="5"></colspec>
- <colspec colwidth="6"></colspec>
+ <colspec colwidth="5*"></colspec>
+ <colspec colwidth="5*"></colspec>
+ <colspec colwidth="6*"></colspec>
<thead>
<row>
<entry morecols="1">
@@ -1502,9 +1502,9 @@
<paragraph>Here's a table with cells spanning several rows:</paragraph>
<table>
<tgroup cols="3">
- <colspec colwidth="24"></colspec>
- <colspec colwidth="12"></colspec>
- <colspec colwidth="18"></colspec>
+ <colspec colwidth="24*"></colspec>
+ <colspec colwidth="12*"></colspec>
+ <colspec colwidth="18*"></colspec>
<thead>
<row>
<entry>
@@ -1559,10 +1559,10 @@
<paragraph>Here's a complex table, which should test all features.</paragraph>
<table>
<tgroup cols="4">
- <colspec colwidth="24"></colspec>
- <colspec colwidth="12"></colspec>
- <colspec colwidth="10"></colspec>
- <colspec colwidth="10"></colspec>
+ <colspec colwidth="24*"></colspec>
+ <colspec colwidth="12*"></colspec>
+ <colspec colwidth="10*"></colspec>
+ <colspec colwidth="10*"></colspec>
<thead>
<row>
<entry>
@@ -1652,9 +1652,9 @@
<table classes="colwidths-given test" width="95%">
<title>list table with integral header</title>
<tgroup cols="3">
- <colspec colwidth="10" stub="1"></colspec>
- <colspec colwidth="8"></colspec>
- <colspec colwidth="20"></colspec>
+ <colspec colwidth="10*" stub="1"></colspec>
+ <colspec colwidth="8*"></colspec>
+ <colspec colwidth="20*"></colspec>
<thead>
<row>
<entry>
@@ -1709,8 +1709,8 @@
<table align="center" classes="colwidths-auto">
<title>center aligned list table</title>
<tgroup cols="2">
- <colspec colwidth="50"></colspec>
- <colspec colwidth="50"></colspec>
+ <colspec colwidth="50*"></colspec>
+ <colspec colwidth="50*"></colspec>
<tbody>
<row>
<entry>
Modified: trunk/docutils/test/test_parsers/test_docutils_xml/test_parse_element.py
===================================================================
--- trunk/docutils/test/test_parsers/test_docutils_xml/test_parse_element.py 2026-08-30 19:26:53 UTC (rev 10396)
+++ trunk/docutils/test/test_parsers/test_docutils_xml/test_parse_element.py 2026-08-31 08:26:50 UTC (rev 10397)
@@ -165,12 +165,12 @@
# from the Exchange Table Model. This will eventually change
# (see https://docutils.sourceforge.io/docs/ref/doctree.html#colwidth).
xml = '<colspec colwidth="33*" stub="1" />'
- expected = {'colwidth': 33, 'stub': 1}
+ expected = {'colwidth': '33*', 'stub': True}
node = docutils_xml.parse_element(xml)
self.assertEqual(node.attributes, self.common_attributes | expected)
# Note: the upstream default unit is "pt", not "*".
xml = '<colspec colwidth="33" stub="1" />'
- expected = {'colwidth': 33, 'stub': 1}
+ expected = {'colwidth': '33', 'stub': True}
node = docutils_xml.parse_element(xml)
self.assertEqual(node.attributes, self.common_attributes | expected)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-08-30 19:26:54
|
Revision: 10396
http://sourceforge.net/p/docutils/code/10396
Author: milde
Date: 2026-08-30 19:26:53 +0000 (Sun, 30 Aug 2026)
Log Message:
-----------
Small fixes.
Correct description of current command line interface in RELEASE-NOTES
"future changes". More concise HISTORY.
Fix/Complete typing hints for directive option validating functions.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docutils/parsers/rst/directives/__init__.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-08-22 20:59:31 UTC (rev 10395)
+++ trunk/docutils/HISTORY.rst 2026-08-30 19:26:53 UTC (rev 10396)
@@ -168,8 +168,7 @@
* docutils/writers/odf_odt/__init__.py
- - Update `Reader.get_transforms()` to remove two of the transforms
- obsoleting `references.DanglingReferences`.
+ - Update `Reader.get_transforms()`.
* docutils/writers/pep_html/__init__.py
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-08-22 20:59:31 UTC (rev 10395)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-08-30 19:26:53 UTC (rev 10396)
@@ -33,7 +33,7 @@
.. code:: diff
- - COMMAND [OPTIONS] [SOURCE [DESTINATION]]
+ - COMMAND [OPTIONS] [SOURCE]
+ COMMAND [OPTIONS] [SOURCE [SOURCE2 [...]]]
Modified: trunk/docutils/docutils/parsers/rst/directives/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/directives/__init__.py 2026-08-22 20:59:31 UTC (rev 10395)
+++ trunk/docutils/docutils/parsers/rst/directives/__init__.py 2026-08-30 19:26:53 UTC (rev 10396)
@@ -20,7 +20,9 @@
TYPE_CHECKING = False
if TYPE_CHECKING:
- from collections.abc import Callable, Sequence
+ from collections.abc import Callable, Container, Sequence
+ from typing import Any
+ from docutils.parsers.rst.languages import RSTLanguageModule
_directive_registry = {
@@ -80,7 +82,10 @@
"""Cache of imported directives."""
-def directive(directive_name, language_module, document):
+def directive(directive_name: str,
+ language_module: RSTLanguageModule,
+ document: nodes.document,
+ ) -> tuple[parsers.rst.Directive, list[nodes.system_message]]:
"""
Locate and return a directive function from its language-dependent name.
If not found in the current language, check English. Return None if the
@@ -139,7 +144,7 @@
return directive, messages
-def register_directive(name, directive) -> None:
+def register_directive(name: str, directive: Callable) -> None:
"""
Register a nonstandard application-defined directive function.
Language lookups are not needed for such functions.
@@ -153,7 +158,7 @@
# see also `parsers.rst.Directive` in ../__init__.py.
-def flag(argument: str) -> None:
+def flag(argument: str|None) -> None:
"""
Check for a valid flag option (no argument) and return ``None``.
(Directive option conversion function.)
@@ -166,7 +171,7 @@
return None
-def unchanged_required(argument: str) -> str:
+def unchanged_required(argument: str|None) -> str:
"""
Return the argument text, unchanged.
@@ -180,7 +185,7 @@
return argument # unchanged!
-def unchanged(argument: str) -> str:
+def unchanged(argument: str|None) -> str:
"""
Return the argument text, unchanged.
(Directive option conversion function.)
@@ -193,7 +198,7 @@
return argument # unchanged!
-def path(argument: str) -> str:
+def path(argument: str|None) -> str:
"""
Return the path argument unwrapped (with newlines removed).
(Directive option conversion function.)
@@ -206,7 +211,7 @@
return ''.join(s.strip() for s in argument.splitlines())
-def uri(argument: str) -> str:
+def uri(argument: str|None) -> str:
"""
Return the URI argument with unescaped whitespace removed.
(Directive option conversion function.)
@@ -221,7 +226,7 @@
for part in parts)
-def nonnegative_int(argument: str) -> int:
+def nonnegative_int(argument: str|int|None) -> int:
"""
Check for a nonnegative integer argument; raise ``ValueError`` if not.
(Directive option conversion function.)
@@ -232,7 +237,7 @@
return value
-def percentage(argument: str) -> int:
+def percentage(argument: str|int|None) -> int:
"""
Check for an integer percentage value with optional percent sign.
(Directive option conversion function.)
@@ -254,7 +259,7 @@
"""
-def get_measure(argument, units):
+def get_measure(argument: str|None, units: Container[str]) -> str:
"""
Check for a positive argument of one of the `units`.
@@ -271,11 +276,12 @@
return f'{value}{unit}'
-def length_or_unitless(argument: str) -> str:
+def length_or_unitless(argument: str|None) -> str:
return get_measure(argument, CSS3_LENGTH_UNITS + ('',))
-def length_or_percentage_or_unitless(argument, default=''):
+def length_or_percentage_or_unitless(argument: str|None,
+ default: str = '') -> str:
"""
Return normalized string of a length or percentage unit.
(Directive option conversion function.)
@@ -301,7 +307,7 @@
raise error
-def class_option(argument: str) -> list[str]:
+def class_option(argument: str|None) -> list[str]:
"""
Convert the argument into a list of ID-compatible strings and return it.
(Directive option conversion function.)
@@ -324,7 +330,7 @@
r'(?:0x|x|\\x|U\+?|\\u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE)
-def unicode_code(code):
+def unicode_code(code: str|None) -> str:
r"""
Convert a Unicode character code to a Unicode character.
(Directive option conversion function.)
@@ -349,7 +355,7 @@
raise ValueError('code too large (%s)' % detail)
-def single_char_or_unicode(argument: str) -> str:
+def single_char_or_unicode(argument: str|None) -> str:
"""
A single character is returned as-is. Unicode character codes are
converted as in `unicode_code`. (Directive option conversion function.)
@@ -361,7 +367,7 @@
return char
-def single_char_or_whitespace_or_unicode(argument: str) -> str:
+def single_char_or_whitespace_or_unicode(argument: str|None) -> str:
"""
As with `single_char_or_unicode`, but "tab" and "space" are also supported.
(Directive option conversion function.)
@@ -375,7 +381,7 @@
return char
-def positive_int(argument: str) -> int:
+def positive_int(argument: str|None|int) -> int:
"""
Converts the argument into an integer. Raises ValueError for negative,
zero, or non-integer values. (Directive option conversion function.)
@@ -386,7 +392,7 @@
return value
-def positive_int_list(argument: str) -> list[int]:
+def positive_int_list(argument: str|None) -> list[int]:
"""
Converts a space- or comma-separated list of values into a Python list
of integers.
@@ -401,7 +407,7 @@
return [positive_int(entry) for entry in entries]
-def encoding(argument: str) -> str:
+def encoding(argument: str|None) -> str:
"""
Verifies the encoding argument by lookup.
(Directive option conversion function.)
@@ -415,7 +421,7 @@
return argument
-def choice(argument, values):
+def choice(argument: str|None, values: Sequence[str]) -> str:
"""
Directive option utility function, supplied to enable options whose
argument must be a member of a finite set of possible values (must be
@@ -442,26 +448,27 @@
% (argument, format_values(values)))
-def format_values(values) -> str:
+def format_values(values: Sequence[str]) -> str:
return '%s, or "%s"' % (', '.join('"%s"' % s for s in values[:-1]),
values[-1])
-def value_or(values: Sequence[str], other: type) -> Callable:
+def value_or(values: Container[str], other: Callable) -> Callable:
"""
Directive option conversion function.
- The argument can be any of `values` or `argument_type`.
+ The argument can be any of `values` or a value compatible with the
+ directive option conversion function `other`.
"""
- def auto_or_other(argument: str):
+ def one_or_other(argument: str|None) -> Any:
if argument in values:
return argument
else:
return other(argument)
- return auto_or_other
+ return one_or_other
-def parser_name(argument: str) -> type[parsers.Parser]:
+def parser_name(argument: str|None) -> type[parsers.Parser]:
"""
Return a docutils parser whose name matches the argument.
(Directive option conversion function.)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-08-22 20:59:33
|
Revision: 10395
http://sourceforge.net/p/docutils/code/10395
Author: milde
Date: 2026-08-22 20:59:31 +0000 (Sat, 22 Aug 2026)
Log Message:
-----------
Stop XML writer from loading external entities when checking raw XML.
Do not activate the "external-general-entities" feature
of the SAX parser used to check raw XML content.
Fixes [bugs:#521].
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/writers/docutils_xml.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-08-21 08:27:55 UTC (rev 10394)
+++ trunk/docutils/HISTORY.rst 2026-08-22 20:59:31 UTC (rev 10395)
@@ -179,7 +179,12 @@
by the HTML writers are of data type str.")
- HTML-escape `interpolation_dict` values extracted from the index.
+* docutils/writers/docutils_xml.py
+ - Do not activate the "external-general-entities" feature of the
+ SAX parser used to check raw XML content. Fixes bug #521.
+
+
Release 0.23 (2026-05-27)
=========================
Modified: trunk/docutils/docutils/writers/docutils_xml.py
===================================================================
--- trunk/docutils/docutils/writers/docutils_xml.py 2026-08-21 08:27:55 UTC (rev 10394)
+++ trunk/docutils/docutils/writers/docutils_xml.py 2026-08-22 20:59:31 UTC (rev 10395)
@@ -75,9 +75,7 @@
generator = '<!-- Generated by Docutils %s -->\n'
xmlparser = xml.sax.make_parser()
- """SAX parser instance to check/extract raw XML."""
- xmlparser.setFeature(
- "http://xml.org/sax/features/external-general-entities", True)
+ """SAX parser instance to check raw XML."""
def __init__(self, document) -> None:
nodes.NodeVisitor.__init__(self, document)
@@ -170,7 +168,7 @@
xml_string = node.astext()
self.output.append(xml_string)
self.default_departure(node) # or not?
- # Check validity of raw XML:
+ # Parse XML content to check for errors:
try:
self.xmlparser.parse(StringIO(xml_string))
except xml.sax._exceptions.SAXParseException:
@@ -179,8 +177,8 @@
srcline = node.line
if not isinstance(node.parent, nodes.TextElement):
srcline += 2 # directive content start line
- msg = 'Invalid raw XML in column %d, line offset %d:\n%s' % (
- col_num, line_num, node.astext())
+ msg = (f'Invalid raw XML in column {col_num}, '
+ f'line offset {line_num}:\n{node.astext()}')
self.warn(msg, source=node.source, line=srcline+line_num-1)
raise nodes.SkipNode # content already processed
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-08-21 08:27:57
|
Revision: 10394
http://sourceforge.net/p/docutils/code/10394
Author: milde
Date: 2026-08-21 08:27:55 +0000 (Fri, 21 Aug 2026)
Log Message:
-----------
Avoid unescaped special characters in PEP HTML output.
Do not use a "raw" html node to mask author email address in PEP transforms.
The email masking is now a bit less obscuring but this should be OK for
local previews (the official PEPs are produced with a different toolchain).
Escape special HTML characters in HTML header generated from index metadata.
Fixes [bugs:#519].
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/transforms/peps.py
trunk/docutils/docutils/writers/pep_html/__init__.py
trunk/docutils/test/functional/expected/pep_html.html
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-08-21 08:27:15 UTC (rev 10393)
+++ trunk/docutils/HISTORY.rst 2026-08-21 08:27:55 UTC (rev 10394)
@@ -113,6 +113,10 @@
- Clear "ids" and "names" in `ContentsFilter` so ids and names stay
unique when copying section title content for the ToC entry.
+* docutils/transforms/peps.py:
+
+ - Don't use raw HTML for masked email addresses.
+
* docutils/transforms/references.py
- `IndirectHyperlinks.resolve_indirect_target()` no longer calls
@@ -173,6 +177,7 @@
`.Writer.assemble_parts()` from `list` to `str`.
(`The Docutils Publisher` says: "all parts returned
by the HTML writers are of data type str.")
+ - HTML-escape `interpolation_dict` values extracted from the index.
Release 0.23 (2026-05-27)
Modified: trunk/docutils/docutils/transforms/peps.py
===================================================================
--- trunk/docutils/docutils/transforms/peps.py 2026-08-21 08:27:15 UTC (rev 10393)
+++ trunk/docutils/docutils/transforms/peps.py 2026-08-21 08:27:55 UTC (rev 10394)
@@ -319,8 +319,8 @@
if ref['refuri'][8:] in non_masked_addresses:
replacement = ref[0]
else:
- replacement_text = ref.astext().replace('@', ' at ')
- replacement = nodes.raw('', replacement_text, format='html')
+ replacement_text = ref.astext().replace('@', ' at ')
+ replacement = nodes.Text(replacement_text)
if pepno is None:
return replacement
else:
Modified: trunk/docutils/docutils/writers/pep_html/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/pep_html/__init__.py 2026-08-21 08:27:15 UTC (rev 10393)
+++ trunk/docutils/docutils/writers/pep_html/__init__.py 2026-08-21 08:27:55 UTC (rev 10394)
@@ -10,6 +10,7 @@
__docformat__ = 'reStructuredText'
+import html
import os
import os.path
@@ -66,12 +67,12 @@
index = self.document.first_child_matching_class(nodes.field_list)
header = self.document[index]
self.pepnum = header[0][1].astext()
- subs['pep'] = self.pepnum
+ subs['pep'] = html.escape(self.pepnum)
try:
subs['pepnum'] = '%04i' % int(self.pepnum)
except ValueError:
subs['pepnum'] = self.pepnum
- self.title = header[1][1].astext()
+ self.title = html.escape(header[1][1].astext())
subs['title'] = self.title
subs['body'] = ''.join(
self.body_pre_docinfo + self.docinfo + self.body)
Modified: trunk/docutils/test/functional/expected/pep_html.html
===================================================================
--- trunk/docutils/test/functional/expected/pep_html.html 2026-08-21 08:27:15 UTC (rev 10393)
+++ trunk/docutils/test/functional/expected/pep_html.html 2026-08-21 08:27:55 UTC (rev 10394)
@@ -33,9 +33,9 @@
</tr>
<tr class="field"><th class="field-name">Last-Modified:</th><td class="field-body"><a class="reference external" href="http://hg.python.org/peps/file/default/pep-0100.txt">A long time ago.</a></td>
</tr>
-<tr class="field"><th class="field-name">Author:</th><td class="field-body">John Doe <john at example.org></td>
+<tr class="field"><th class="field-name">Author:</th><td class="field-body">John Doe <john at example.org></td>
</tr>
-<tr class="field"><th class="field-name">Discussions-To:</th><td class="field-body"><<a class="reference external" href="mailto:devnull%40example.org?subject=PEP%20100">devnull at example.org</a>></td>
+<tr class="field"><th class="field-name">Discussions-To:</th><td class="field-body"><<a class="reference external" href="mailto:devnull%40example.org?subject=PEP%20100">devnull at example<span>.</span>org</a>></td>
</tr>
<tr class="field"><th class="field-name">Status:</th><td class="field-body">Draft</td>
</tr>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-08-21 08:27:18
|
Revision: 10393
http://sourceforge.net/p/docutils/code/10393
Author: milde
Date: 2026-08-21 08:27:15 +0000 (Fri, 21 Aug 2026)
Log Message:
-----------
Deprecate obsolete parts of PEP processing.
Since several years, PEPs are no longer generated using Docutils' "rst2pephtml"
but a Sphinx with https://github.com/python/peps/tree/main/pep_sphinx_extensions.
We keep the PEP reader and writer as a way for PEP authors to easily preview
their drafts and edits (when restricting the rST content to the directives and
roles supported by Docutils).
Deprecate the `--no-random`, `--pep-home`, and `--python-home` settings
of the "pep_html" writer and hide them from the command line help.
Also deprecate the `transforms.peps.PEPZero` and `transforms.peps.PEPZeroSpecial`
classes. (PEP 0 is no longer generated from a rST source.)
Announce removals in Docutils 2.0.
Modified Paths:
--------------
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/user/config.rst
trunk/docutils/docutils/transforms/peps.py
trunk/docutils/docutils/writers/pep_html/__init__.py
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-08-20 22:07:10 UTC (rev 10392)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-08-21 08:27:15 UTC (rev 10393)
@@ -148,6 +148,15 @@
* Drop short option ``-e`` in Docutils 2.0.
Use the long equivalent ``--error-encoding``.
+* Remove the configuration settings `no_random`, `pep_home`, and
+ `python_home` of the "pep_html" writer in Docutils 2.0.
+ The first two are ignored since Docutils 0.19, the Python home URL
+ is pretty stable by now and can be adapted in a custom template.
+
+ Remove `transforms.peps.PEPZero` and `transforms.peps.PEPZeroSpecial`
+ in Docutils 2.0.
+ PEP 0 (the PEP index) is no longer generated from a rST source.
+
* Remove the "reader_name", "parser_name", and "writer_name" arguments of
`core.Publisher.__init__()` and the `core.publish_*()` convenience
functions as well as the "parser_name" argument of `Reader.__init__()`
Modified: trunk/docutils/docs/user/config.rst
===================================================================
--- trunk/docutils/docs/user/config.rst 2026-08-20 22:07:10 UTC (rev 10392)
+++ trunk/docutils/docs/user/config.rst 2026-08-21 08:27:15 UTC (rev 10393)
@@ -1444,8 +1444,8 @@
Path [#pwd]_ to template file, which must be encoded in UTF-8.
See also `template [latex writers]`_.
-:Default: "template.txt" in the writer's directory (installed automatically)
- For the exact machine-specific path, use the ``--help`` option).
+:Default: "template.txt" in the writer's directory (installed automatically).
+ [#machine-specific-path]_
:Option: ``--template``.
@@ -1569,29 +1569,33 @@
.. class:: run-in narrow
:`initial_header_level`_: 1 (for "<h1>").
-:`stylesheet_path <stylesheet_path [html writers]_>`__: "pep.css".
+:`stylesheet_path <stylesheet_path [html writers]_>`__:
+ ``docutils/writers/pep_html/pep.css`` in the installation directory.
+ [#machine-specific-path]_
:`template <template [html writers]_>`__:
``docutils/writers/pep_html/template.txt`` in the installation directory.
- For the exact machine-specific path, use the ``--help`` option.
+ [#machine-specific-path]_
no_random
"""""""""
-Do not use a random banner image. Mainly used to get predictable
-results when testing.
+Ignored since Docutils 0.19. Will be removed in Docutils 2.0.
-*Default*: None (use random banner). *Options*: ``--no-random`` (hidden).
+*Default*: None. *Options*: ``--no-random`` (hidden).
pep_home
""""""""
-Home URL prefix for PEPs.
+Ignored since Docutils 0.19. Will be removed in Docutils 2.0.
-*Default*: "." (current directory). *Option*: ``--pep-home``.
+*Default*: "." *Option*: ``--pep-home`` (hidden).
python_home
"""""""""""
Python's home URL.
+Deprecated (if required, the URL can be adapted in a custom `template
+<template [html writers]_>`__).
+Will be removed in Docutils 2.0.
-*Default*: "https://www.python.org". *Option*: ``--python-home``.
+*Default*: "https://www.python.org". *Option*: ``--python-home`` (hidden).
[s5_html writer]
@@ -1606,8 +1610,7 @@
:compact_lists_: disable compact lists.
:template__: ``docutils/writers/s5_html/template.txt`` in the
- installation directory. For the exact machine-specific
- path, use the ``--help`` option.
+ installation directory. [#machine-specific-path]_
__ `template [html writers]`_
@@ -2579,9 +2582,13 @@
buildhtml_ application are resolved relative to the directory of
the respective configuration file.
+.. [#machine-specific-path] The ``--help`` command line option shows the
+ actual, machine-specific path.
+
.. [#SectNum] Added by the `SectNum` transform_, if and only if there
is a `"sectnum" directive`_ in the source document.
+
__ https://docs.python.org/3/library/codecs.html#codecs.register
Modified: trunk/docutils/docutils/transforms/peps.py
===================================================================
--- trunk/docutils/docutils/transforms/peps.py 2026-08-20 22:07:10 UTC (rev 10392)
+++ trunk/docutils/docutils/transforms/peps.py 2026-08-21 08:27:15 UTC (rev 10393)
@@ -18,6 +18,8 @@
import os
import re
import time
+import warnings
+
from docutils import nodes, utils, languages
from docutils import DataError
from docutils.transforms import Transform
@@ -222,10 +224,17 @@
"""
Special processing for PEP 0.
+
+ Deprecated. Will be removed in Docutils 2.0.
"""
default_priority = 760
+ def __init__(self, document, startnode=None) -> None:
+ warnings.warn('The `peps.PEPZero` transform will be removed '
+ 'in Docutils 2.0.', DeprecationWarning, stacklevel=2)
+ super().__init__(document, startnode)
+
def apply(self) -> None:
visitor = PEPZeroSpecial(self.document)
self.document.walk(visitor)
@@ -241,10 +250,17 @@
- Link PEP numbers in the second column of 4-column tables to the PEPs
themselves.
+
+ Deprecated. Will be removed in Docutils 2.0.
"""
pep_url = Headers.pep_url
+ def __init__(self, document, startnode=None) -> None:
+ warnings.warn('The `peps.PEPZeroSpecial` transform will be removed '
+ 'in Docutils 2.0.', DeprecationWarning, stacklevel=2)
+ super().__init__(document, startnode)
+
def unknown_visit(self, node) -> None:
pass
Modified: trunk/docutils/docutils/writers/pep_html/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/pep_html/__init__.py 2026-08-20 22:07:10 UTC (rev 10392)
+++ trunk/docutils/docutils/writers/pep_html/__init__.py 2026-08-21 08:27:15 UTC (rev 10393)
@@ -32,19 +32,18 @@
os.path.join(os.path.dirname(__file__), default_template))
settings_spec = html4css1.Writer.settings_spec + (
- 'PEP/HTML Writer Options',
+ 'PEP/HTML Writer Option Defaults',
'For the PEP/HTML writer, the default value for the --stylesheet-path '
'option is "%s", and the default value for --template is "%s". '
'See HTML Writer Options above.'
% (default_stylesheet_path, default_template_path),
- (('Python\'s home URL. Default is "https://www.python.org".',
+ ((frontend.SUPPRESS_HELP, # deprecated
['--python-home'],
{'default': 'https://www.python.org', 'metavar': '<URL>'}),
- ('Home URL prefix for PEPs. Default is "." (current directory).',
+ (frontend.SUPPRESS_HELP, # ignored since Docutils 0.19 (2022-07-05)
['--pep-home'],
{'default': '.', 'metavar': '<URL>'}),
- # For testing.
- (frontend.SUPPRESS_HELP,
+ (frontend.SUPPRESS_HELP, # ignored since Docutils 0.19 (2022-07-05)
['--no-random'],
{'action': 'store_true', 'validator': frontend.validate_boolean}),))
@@ -64,20 +63,10 @@
settings = self.document.settings
pyhome = settings.python_home
subs['pyhome'] = pyhome
- subs['pephome'] = settings.pep_home
- if pyhome == '..':
- subs['pepindex'] = '.'
- else:
- subs['pepindex'] = pyhome + '/dev/peps'
index = self.document.first_child_matching_class(nodes.field_list)
header = self.document[index]
self.pepnum = header[0][1].astext()
subs['pep'] = self.pepnum
- if settings.no_random:
- subs['banner'] = 0
- else:
- import random
- subs['banner'] = random.randrange(64)
try:
subs['pepnum'] = '%04i' % int(self.pepnum)
except ValueError:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-08-20 22:07:12
|
Revision: 10392
http://sourceforge.net/p/docutils/code/10392
Author: milde
Date: 2026-08-20 22:07:10 +0000 (Thu, 20 Aug 2026)
Log Message:
-----------
Fixes for PEP reader and writer.
Update "pep"reader docstring.
Change the type of the "title" part returned by
`pep_html.Writer.assemble_parts()` from `list` to `str`:
> All parts returned by the HTML writers are of data type str.
>
> - docs/api/publisher.html
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/readers/pep.py
trunk/docutils/docutils/writers/pep_html/__init__.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-07-22 20:59:24 UTC (rev 10391)
+++ trunk/docutils/HISTORY.rst 2026-08-20 22:07:10 UTC (rev 10392)
@@ -167,7 +167,14 @@
- Update `Reader.get_transforms()` to remove two of the transforms
obsoleting `references.DanglingReferences`.
+* docutils/writers/pep_html/__init__.py
+ - Change the type of the "title" part returned by
+ `.Writer.assemble_parts()` from `list` to `str`.
+ (`The Docutils Publisher` says: "all parts returned
+ by the HTML writers are of data type str.")
+
+
Release 0.23 (2026-05-27)
=========================
Modified: trunk/docutils/docutils/readers/pep.py
===================================================================
--- trunk/docutils/docutils/readers/pep.py 2026-07-22 20:59:24 UTC (rev 10391)
+++ trunk/docutils/docutils/readers/pep.py 2026-08-20 22:07:10 UTC (rev 10392)
@@ -44,11 +44,11 @@
inliner_class = rst.states.Inliner
def __init__(self, parser=None, parser_name=None) -> None:
- """`parser` should be ``None``, `parser_name` is ignored.
+ """
+ Initialize the "rst" parser with PEP-specific settings.
- The default parser is "rst" with PEP-specific settings
- (since Docutils 0.3). Since Docutils 0.22, `parser` is ignored,
- if it is a `str` instance.
+ A custom parser instance may be passed as `parser`. The argument
+ `parser_name` and string-values for `parser` are ignored.
"""
if parser is None or isinstance(parser, str):
parser = rst.Parser(rfc2822=True, inliner=self.inliner_class())
Modified: trunk/docutils/docutils/writers/pep_html/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/pep_html/__init__.py 2026-07-22 20:59:24 UTC (rev 10391)
+++ trunk/docutils/docutils/writers/pep_html/__init__.py 2026-08-20 22:07:10 UTC (rev 10392)
@@ -90,7 +90,7 @@
def assemble_parts(self) -> None:
html4css1.Writer.assemble_parts(self)
- self.parts['title'] = [self.title]
+ self.parts['title'] = self.title
self.parts['pepnum'] = self.pepnum
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-22 20:59:27
|
Revision: 10391
http://sourceforge.net/p/docutils/code/10391
Author: milde
Date: 2026-07-22 20:59:24 +0000 (Wed, 22 Jul 2026)
Log Message:
-----------
Use `<inline>` elements for inline targets (anchors).
As all Doctree elements support "ids" and "names" attributes, there is no need
to use a `<target>` element, the generic `<inline>` is well suited.
Therefore, `<target>` elements will become "Empty Body Elements" and
use of `<target>` in inline context or with content become invalid in
Docutils 2.0.
The "rst" parser now uses `<inline>` (instead of `<target>`) elements
for "inline internal targets".
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/ref/doctree.rst
trunk/docutils/docs/ref/docutils.dtd
trunk/docutils/docs/ref/rst/restructuredtext.rst
trunk/docutils/docutils/nodes.py
trunk/docutils/docutils/parsers/rst/states.py
trunk/docutils/docutils/transforms/parts.py
trunk/docutils/docutils/transforms/references.py
trunk/docutils/docutils/writers/latex2e/__init__.py
trunk/docutils/test/functional/expected/footnote-references_latex.tex
trunk/docutils/test/functional/expected/standalone_rst_docutils_xml.xml
trunk/docutils/test/functional/expected/standalone_rst_html4css1.html
trunk/docutils/test/functional/expected/standalone_rst_html5.html
trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt
trunk/docutils/test/test_parsers/test_rst/test_character_level_inline_markup.py
trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py
trunk/docutils/test/test_parsers/test_rst/test_targets.py
trunk/docutils/test/test_readers/test_pep/test_inline_markup.py
trunk/docutils/test/test_transforms/test_contents.py
trunk/docutils/test/test_transforms/test_hyperlinks.py
trunk/docutils/test/test_transforms/test_smartquotes.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/HISTORY.rst 2026-07-22 20:59:24 UTC (rev 10391)
@@ -56,6 +56,8 @@
- "lazy IDs":
`document.note_explicit_target()` and `document.note_anonymous_target()`
generate identifiers only if the `legacy_ids`_ setting is True.
+ - Add `Targetable` to parent classes of `inline` to allow test whether
+ inline internal targets are referenced.
* docutils/parsers/__init__.py
@@ -92,6 +94,7 @@
- Generate INFO message, if a directive that does not take
arguments has content above and below directive options.
- Ignore the "match_titles" argument of `RSTState.nested_list_parse()`.
+ - Use <inline> elements in `inline_internal_target()`.
* docutils/readers/standalone.py
@@ -107,6 +110,8 @@
- "lazy IDs": `Contents.build_contents()` ensures sections have an ID
and prefers IDs from external targets if `legacy_ids`_ is False.
+ - Clear "ids" and "names" in `ContentsFilter` so ids and names stay
+ unique when copying section title content for the ToC entry.
* docutils/transforms/references.py
@@ -121,6 +126,8 @@
- Fix anonymous hyperlinks to "clickable" images: "Propagation" of a
<target> in front of a "clickable" image now transfers "ids" and
"names" to the `<image>`, not the wrapping `<reference>`.
+ - Also check `nodes.inline` instances in `ReportUnreferencedTargets`
+ to keep reporting unreferenced inline links.
* docutils/transforms/universal.py
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-07-22 20:59:24 UTC (rev 10391)
@@ -46,10 +46,9 @@
Document Tree / Docutils DTD
----------------------------
-* Inline `\<target>`_ elements and <target> elements with content will be
- deprecated in Docutils 1.0 and invalid in Docutils 2.0.
- The "rst" parser will use <inline> elements for inline targets
- in Docutils 1.0.
+* Inline `\<target>`_ elements and <target> elements with content are
+ deprecated and will be invalid in Docutils 2.0. (The "rst" parser
+ uses <inline> elements for `inline targets`_ since Docutils 1.0.)
* To match the definition in the "Exchange Table Model", the
`"colwidth" attribute`_ will be stored as a `str` (instead of
@@ -207,6 +206,8 @@
- The <footnote> element's first child (<label>) is now mandatory.
- Use the ``%tbl.table.att`` parameter entity instead of ``%bodyatt``
to customize the <table> element's attribute list in Docutils 1.0.
+ - Inline `\<target>`_ elements and <target> elements with content are
+ deprecated.
Configuration changes:
- `Auto-detection`_ of the input encoding is no longer supported.
@@ -233,6 +234,7 @@
- "lazy IDs": Generate target ids_ in transforms -- after parsing and
only if required in the output document.
Keep behaviour backwards compatible with the legacy_ids_ setting.
+ - Use <inline> elements for `inline targets`_.
HTML5 writer:
- Use normal font size and colour for informal titles of type "rubric".
@@ -1616,7 +1618,6 @@
.. _"class": docs/ref/rst/directives.html#class
.. _csv-table: docs/ref/rst/directives.html#csv-table
.. _"date": docs/ref/rst/directives.html#date
-.. _doctest block: docs/ref/rst/restructuredtext.html#doctest-blocks
.. _"figure": docs/ref/rst/directives.html#figure
.. _identifier normalization:
docs/ref/rst/directives.html#identifier-normalization
@@ -1632,6 +1633,10 @@
docs/ref/rst/definitions.html#semantic-inline-markup-roles
.. _LaTeX syntax for mathematics: docs/ref/rst/mathematics.html
+.. _doctest block: docs/ref/rst/restructuredtext.html#doctest-blocks
+.. _inline targets:
+ docs/ref/rst/restructuredtext.html#inline-internal-targets
+
.. _configuration settings: docs/user/config.html
.. _auto-detection: docs/user/config.html#auto-detect
.. _auto_id_prefix: docs/user/config.html#auto-id-prefix
Modified: trunk/docutils/docs/ref/doctree.rst
===================================================================
--- trunk/docutils/docs/ref/doctree.rst 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/docs/ref/doctree.rst 2026-07-22 20:59:24 UTC (rev 10391)
@@ -310,7 +310,7 @@
`\<footnote_reference>`_, `\<generated>`_, `\<image>`_, `\<inline>`_,
`\<literal>`_, `\<math>`_, `\<problematic>`_, `\<raw>`_, `\<reference>`_,
`\<strong>`_, `\<subscript>`_, `\<substitution_reference>`_,
- `\<superscript>`_, `\<target>`_, `\<title_reference>`_
+ `\<superscript>`_, `\<target>`_ [#inline-targets]_, `\<title_reference>`_
:Docutils class:
``nodes.Inline``
:Parameter Entities:
@@ -2316,8 +2316,8 @@
:Category: `Inline Elements`_
:Analogues: <inline> is analogous to the HTML_ <span> element and the
DocBook_ <phrase> element.
-:Processing: Writers_ typically pass the classes_ attribute to the output
- document and leave styling to the backend or a custom
+:Processing: Writers_ typically pass the classes_ and ids_ attributes to the
+ output document and leave styling to the backend or a custom
stylesheet_. They may also process the classes_ attribute
and convert the <inline> element to a specific element or
render the content distinctly for specific class values.
@@ -2346,7 +2346,10 @@
<inline classes="custom">
interpreted text
+See `\<target>`_ for an example of an <inline> element used as
+`inline target`_ (anchor).
+
<label>
=======
@@ -3238,7 +3241,7 @@
.
<paragraph>
Matching targets must exist in the document, e.g., a
- <target ids="simple" names="simple">
+ <inline ids="simple" names="simple">
simple
inline target or the explicit targets below.
<target ids="phrase-refs" names="phrase\ refs" refuri="doctree.rst">
@@ -3260,7 +3263,7 @@
.
<paragraph>
Matching targets must exist in the document, e.g., a
- <target ids="simple" names="simple">
+ <inline ids="simple" names="simple">
simple
inline target or the explicit targets below.
<target ids="phrase-refs" names="phrase\ refs" refuri="doctree.rst">
@@ -3956,19 +3959,17 @@
provides ids_ or names_ for its content or, if empty, the
next element.
:Parents: all elements employing `%body.elements`_, `%structure.model`_,
- or `%text.model`_ in their content models
-:Children: only text data [#target-content]_
+ or `%text.model`_ [#inline-targets]_ in their content models
+:Children: inline targets may contain text data [#target-content]_
:Attributes: anonymous_, refid_, refname_, refuri_, and
the `common attributes`_.
-.. [#inline-targets] Inline <target> elements will be deprecated in
- Docutils 1.0 and invalid in Docutils 2.0. The "rst" parser will
- use `\<inline>`_ elements for inline targets.
+.. [#inline-targets] Inline <target> elements are deprecated and
+ will be invalid in Docutils 2.0.
+.. [#target-content] <target> elements with content are deprecated
+ and will be invalid in Docutils 2.0.
-.. [#target-content] <target> elements with content will be deprecated in
- Docutils 1.0 and invalid in Docutils 2.0.
-
Examples
--------
@@ -3992,7 +3993,7 @@
<paragraph>
The hyperlink target above points to this paragraph
with an
- <target ids="inline-target" names="inline\ target">
+ <inline ids="inline-target" names="inline\ target">
inline target
.
@@ -4006,7 +4007,7 @@
<paragraph ids="explicit-target alias" names="explicit\ target alias">
The hyperlink target above points to this paragraph
with an
- <target ids="inline-target" names="inline\ target">
+ <inline ids="inline-target" names="inline\ target">
inline target
.
@@ -5573,6 +5574,7 @@
:end-before:
:literal:
+Inline <target> elements are deprecated. [#inline-targets]_
The `%additional.inline.elements`_ placeholder can be used by
wrapper DTDs to extend ``%inline.elements``.
@@ -5706,7 +5708,8 @@
`\<reference>`_, `\<revision>`_, `\<rubric>`_,
`\<status>`_, `\<strong>`_, `\<subscript>`_, `\<substitution_definition>`_,
`\<substitution_reference>`_, `\<subtitle>`_, `\<superscript>`_,
-`\<target>`_, `\<term>`_, `\<title>`_, `\<title_reference>`_, `\<version>`_
+`\<target>`_ [#target-content]_, `\<term>`_, `\<title>`_,
+`\<title_reference>`_, `\<version>`_
.. _%additional.basic.atts:
@@ -5970,6 +5973,7 @@
.. _hyperlink references: rst/restructuredtext.html#hyperlink-references
.. _implicit hyperlink targets: rst/restructuredtext.html#implicit-hyperlink-targets
.. _indirect target: rst/restructuredtext.html#indirect-hyperlink-targets
+.. _inline target: rst/restructuredtext.html#inline-internal-targets
.. _inline literals: rst/restructuredtext.html#inline-literals
.. _inline markup: rst/restructuredtext.html#inline-markup
.. _internal hyperlink targets: rst/restructuredtext.html#internal-hyperlink-targets
Modified: trunk/docutils/docs/ref/docutils.dtd
===================================================================
--- trunk/docutils/docs/ref/docutils.dtd 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/docs/ref/docutils.dtd 2026-07-22 20:59:24 UTC (rev 10391)
@@ -188,6 +188,7 @@
| table | target | tip | warning
%additional.body.elements; ">
+<!-- inline targets are deprecated and will be invalid in Docutils 2.0 -->
<!ENTITY % additional.inline.elements "">
<!ENTITY % inline.elements
" abbreviation | acronym | citation_reference | emphasis
@@ -533,6 +534,7 @@
<!ATTLIST rubric %basic.atts;>
<!-- Empty except when used as an inline element. -->
+<!-- target content is deprecated and will be invalid in Docutils 2.0 -->
<!ELEMENT target %text.model;>
<!ATTLIST target
%basic.atts;
Modified: trunk/docutils/docs/ref/rst/restructuredtext.rst
===================================================================
--- trunk/docutils/docs/ref/rst/restructuredtext.rst 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/docs/ref/rst/restructuredtext.rst 2026-07-22 20:59:24 UTC (rev 10391)
@@ -2965,7 +2965,7 @@
Inline Internal Targets
------------------------
-:Doctree element: `\<target>`_
+:Doctree element: `\<inline>`_
:Start/End strings: ``_``` `````
:See also: `hyperlink targets`_
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/docutils/nodes.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -2653,7 +2653,7 @@
class acronym(Inline, TextElement): pass
class emphasis(Inline, TextElement): pass
class generated(Inline, TextElement): pass
-class inline(Inline, TextElement): pass
+class inline(Inline, TextElement, Targetable): pass
class literal(Inline, TextElement): pass
class strong(Inline, TextElement): pass
class subscript(Inline, TextElement): pass
Modified: trunk/docutils/docutils/parsers/rst/states.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/states.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/docutils/parsers/rst/states.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -833,9 +833,10 @@
node = nodeclass(rawsource, text)
return (string[:matchstart], [node],
string[textend:], [], endmatch.group(1))
+ role = 'target' if string[matchstart] == '_' else nodeclass.__name__
msg = self.reporter.warning(
- 'Inline %s start-string without end-string.'
- % nodeclass.__name__, line=lineno)
+ f'Inline {role} start-string without end-string.',
+ line=lineno)
text = unescape(string[matchstart:matchend], True)
prb = self.problematic(text, text, msg)
return string[:matchstart], [prb], string[matchend:], [msg], ''
@@ -1009,13 +1010,13 @@
def inline_internal_target(self, match, lineno):
before, inlines, remaining, sysmessages, endstring = self.inline_obj(
- match, lineno, self.patterns.target, nodes.target)
- if inlines and isinstance(inlines[0], nodes.target):
+ match, lineno, self.patterns.target, nodes.inline)
+ if inlines and isinstance(inlines[0], nodes.inline):
assert len(inlines) == 1
- target = inlines[0]
- name = normalize_name(target.astext())
- target['names'].append(name)
- self.document.note_explicit_target(target, self.parent)
+ inline_target = inlines[0]
+ name = normalize_name(inline_target.astext())
+ inline_target['names'].append(name)
+ self.document.note_explicit_target(inline_target, self.parent)
return before, inlines, remaining, sysmessages
def substitution_reference(self, match, lineno):
Modified: trunk/docutils/docutils/transforms/parts.py
===================================================================
--- trunk/docutils/docutils/transforms/parts.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/docutils/transforms/parts.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -162,6 +162,17 @@
def get_entry_text(self):
return self.get_tree_copy().children
+ def default_visit(self, node) -> None:
+ # Copy the current node, and make it the new acting parent.
+ # remove "names" and "ids" (must be unique)
+ super().default_visit(node)
+ self.parent['names'] = []
+ self.parent['ids'] = []
+
+ def visit_Text(self, node):
+ # Text nodes have no attributes, just copy
+ super().default_visit(node)
+
def visit_citation_reference(self, node):
raise nodes.SkipNode
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -1043,11 +1043,13 @@
This makes it unsuited for applications like `Sphinx`, that manage
hyperlinks between a set of related documents.
"""
+ # TODO: also check names set with the ":name:" directive options?
+
# Apply after `MatchReferences` (730) but before `Messages` (860):
default_priority = 855
def apply(self) -> None:
- for target in self.document.findall(nodes.target):
+ for target in self.document.findall((nodes.target, nodes.inline)):
if target.referenced:
continue
if target.get('anonymous'):
@@ -1058,6 +1060,8 @@
naming = target['names'][0]
elif target['ids']:
naming = target['ids'][0]
+ elif isinstance(target, nodes.inline):
+ continue
else:
# Propagated target: "ids" and "names" attributes moved
# to the node indicated by "refname" or "refid".
Modified: trunk/docutils/docutils/writers/latex2e/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/latex2e/__init__.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/docutils/writers/latex2e/__init__.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -2546,6 +2546,10 @@
set_anchor = not (isinstance(node.parent, anchor_nodes)
or isinstance(node, anchor_nodes))
add_newline = isinstance(node, nodes.paragraph)
+ # wrap line before inline target
+ if isinstance(node, nodes.inline) and node['ids']:
+ self.out.append('%')
+ self.out.append('\n')
self.out += self.ids_to_labels(node, set_anchor, newline=add_newline)
# Handle "classes" attribute:
for cls in node['classes']:
@@ -3153,7 +3157,7 @@
self.duclass_close(node)
def visit_target(self, node) -> None:
- # Skip indirect targets:
+ # Skip external and indirect targets:
if ('refuri' in node # external hyperlink
or 'refid' in node # resolved internal link
or 'refname' in node): # unresolved internal link
Modified: trunk/docutils/test/functional/expected/footnote-references_latex.tex
===================================================================
--- trunk/docutils/test/functional/expected/footnote-references_latex.tex 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/functional/expected/footnote-references_latex.tex 2026-07-22 20:59:24 UTC (rev 10391)
@@ -160,12 +160,12 @@
\texttt{\_`4`} and \texttt{\_`exi`} would lead to a \textquotedbl{}duplicate target name\textquotedbl{} ERROR .
The markup characters for auto-labeled footnotes \textquotedbl{}%
-\phantomsection\label{target-1}*\textquotedbl{} and \textquotedbl{}%
-\phantomsection\label{target-2}\#\textquotedbl{} and
+\phantomsection\label{inline-1}*\textquotedbl{} and \textquotedbl{}%
+\phantomsection\label{inline-2}\#\textquotedbl{} and
the symbols selected by auto-symbol footnotes \textquotedbl{}%
-\phantomsection\label{target-3}†\textquotedbl{} do not become
+\phantomsection\label{inline-3}†\textquotedbl{} do not become
reference names. They can be used in other hyperref targets allowing
-links to \hyperref[target-1]{*}, \hyperref[target-2]{\#} and \hyperref[target-3]{†}.
+links to \hyperref[inline-1]{*}, \hyperref[inline-2]{\#} and \hyperref[inline-3]{†}.
\subsection{5%
@@ -174,9 +174,9 @@
Both, explicit and implicit targets with a number as reference name (e.g.
the inline target \textquotedbl{}%
-\phantomsection\label{target-4}2\textquotedbl{} and the section title \textquotedbl{}5\textquotedbl{} above) cause a gap in
+\phantomsection\label{inline-4}2\textquotedbl{} and the section title \textquotedbl{}5\textquotedbl{} above) cause a gap in
footnote auto-numbering.\footref{latex} The number can be used in a
-footnote-reference although it does not refer to a footnote!\textsuperscript{\hyperref[section-2]{5}}\textsuperscript{\hyperref[target-4]{2}}
+footnote-reference although it does not refer to a footnote!\textsuperscript{\hyperref[section-2]{5}}\textsuperscript{\hyperref[inline-4]{2}}
\begin{DUclass}{admonition-todo}
\begin{DUadmonition}
Modified: trunk/docutils/test/functional/expected/standalone_rst_docutils_xml.xml
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_docutils_xml.xml 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/functional/expected/standalone_rst_docutils_xml.xml 2026-07-22 20:59:24 UTC (rev 10391)
@@ -245,7 +245,7 @@
numbered <footnote_reference ids="footnote-reference-1" refid="footnote-1">1</footnote_reference>, anonymous auto-numbered <footnote_reference auto="1" ids="footnote-reference-2" refid="footnote-2">3</footnote_reference>, labeled auto-numbered
<footnote_reference auto="1" ids="footnote-reference-3" refid="label">2</footnote_reference>, or symbolic <footnote_reference auto="*" ids="footnote-reference-4" refid="footnote-3">*</footnote_reference>), citation references (see <citation_reference ids="citation-reference-1" refid="cit2002">CIT2002</citation_reference>),
substitution references (<image alt="EXAMPLE" uri="../../../docs/user/rst/images/biohazard.png"></image> &
- a <emphasis>trimmed heart</emphasis> <literal>(U+2665):</literal>♥), and <target ids="inline-hyperlink-targets" names="inline\ hyperlink\ targets">inline hyperlink targets</target>
+ a <emphasis>trimmed heart</emphasis> <literal>(U+2665):</literal>♥), and <inline ids="inline-hyperlink-targets" names="inline\ hyperlink\ targets">inline hyperlink targets</inline>
(see <reference refid="targets">Targets</reference> below for a reference back to here). Character-level
inline markup is also possible (although exceedingly ugly!) in <emphasis>re</emphasis><literal>Structured</literal><emphasis>Text</emphasis>. Problems are indicated by <problematic ids="problematic-1" refid="system-message-1">|problematic|</problematic> text
(generated by processing errors; this one is intentional). Here is a
@@ -1346,7 +1346,7 @@
Inline markup is supported, e.g. <emphasis>emphasis</emphasis>, <strong>strong</strong>, <literal>literal
text</literal>, <subscript>sub-</subscript> and <superscript>super</superscript>scripts,
inline formulas: <math>A = 2 \pi r^2</math>,
-footnotes <footnote_reference ids="footnote-reference-9" refid="footnote-1">1</footnote_reference>, <target ids="hyperlink-targets" names="hyperlink\ targets">hyperlink targets</target>, and <reference refuri="http://www.python.org/">references</reference><target ids="references" names="references" refuri="http://www.python.org/"></target>.</literal_block>
+footnotes <footnote_reference ids="footnote-reference-9" refid="footnote-1">1</footnote_reference>, <inline ids="hyperlink-targets" names="hyperlink\ targets">hyperlink targets</inline>, and <reference refuri="http://www.python.org/">references</reference><target ids="references" names="references" refuri="http://www.python.org/"></target>.</literal_block>
</section>
<section ids="code" names="code">
<title auto="1" refid="toc-entry-52"><generated classes="sectnum">2.14.10 </generated>Code</title>
Modified: trunk/docutils/test/functional/expected/standalone_rst_html4css1.html
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_html4css1.html 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/functional/expected/standalone_rst_html4css1.html 2026-07-22 20:59:24 UTC (rev 10391)
@@ -179,7 +179,7 @@
numbered <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a>, anonymous auto-numbered <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[3]</a>, labeled auto-numbered
<a class="footnote-reference" href="#label" id="footnote-reference-3">[2]</a>, or symbolic <a class="footnote-reference" href="#footnote-3" id="footnote-reference-4">[*]</a>), citation references (see <a class="citation-reference" href="#cit2002" id="citation-reference-1">[CIT2002]</a>),
substitution references (<img alt="EXAMPLE" src="../../../docs/user/rst/images/biohazard.png" /> &
-a <em>trimmed heart</em> <tt class="docutils literal">(U+2665):</tt>♥), and <span class="target" id="inline-hyperlink-targets">inline hyperlink targets</span>
+a <em>trimmed heart</em> <tt class="docutils literal">(U+2665):</tt>♥), and <span id="inline-hyperlink-targets">inline hyperlink targets</span>
(see <a class="reference internal" href="#targets">Targets</a> below for a reference back to here). Character-level
inline markup is also possible (although exceedingly ugly!) in <em>re</em><tt class="docutils literal">Structured</tt><em>Text</em>. Problems are indicated by <a href="#system-message-1"><span class="problematic" id="problematic-1">|problematic|</span></a> text
(generated by processing errors; this one is intentional). Here is a
@@ -1015,7 +1015,7 @@
Inline markup is supported, e.g. <em>emphasis</em>, <strong>strong</strong>, <tt class="docutils literal">literal
text</tt>, <span class="subscript">sub-</span> and <span class="superscript">super</span>scripts,
inline formulas: <span class="formula"><i>A</i> = 2<i>π</i><i>r</i><sup>2</sup></span>,
-footnotes <a class="footnote-reference" href="#footnote-1" id="footnote-reference-9">[1]</a>, <span class="target" id="hyperlink-targets">hyperlink targets</span>, and <a class="reference external" href="http://www.python.org/">references</a>.
+footnotes <a class="footnote-reference" href="#footnote-1" id="footnote-reference-9">[1]</a>, <span id="hyperlink-targets">hyperlink targets</span>, and <a class="reference external" href="http://www.python.org/">references</a>.
</pre>
</div>
<div class="section" id="code">
Modified: trunk/docutils/test/functional/expected/standalone_rst_html5.html
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_html5.html 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/functional/expected/standalone_rst_html5.html 2026-07-22 20:59:24 UTC (rev 10391)
@@ -196,7 +196,7 @@
numbered <a class="brackets" href="#footnote-1" id="footnote-reference-1" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a>, anonymous auto-numbered <a class="brackets" href="#footnote-2" id="footnote-reference-2" role="doc-noteref"><span class="fn-bracket">[</span>3<span class="fn-bracket">]</span></a>, labeled auto-numbered
<a class="brackets" href="#label" id="footnote-reference-3" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a>, or symbolic <a class="brackets" href="#footnote-3" id="footnote-reference-4" role="doc-noteref"><span class="fn-bracket">[</span>*<span class="fn-bracket">]</span></a>), citation references (see <a class="citation-reference" href="#cit2002" id="citation-reference-1" role="doc-biblioref">[CIT2002]</a>),
substitution references (<img alt="EXAMPLE" src="../../../docs/user/rst/images/biohazard.png" /> &
-a <em>trimmed heart</em> <span class="docutils literal">(U+2665):</span>♥), and <span class="target" id="inline-hyperlink-targets">inline hyperlink targets</span>
+a <em>trimmed heart</em> <span class="docutils literal">(U+2665):</span>♥), and <span id="inline-hyperlink-targets">inline hyperlink targets</span>
(see <a class="reference internal" href="#another-target">Targets</a> below for a reference back to here). Character-level
inline markup is also possible (although exceedingly ugly!) in <em>re</em><span class="docutils literal">Structured</span><em>Text</em>. Problems are indicated by <a href="#system-message-1"><span class="problematic" id="problematic-1">|problematic|</span></a> text
(generated by processing errors; this one is intentional). Here is a
@@ -1025,7 +1025,7 @@
<mn>2</mn>
</msup>
</math>,
-footnotes <a class="brackets" href="#footnote-1" id="footnote-reference-9" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a>, <span class="target" id="hyperlink-targets">hyperlink targets</span>, and <a class="reference external" href="http://www.python.org/">references</a>.</pre>
+footnotes <a class="brackets" href="#footnote-1" id="footnote-reference-9" role="doc-noteref"><span class="fn-bracket">[</span>1<span class="fn-bracket">]</span></a>, <span id="hyperlink-targets">hyperlink targets</span>, and <a class="reference external" href="http://www.python.org/">references</a>.</pre>
</section>
<section id="code">
<h4><a class="toc-backref" href="#toc-entry-64" role="doc-backlink"><span class="sectnum">2.14.10 </span>Code</a><a class="self-link" title="link to this section" href="#code"></a></h4>
Modified: trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2026-07-22 20:59:24 UTC (rev 10391)
@@ -471,7 +471,7 @@
(U+2665):
♥
), and
- <target ids="inline-hyperlink-targets" names="inline\ hyperlink\ targets">
+ <inline ids="inline-hyperlink-targets" names="inline\ hyperlink\ targets">
inline hyperlink targets
(see
@@ -1920,7 +1920,7 @@
<footnote_reference ids="footnote-reference-9" refid="footnote-1">
1
,
- <target ids="hyperlink-targets" names="hyperlink\ targets">
+ <inline ids="hyperlink-targets" names="hyperlink\ targets">
hyperlink targets
, and
<reference refuri="http://www.python.org/">
Modified: trunk/docutils/test/test_parsers/test_rst/test_character_level_inline_markup.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_character_level_inline_markup.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/test_parsers/test_rst/test_character_level_inline_markup.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -326,7 +326,7 @@
This isn't a _target; targets require backquotes.
<paragraph>
With simple-inline-markup, \n\
- <target ids="this" names="this">
+ <inline ids="this" names="this">
this
_ is a a target followed by an
underscore.
Modified: trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -1168,10 +1168,10 @@
Report duplicate refname.
<paragraph>
Explicit targets: \n\
- <target names="file.txt">
+ <inline names="file.txt">
file.txt
, \n\
- <target names="file.html">
+ <inline names="file.html">
file.html
.
<system_message level="1" line="6" source="test data" type="INFO">
@@ -1295,10 +1295,10 @@
Duplicate refnames in references with embedded alias.
<paragraph>
Explicit targets: \n\
- <target names="tg1">
+ <inline names="tg1">
tg1
and \n\
- <target names="tg2">
+ <inline names="tg2">
tg2
.
<system_message level="1" line="6" source="test data" type="INFO">
@@ -1334,19 +1334,19 @@
"""\
<document source="test data">
<paragraph>
- <target names="target">
+ <inline names="target">
target
<paragraph>
Here is \n\
- <target names="another\\ target">
+ <inline names="another\\ target">
another target
in some text. And \n\
- <target names="yet\\ another\\ target">
+ <inline names="yet\\ another\\ target">
yet
another target
, spanning lines.
<paragraph>
- <target names="here\\ is\\ a\\ target">
+ <inline names="here\\ is\\ a\\ target">
Here is a TaRgeT
with case and spacial difficulties.
"""],
@@ -1357,10 +1357,10 @@
<document source="test data">
<paragraph>
l'
- <target names="target1">
+ <inline names="target1">
target1
and l\u2019
- <target names="target2">
+ <inline names="target2">
target2
with apostrophe
"""],
@@ -1373,21 +1373,21 @@
<document source="test data">
<paragraph>
quoted '
- <target names="target1">
+ <inline names="target1">
target1
', quoted "
- <target names="target2">
+ <inline names="target2">
target2
",
quoted \u2018
- <target names="target3">
+ <inline names="target3">
target3
\u2019, quoted \u201c
- <target names="target4">
+ <inline names="target4">
target4
\u201d,
quoted \xab
- <target names="target5">
+ <inline names="target5">
target5
\xbb
"""],
@@ -1399,19 +1399,19 @@
"""\
<document source="test data">
<paragraph>
- <target names="'target1'">
+ <inline names="'target1'">
'target1'
with quotes, \n\
- <target names=""target2"">
+ <inline names=""target2"">
"target2"
with quotes,
- <target names="\u2018target3\u2019">
+ <inline names="\u2018target3\u2019">
\u2018target3\u2019
with quotes, \n\
- <target names="\u201ctarget4\u201d">
+ <inline names="\u201ctarget4\u201d">
\u201ctarget4\u201d
with quotes,
- <target names="\xabtarget5\xbb">
+ <inline names="\xabtarget5\xbb">
\xabtarget5\xbb
with quotes
"""],
Modified: trunk/docutils/test/test_parsers/test_rst/test_targets.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -265,7 +265,7 @@
<document source="test data">
<paragraph>
Duplicate indirect \n\
- <target names="targets">
+ <inline names="targets">
targets
(same refname):
<target names="link" refname="targets">
@@ -482,7 +482,7 @@
<line>
Do not insert <system_message> element for duplicate
<line>
- <target dupnames="target" ids="target-2">
+ <inline dupnames="target" ids="target-2">
target
, if this results in an invalid doctree.
<rubric dupnames="target" ids="target-3">
@@ -496,7 +496,7 @@
with
<field>
<field_name>
- <target dupnames="target" ids="target-4">
+ <inline dupnames="target" ids="target-4">
target
<field_body>
<paragraph>
@@ -735,7 +735,7 @@
<line>
Do not insert <system_message> element for duplicate
<line>
- <target dupnames="target" ids="target-5">
+ <inline dupnames="target" ids="target-5">
target
, if this results in an invalid doctree.
<rubric dupnames="target" ids="target-6">
@@ -749,7 +749,7 @@
with
<field>
<field_name>
- <target dupnames="target" ids="target-7">
+ <inline dupnames="target" ids="target-7">
target
<field_body>
<paragraph>
@@ -946,7 +946,7 @@
<document source="test data">
<paragraph>
Duplicate indirect \n\
- <target ids="targets" names="targets">
+ <inline ids="targets" names="targets">
targets
(same refname):
<target ids="link" names="link" refname="targets">
@@ -1163,7 +1163,7 @@
<line>
Do not insert <system_message> element for duplicate
<line>
- <target dupnames="target" ids="id5">
+ <inline dupnames="target" ids="id5">
target
, if this results in an invalid doctree.
<rubric dupnames="target" ids="id6">
@@ -1177,7 +1177,7 @@
with
<field>
<field_name>
- <target dupnames="target" ids="id7">
+ <inline dupnames="target" ids="id7">
target
<field_body>
<paragraph>
Modified: trunk/docutils/test/test_readers/test_pep/test_inline_markup.py
===================================================================
--- trunk/docutils/test/test_readers/test_pep/test_inline_markup.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/test_readers/test_pep/test_inline_markup.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -125,7 +125,7 @@
<emphasis>
completeness
, \n\
- <target ids="let-s" names="let's">
+ <inline ids="let-s" names="let's">
let's
\n\
<literal>
Modified: trunk/docutils/test/test_transforms/test_contents.py
===================================================================
--- trunk/docutils/test/test_transforms/test_contents.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/test_transforms/test_contents.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -26,6 +26,8 @@
class TransformTestCase(unittest.TestCase):
+ maxDiff = None
+
def test_transforms(self):
parser = Parser()
settings = get_default_settings(Parser)
@@ -86,7 +88,8 @@
<list_item>
<paragraph>
<reference ids="toc-entry-3" refid="title-3">
- Title
+ <inline>
+ Title
3
<list_item>
<paragraph>
@@ -106,7 +109,7 @@
Paragraph 2.
<section ids="title-3" names="title\\ 3">
<title refid="toc-entry-3">
- <target ids="title" names="title">
+ <inline ids="title" names="title">
Title
3
<paragraph>
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -859,7 +859,7 @@
Target name overrides implicit target name "foo".
<paragraph>
With legacy_ids = True, an explicit target \n\
- <target ids="foo-1" names="foo">
+ <inline ids="foo-1" names="foo">
foo
overrides a
homonymous implicit target but gets a "diambiguated" identifier.
@@ -891,7 +891,7 @@
Target name overrides implicit target name "foo".
<paragraph>
If an implicit target precedes a homonymous explicit target \n\
- <target ids="foo-1" names="foo">
+ <inline ids="foo-1" names="foo">
foo
,
the explicit target takes over the reference name but not the identifier.
@@ -1325,7 +1325,7 @@
Target name overrides implicit target name "foo".
<paragraph>
With legacy_ids = False, an explicit target \n\
- <target ids="foo" names="foo">
+ <inline ids="foo" names="foo">
foo
takes over the
reference name and identifier of a homonymous implicit target.
Modified: trunk/docutils/test/test_transforms/test_smartquotes.py
===================================================================
--- trunk/docutils/test/test_transforms/test_smartquotes.py 2026-07-22 20:59:04 UTC (rev 10390)
+++ trunk/docutils/test/test_transforms/test_smartquotes.py 2026-07-22 20:59:24 UTC (rev 10391)
@@ -239,7 +239,7 @@
<list_item>
<paragraph>
Around “
- <target ids="targets" names="targets">
+ <inline ids="targets" names="targets">
targets
”, “
<emphasis>
@@ -292,7 +292,7 @@
(in French, smart quotes expand to two characters).
<paragraph classes="language-fr-ch-x-altquot">
Around «\u202f
- <target ids="targets" names="targets">
+ <inline ids="targets" names="targets">
targets
\u202f», «\u202f
<emphasis>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-22 20:59:06
|
Revision: 10390
http://sourceforge.net/p/docutils/code/10390
Author: milde
Date: 2026-07-22 20:59:04 +0000 (Wed, 22 Jul 2026)
Log Message:
-----------
The `<footnote>` element's first child (`<label>`) is now mandatory.
The rST parser always only created footnotes with label.
The "doctree" element reference says
"The <footnote> element is used for labelled notes ...".
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/ref/doctree.rst
trunk/docutils/docs/ref/docutils.dtd
trunk/docutils/docutils/nodes.py
trunk/docutils/test/test_nodes.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-07-21 17:55:03 UTC (rev 10389)
+++ trunk/docutils/HISTORY.rst 2026-07-22 20:59:04 UTC (rev 10390)
@@ -19,6 +19,7 @@
* docs/ref/docutils.dtd
+ - The <footnote> element's first child (<label>) is now mandatory.
- Use the ``%tbl.table.att`` parameter entity instead of ``%bodyatt``
to customize the <table> element's attribute list.
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-07-21 17:55:03 UTC (rev 10389)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-07-22 20:59:04 UTC (rev 10390)
@@ -46,9 +46,6 @@
Document Tree / Docutils DTD
----------------------------
-* The <footnote> element's first child (<label>) will become mandatory
- in Docutils 1.0.
-
* Inline `\<target>`_ elements and <target> elements with content will be
deprecated in Docutils 1.0 and invalid in Docutils 2.0.
The "rst" parser will use <inline> elements for inline targets
@@ -207,6 +204,7 @@
Document Tree / Docutils DTD:
- Drop the `name` attribute from <reference> nodes.
+ - The <footnote> element's first child (<label>) is now mandatory.
- Use the ``%tbl.table.att`` parameter entity instead of ``%bodyatt``
to customize the <table> element's attribute list in Docutils 1.0.
Modified: trunk/docutils/docs/ref/doctree.rst
===================================================================
--- trunk/docutils/docs/ref/doctree.rst 2026-07-21 17:55:03 UTC (rev 10389)
+++ trunk/docutils/docs/ref/doctree.rst 2026-07-22 20:59:04 UTC (rev 10390)
@@ -2049,14 +2049,14 @@
:Parents: all elements employing `%body.elements`_ or
`%structure.model`_ in their content models
-:Children: <footnote> elements begin with an optional [#]_ `\<label>`_
+:Children: <footnote> elements begin with a `\<label>`_ [#]_
and contain `body elements`_::
- (label?, (%body.elements;)+)
+ (label, (%body.elements;)+)
:Attributes: the `common attributes`_ plus auto_ and backrefs_.
-.. [#] The footnote label will become mandatory in Docutils 1.0.
+.. [#] The footnote label was optional in Docutils < 1.0.
Examples
--------
Modified: trunk/docutils/docs/ref/docutils.dtd
===================================================================
--- trunk/docutils/docs/ref/docutils.dtd 2026-07-21 17:55:03 UTC (rev 10389)
+++ trunk/docutils/docs/ref/docutils.dtd 2026-07-22 20:59:04 UTC (rev 10390)
@@ -515,7 +515,7 @@
<!ELEMENT admonition (title, (%body.elements;)+)>
<!ATTLIST admonition %basic.atts;>
-<!ELEMENT footnote (label?, (%body.elements;)+)>
+<!ELEMENT footnote (label, (%body.elements;)+)>
<!ATTLIST footnote
%basic.atts;
%backrefs.att;
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-07-21 17:55:03 UTC (rev 10389)
+++ trunk/docutils/docutils/nodes.py 2026-07-22 20:59:04 UTC (rev 10390)
@@ -2536,9 +2536,9 @@
class footnote(General, BackLinkable, Element, Labeled, Targetable):
"""Labelled note providing additional context (footnote or endnote)."""
valid_attributes: Final = Element.valid_attributes + ('auto', 'backrefs')
- content_model: Final = ((label, '?'), (Body, '+'))
- # (label?, (%body.elements;)+)
- # The label will become required in Docutils 1.0.
+ content_model: Final = ((label, '.'), (Body, '+'))
+ # (label, (%body.elements;)+)
+ # The label was optional in Docutils < 1.0.
class citation(General, BackLinkable, Element, Labeled, Targetable):
Modified: trunk/docutils/test/test_nodes.py
===================================================================
--- trunk/docutils/test/test_nodes.py 2026-07-21 17:55:03 UTC (rev 10389)
+++ trunk/docutils/test/test_nodes.py 2026-07-22 20:59:04 UTC (rev 10390)
@@ -766,15 +766,11 @@
note.append(nodes.enumerated_list())
self.assertEqual(note.validate_content(), [])
- # footnote: (label?, (%body.elements;)+)
- # TODO: use case for footnote without label (make it required?)
- # rST parser can generate footnotes without body elements!
- footnote = nodes.footnote('', hint)
+ # footnote: (label, (%body.elements;)+)
+ footnote = nodes.footnote('', nodes.label('', '1'), hint)
self.assertEqual(footnote.validate_content(), [])
# citation: (label, (%body.elements;)+)
- # TODO: rST parser allows empty citation
- # (see test_rst/test_citations.py). Is this sensible?
citation = nodes.citation('', hint)
with self.assertRaisesRegex(nodes.ValidationError,
'Expecting child of type <label>,'
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-21 17:55:05
|
Revision: 10389
http://sourceforge.net/p/docutils/code/10389
Author: milde
Date: 2026-07-21 17:55:03 +0000 (Tue, 21 Jul 2026)
Log Message:
-----------
Use `%tbl.table.att` instead of `%bodyatt` in docutils.dtd.
Use the ``%tbl.table.att`` parameter entity instead of ``%bodyatt``
to customize the <table> element's attribute list.
The "CALS XML Exchange Table Model" defines both parameter entities
(%bodyatt for backwards compatibility).
Move the reference to the CALS-table model behind the declarations of
the customization parameter entities:
> [...] these entities can be redefined (by giving the appropriate
> parameter entity declaration(s) prior to the reference
> to this Table Model declaration set entity)
-- https://www.oasis-open.org/specs/tm9901.html
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/ref/doctree.rst
trunk/docutils/docs/ref/docutils.dtd
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-07-16 10:43:55 UTC (rev 10388)
+++ trunk/docutils/HISTORY.rst 2026-07-21 17:55:03 UTC (rev 10389)
@@ -17,6 +17,11 @@
Release 1.0b1.dev (unpublished)
===============================
+* docs/ref/docutils.dtd
+
+ - Use the ``%tbl.table.att`` parameter entity instead of ``%bodyatt``
+ to customize the <table> element's attribute list.
+
* docutils/__init__.py
- Remove `TransformSpec.unknown_reference_resolvers`.
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-07-16 10:43:55 UTC (rev 10388)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-07-21 17:55:03 UTC (rev 10389)
@@ -46,9 +46,6 @@
Document Tree / Docutils DTD
----------------------------
-* Use the ``%tbl.table.att`` parameter entity instead of ``%bodyatt``
- to customize the <table> element's attribute list in Docutils 1.0.
-
* The <footnote> element's first child (<label>) will become mandatory
in Docutils 1.0.
@@ -210,6 +207,8 @@
Document Tree / Docutils DTD:
- Drop the `name` attribute from <reference> nodes.
+ - Use the ``%tbl.table.att`` parameter entity instead of ``%bodyatt``
+ to customize the <table> element's attribute list in Docutils 1.0.
Configuration changes:
- `Auto-detection`_ of the input encoding is no longer supported.
@@ -292,6 +291,8 @@
`writers.latex2e.SortableDict`
Not used and deprecated since Docutils 0.22.
+Bugfixes and improvements (see HISTORY_).
+
.. [#cross-links] This includes links from the table of contents_ and
"`section self-links <section_self_link_>`_" added by the HTML5
writer.
Modified: trunk/docutils/docs/ref/doctree.rst
===================================================================
--- trunk/docutils/docs/ref/doctree.rst 2026-07-16 10:43:55 UTC (rev 10388)
+++ trunk/docutils/docs/ref/doctree.rst 2026-07-21 17:55:03 UTC (rev 10389)
@@ -3900,7 +3900,7 @@
:Attributes: The <table> element may contain the frame_, colsep_,
rowsep_, and pgwide_ attributes (ignored by Docutils)
- and (via the `%bodyatt`_ parameter entity)
+ and (via the `%tbl.table.att`_ parameter entity)
the `common attributes`_, align_, and width_.
__ https://www.oasis-open.org/specs/tm9901.html#AEN142
@@ -5344,9 +5344,8 @@
The ``%bodyatt`` parameter entity is defined in the `Exchange Table Model`_
to allow customization of the `\<table>`_ element's attribute list.
-The `Docutils Generic DTD`_ redefines it to add align_, width_, and the
-`common attributes`_. (In Docutils versions ≥ 1.0, the `%tbl.table.att`_
-parameter entity will be redefined instead.)
+It was used (instead of `%tbl.table.att`_) in Docutils versions < 1.0 to
+add align_, width_, and the `common attributes`_.
``%fixedspace.att``
@@ -5480,8 +5479,8 @@
Model`_ to allow customization of the `\<table>`_ element's attribute
list.
-Docutils versions ≥ 1.0 will use ``%tbl.table.att`` (instead of the
-obsolete `%bodyatt`_) to add align_, width_, and the `common attributes`_.
+The `Docutils Generic DTD`_ redefines it to add align_, width_, and the
+`common attributes`_ (Docutils versions < 1.0 used `%bodyatt`_ instead).
``%tbl.tbody.att``
Modified: trunk/docutils/docs/ref/docutils.dtd
===================================================================
--- trunk/docutils/docs/ref/docutils.dtd 2026-07-16 10:43:55 UTC (rev 10388)
+++ trunk/docutils/docs/ref/docutils.dtd 2026-07-21 17:55:03 UTC (rev 10389)
@@ -218,16 +218,13 @@
http://www.oasis-open.org/html/tm9901.htm).
-->
-<!ENTITY % calstblx PUBLIC
- "-//OASIS//DTD XML Exchange Table Model 19990315//EN"
- "soextblx.dtd">
-
<!-- These parameter entities customize the table model DTD. -->
-<!-- table element TODO: use %tbl.table.att. Keep or drop pgwide? -->
-<!ENTITY % bodyatt
+<!-- table element the "pgwide" attribute is ignored by Docutils -->
+<!ENTITY % tbl.table.att
" %basic.atts;
%align-h.att;
- width %measure; #IMPLIED ">
+ width %measure; #IMPLIED
+ pgwide %yesorno; #IMPLIED ">
<!-- 1 colspec element is expected per table column: -->
<!ENTITY % tbl.tgroup.mdl "colspec+,thead?,tbody">
<!ENTITY % tbl.tgroup.att " %basic.atts; ">
@@ -243,6 +240,10 @@
" %basic.atts;
morecols %number; #IMPLIED ">
+<!ENTITY % calstblx PUBLIC
+ "-//OASIS//DTD XML Exchange Table Model 19990315//EN"
+ "soextblx.dtd">
+
<!--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Root Element
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-16 10:43:58
|
Revision: 10388
http://sourceforge.net/p/docutils/code/10388
Author: milde
Date: 2026-07-16 10:43:55 +0000 (Thu, 16 Jul 2026)
Log Message:
-----------
Fix anonymous hyperlinks to "clickable" images.
Images with :target: option are wrapped in a `<reference>`
to the specified target.
Anonymous links to the image were redirected to the image's target (sic!).
Propagation of internal targets to the next "suitable" element now transfers
"ids" and "names" to the `<image>`, not the wrapping `<reference>`.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/transforms/references.py
trunk/docutils/test/test_transforms/test_hyperlinks.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-07-16 10:43:46 UTC (rev 10387)
+++ trunk/docutils/HISTORY.rst 2026-07-16 10:43:55 UTC (rev 10388)
@@ -108,10 +108,13 @@
the `unknown_reference_resolvers` hook.
- 3 new transforms, `MatchReferences`, `ReportDanglingReferences`,
and `ReportUnreferencedLinks` obsolete `DanglingReferences`.
+ - "lazy IDs": Handle hyperlink targets without ID;
+ if required, generate and set one.
- Add INFO system_message if a <target> cannot be propagated
to the next node.
- - "lazy IDs": Handle hyperlink targets without ID;
- if required, generate and set one.
+ - Fix anonymous hyperlinks to "clickable" images: "Propagation" of a
+ <target> in front of a "clickable" image now transfers "ids" and
+ "names" to the `<image>`, not the wrapping `<reference>`.
* docutils/transforms/universal.py
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-07-16 10:43:46 UTC (rev 10387)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-16 10:43:55 UTC (rev 10388)
@@ -148,6 +148,11 @@
if (isinstance(candidate, (nodes.Invisible, nodes.Targetable))
and not isinstance(candidate, nodes.target)):
return None
+ # If the next element is a "clickable" image (a <reference>
+ # wrapped around an <image>), return the <image>
+ if (isinstance(candidate, nodes.reference) and len(candidate) == 1
+ and isinstance(candidate[0], nodes.image)):
+ return candidate[0]
return candidate
def is_internal(self, node: nodes.Node) -> bool:
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-16 10:43:46 UTC (rev 10387)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-16 10:43:55 UTC (rev 10388)
@@ -1041,15 +1041,13 @@
<target ids="external" names="external" refuri="http://uri">
<target ids="indirect" names="indirect" refuri="http://uri">
<target refid="internal">
- <reference ids="internal" names="internal" refuri="http://uri">
- <image uri="picture.png">
<reference refuri="http://uri">
+ <image ids="internal" names="internal" uri="picture.png">
+ <reference refuri="http://uri">
<image uri="picture.png">
<reference refid="internal">
<image uri="picture.png">
"""],
-# TODO: Anonymous links to a "clickable image should go
-# to the image, not the image's click-target!
["""\
.. _img1:
.. image:: pic1.png
@@ -1062,18 +1060,18 @@
Named link to img1_ with target and anonymous links to
the targetless img2__ and
-img3__ with target (sic!).
+img3__ with target.
""",
"""\
<document source="test data">
<target refid="img1">
- <reference ids="img1" names="img1" refuri="uri1.html">
- <image uri="pic1.png">
+ <reference refuri="uri1.html">
+ <image ids="img1" names="img1" uri="pic1.png">
<target anonymous="1" refid="target-1">
<image ids="target-1" uri="pic2.png">
<target anonymous="1" refid="target-2">
- <reference ids="target-2" refuri="uri3.html">
- <image uri="pic3.png">
+ <reference refuri="uri3.html">
+ <image ids="target-2" uri="pic3.png">
<paragraph>
Named link to \n\
<reference refid="img1">
@@ -1083,9 +1081,9 @@
<reference anonymous="1" refid="target-1">
img2
and
- <reference anonymous="1" refuri="uri3.html">
+ <reference anonymous="1" refid="target-2">
img3
- with target (sic!).
+ with target.
"""],
["""\
__
@@ -1093,7 +1091,7 @@
.. image:: pic1.png
:target: uri1.html
-Two anonymous__ links to an `image with target`__ (sic!).
+Two anonymous__ links to an `image with target`__.
.. _named:
__
@@ -1100,7 +1098,7 @@
.. image:: pic2.png
:target: uri2.html
-Named_ and anonymous__ link to an image with target (sic!).
+Named_ and anonymous__ link to an image with target.
__
.. _named link:
@@ -1107,44 +1105,44 @@
.. image:: pic3.png
:target: uri3.html
-Anonymous__ and `named link`_ to an image with target (sic!).
+Anonymous__ and `named link`_ to an image with target.
""",
"""\
<document source="test data">
<target anonymous="1" refid="target-1">
<target anonymous="1" refid="target-2">
- <reference ids="target-2 target-1" refuri="uri1.html">
- <image uri="pic1.png">
+ <reference refuri="uri1.html">
+ <image ids="target-2 target-1" uri="pic1.png">
<paragraph>
Two \n\
- <reference anonymous="1" refuri="uri1.html">
+ <reference anonymous="1" refid="target-2">
anonymous
links to an \n\
- <reference anonymous="1" refuri="uri1.html">
+ <reference anonymous="1" refid="target-2">
image with target
- (sic!).
+ .
<target refid="named">
<target anonymous="1" refid="target-3">
- <reference ids="target-3 named" names="named" refuri="uri2.html">
- <image uri="pic2.png">
+ <reference refuri="uri2.html">
+ <image ids="target-3 named" names="named" uri="pic2.png">
<paragraph>
<reference refid="named">
Named
and \n\
- <reference anonymous="1" refuri="uri2.html">
+ <reference anonymous="1" refid="target-3">
anonymous
- link to an image with target (sic!).
+ link to an image with target.
<target anonymous="1" refid="target-4">
<target refid="named-link">
- <reference ids="named-link target-4" names="named\\ link" refuri="uri3.html">
- <image uri="pic3.png">
+ <reference refuri="uri3.html">
+ <image ids="named-link target-4" names="named\\ link" uri="pic3.png">
<paragraph>
- <reference anonymous="1" refuri="uri3.html">
+ <reference anonymous="1" refid="named-link">
Anonymous
and \n\
<reference refid="named-link">
named link
- to an image with target (sic!).
+ to an image with target.
"""],
["""\
.. __: http://full
@@ -1477,10 +1475,10 @@
<document source="test data">
<target names="external" refuri="http://uri">
<target names="indirect" refuri="http://uri">
- <target refname="internal">
- <reference ids="internal" names="internal" refuri="http://uri">
- <image uri="picture.png">
+ <target refid="internal">
<reference refuri="http://uri">
+ <image ids="internal" names="internal" uri="picture.png">
+ <reference refuri="http://uri">
<image uri="picture.png">
<reference refid="internal">
<image uri="picture.png">
@@ -1499,18 +1497,18 @@
Named link to img1_ with target and anonymous links to
the targetless img2__ and
-img3__ with target (sic!).
+img3__ with target.
""",
"""\
<document source="test data">
- <target refname="img1">
- <reference ids="img1" names="img1" refuri="uri1.html">
- <image uri="pic1.png">
+ <target refid="img1">
+ <reference refuri="uri1.html">
+ <image ids="img1" names="img1" uri="pic1.png">
<target anonymous="1" refid="image-1">
<image ids="image-1" uri="pic2.png">
- <target anonymous="1" refid="reference-1">
- <reference ids="reference-1" refuri="uri3.html">
- <image uri="pic3.png">
+ <target anonymous="1" refid="image-2">
+ <reference refuri="uri3.html">
+ <image ids="image-2" uri="pic3.png">
<paragraph>
Named link to \n\
<reference refid="img1">
@@ -1520,9 +1518,9 @@
<reference anonymous="1" refid="image-1">
img2
and
- <reference anonymous="1" refuri="uri3.html">
+ <reference anonymous="1" refid="image-2">
img3
- with target (sic!).
+ with target.
"""],
["""\
__
@@ -1530,7 +1528,7 @@
.. image:: pic1.png
:target: uri1.html
-Two anonymous__ links to an `image with target`__ (sic!).
+Two anonymous__ links to an `image with target`__.
.. _named:
__
@@ -1537,7 +1535,7 @@
.. image:: pic2.png
:target: uri2.html
-Named_ and anonymous__ link to an image with target (sic!).
+Named_ and anonymous__ link to an image with target.
__
.. _named link:
@@ -1544,44 +1542,44 @@
.. image:: pic3.png
:target: uri3.html
-Anonymous__ and `named link`_ to an image with target (sic!).
+Anonymous__ and `named link`_ to an image with target.
""",
"""\
<document source="test data">
<target anonymous="1">
- <target anonymous="1" refid="reference-1">
- <reference ids="reference-1" refuri="uri1.html">
- <image uri="pic1.png">
+ <target anonymous="1" refid="image-1">
+ <reference refuri="uri1.html">
+ <image ids="image-1" uri="pic1.png">
<paragraph>
Two \n\
- <reference anonymous="1" refuri="uri1.html">
+ <reference anonymous="1" refid="image-1">
anonymous
links to an \n\
- <reference anonymous="1" refuri="uri1.html">
+ <reference anonymous="1" refid="image-1">
image with target
- (sic!).
- <target refname="named">
- <target anonymous="1" refname="named">
- <reference ids="named" names="named" refuri="uri2.html">
- <image uri="pic2.png">
+ .
+ <target refid="named">
+ <target anonymous="1" refid="named">
+ <reference refuri="uri2.html">
+ <image ids="named" names="named" uri="pic2.png">
<paragraph>
<reference refid="named">
Named
and \n\
- <reference anonymous="1" refuri="uri2.html">
+ <reference anonymous="1" refid="named">
anonymous
- link to an image with target (sic!).
+ link to an image with target.
<target anonymous="1" refname="named link">
- <target refname="named link">
- <reference ids="named-link" names="named\\ link" refuri="uri3.html">
- <image uri="pic3.png">
+ <target refid="named-link">
+ <reference refuri="uri3.html">
+ <image ids="named-link" names="named\\ link" uri="pic3.png">
<paragraph>
- <reference anonymous="1" refuri="uri3.html">
+ <reference anonymous="1" refid="named-link">
Anonymous
and \n\
<reference refid="named-link">
named link
- to an image with target (sic!).
+ to an image with target.
"""],
["""\
.. __: http://full
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-16 10:43:49
|
Revision: 10387
http://sourceforge.net/p/docutils/code/10387
Author: milde
Date: 2026-07-16 10:43:46 +0000 (Thu, 16 Jul 2026)
Log Message:
-----------
Simplify logic in AnonymousHyperlinks transform.
No change to the behaviour.
Modified Paths:
--------------
trunk/docutils/docutils/transforms/references.py
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-07-16 10:43:33 UTC (rev 10386)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-16 10:43:46 UTC (rev 10387)
@@ -218,20 +218,18 @@
ref['refuri'] = target['refuri']
ref.resolved = True
break
- else:
- if not target['ids']:
- if 'refid' in target: # propagated target
- target = self.document.ids[target['refid']]
- elif 'refname' in target: # indirect target
- target = self.document.names[target['refname']]
- elif next_node := self.next_suitable_node(target):
- target = next_node
- else:
- self.document.set_id(target)
- continue
+ if target['ids']:
ref['refid'] = target['ids'][0]
self.document.note_refid(ref)
break
+ if 'refid' in target: # propagated target
+ target = self.document.ids[target['refid']]
+ elif 'refname' in target: # indirect target
+ target = self.document.names[target['refname']]
+ elif next_node := self.next_suitable_node(target):
+ target = next_node
+ else:
+ self.document.set_id(target)
class IndirectHyperlinks(Transform):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-16 10:43:42
|
Revision: 10386
http://sourceforge.net/p/docutils/code/10386
Author: milde
Date: 2026-07-16 10:43:33 +0000 (Thu, 16 Jul 2026)
Log Message:
-----------
Fix issue with inline targets containing substring "refname" or "refuri".
`nodes.Node.next_node()` may return a `nodes.Text` instance
where ``if "refname" in node`` does not test for attributes but
the substring "refname" in the text content.
This led to `<target names="%refname.att">%refname.att</target>`
beeing wrongly identified as an indirect target and a subsequent
AssertionError because the corresponding `<reference>` did not get
a "refid" attribute.
Adding a check makes `PropagateTargets.next_suitable_target()`
return None if called with a non-empty start target.
For added robustness, `PropagateTargets.is_internal()` checks if
the given argument is a `nodes.Element` instance.
Modified Paths:
--------------
trunk/docutils/docutils/nodes.py
trunk/docutils/docutils/transforms/references.py
trunk/docutils/docutils/writers/_html_base.py
trunk/docutils/test/test_nodes.py
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-07-16 10:43:24 UTC (rev 10385)
+++ trunk/docutils/docutils/nodes.py 2026-07-16 10:43:33 UTC (rev 10386)
@@ -688,6 +688,9 @@
def __contains__(self, key: str | Node) -> bool:
# Test for both, children and attributes with operator ``in``.
+ #
+ # Caution: Document Tree traversal also returns Text nodes where
+ # ``in`` looks for substrings in the text content.
if isinstance(key, str):
return key in self.attributes
return key in self.children
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-07-16 10:43:24 UTC (rev 10385)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-16 10:43:33 UTC (rev 10386)
@@ -133,8 +133,11 @@
target['names'] = []
def next_suitable_node(self, target: nodes.Element) -> nodes.Element:
- if not isinstance(target, nodes.target):
- return None # only <target> ids/names are propagated
+ # Return the next suitable element for the transfer of the
+ # "names" and "ids" attributes from an empty "internal" <target>
+ # (target propagation).
+ if not isinstance(target, nodes.target) or len(target):
+ return None
candidate = target.next_node(ascend=True)
# skip system messages (may be removed by universal.FilterMessages)
while isinstance(candidate, nodes.system_message):
@@ -147,8 +150,10 @@
return None
return candidate
- def is_internal(self, node: nodes.Element) -> bool:
- # Return True, if `node` is an internal hyperlink target.
+ def is_internal(self, node: nodes.Node) -> bool:
+ # Return True, if `node` is a potential internal hyperlink target.
+ if not isinstance(node, nodes.Element):
+ return False
if 'refid' in node or 'refname' in node or 'refuri' in node:
return False # node is indirect or external target
# check destination of chained targets:
Modified: trunk/docutils/docutils/writers/_html_base.py
===================================================================
--- trunk/docutils/docutils/writers/_html_base.py 2026-07-16 10:43:24 UTC (rev 10385)
+++ trunk/docutils/docutils/writers/_html_base.py 2026-07-16 10:43:33 UTC (rev 10386)
@@ -1526,7 +1526,7 @@
atts['classes'].append('external')
else:
assert 'refid' in node, \
- 'References must have "refuri" or "refid" attribute.'
+ f'Reference without "refuri" or "refid" attribute: {node}'
atts['href'] = '#' + node['refid']
atts['classes'].append('internal')
if len(node) == 1 and isinstance(node[0], nodes.image):
Modified: trunk/docutils/test/test_nodes.py
===================================================================
--- trunk/docutils/test/test_nodes.py 2026-07-16 10:43:24 UTC (rev 10385)
+++ trunk/docutils/test/test_nodes.py 2026-07-16 10:43:33 UTC (rev 10386)
@@ -94,6 +94,14 @@
e[0][1] += nodes.Text('some text')
e += nodes.Element()
e += nodes.Element()
+ # Tree Index testlist
+ # <Element> e
+ # <Element> e[0] skip
+ # <Element> e[0][0]
+ # <TextElement> e[0][1] skip
+ # <Text> e[0][1][0]
+ # <Element> e[1] skip
+ # <Element> e[2]
self.testlist = [e[0], e[0][1], e[1]]
compare = [(e, e[0][0]),
(e[0], e[0][0]),
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-16 10:43:26
|
Revision: 10385
http://sourceforge.net/p/docutils/code/10385
Author: milde
Date: 2026-07-16 10:43:24 +0000 (Thu, 16 Jul 2026)
Log Message:
-----------
"lazy IDs": handle "chained" targets.
Recursively test the next nodes of a to-be-propagated target; only set IDs
if it is an explicit internal target.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docutils/transforms/references.py
trunk/docutils/test/test_transforms/test_hyperlinks.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-07-16 10:43:14 UTC (rev 10384)
+++ trunk/docutils/HISTORY.rst 2026-07-16 10:43:24 UTC (rev 10385)
@@ -99,18 +99,18 @@
* docutils/transforms/parts.py:
- - `Contents.build_contents()`: ensure sections have an ID and prefer
- IDs from external targets with "lazy IDs" (`legacy_ids`_ False).
+ - "lazy IDs": `Contents.build_contents()` ensures sections have an ID
+ and prefers IDs from external targets if `legacy_ids`_ is False.
* docutils/transforms/references.py
- `IndirectHyperlinks.resolve_indirect_target()` no longer calls
- `unknown_reference_resolvers` and only sets IDs if required.
+ the `unknown_reference_resolvers` hook.
- 3 new transforms, `MatchReferences`, `ReportDanglingReferences`,
and `ReportUnreferencedLinks` obsolete `DanglingReferences`.
- Add INFO system_message if a <target> cannot be propagated
to the next node.
- - support "lazy IDs": Handle hyperlink targets without ID;
+ - "lazy IDs": Handle hyperlink targets without ID;
if required, generate and set one.
* docutils/transforms/universal.py
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-07-16 10:43:14 UTC (rev 10384)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-07-16 10:43:24 UTC (rev 10385)
@@ -233,11 +233,9 @@
rST parser:
- Warn if a `"figure"`_ directive is missing both caption and legend.
- - Don't generate identifiers for indirect or external targets
- (unless legacy_ids_ is True).
- - Generate identifiers for implicit targets (mainly sections) only if
- there is a cross-link to the target [#cross-links]_ and no "explicit"
- identifier (unless legacy_ids_ is True).
+ - "lazy IDs": Generate target ids_ in transforms -- after parsing and
+ only if required in the output document.
+ Keep behaviour backwards compatible with the legacy_ids_ setting.
HTML5 writer:
- Use normal font size and colour for informal titles of type "rubric".
@@ -298,6 +296,7 @@
"`section self-links <section_self_link_>`_" added by the HTML5
writer.
+
Release 0.23 (2026-05-27)
=========================
@@ -1609,8 +1608,9 @@
.. _Docutils Document Model:
.. _Docutils XML: docs/ref/doctree.html
.. _"colwidth" attribute: docs/ref/doctree.html#colwidth
+.. _<doctest_block>: docs/ref/doctree.html#doctest-block
.. _identifier: docs/ref/doctree.html#identifiers
-.. _<doctest_block>: docs/ref/doctree.html#doctest-block
+.. _ids: docs/ref/doctree.html#ids
.. _reference names: docs/ref/doctree.html#reference-names
.. _<target>: docs/ref/doctree.html#target
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-07-16 10:43:14 UTC (rev 10384)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-16 10:43:24 UTC (rev 10385)
@@ -69,7 +69,7 @@
if node is None or not self.document.nametypes[name]:
continue
# Skip external or indirect targets:
- if 'refid' in node or 'refname' in node or 'refuri' in node:
+ if not self.is_internal(node):
continue
self.document.set_id(node)
# Now propatate internal <target>s:
@@ -80,15 +80,8 @@
or 'refname' in target
or 'refuri' in target):
continue
- next_node = target.next_node(ascend=True)
- # skip system messages (may be removed by universal.FilterMessages)
- while isinstance(next_node, nodes.system_message):
- next_node = next_node.next_node(ascend=True, descend=False)
- # Do not move names and ids into Invisibles (we'd lose the
- # attributes) or different Targetables (e.g. footnotes).
- if (next_node is None
- or isinstance(next_node, (nodes.Invisible, nodes.Targetable))
- and not isinstance(next_node, nodes.target)):
+ next_node = self.next_suitable_node(target)
+ if next_node is None:
self.document.reporter.info(
f'Cannot propagate target "{" ".join(target["names"])}" '
'to next element', base_node=target)
@@ -135,13 +128,37 @@
self.document.note_refname(target)
elif next_node['names']:
target['refname'] = next_node['names'][0]
- else:
+ elif 'anonymous' not in next_node:
target['refid'] = self.document.set_id(next_node)
target['names'] = []
+ def next_suitable_node(self, target: nodes.Element) -> nodes.Element:
+ if not isinstance(target, nodes.target):
+ return None # only <target> ids/names are propagated
+ candidate = target.next_node(ascend=True)
+ # skip system messages (may be removed by universal.FilterMessages)
+ while isinstance(candidate, nodes.system_message):
+ candidate = candidate.next_node(ascend=True, descend=False)
+ # Do not move names and ids into Invisibles (we'd lose the
+ # attributes) or Targetables (<citation>, <footnote>).
+ # Other <target>s are OK. TODO: why no citations and footnotes?
+ if (isinstance(candidate, (nodes.Invisible, nodes.Targetable))
+ and not isinstance(candidate, nodes.target)):
+ return None
+ return candidate
-class AnonymousHyperlinks(Transform):
+ def is_internal(self, node: nodes.Element) -> bool:
+ # Return True, if `node` is an internal hyperlink target.
+ if 'refid' in node or 'refname' in node or 'refuri' in node:
+ return False # node is indirect or external target
+ # check destination of chained targets:
+ if next_node := self.next_suitable_node(node):
+ return self.is_internal(next_node)
+ return True
+
+class AnonymousHyperlinks(PropagateTargets):
+
"""
Link anonymous references to targets. Given::
@@ -186,6 +203,7 @@
msg.add_backref(prbid)
ref.replace_self(prb)
return
+
for ref, target in zip(anonymous_refs, anonymous_targets):
if ref.hasattr('refid') or ref.hasattr('refuri'):
continue
@@ -201,6 +219,8 @@
target = self.document.ids[target['refid']]
elif 'refname' in target: # indirect target
target = self.document.names[target['refname']]
+ elif next_node := self.next_suitable_node(target):
+ target = next_node
else:
self.document.set_id(target)
continue
@@ -1032,8 +1052,8 @@
naming = target['ids'][0]
else:
# Propagated target: "ids" and "names" attributes moved
- # to the node indicated by "refid" or "refname".
- naming = target.get('refid') or target.get('refname', '???')
+ # to the node indicated by "refname" or "refid".
+ naming = target.get('refname') or target.get('refid', '???')
self.document.reporter.info(
f'Hyperlink target "{naming}" is not referenced.',
base_node=target)
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-16 10:43:14 UTC (rev 10384)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-16 10:43:24 UTC (rev 10385)
@@ -1300,8 +1300,8 @@
<reference refuri="URI">
target2
, not the Title.
- <target refid="target1">
- <target ids="target1" names="target2 target1" refuri="URI">
+ <target refuri="URI">
+ <target names="target2 target1" refuri="URI">
<section names="title">
<title>
Title
@@ -1401,8 +1401,8 @@
""",
"""\
<document source="test data">
- <target refid="chained">
- <target ids="chained" names="external\\ hyperlink chained" refuri="http://uri">
+ <target refuri="http://uri">
+ <target names="external\\ hyperlink chained" refuri="http://uri">
<paragraph>
<reference refuri="http://uri">
External hyperlink
@@ -1450,7 +1450,7 @@
<document source="test data">
<target names="external\\ hyperlink" refuri="http://uri">
<target refuri="http://uri">
- <target ids="chained" names="indirect\\ hyperlink chained" refuri="http://uri">
+ <target names="indirect\\ hyperlink chained" refuri="http://uri">
<paragraph>
<reference refuri="http://uri">
Chained
@@ -1477,7 +1477,7 @@
<document source="test data">
<target names="external" refuri="http://uri">
<target names="indirect" refuri="http://uri">
- <target refid="internal">
+ <target refname="internal">
<reference ids="internal" names="internal" refuri="http://uri">
<image uri="picture.png">
<reference refuri="http://uri">
@@ -1503,7 +1503,7 @@
""",
"""\
<document source="test data">
- <target refid="img1">
+ <target refname="img1">
<reference ids="img1" names="img1" refuri="uri1.html">
<image uri="pic1.png">
<target anonymous="1" refid="image-1">
@@ -1548,9 +1548,9 @@
""",
"""\
<document source="test data">
- <target anonymous="1" refid="target-1">
- <target anonymous="1" refid="target-1">
- <reference ids="target-1" refuri="uri1.html">
+ <target anonymous="1">
+ <target anonymous="1" refid="reference-1">
+ <reference ids="reference-1" refuri="uri1.html">
<image uri="pic1.png">
<paragraph>
Two \n\
@@ -1560,8 +1560,8 @@
<reference anonymous="1" refuri="uri1.html">
image with target
(sic!).
- <target refid="named">
- <target anonymous="1" refid="named">
+ <target refname="named">
+ <target anonymous="1" refname="named">
<reference ids="named" names="named" refuri="uri2.html">
<image uri="pic2.png">
<paragraph>
@@ -1572,7 +1572,7 @@
anonymous
link to an image with target (sic!).
<target anonymous="1" refname="named link">
- <target refid="named-link">
+ <target refname="named link">
<reference ids="named-link" names="named\\ link" refuri="uri3.html">
<image uri="pic3.png">
<paragraph>
@@ -1590,20 +1590,23 @@
.. _external: http://indirect.external
__ external_
__
+__
`Full syntax anonymous external hyperlink reference`__,
`chained anonymous external reference`__,
`simplified syntax anonymous external hyperlink reference`__,
`indirect anonymous hyperlink reference`__,
-`internal anonymous hyperlink reference`__.
+`internal anonymous hyperlink reference`__,
+`second internal anonymous hyperlink reference`__.
""",
"""\
<document source="test data">
<target anonymous="1" refuri="http://full">
- <target anonymous="1" refid="target-1">
- <target anonymous="1" ids="target-1" refuri="http://simplified">
+ <target anonymous="1">
+ <target anonymous="1" refuri="http://simplified">
<target names="external" refuri="http://indirect.external">
<target anonymous="1" refuri="http://indirect.external">
+ <target anonymous="1">
<target anonymous="1" refid="paragraph-1">
<paragraph ids="paragraph-1">
<reference anonymous="1" refuri="http://full">
@@ -1620,6 +1623,9 @@
,
<reference anonymous="1" refid="paragraph-1">
internal anonymous hyperlink reference
+ ,
+ <reference anonymous="1" refid="paragraph-1">
+ second internal anonymous hyperlink reference
.
"""],
["""\
@@ -1630,8 +1636,8 @@
""",
"""\
<document source="test data">
- <target refid="chained">
- <target anonymous="1" ids="chained" names="chained" refuri="http://anonymous">
+ <target refuri="http://anonymous">
+ <target anonymous="1" names="chained" refuri="http://anonymous">
<paragraph>
<reference anonymous="1" refuri="http://anonymous">
Anonymous
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-16 10:43:18
|
Revision: 10384
http://sourceforge.net/p/docutils/code/10384
Author: milde
Date: 2026-07-16 10:43:14 +0000 (Thu, 16 Jul 2026)
Log Message:
-----------
"lazy IDs": postpone generation of IDs for anonymous targets.
Generate IDs for explicit targets after parsing is complete:
`nodes.document.note_explicit_target()` only generates an ID for the target,
if the "legacy_ids" setting is True.
The `transforms.references.PropagateTargets` transform now can also
propagate targets without reference name or ID and sets an ID on the
destination of the propagation if required.
This is a precondition for a future check whether the destination of
to-be-propagated anonymous targets is an external or indirect target
that does not require an ID.
Anonymous internal targets now re-use an existing ID or get an auto-ID
based on the tagname of the target element
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/nodes.py
trunk/docutils/docutils/transforms/references.py
trunk/docutils/test/test_transforms/test_hyperlinks.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-07-15 18:57:56 UTC (rev 10383)
+++ trunk/docutils/HISTORY.rst 2026-07-16 10:43:14 UTC (rev 10384)
@@ -47,9 +47,9 @@
- Remove "name" from `reference.valid_attributes`.
- Remove the internal attribute `Targetable.indirect_reference_name`.
- - "lazy IDs": `document.note_explicit_target()` and
- `document.note_anonymous_target()` generate identifiers for indirect
- or external targets only if the `legacy_ids`_ setting is True.
+ - "lazy IDs":
+ `document.note_explicit_target()` and `document.note_anonymous_target()`
+ generate identifiers only if the `legacy_ids`_ setting is True.
* docutils/parsers/__init__.py
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-07-15 18:57:56 UTC (rev 10383)
+++ trunk/docutils/docutils/nodes.py 2026-07-16 10:43:14 UTC (rev 10384)
@@ -2192,8 +2192,7 @@
self.note_refname(target)
def note_anonymous_target(self, target: target) -> None:
- if (getattr(self.settings, "legacy_ids", True)
- or 'refuri' not in target and 'refname' not in target):
+ if getattr(self.settings, "legacy_ids", True):
self.set_id(target)
def note_autofootnote(self, footnote: footnote) -> None:
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-07-15 18:57:56 UTC (rev 10383)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-16 10:43:14 UTC (rev 10384)
@@ -43,7 +43,7 @@
Given the following nodes::
<target names="internal1">
- <target anonymous="1" ids="id1">
+ <target anonymous="1">
<target names="internal2">
<paragraph>
This is a test.
@@ -53,9 +53,9 @@
to the paragraph itself::
<target refid="internal1">
- <target anonymous="1" refid="id1">
+ <target anonymous="1" refid="internal1">
<target refid="internal2">
- <paragraph ids="internal2 id1 internal1" names="internal2 internal1">
+ <paragraph ids="internal2 internal1" names="internal2 internal1">
This is a test.
"""
@@ -124,13 +124,20 @@
next_node, nodes.caption):
target.parent.remove(target)
continue
- # Set refid to point to the first former ID of target
- # which is now an ID of next_node.
- target['refid'] = target['ids'][0]
+ # Set refid or refname to point to the next_node.
# Clear ids and names; they have been moved to next_node.
- target['ids'] = []
+ if target['ids']:
+ target['refid'] = target['ids'][0]
+ self.document.note_refid(target)
+ target['ids'] = []
+ elif target['names']:
+ target['refname'] = target['names'][0]
+ self.document.note_refname(target)
+ elif next_node['names']:
+ target['refname'] = next_node['names'][0]
+ else:
+ target['refid'] = self.document.set_id(next_node)
target['names'] = []
- self.document.note_refid(target)
class AnonymousHyperlinks(Transform):
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-15 18:57:56 UTC (rev 10383)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-16 10:43:14 UTC (rev 10384)
@@ -1506,10 +1506,10 @@
<target refid="img1">
<reference ids="img1" names="img1" refuri="uri1.html">
<image uri="pic1.png">
- <target anonymous="1" refid="target-1">
- <image ids="target-1" uri="pic2.png">
- <target anonymous="1" refid="target-2">
- <reference ids="target-2" refuri="uri3.html">
+ <target anonymous="1" refid="image-1">
+ <image ids="image-1" uri="pic2.png">
+ <target anonymous="1" refid="reference-1">
+ <reference ids="reference-1" refuri="uri3.html">
<image uri="pic3.png">
<paragraph>
Named link to \n\
@@ -1517,7 +1517,7 @@
img1
with target and anonymous links to
the targetless \n\
- <reference anonymous="1" refid="target-1">
+ <reference anonymous="1" refid="image-1">
img2
and
<reference anonymous="1" refuri="uri3.html">
@@ -1549,8 +1549,8 @@
"""\
<document source="test data">
<target anonymous="1" refid="target-1">
- <target anonymous="1" refid="target-2">
- <reference ids="target-2 target-1" refuri="uri1.html">
+ <target anonymous="1" refid="target-1">
+ <reference ids="target-1" refuri="uri1.html">
<image uri="pic1.png">
<paragraph>
Two \n\
@@ -1561,8 +1561,8 @@
image with target
(sic!).
<target refid="named">
- <target anonymous="1" refid="target-3">
- <reference ids="target-3 named" names="named" refuri="uri2.html">
+ <target anonymous="1" refid="named">
+ <reference ids="named" names="named" refuri="uri2.html">
<image uri="pic2.png">
<paragraph>
<reference refid="named">
@@ -1571,9 +1571,9 @@
<reference anonymous="1" refuri="uri2.html">
anonymous
link to an image with target (sic!).
- <target anonymous="1" refid="target-4">
+ <target anonymous="1" refname="named link">
<target refid="named-link">
- <reference ids="named-link target-4" names="named\\ link" refuri="uri3.html">
+ <reference ids="named-link" names="named\\ link" refuri="uri3.html">
<image uri="pic3.png">
<paragraph>
<reference anonymous="1" refuri="uri3.html">
@@ -1604,8 +1604,8 @@
<target anonymous="1" ids="target-1" refuri="http://simplified">
<target names="external" refuri="http://indirect.external">
<target anonymous="1" refuri="http://indirect.external">
- <target anonymous="1" refid="target-2">
- <paragraph ids="target-2">
+ <target anonymous="1" refid="paragraph-1">
+ <paragraph ids="paragraph-1">
<reference anonymous="1" refuri="http://full">
Full syntax anonymous external hyperlink reference
,
@@ -1618,7 +1618,7 @@
<reference anonymous="1" refuri="http://indirect.external">
indirect anonymous hyperlink reference
,
- <reference anonymous="1" refid="target-2">
+ <reference anonymous="1" refid="paragraph-1">
internal anonymous hyperlink reference
.
"""],
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-15 18:57:59
|
Revision: 10383
http://sourceforge.net/p/docutils/code/10383
Author: milde
Date: 2026-07-15 18:57:56 +0000 (Wed, 15 Jul 2026)
Log Message:
-----------
"lazy IDs": postpone generation of IDs for explicit targets.
Generate IDs for explicit targets after parsing is complete:
`nodes.document.note_explicit_target()` only generates an ID for the target,
if the "legacy_ids" setting is True.
The `transforms.references.PropagateTargets` transform adds IDs to
internal explicit targets (which may also be <topics> or other elements)
before "propagating" empty targets.
`transforms.references.Footnotes.number_footnote_references()`
sets IDs on footnotes with "reference name" but no ID.
This is a precondition for a future check whether the destination of
to-be-propagated targets is an external or indirect target that does
not require an ID. For example in
~~~
.. _e.g.:
.. _example: eg.html
~~~
the second target may become `<target names="example e.g." refuri="eg.html">`
instead of `<target ids="e-g" names="example e.g." refuri="eg.html">`.
Adapt tests: the output of parser tests has no IDs for explicit targets,
nor has the output of transform tests that do not run the `PropagateTargets`
transform.
Modified Paths:
--------------
trunk/docutils/docutils/nodes.py
trunk/docutils/docutils/transforms/references.py
trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py
trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py
trunk/docutils/test/test_parsers/test_rst/test_targets.py
trunk/docutils/test/test_transforms/test_doctitle.py
trunk/docutils/test/test_transforms/test_hyperlinks.py
trunk/docutils/test/test_transforms/test_transitions.py
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-07-14 13:32:05 UTC (rev 10382)
+++ trunk/docutils/docutils/nodes.py 2026-07-15 18:57:56 UTC (rev 10383)
@@ -2177,8 +2177,7 @@
def note_explicit_target(self, target: Element,
msgnode: Element|None = None) -> None:
self.note_names(target, msgnode, explicit=True)
- if (getattr(self.settings, "legacy_ids", True)
- or 'refuri' not in target and 'refname' not in target):
+ if getattr(self.settings, "legacy_ids", True):
self.set_id(target, msgnode)
def note_refname(self, node: Element) -> None:
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-07-14 13:32:05 UTC (rev 10382)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-15 18:57:56 UTC (rev 10383)
@@ -42,14 +42,15 @@
Given the following nodes::
- <target ids="internal1" names="internal1">
+ <target names="internal1">
<target anonymous="1" ids="id1">
- <target ids="internal2" names="internal2">
+ <target names="internal2">
<paragraph>
This is a test.
- `PropagateTargets` propagates the ids and names of the internal
- targets preceding the paragraph to the paragraph itself::
+ `PropagateTargets` ensures internal targets have an ID and propagates
+ the IDs and names of the internal targets preceding the paragraph
+ to the paragraph itself::
<target refid="internal1">
<target anonymous="1" refid="id1">
@@ -61,6 +62,17 @@
default_priority = 260
def apply(self) -> None:
+ # Ensure explicit internal targets ("named" elements) have an ID:
+ if not getattr(self.document.settings, "legacy_ids", True):
+ for name, node in self.document.names.items():
+ # Skip targets with duplicate or implicit names:
+ if node is None or not self.document.nametypes[name]:
+ continue
+ # Skip external or indirect targets:
+ if 'refid' in node or 'refname' in node or 'refuri' in node:
+ continue
+ self.document.set_id(node)
+ # Now propatate internal <target>s:
for target in self.document.findall(nodes.target):
# Only block-level targets without reference (like ".. _target:"):
if (len(target) or isinstance(target.parent, nodes.TextElement)
@@ -590,8 +602,9 @@
ref.replace_self(prb)
break
ref += nodes.Text(label)
- id = self.document.nameids[label]
- footnote = self.document.ids[id]
+ footnote = self.document.names[label]
+ id = (self.document.nameids.get(label)
+ or self.document.set_id(footnote))
ref['refid'] = id
self.document.note_refid(ref)
assert len(ref['ids']) == 1
Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2026-07-14 13:32:05 UTC (rev 10382)
+++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2026-07-15 18:57:56 UTC (rev 10383)
@@ -179,7 +179,7 @@
<section names="include\\ test">
<title>
Include Test
- <literal_block classes="test" ids="my-name" names="my\\ name" source="{include1}" xml:space="preserve">
+ <literal_block classes="test" names="my\\ name" source="{include1}" xml:space="preserve">
Inclusion 1
-----------
\n\
@@ -244,7 +244,7 @@
<document source="test data">
<paragraph>
Include code
- <literal_block classes="code test" ids="my-name" names="my\\ name" source="{include1}" xml:space="preserve">
+ <literal_block classes="code test" names="my\\ name" source="{include1}" xml:space="preserve">
Inclusion 1
-----------
\n\
Modified: trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py 2026-07-14 13:32:05 UTC (rev 10382)
+++ trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py 2026-07-15 18:57:56 UTC (rev 10383)
@@ -1168,10 +1168,10 @@
Report duplicate refname.
<paragraph>
Explicit targets: \n\
- <target ids="file-txt" names="file.txt">
+ <target names="file.txt">
file.txt
, \n\
- <target ids="file-html" names="file.html">
+ <target names="file.html">
file.html
.
<system_message level="1" line="6" source="test data" type="INFO">
@@ -1295,10 +1295,10 @@
Duplicate refnames in references with embedded alias.
<paragraph>
Explicit targets: \n\
- <target ids="tg1" names="tg1">
+ <target names="tg1">
tg1
and \n\
- <target ids="tg2" names="tg2">
+ <target names="tg2">
tg2
.
<system_message level="1" line="6" source="test data" type="INFO">
@@ -1334,19 +1334,19 @@
"""\
<document source="test data">
<paragraph>
- <target ids="target" names="target">
+ <target names="target">
target
<paragraph>
Here is \n\
- <target ids="another-target" names="another\\ target">
+ <target names="another\\ target">
another target
in some text. And \n\
- <target ids="yet-another-target" names="yet\\ another\\ target">
+ <target names="yet\\ another\\ target">
yet
another target
, spanning lines.
<paragraph>
- <target ids="here-is-a-target" names="here\\ is\\ a\\ target">
+ <target names="here\\ is\\ a\\ target">
Here is a TaRgeT
with case and spacial difficulties.
"""],
@@ -1357,10 +1357,10 @@
<document source="test data">
<paragraph>
l'
- <target ids="target1" names="target1">
+ <target names="target1">
target1
and l\u2019
- <target ids="target2" names="target2">
+ <target names="target2">
target2
with apostrophe
"""],
@@ -1373,21 +1373,21 @@
<document source="test data">
<paragraph>
quoted '
- <target ids="target1" names="target1">
+ <target names="target1">
target1
', quoted "
- <target ids="target2" names="target2">
+ <target names="target2">
target2
",
quoted \u2018
- <target ids="target3" names="target3">
+ <target names="target3">
target3
\u2019, quoted \u201c
- <target ids="target4" names="target4">
+ <target names="target4">
target4
\u201d,
quoted \xab
- <target ids="target5" names="target5">
+ <target names="target5">
target5
\xbb
"""],
@@ -1399,19 +1399,19 @@
"""\
<document source="test data">
<paragraph>
- <target ids="target1" names="'target1'">
+ <target names="'target1'">
'target1'
with quotes, \n\
- <target ids="target2" names=""target2"">
+ <target names=""target2"">
"target2"
with quotes,
- <target ids="target3" names="\u2018target3\u2019">
+ <target names="\u2018target3\u2019">
\u2018target3\u2019
with quotes, \n\
- <target ids="target4" names="\u201ctarget4\u201d">
+ <target names="\u201ctarget4\u201d">
\u201ctarget4\u201d
with quotes,
- <target ids="target5" names="\xabtarget5\xbb">
+ <target names="\xabtarget5\xbb">
\xabtarget5\xbb
with quotes
"""],
Modified: trunk/docutils/test/test_parsers/test_rst/test_targets.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-07-14 13:32:05 UTC (rev 10382)
+++ trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-07-15 18:57:56 UTC (rev 10383)
@@ -53,7 +53,7 @@
""",
"""\
<document source="test data">
- <target ids="target" names="target">
+ <target names="target">
<paragraph>
(Internal hyperlink target.)
"""],
@@ -62,7 +62,7 @@
""",
"""\
<document source="test data">
- <target ids="optional-space-before-colon" names="optional\\ space\\ before\\ colon">
+ <target names="optional\\ space\\ before\\ colon">
"""],
[r"""
External hyperlink targets:
@@ -115,9 +115,9 @@
""",
"""\
<document source="test data">
- <target ids="a-long-target-name" names="a\\ long\\ target\\ name">
- <target ids="a-target-name-including-a-colon-quoted" names="a\\ target\\ name:\\ including\\ a\\ colon\\ (quoted)">
- <target ids="a-target-name-including-a-colon-escaped" names="a\\ target\\ name:\\ including\\ a\\ colon\\ (escaped)">
+ <target names="a\\ long\\ target\\ name">
+ <target names="a\\ target\\ name:\\ including\\ a\\ colon\\ (quoted)">
+ <target names="a\\ target\\ name:\\ including\\ a\\ colon\\ (escaped)">
"""],
["""\
.. _`target: No matching backquote.
@@ -144,8 +144,8 @@
""",
"""\
<document source="test data">
- <target ids="a-very-long-target-name-split-across-lines" names="a\\ very\\ long\\ target\\ name,\\ split\\ across\\ lines">
- <target ids="and-another-with-backquotes" names="and\\ another,\\ with\\ backquotes">
+ <target names="a\\ very\\ long\\ target\\ name,\\ split\\ across\\ lines">
+ <target names="and\\ another,\\ with\\ backquotes">
"""],
["""\
External hyperlink:
@@ -265,7 +265,7 @@
<document source="test data">
<paragraph>
Duplicate indirect \n\
- <target ids="targets" names="targets">
+ <target names="targets">
targets
(same refname):
<target names="link" refname="targets">
@@ -330,7 +330,7 @@
<system_message level="1" line="6" source="test data" type="INFO">
<paragraph>
Target name overrides implicit target name "title".
- <target ids="title" names="title">
+ <target names="title">
<paragraph>
Paragraph.
"""],
@@ -376,19 +376,19 @@
<document source="test data">
<paragraph>
Duplicate explicit targets.
- <target dupnames="title" ids="title">
+ <target dupnames="title">
<paragraph>
First.
<system_message level="2" line="7" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "title".
- <target dupnames="title" ids="title-1">
+ <target dupnames="title">
<paragraph>
Second.
<system_message level="2" line="11" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "title".
- <target dupnames="title" ids="title-2">
+ <target dupnames="title">
<paragraph>
Third.
"""],
@@ -409,7 +409,7 @@
<document source="test data">
<paragraph>
Duplicate explicit/directive targets.
- <target dupnames="title" ids="title">
+ <target dupnames="title">
<paragraph>
First.
<rubric dupnames="title" ids="title-1">
@@ -471,7 +471,7 @@
<system_message level="2" line="12" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "target".
- <target dupnames="target" ids="target-2">
+ <target dupnames="target">
<paragraph>
Explicit internal target.
<system_message level="2" line="16" source="test data" type="WARNING">
@@ -482,10 +482,10 @@
<line>
Do not insert <system_message> element for duplicate
<line>
- <target dupnames="target" ids="target-3">
+ <target dupnames="target" ids="target-2">
target
, if this results in an invalid doctree.
- <rubric dupnames="target" ids="target-4">
+ <rubric dupnames="target" ids="target-3">
directive with target
<field_list>
<field>
@@ -496,7 +496,7 @@
with
<field>
<field_name>
- <target dupnames="target" ids="target-5">
+ <target dupnames="target" ids="target-4">
target
<field_body>
<paragraph>
Modified: trunk/docutils/test/test_transforms/test_doctitle.py
===================================================================
--- trunk/docutils/test/test_transforms/test_doctitle.py 2026-07-14 13:32:05 UTC (rev 10382)
+++ trunk/docutils/test/test_transforms/test_doctitle.py 2026-07-15 18:57:56 UTC (rev 10383)
@@ -227,7 +227,7 @@
Title
<substitution_definition names="foo">
bar
- <target ids="invisible-target" names="invisible\\ target">
+ <target names="invisible\\ target">
<paragraph>
This title should be the document title despite the
substitution_definition.
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-14 13:32:05 UTC (rev 10382)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-15 18:57:56 UTC (rev 10383)
@@ -1485,7 +1485,105 @@
<reference refid="internal">
<image uri="picture.png">
"""],
+# TODO: Anonymous links to a "clickable image should go
+# to the image, not the image's click-target!
["""\
+.. _img1:
+.. image:: pic1.png
+ :target: uri1.html
+__
+.. image:: pic2.png
+__
+.. image:: pic3.png
+ :target: uri3.html
+
+Named link to img1_ with target and anonymous links to
+the targetless img2__ and
+img3__ with target (sic!).
+""",
+"""\
+<document source="test data">
+ <target refid="img1">
+ <reference ids="img1" names="img1" refuri="uri1.html">
+ <image uri="pic1.png">
+ <target anonymous="1" refid="target-1">
+ <image ids="target-1" uri="pic2.png">
+ <target anonymous="1" refid="target-2">
+ <reference ids="target-2" refuri="uri3.html">
+ <image uri="pic3.png">
+ <paragraph>
+ Named link to \n\
+ <reference refid="img1">
+ img1
+ with target and anonymous links to
+ the targetless \n\
+ <reference anonymous="1" refid="target-1">
+ img2
+ and
+ <reference anonymous="1" refuri="uri3.html">
+ img3
+ with target (sic!).
+"""],
+["""\
+__
+__
+.. image:: pic1.png
+ :target: uri1.html
+
+Two anonymous__ links to an `image with target`__ (sic!).
+
+.. _named:
+__
+.. image:: pic2.png
+ :target: uri2.html
+
+Named_ and anonymous__ link to an image with target (sic!).
+
+__
+.. _named link:
+.. image:: pic3.png
+ :target: uri3.html
+
+Anonymous__ and `named link`_ to an image with target (sic!).
+""",
+"""\
+<document source="test data">
+ <target anonymous="1" refid="target-1">
+ <target anonymous="1" refid="target-2">
+ <reference ids="target-2 target-1" refuri="uri1.html">
+ <image uri="pic1.png">
+ <paragraph>
+ Two \n\
+ <reference anonymous="1" refuri="uri1.html">
+ anonymous
+ links to an \n\
+ <reference anonymous="1" refuri="uri1.html">
+ image with target
+ (sic!).
+ <target refid="named">
+ <target anonymous="1" refid="target-3">
+ <reference ids="target-3 named" names="named" refuri="uri2.html">
+ <image uri="pic2.png">
+ <paragraph>
+ <reference refid="named">
+ Named
+ and \n\
+ <reference anonymous="1" refuri="uri2.html">
+ anonymous
+ link to an image with target (sic!).
+ <target anonymous="1" refid="target-4">
+ <target refid="named-link">
+ <reference ids="named-link target-4" names="named\\ link" refuri="uri3.html">
+ <image uri="pic3.png">
+ <paragraph>
+ <reference anonymous="1" refuri="uri3.html">
+ Anonymous
+ and \n\
+ <reference refid="named-link">
+ named link
+ to an image with target (sic!).
+"""],
+["""\
.. __: http://full
__
__ http://simplified
Modified: trunk/docutils/test/test_transforms/test_transitions.py
===================================================================
--- trunk/docutils/test/test_transforms/test_transitions.py 2026-07-14 13:32:05 UTC (rev 10382)
+++ trunk/docutils/test/test_transforms/test_transitions.py 2026-07-15 18:57:56 UTC (rev 10383)
@@ -198,7 +198,7 @@
<system_message level="2" line="3" source="test data" type="WARNING">
<paragraph>
Transition at the end of the document.
- <target ids="anchor" names="anchor">
+ <target names="anchor">
<substitution_definition names="substitution\\ reference">
is invisible
"""],
@@ -316,7 +316,7 @@
<footer>
<paragraph>
will move away
- <target ids="anchor" names="anchor">
+ <target names="anchor">
<substitution_definition names="substitution\\ reference">
is invisible
<transition classes="classy">
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-14 13:32:08
|
Revision: 10382
http://sourceforge.net/p/docutils/code/10382
Author: milde
Date: 2026-07-14 13:32:05 +0000 (Tue, 14 Jul 2026)
Log Message:
-----------
"lazy IDs": Don't generate IDs for external and indirect targets.
External and indirect targets have a "refuri", "refname" or "refid"
attribute that is transferred to all references to this target
(by the `IndirectHyperlinks` transform for named targets and by the
`AnonymousHyperlinks` transform for anonymouns targets).
The target's ID is not required and not shown in the output.
The change keeps the "identifier" namespace clean.
Example: The reference names "topic" and "<topic>" both map to the ID "topic".
With "legacy_ids", the section title in the following sample
would get the ID "topic-1":
~~~
.. _<topic>: ../doctree.html#topic
Topic
=====
:Doctree Element: `\<topic>`_
~~~
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/ref/rst/directives.rst
trunk/docutils/docs/user/config.rst
trunk/docutils/docutils/nodes.py
trunk/docutils/docutils/parsers/__init__.py
trunk/docutils/docutils/transforms/references.py
trunk/docutils/test/data/help/docutils.rst
trunk/docutils/test/data/help/rst2html.rst
trunk/docutils/test/data/help/rst2latex.rst
trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt
trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py
trunk/docutils/test/test_parsers/test_rst/test_targets.py
trunk/docutils/test/test_transforms/test_hyperlinks.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/HISTORY.rst 2026-07-14 13:32:05 UTC (rev 10382)
@@ -47,6 +47,9 @@
- Remove "name" from `reference.valid_attributes`.
- Remove the internal attribute `Targetable.indirect_reference_name`.
+ - "lazy IDs": `document.note_explicit_target()` and
+ `document.note_anonymous_target()` generate identifiers for indirect
+ or external targets only if the `legacy_ids`_ setting is True.
* docutils/parsers/__init__.py
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-07-14 13:32:05 UTC (rev 10382)
@@ -233,6 +233,8 @@
rST parser:
- Warn if a `"figure"`_ directive is missing both caption and legend.
+ - Don't generate identifiers for indirect or external targets
+ (unless legacy_ids_ is True).
- Generate identifiers for implicit targets (mainly sections) only if
there is a cross-link to the target [#cross-links]_ and no "explicit"
identifier (unless legacy_ids_ is True).
Modified: trunk/docutils/docs/ref/rst/directives.rst
===================================================================
--- trunk/docutils/docs/ref/rst/directives.rst 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/docs/ref/rst/directives.rst 2026-07-14 13:32:05 UTC (rev 10382)
@@ -57,6 +57,7 @@
`specific admonitions`_.
+.. _specific admonitions:
.. _attention:
.. _caution:
.. _danger:
@@ -760,7 +761,7 @@
See Epigraph_ above for an analogous example.
-.. compound:
+.. _compound:
Compound Paragraph
==================
@@ -1152,8 +1153,7 @@
Document Parts
----------------
-.. A ``_contents:`` hyperlink here became id "contents-1"
- (name clash with the generated ToC)
+.. _contents:
Table of Contents
=================
@@ -1795,6 +1795,7 @@
A URI reference to a raw data file to be included.
+.. _class:
.. _class directive:
.. _rst-class:
@@ -2257,8 +2258,7 @@
:alt: example picture
:class: large-pics
- is the recommended syntax alternative to a preceding
- `class directive`_ ::
+ is the recommended syntax alternative to a preceding "class_" directive ::
.. class:: large-pics
.. image:: bild.png
Modified: trunk/docutils/docs/user/config.rst
===================================================================
--- trunk/docutils/docs/user/config.rst 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/docs/user/config.rst 2026-07-14 13:32:05 UTC (rev 10382)
@@ -799,9 +799,10 @@
Keep element identifiers_ compatible to Docutils ≤ 0.22.
If "legacy_ids" is False or with the command line option ``--lazy-ids``,
-the generation of identifiers_ from the `reference names`_ of
-`implicit targets`_ is done after parsing is complete and only
-if required by an internal cross-link [#cross-link]_.
+no identifiers_ are generated for `external <external targets_>`__ and
+`indirect targets`_. The generation of identifiers_ from the
+`reference names`_ of `implicit targets`_ is done after parsing is
+complete and only if required by an internal cross-link [#cross-link]_.
An existing identifier from an `explicit target`_ is re-used instead of
generating an additional identifier for the "implicit" reference name.
@@ -2689,6 +2690,7 @@
.. _explicit target:
.. _explicit targets: ../ref/rst/restructuredtext.html#explicit-hyperlink-targets
.. _explicit internal target: ../ref/rst/restructuredtext.html#internal-hyperlink-targets
+.. _external targets: ../ref/rst/restructuredtext.html#external-hyperlink-targets
.. _field lists: ../ref/rst/restructuredtext.html#field-lists
.. _field names: ../ref/rst/restructuredtext.html#field-names
.. _footnotes: ../ref/rst/restructuredtext.html#footnotes
@@ -2697,6 +2699,7 @@
.. _implicit hyperlink targets:
.. _implicit target:
.. _implicit targets: ../ref/rst/restructuredtext.html#implicit-hyperlink-targets
+.. _indirect targets: ../ref/rst/restructuredtext.html#indirect-hyperlink-targets
.. _interpreted text role: ../ref/rst/restructuredtext.html#interpreted-text
.. _inline markup recognition rules:
../ref/rst/restructuredtext.html#inline-markup-recognition-rules
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/docutils/nodes.py 2026-07-14 13:32:05 UTC (rev 10382)
@@ -2177,7 +2177,9 @@
def note_explicit_target(self, target: Element,
msgnode: Element|None = None) -> None:
self.note_names(target, msgnode, explicit=True)
- self.set_id(target, msgnode)
+ if (getattr(self.settings, "legacy_ids", True)
+ or 'refuri' not in target and 'refname' not in target):
+ self.set_id(target, msgnode)
def note_refname(self, node: Element) -> None:
self.refnames.setdefault(node['refname'], []).append(node)
@@ -2191,7 +2193,9 @@
self.note_refname(target)
def note_anonymous_target(self, target: target) -> None:
- self.set_id(target)
+ if (getattr(self.settings, "legacy_ids", True)
+ or 'refuri' not in target and 'refname' not in target):
+ self.set_id(target)
def note_autofootnote(self, footnote: footnote) -> None:
self.set_id(footnote)
Modified: trunk/docutils/docutils/parsers/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/__init__.py 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/docutils/parsers/__init__.py 2026-07-14 13:32:05 UTC (rev 10382)
@@ -51,7 +51,8 @@
['--legacy-ids'],
{'action': 'store_true', 'default': True,
'validator': frontend.validate_boolean}),
- ('Generate IDs for implicit targets only if required.',
+ ('Generate IDs for implicit targets only if required; '
+ 'no IDs for external and indirect targets.',
['--lazy-ids'],
{'dest': 'legacy_ids', 'action': 'store_false'}),
('Validate the document tree after parsing.',
@@ -101,7 +102,7 @@
'xml': 'docutils.parsers.docutils_xml',
# 3rd-party Markdown parsers
'myst': 'myst_parser.docutils_',
- # 'pycmark': works out of the box
+ # 'pycmark': works out of the box (with `legacy_ids`)
# dispatcher for 3rd-party Markdown parsers
'commonmark': 'docutils.parsers.commonmark_wrapper',
'markdown': 'docutils.parsers.commonmark_wrapper',
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-14 13:32:05 UTC (rev 10382)
@@ -178,8 +178,12 @@
break
else:
if not target['ids']:
- # Propagated target.
- target = self.document.ids[target['refid']]
+ if 'refid' in target: # propagated target
+ target = self.document.ids[target['refid']]
+ elif 'refname' in target: # indirect target
+ target = self.document.names[target['refname']]
+ else:
+ self.document.set_id(target)
continue
ref['refid'] = target['ids'][0]
self.document.note_refid(ref)
@@ -254,13 +258,17 @@
reftarget = self.document.ids.get(refid)
else:
reftarget = self.document.names.get(refname)
- refid = self.document.nameids.get(refname)
- if reftarget and not refid:
- refid = self.document.set_id(reftarget)
+ if getattr(self.document.settings, "legacy_ids", True):
+ refid = self.document.nameids.get(refname)
if not reftarget:
self.nonexistent_indirect_target(target)
return
- reftarget.note_referenced_by(id=refid)
+
+ if refid:
+ reftarget.note_referenced_by(id=refid)
+ else:
+ reftarget.note_referenced_by(name=refname)
+
if (isinstance(reftarget, nodes.target)
and not reftarget.resolved
and reftarget.hasattr('refname')):
@@ -277,12 +285,12 @@
elif reftarget.hasattr('refid'):
target['refid'] = reftarget['refid']
self.document.note_refid(target)
- elif reftarget['ids']:
+ else: # internal target
+ if not refid:
+ refid = self.document.set_id(reftarget)
target['refid'] = refid
self.document.note_refid(target)
- else:
- self.nonexistent_indirect_target(target)
- return
+ # Mark target as resolved:
if refname is not None:
del target['refname']
target.resolved = True
@@ -1003,9 +1011,9 @@
elif target['ids']:
naming = target['ids'][0]
else:
- # Hack: Propagated targets always have their refid
- # attribute set.
- naming = target['refid']
+ # Propagated target: "ids" and "names" attributes moved
+ # to the node indicated by "refid" or "refname".
+ naming = target.get('refid') or target.get('refname', '???')
self.document.reporter.info(
f'Hyperlink target "{naming}" is not referenced.',
base_node=target)
Modified: trunk/docutils/test/data/help/docutils.rst
===================================================================
--- trunk/docutils/test/data/help/docutils.rst 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/test/data/help/docutils.rst 2026-07-14 13:32:05 UTC (rev 10382)
@@ -90,7 +90,8 @@
Maximal number of characters in an input line.
(default 10 000)
--legacy-ids Keep IDs backwards compatible. (default)
---lazy-ids Generate IDs for implicit targets only if required.
+--lazy-ids Generate IDs for implicit targets only if required; no
+ IDs for external and indirect targets.
--validate Validate the document tree after parsing.
--no-validation Do not validate the document tree. (default)
Modified: trunk/docutils/test/data/help/rst2html.rst
===================================================================
--- trunk/docutils/test/data/help/rst2html.rst 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/test/data/help/rst2html.rst 2026-07-14 13:32:05 UTC (rev 10382)
@@ -91,7 +91,8 @@
Maximal number of characters in an input line.
(default 10 000)
--legacy-ids Keep IDs backwards compatible. (default)
---lazy-ids Generate IDs for implicit targets only if required.
+--lazy-ids Generate IDs for implicit targets only if required; no
+ IDs for external and indirect targets.
--validate Validate the document tree after parsing.
--no-validation Do not validate the document tree. (default)
Modified: trunk/docutils/test/data/help/rst2latex.rst
===================================================================
--- trunk/docutils/test/data/help/rst2latex.rst 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/test/data/help/rst2latex.rst 2026-07-14 13:32:05 UTC (rev 10382)
@@ -91,7 +91,8 @@
Maximal number of characters in an input line.
(default 10 000)
--legacy-ids Keep IDs backwards compatible. (default)
---lazy-ids Generate IDs for implicit targets only if required.
+--lazy-ids Generate IDs for implicit targets only if required; no
+ IDs for external and indirect targets.
--validate Validate the document tree after parsing.
--no-validation Do not validate the document tree. (default)
Modified: trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2026-07-14 13:32:05 UTC (rev 10382)
@@ -497,8 +497,8 @@
<reference refid="subtitle">
subtitle
.
- <target anonymous="1" ids="target-1" refuri="http://www.python.org/">
- <target anonymous="1" ids="target-2" refuri="https://docutils.sourceforge.io/">
+ <target anonymous="1" refuri="http://www.python.org/">
+ <target anonymous="1" refuri="https://docutils.sourceforge.io/">
<paragraph>
The default role for interpreted text is
<title_reference>
@@ -1054,7 +1054,7 @@
<reference anonymous="1" refid="label">
hyperlink reference
.
- <target anonymous="1" ids="target-3" refid="label">
+ <target anonymous="1" refid="label">
<footnote auto="1" backrefs="footnote-reference-2" ids="footnote-2" names="3">
<label>
3
@@ -1142,7 +1142,7 @@
<footnote_reference auto="1" ids="footnote-reference-11" refid="footnote-6">
5
".
- <target ids="python" names="python" refuri="http://www.python.org/">
+ <target names="python" refuri="http://www.python.org/">
<paragraph>
Targets may be indirect and anonymous. Thus
<reference anonymous="1" refid="another-target">
@@ -1152,7 +1152,7 @@
<reference refid="another-target">
Targets
section.
- <target anonymous="1" ids="target-4" refid="another-target">
+ <target anonymous="1" refid="another-target">
<paragraph>
Here's a
<problematic ids="problematic-2" refid="system-message-4">
@@ -1265,7 +1265,7 @@
<footnote_reference auto="1" ids="footnote-reference-16" refid="footnote-9">
8
.
- <target anonymous="1" ids="target-5" refuri="https://docutils.sourceforge.io/docs/ref/rst/directives.html">
+ <target anonymous="1" refuri="https://docutils.sourceforge.io/docs/ref/rst/directives.html">
<section ids="document-parts" names="document\ parts">
<title auto="1" refid="toc-entry-43">
<generated classes="sectnum">
@@ -1627,7 +1627,7 @@
And, by the way...
<paragraph>
You can make up your own admonition too.
- <target ids="docutils" names="docutils" refuri="https://docutils.sourceforge.io/">
+ <target names="docutils" refuri="https://docutils.sourceforge.io/">
<section ids="topics-sidebars-and-rubrics" names="topics,\ sidebars,\ and\ rubrics">
<title auto="1" refid="toc-entry-47">
<generated classes="sectnum">
@@ -2004,7 +2004,7 @@
<inline classes="ln">
2
.. footer:: Document footer
- <target ids="pygments" names="pygments" refuri="http://pygments.org/">
+ <target names="pygments" refuri="http://pygments.org/">
<section ids="meta" names="meta">
<title auto="1" refid="toc-entry-53">
<generated classes="sectnum">
@@ -2019,7 +2019,7 @@
9
is used to specify metadata to be stored in,
e.g., HTML META tags or ODT file properties.
- <target anonymous="1" ids="target-6" refuri="https://docutils.sourceforge.io/docs/ref/rst/directives.html#metadata">
+ <target anonymous="1" refuri="https://docutils.sourceforge.io/docs/ref/rst/directives.html#metadata">
<section ids="substitution-definitions" names="substitution\ definitions">
<title auto="1" refid="toc-entry-34">
<generated classes="sectnum">
Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2026-07-14 13:32:05 UTC (rev 10382)
@@ -44,7 +44,7 @@
settings = get_default_settings(Parser)
settings.warning_stream = ''
settings.halt_level = 5
- settings.legacy_ids = False
+ settings.legacy_ids = False # except for pycmark (see below)
for name, cases in totest.items():
if name == 'with transforms':
continue # see test_publish() below
@@ -55,7 +55,10 @@
self.skipTest('no markdown parser available')
if name == 'include_parsed_code' and not with_pygments:
self.skipTest('syntax highlight requires pygments')
- document = new_document('test data', settings.copy())
+ mysettings = settings.copy()
+ if name == 'include_markdown':
+ mysettings.legacy_ids = True # keep pycmark happy
+ document = new_document('test data', mysettings)
parser.parse(case_input, document)
output = document.pformat()
self.assertEqual(case_expected, output)
@@ -1567,7 +1570,7 @@
<document source="test data">
<paragraph>
Include Markdown source.
- <section depth="1">
+ <section depth="1" ids="section-1">
<title>
Title 1
<paragraph>
Modified: trunk/docutils/test/test_parsers/test_rst/test_targets.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-07-14 13:32:05 UTC (rev 10382)
@@ -86,11 +86,11 @@
<document source="test data">
<paragraph>
External hyperlink targets:
- <target ids="one-liner" names="one-liner" refuri="http://structuredtext.sourceforge.net">
- <target ids="starts-on-this-line" names="starts-on-this-line" refuri="http://structuredtext.sourceforge.net">
- <target ids="entirely-below" names="entirely-below" refuri="http://structuredtext.sourceforge.net">
- <target ids="escaped-whitespace" names="escaped-whitespace" refuri="http://example.org/a path with spaces.html">
- <target ids="not-indirect" names="not-indirect" refuri="uri_">
+ <target names="one-liner" refuri="http://structuredtext.sourceforge.net">
+ <target names="starts-on-this-line" refuri="http://structuredtext.sourceforge.net">
+ <target names="entirely-below" refuri="http://structuredtext.sourceforge.net">
+ <target names="escaped-whitespace" refuri="http://example.org/a path with spaces.html">
+ <target names="not-indirect" refuri="uri_">
"""],
["""\
Indirect hyperlink targets:
@@ -103,8 +103,8 @@
<document source="test data">
<paragraph>
Indirect hyperlink targets:
- <target ids="target1" names="target1" refname="reference">
- <target ids="target2" names="target2" refname="phrase-link reference">
+ <target names="target1" refname="reference">
+ <target names="target2" refname="phrase-link reference">
"""],
["""\
.. _a long target name:
@@ -156,7 +156,7 @@
<document source="test data">
<paragraph>
External hyperlink:
- <target ids="target" names="target" refuri="http://www.python.org/">
+ <target names="target" refuri="http://www.python.org/">
"""],
["""\
.. _email: jd...@ex...
@@ -166,8 +166,8 @@
""",
"""\
<document source="test data">
- <target ids="email" names="email" refuri="mailto:jd...@ex...">
- <target ids="multi-line-email" names="multi-line\\ email" refuri="mailto:jd...@ex...">
+ <target names="email" refuri="mailto:jd...@ex...">
+ <target names="multi-line\\ email" refuri="mailto:jd...@ex...">
"""],
["""\
Malformed target:
@@ -189,7 +189,7 @@
malformed hyperlink target.
<paragraph>
Target beginning with an underscore:
- <target ids="target" names="_target" refuri="OK">
+ <target names="_target" refuri="OK">
"""],
["""\
Duplicate external targets (different URIs):
@@ -202,11 +202,11 @@
<document source="test data">
<paragraph>
Duplicate external targets (different URIs):
- <target dupnames="target" ids="target" refuri="first">
+ <target dupnames="target" refuri="first">
<system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "target".
- <target dupnames="target" ids="target-1" refuri="second">
+ <target dupnames="target" refuri="second">
"""],
["""\
Duplicate external targets (same URIs):
@@ -219,11 +219,11 @@
<document source="test data">
<paragraph>
Duplicate external targets (same URIs):
- <target ids="target" names="target" refuri="first">
+ <target names="target" refuri="first">
<system_message level="1" line="5" source="test data" type="INFO">
<paragraph>
Duplicate name "target" for external target "first".
- <target dupnames="target" ids="target-1" refuri="first">
+ <target dupnames="target" refuri="first">
"""],
["""\
Duplicate external targets (embedded/explicit, same URIs):
@@ -250,7 +250,7 @@
<system_message level="1" line="7" source="test data" type="INFO">
<paragraph>
Duplicate name "example" for external target "example.rst".
- <target dupnames="example" ids="example-1" refuri="example.rst">
+ <target dupnames="example" refuri="example.rst">
"""],
["""\
Duplicate indirect _`targets` (same refname):
@@ -268,11 +268,11 @@
<target ids="targets" names="targets">
targets
(same refname):
- <target ids="link" names="link" refname="targets">
+ <target names="link" refname="targets">
<system_message level="1" line="5" source="test data" type="INFO">
<paragraph>
Duplicate name "link" for external target "targets".
- <target dupnames="link" ids="link-1" refname="targets">
+ <target dupnames="link" refname="targets">
<paragraph>
do not conflict. The reference name can be used in a \n\
<reference refname="link">
@@ -477,15 +477,15 @@
<system_message level="2" line="16" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "target".
- <target dupnames="target" ids="target-3" refuri="Explicit_external_target">
+ <target dupnames="target" refuri="Explicit_external_target">
<line_block>
<line>
Do not insert <system_message> element for duplicate
<line>
- <target dupnames="target" ids="target-4">
+ <target dupnames="target" ids="target-3">
target
, if this results in an invalid doctree.
- <rubric dupnames="target" ids="target-5">
+ <rubric dupnames="target" ids="target-4">
directive with target
<field_list>
<field>
@@ -496,7 +496,7 @@
with
<field>
<field_name>
- <target dupnames="target" ids="target-6">
+ <target dupnames="target" ids="target-5">
target
<field_body>
<paragraph>
@@ -523,8 +523,8 @@
<system_message level="2" line="3" source="test data" type="WARNING">
<paragraph>
malformed hyperlink target.
- <target ids="escaped-colon" names="escaped\\ colon:" refuri="OK">
- <target ids="unescaped-colon-quoted" names="unescaped\\ colon,\\ quoted:" refuri="OK">
+ <target names="escaped\\ colon:" refuri="OK">
+ <target names="unescaped\\ colon,\\ quoted:" refuri="OK">
"""],
])
@@ -768,7 +768,7 @@
<document source="test data">
<paragraph>
Anonymous external hyperlink target:
- <target anonymous="1" ids="target-1" refuri="http://w3c.org/">
+ <target anonymous="1" refuri="http://w3c.org/">
"""],
["""\
Anonymous external hyperlink target:
@@ -779,7 +779,7 @@
<document source="test data">
<paragraph>
Anonymous external hyperlink target:
- <target anonymous="1" ids="target-1" refuri="http://w3c.org/">
+ <target anonymous="1" refuri="http://w3c.org/">
"""],
["""\
Anonymous indirect hyperlink target:
@@ -790,7 +790,7 @@
<document source="test data">
<paragraph>
Anonymous indirect hyperlink target:
- <target anonymous="1" ids="target-1" refname="reference">
+ <target anonymous="1" refname="reference">
"""],
["""\
Anonymous external hyperlink target, not indirect:
@@ -803,8 +803,8 @@
<document source="test data">
<paragraph>
Anonymous external hyperlink target, not indirect:
- <target anonymous="1" ids="target-1" refuri="uri_">
- <target anonymous="1" ids="target-2" refuri="thisURIendswithanunderscore_">
+ <target anonymous="1" refuri="uri_">
+ <target anonymous="1" refuri="thisURIendswithanunderscore_">
"""],
["""\
Anonymous indirect hyperlink targets:
@@ -817,8 +817,8 @@
<document source="test data">
<paragraph>
Anonymous indirect hyperlink targets:
- <target anonymous="1" ids="target-1" refname="reference">
- <target anonymous="1" ids="target-2" refname="a very long reference">
+ <target anonymous="1" refname="reference">
+ <target anonymous="1" refname="a very long reference">
"""],
["""\
Mixed anonymous & named indirect hyperlink targets:
@@ -839,19 +839,19 @@
<document source="test data">
<paragraph>
Mixed anonymous & named indirect hyperlink targets:
- <target anonymous="1" ids="target-1" refname="reference">
- <target anonymous="1" ids="target-2" refname="reference">
- <target anonymous="1" ids="target-3" refname="reference">
- <target ids="target1" names="target1" refname="reference">
+ <target anonymous="1" refname="reference">
+ <target anonymous="1" refname="reference">
+ <target anonymous="1" refname="reference">
+ <target names="target1" refname="reference">
<system_message level="2" line="7" source="test data" type="WARNING">
<paragraph>
Explicit markup ends without a blank line; unexpected unindent.
<paragraph>
no blank line
- <target ids="target2" names="target2" refname="reference">
- <target anonymous="1" ids="target-4" refname="reference">
- <target anonymous="1" ids="target-5" refname="reference">
- <target anonymous="1" ids="target-6" refname="reference">
+ <target names="target2" refname="reference">
+ <target anonymous="1" refname="reference">
+ <target anonymous="1" refname="reference">
+ <target anonymous="1" refname="reference">
<system_message level="2" line="13" source="test data" type="WARNING">
<paragraph>
Explicit markup ends without a blank line; unexpected unindent.
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-14 13:31:29 UTC (rev 10381)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-14 13:32:05 UTC (rev 10382)
@@ -594,7 +594,8 @@
"""],
])
-totest['explicit hyperlinks legacy'] = ({'legacy_ids': True}, [
+# explicit internal hyperlinks are not affected by "legacy_ids"
+totest['explicit internal hyperlinks (legacy_ids)'] = ({'legacy_ids': True}, [
["""\
.. _internal hyperlink:
@@ -643,24 +644,6 @@
The results of the transform are not visible at the XML level.
"""],
["""\
-.. _chained:
-__ http://anonymous
-
-Anonymous__ and chained_ both refer to the same URI.
-""",
-"""\
-<document source="test data">
- <target refid="chained">
- <target anonymous="1" ids="target-1 chained" names="chained" refuri="http://anonymous">
- <paragraph>
- <reference anonymous="1" refuri="http://anonymous">
- Anonymous
- and \n\
- <reference refuri="http://anonymous">
- chained
- both refer to the same URI.
-"""],
-["""\
.. _a:
.. _b:
@@ -730,125 +713,209 @@
b
"""],
["""\
-.. _external hyperlink: http://uri
+Unknown reference_.
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Unknown \n\
+ <problematic ids="problematic-1" refid="system-message-1">
+ reference_
+ .
+ <system_message backrefs="problematic-1" ids="system-message-1" level="3" line="1" source="test data" type="ERROR">
+ <paragraph>
+ Unknown target name: "reference".
+"""],
+["""\
+Duplicate manual footnote labels, with reference ([1]_):
-`External hyperlink`_ reference.
+.. [1] Footnote.
+
+.. [1] Footnote.
""",
"""\
<document source="test data">
- <target ids="external-hyperlink" names="external\\ hyperlink" refuri="http://uri">
<paragraph>
- <reference refuri="http://uri">
- External hyperlink
- reference.
+ Duplicate manual footnote labels, with reference (
+ <problematic ids="footnote-reference-1" refid="system-message-1">
+ [1]_
+ ):
+ <footnote dupnames="1" ids="footnote-1">
+ <label>
+ 1
+ <paragraph>
+ Footnote.
+ <footnote dupnames="1" ids="footnote-2">
+ <label>
+ 1
+ <system_message backrefs="footnote-2" level="2" line="5" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "1".
+ <paragraph>
+ Footnote.
+ <system_message backrefs="footnote-reference-1" ids="system-message-1" level="3" line="1" source="test data" type="ERROR">
+ <paragraph>
+ Duplicate target name, cannot be used as a unique reference: "1".
"""],
+])
+
+totest['explicit internal hyperlinks (lazy_ids)'] = ({'legacy_ids': False},
+ # all samples compile as before
+ totest['explicit internal hyperlinks (legacy_ids)'][1])
+
+# implicit, indirect, and external hyperlinks get IDs with "legacy_ids"
+totest['various hyperlinks (legacy_ids)'] = ({'legacy_ids': True}, [
["""\
-.. _external hyperlink: http://uri
-.. _indirect target: `external hyperlink`_
+.. contents:: Table of Contents
+.. _indirect reference to the table of contents: `table of contents`_
+
+Section
+=======
+
+Testing an `indirect reference to the table of contents`_.
""",
"""\
<document source="test data">
- <target ids="external-hyperlink" names="external\\ hyperlink" refuri="http://uri">
- <target ids="indirect-target" names="indirect\\ target" refuri="http://uri">
- <system_message level="1" line="2" source="test data" type="INFO">
+ <topic classes="contents" ids="table-of-contents" names="table\\ of\\ contents">
+ <title>
+ Table of Contents
+ <bullet_list>
+ <list_item>
+ <paragraph>
+ <reference ids="toc-entry-1" refid="section">
+ Section
+ <target ids="indirect-reference-to-the-table-of-contents" names="indirect\\ reference\\ to\\ the\\ table\\ of\\ contents" refid="table-of-contents">
+ <section ids="section" names="section">
+ <title refid="toc-entry-1">
+ Section
<paragraph>
- Hyperlink target "indirect target" is not referenced.
+ Testing an \n\
+ <reference refid="table-of-contents">
+ indirect reference to the table of contents
+ .
"""],
["""\
-.. _chained:
-.. _external hyperlink: http://uri
+.. _explicit target:
-`External hyperlink`_ reference
-and a chained_ reference too.
+Title
+-----
+
+Let's reference the `explicit target`_ to avoid an irrelevant error.
""",
"""\
<document source="test data">
- <target refid="chained">
- <target ids="external-hyperlink chained" names="external\\ hyperlink chained" refuri="http://uri">
- <paragraph>
- <reference refuri="http://uri">
- External hyperlink
- reference
- and a \n\
- <reference refuri="http://uri">
- chained
- reference too.
+ <target refid="explicit-target">
+ <section ids="title explicit-target" names="title explicit\\ target">
+ <title>
+ Title
+ <paragraph>
+ Let's reference the \n\
+ <reference refid="explicit-target">
+ explicit target
+ to avoid an irrelevant error.
"""],
["""\
-.. _external hyperlink: http://uri
-.. _indirect hyperlink: `external hyperlink`_
+target1_ should be an alias of target2_, not the Title.
-`Indirect hyperlink`_ reference.
+.. _target1:
+.. _target2: URI
+
+Title
+=====
""",
"""\
<document source="test data">
- <target ids="external-hyperlink" names="external\\ hyperlink" refuri="http://uri">
- <target ids="indirect-hyperlink" names="indirect\\ hyperlink" refuri="http://uri">
<paragraph>
- <reference refuri="http://uri">
- Indirect hyperlink
- reference.
+ <reference refuri="URI">
+ target1
+ should be an alias of \n\
+ <reference refuri="URI">
+ target2
+ , not the Title.
+ <target refid="target1">
+ <target ids="target2 target1" names="target2 target1" refuri="URI">
+ <section ids="title" names="title">
+ <title>
+ Title
"""],
["""\
-.. _external hyperlink: http://uri
-.. _chained:
-.. _indirect hyperlink: `external hyperlink`_
+foo
+---
-Chained_ `indirect hyperlink`_ reference.
+With legacy_ids = True, an explicit target _`foo` overrides a
+homonymous implicit target but gets a "diambiguated" identifier.
+
+The reference foo_ points to the explicit target.
+Referencing from an external document requires the
+non-obvious fragment identifier "#foo-1".
""",
"""\
<document source="test data">
- <target ids="external-hyperlink" names="external\\ hyperlink" refuri="http://uri">
- <target refuri="http://uri">
- <target ids="indirect-hyperlink chained" names="indirect\\ hyperlink chained" refuri="http://uri">
- <paragraph>
- <reference refuri="http://uri">
- Chained
- \n\
- <reference refuri="http://uri">
- indirect hyperlink
- reference.
+ <section dupnames="foo" ids="foo">
+ <title>
+ foo
+ <system_message backrefs="foo-1" level="1" line="5" source="test data" type="INFO">
+ <paragraph>
+ Target name overrides implicit target name "foo".
+ <paragraph>
+ With legacy_ids = True, an explicit target \n\
+ <target ids="foo-1" names="foo">
+ foo
+ overrides a
+ homonymous implicit target but gets a "diambiguated" identifier.
+ <paragraph>
+ The reference \n\
+ <reference refid="foo-1">
+ foo
+ points to the explicit target.
+ Referencing from an external document requires the
+ non-obvious fragment identifier "#foo-1".
"""],
["""\
-.. __: http://full
-__
-__ http://simplified
-.. _external: http://indirect.external
-__ external_
-__
+foo
+---
-`Full syntax anonymous external hyperlink reference`__,
-`chained anonymous external reference`__,
-`simplified syntax anonymous external hyperlink reference`__,
-`indirect anonymous hyperlink reference`__,
-`internal anonymous hyperlink reference`__.
+If an implicit target precedes a homonymous explicit target _`foo`,
+the explicit target takes over the reference name but not the identifier.
+
+The reference foo_ points to the explicit target. However, referencing from
+an external document requires the non-obvious fragment identifier "#foo-1".
""",
"""\
<document source="test data">
- <target anonymous="1" ids="target-1" refuri="http://full">
- <target anonymous="1" refid="target-2">
- <target anonymous="1" ids="target-3 target-2" refuri="http://simplified">
- <target ids="external" names="external" refuri="http://indirect.external">
- <target anonymous="1" ids="target-4" refuri="http://indirect.external">
- <target anonymous="1" refid="target-5">
- <paragraph ids="target-5">
- <reference anonymous="1" refuri="http://full">
- Full syntax anonymous external hyperlink reference
- ,
- <reference anonymous="1" refuri="http://simplified">
- chained anonymous external reference
- ,
- <reference anonymous="1" refuri="http://simplified">
- simplified syntax anonymous external hyperlink reference
- ,
- <reference anonymous="1" refuri="http://indirect.external">
- indirect anonymous hyperlink reference
- ,
- <reference anonymous="1" refid="target-5">
- internal anonymous hyperlink reference
- .
+ <section dupnames="foo" ids="foo">
+ <title>
+ foo
+ <system_message backrefs="foo-1" level="1" line="5" source="test data" type="INFO">
+ <paragraph>
+ Target name overrides implicit target name "foo".
+ <paragraph>
+ If an implicit target precedes a homonymous explicit target \n\
+ <target ids="foo-1" names="foo">
+ foo
+ ,
+ the explicit target takes over the reference name but not the identifier.
+ <paragraph>
+ The reference \n\
+ <reference refid="foo-1">
+ foo
+ points to the explicit target. However, referencing from
+ an external document requires the non-obvious fragment identifier "#foo-1".
"""],
["""\
+.. _external hyperlink: http://uri
+
+`External hyperlink`_ reference.
+""",
+"""\
+<document source="test data">
+ <target ids="external-hyperlink" names="external\\ hyperlink" refuri="http://uri">
+ <paragraph>
+ <reference refuri="http://uri">
+ External hyperlink
+ reference.
+"""],
+["""\
Duplicate external target_'s (different URIs):
.. _target: first
@@ -889,29 +956,73 @@
<target dupnames="target" ids="target-1" refuri="second">
"""],
["""\
-Several__ anonymous__ hyperlinks__, but not enough targets.
+.. _chained:
+.. _external hyperlink: http://uri
-__ http://example.org
+`External hyperlink`_ reference
+and a chained_ reference too.
""",
"""\
<document source="test data">
+ <target refid="chained">
+ <target ids="external-hyperlink chained" names="external\\ hyperlink chained" refuri="http://uri">
<paragraph>
- <problematic ids="problematic-1" refid="system-message-1">
- Several__
- \n\
- <problematic ids="problematic-2" refid="system-message-1">
- anonymous__
- \n\
- <problematic ids="problematic-3" refid="system-message-1">
- hyperlinks__
- , but not enough targets.
- <target anonymous="1" ids="target-1" refuri="http://example.org">
- <system_message backrefs="problematic-1 problematic-2 problematic-3" ids="system-message-1" level="3" source="test data" type="ERROR">
+ <reference refuri="http://uri">
+ External hyperlink
+ reference
+ and a \n\
+ <reference refuri="http://uri">
+ chained
+ reference too.
+"""],
+["""\
+.. _external hyperlink: http://uri
+.. _indirect target: `external hyperlink`_
+""",
+"""\
+<document source="test data">
+ <target ids="external-hyperlink" names="external\\ hyperlink" refuri="http://uri">
+ <target ids="indirect-target" names="indirect\\ target" refuri="http://uri">
+ <system_message level="1" line="2" source="test data" type="INFO">
<paragraph>
- Anonymous hyperlink mismatch: 3 references but 1 targets.
- See "backrefs" attribute for IDs.
+ Hyperlink target "indirect target" is not referenced.
"""],
["""\
+.. _external hyperlink: http://uri
+.. _indirect hyperlink: `external hyperlink`_
+
+`Indirect hyperlink`_ reference.
+""",
+"""\
+<document source="test data">
+ <target ids="external-hyperlink" names="external\\ hyperlink" refuri="http://uri">
+ <target ids="indirect-hyperlink" names="indirect\\ hyperlink" refuri="http://uri">
+ <paragraph>
+ <reference refuri="http://uri">
+ Indirect hyperlink
+ reference.
+"""],
+["""\
+.. _external hyperlink: http://uri
+.. _chained:
+.. _indirect hyperlink: `external hyperlink`_
+
+Chained_ `indirect hyperlink`_ reference.
+""",
+"""\
+<document source="test data">
+ <target ids="external-hyperlink" names="external\\ hyperlink" refuri="http://uri">
+ <target refuri="http://uri">
+ <target ids="indirect-hyperlink chained" names="indirect\\ hyperlink chained" refuri="http://uri">
+ <paragraph>
+ <reference refuri="http://uri">
+ Chained
+ \n\
+ <reference refuri="http://uri">
+ indirect hyperlink
+ reference.
+"""],
+["""\
.. _external: http://uri
.. _indirect: external_
.. _internal:
@@ -1036,57 +1147,89 @@
to an image with target (sic!).
"""],
["""\
-Unknown reference_.
+.. __: http://full
+__
+__ http://simplified
+.. _external: http://indirect.external
+__ external_
+__
+
+`Full syntax anonymous external hyperlink reference`__,
+`chained anonymous external reference`__,
+`simplified syntax anonymous external hyperlink reference`__,
+`indirect anonymous hyperlink reference`__,
+`internal anonymous hyperlink reference`__.
""",
"""\
<document source="test data">
- <paragraph>
- Unknown \n\
- <problematic ids="problematic-1" refid="system-message-1">
- reference_
+ <target anonymous="1" ids="target-1" refuri="http://full">
+ <target anonymous="1" refid="target-2">
+ <target anonymous="1" ids="target-3 target-2" refuri="http://simplified">
+ <target ids="external" names="external" refuri="http://indirect.external">
+ <target anonymous="1" ids="target-4" refuri="http://indirect.external">
+ <target anonymous="1" refid="target-5">
+ <paragraph ids="target-5">
+ <reference anonymous="1" refuri="http://full">
+ Full syntax anonymous external hyperlink reference
+ ,
+ <reference anonymous="1" refuri="http://simplified">
+ chained anonymous external reference
+ ,
+ <reference anonymous="1" refuri="http://simplified">
+ simplified syntax anonymous external hyperlink reference
+ ,
+ <reference anonymous="1" refuri="http://indirect.external">
+ indirect anonymous hyperlink reference
+ ,
+ <reference anonymous="1" refid="target-5">
+ internal anonymous hyperlink reference
.
- <system_message backrefs="problematic-1" ids="system-message-1" level="3" line="1" source="test data" type="ERROR">
- <paragraph>
- Unknown target name: "reference".
"""],
["""\
-Duplicate manual footnote labels, with reference ([1]_):
+.. _chained:
+__ http://anonymous
-.. [1] Footnote.
+Anonymous__ and chained_ both refer to the same URI.
+""",
+"""\
+<document source="test data">
+ <target refid="chained">
+ <target anonymous="1" ids="target-1 chained" names="chained" refuri="http://anonymous">
+ <paragraph>
+ <reference anonymous="1" refuri="http://anonymous">
+ Anonymous
+ and \n\
+ <reference refuri="http://anonymous">
+ chained
+ both refer to the same URI.
+"""],
+["""\
+Several__ anonymous__ hyperlinks__, but not enough targets.
-.. [1] Footnote.
+__ http://example.org
""",
"""\
<document source="test data">
<paragraph>
- Duplicate manual footnote labels, with reference (
- <problematic ids="footnote-reference-1" refid="system-message-1">
- [1]_
- ):
- <footnote dupnames="1" ids="footnote-1">
- <label>
- 1
+ <problematic ids="problematic-1" refid="system-message-1">
+ Several__
+ \n\
+ <problematic ids="problematic-2" refid="system-message-1">
+ anonymous__
+ \n\
+ <problematic ids="problematic-3" refid="system-message-1">
+ hyperlinks__
+ , but not enough targets.
+ <target anonymous="1" ids="target-1" refuri="http://example.org">
+ <system_message backrefs="problematic-1 problematic-2 problematic-3" ids="system-message-1" level="3" source="test data" type="ERROR">
<paragraph>
- Footnote.
- <footnote dupnames="1" ids="footnote-2">
- <label>
- 1
- <system_message backrefs="footnote-2" level="2" line="5" source="test data" type="WARNING">
- <paragraph>
- Duplicate explicit target name: "1".
- <paragraph>
- Footnote.
- <system_message backrefs="footnote-reference-1" ids="system-message-1" level="3" line="1" source="test data" type="ERROR">
- <paragraph>
- Duplicate target name, cannot be used as a unique reference: "1".
+ Anonymous hyperlink mismatch: 3 references but 1 targets.
+ See "backrefs" attribute for IDs.
"""],
])
-totest['explicit hyperlinks'] = ({'legacy_ids': False},
- # all samples compile as before
- totest['explicit hyperlinks legacy'][1])
-
-totest['implicit hyperlinks legacy'] = ({'legacy_ids': True}, [
+# implicit, indirect, and external hyperlinks get *no* IDs with "lazy_ids"
+totest['various hyperlinks (lazy_ids)'] = ({'legacy_ids': False}, [
["""\
.. contents:: Table of Contents
.. _indirect reference to the table of contents: `table of contents`_
@@ -1106,7 +1249,7 @@
<paragraph>
<reference ids="toc-entry-1" refid="section">
Section
- <target ids="indirect-reference-to-the-table-of-contents" names="indirect\\ reference\\ to\\ the\\ table\\ of\\ contents" refid="table-of-contents">
+ <target names="indirect\\ reference\\ to\\ the\\ table\\ of\\ contents" refid="table-of-contents">
<section ids="section" names="section">
<title refid="toc-entry-1">
Section
@@ -1122,22 +1265,25 @@
Title
-----
-Let's reference it (`explicit target`_) to avoid an irrelevant error.
+References to the section (title_) use the ID from the `explicit target`_.
""",
"""\
<document source="test data">
<target refid="explicit-target">
- <section ids="title explicit-target" names="title explicit\\ target">
+ <section ids="explicit-target" names="title explicit\\ target">
<title>
Title
<paragraph>
- Let's reference it (
+ References to the section (
<reference refid="explicit-target">
+ title
+ ) use the ID from the \n\
+ <reference refid="explicit-target">
explicit target
- ) to avoid an irrelevant error.
+ .
"""],
["""\
-target1_ should refer to target2_, not the Title.
+target1_ should be an alias of target2_, not the Title.
.. _target1:
.. _target2: URI
@@ -1150,185 +1296,274 @@
<paragraph>
<reference refuri="URI">
target1
- should refer to \n\
+ should be an alias of \n\
<reference refuri="URI">
target2
, not the Title.
<target refid="target1">
- <target ids="target2 target1" names="target2 target1" refuri="URI">
- <section ids="title" names="title">
+ <target ids="target1" names="target2 target1" refuri="URI">
+ <section names="title">
<title>
Title
"""],
["""\
-An explicit target _`foo` overrides a homonymous implicit target.
-
foo
---
+With legacy_ids = False, an explicit target _`foo` takes over the
+reference name and identifier of a homonymous implicit target.
+
The reference foo_ points to the explicit target.
+Referencing from an external document can be done
+using the matching fragment identifier "#foo".
""",
"""\
<document source="test data">
- <paragraph>
- An explicit target \n\
- <target ids="foo" names="foo">
- foo
- overrides a homonymous implicit target.
- <section dupnames="foo" ids="foo-1">
+ <section dupnames="foo">
<title>
foo
- <system_message backrefs="foo-1" level="1" line="4" source="test data" type="INFO">
+ <system_message backrefs="foo" level="1" line="5" source="test data" type="INFO">
<paragraph>
- Duplicate implicit target name: "foo".
+ Target name overrides implicit target name "foo".
<paragraph>
+ With legacy_ids = False, an explicit target \n\
+ <target ids="foo" names="foo">
+ foo
+ takes over the
+ reference name and identifier of a homonymous implicit target.
+ <paragraph>
The reference \n\
<reference refid="foo">
foo
points to the explicit target.
+ Referencing from an external document can be done
+ using the matching fragment identifier "#foo".
"""],
["""\
-foo
----
+.. _external hyperlink: http://uri
-If an implicit target precedes a homonymous explicit target _`foo`,
-the explicit target takes over the reference name but not the identifier.
+`External hyperlink`_ reference.
+""",
+"""\
+<document source="test data">
+ <target names="external\\ hyperlink" refuri="http://uri">
+ <paragraph>
+ <reference refuri="http://uri">
+ External hyperlink
+ reference.
+"""],
+["""\
+Duplicate external target_'s (different URIs):
-The reference foo_ points to the explicit target. However, referencing from
-an external document requires the non-obvious fragment identifier "#foo-1".
+.. _target: first
+
+.. _target: second
""",
"""\
<document source="test data">
- <section dupnames="foo" ids="foo">
- <title>
- foo
- <system_message backrefs="foo-1" level="1" line="5" source="test data" type="INFO">
- <paragraph>
- Target name overrides implicit target name "foo".
+ <paragraph>
+ Duplicate external \n\
+ <problematic ids="problematic-1" refid="system-message-1">
+ target_
+ 's (different URIs):
+ <target dupnames="target" refuri="first">
+ <system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
- If an implicit target precedes a homonymous explicit target \n\
- <target ids="foo-1" names="foo">
- foo
- ,
- the explicit target takes over the reference name but not the identifier.
+ Duplicate explicit target name: "target".
+ <target dupnames="target" refuri="second">
+ <system_message backrefs="problematic-1" ids="system-message-1" level="3" line="1" source="test data" type="ERROR">
<paragraph>
- The reference \n\
- <reference refid="foo-1">
- foo
- points to the explicit target. However, referencing from
- an external document requires the non-obvious fragment identifier "#foo-1".
+ Duplicate target name, cannot be used as a unique reference: "target".
"""],
-])
-
-totest['implicit hyperlinks'] = ({'legacy_ids': False}, [
["""\
-.. contents:: Table of Contents
-.. _indirect reference to the table of contents: `table of contents`_
+Duplicate external targets (different URIs) without reference:
-Section
-=======
+.. _target: first
-Testing an `indirect reference to the table of contents`_.
+.. _target: second
""",
"""\
<document source="test data">
- <topic classes="contents" ids="table-of-contents" names="table\\ of\\ contents">
- <title>
- Table of Contents
- <bullet_list>
- <list_item>
- <paragraph>
- <reference ids="toc-entry-1" refid="section">
- Section
- <target ids="indirect-reference-to-the-table-of-contents" names="indirect\\ reference\\ to\\ the\\ table\\ of\\ contents" refid="table-of-contents">
- <section ids="section" names="section">
- <title refid="toc-entry-1">
- Section
+ <paragraph>
+ Duplicate external targets (different URIs) without reference:
+ <target dupnames="target" refuri="first">
+ <system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
- Testing an \n\
- <reference refid="table-of-contents">
- indirect reference to the table of contents
- .
+ Duplicate explicit target name: "target".
+ <target dupnames="target" refuri="second">
"""],
["""\
-.. _explicit target:
+.. _chained:
+.. _external hyperlink: http://uri
-Title
------
-
-References to the section (title_) use the ID from the `explicit target`_.
+`External hyperlink`_ reference
+and a chained_ reference too.
""",
"""\
<document source="test data">
- <target refid="explicit-target">
- <section ids="explicit-target" names="title explicit\\ target">
- <title>
- Title
+ <target refid="chained">
+ <target ids="chained" names="external\\ hyperlink chained" refuri="http://uri">
+ <paragraph>
+ <reference refuri="http://uri">
+ External hyperlink
+ reference
+ and a \n\
+ <reference refuri="http://uri">
+ chained
+ reference too.
+"""],
+["""\
+.. _external hyperlink: http://uri
+.. _indirect target: `external hyperlink`_
+""",
+"""\
+<document source="test data">
+ <target names="external\\ hyperlink" refuri="http://uri">
+ <target names="indirect\\ target" refuri="http://uri">
+ <system_message level="1" line="2" source="test data" type="INFO">
<paragraph>
- References to the section (
- <reference refid="explicit-target">
- title
- ) use the ID from the \n\
- <reference refid="explicit-target">
- explicit target
- .
+ Hyperlink target "indirect target" is not referenced.
"""],
["""\
-target1_ should refer to target2_, not the Title.
+.. _external hyperlink: http://uri
+.. _indirect hyperlink: `external hyperlink`_
-.. _target1:
-.. _target2: URI
+`Indirect hyperlink`_ reference.
+""",
+"""\
+<document source="test data">
+ <target names="external\\ hyperlink" refuri="http://uri">
+ <target names="indirect\\ hyperlink" refuri="http://uri">
+ <paragraph>
+ <reference refuri="http://uri">
+ Indirect hyperlink
+ reference.
+"""],
+["""\
+.. _external hyperlink: http://uri
+.. _chained:
+.. _indirect hyperlink: `external hyperlink`_
-Title
-=====
+Chained_ `indirect hyperlink`_ reference.
""",
"""\
<document source="test data">
+ <target names="external\\ hyperlink" refuri="http://uri">
+ <target refuri="http://uri">
+ <target ids="chained" names="indirect\\ hyperlink chained" refuri="http://uri">
<paragraph>
- <reference refuri="URI">
- target1
- should refer to \n\
- <reference refuri="URI">
- target2
- , not the Title.
- <target refid="target1">
- <target ids="target2 target1" names="target2 target1" refuri="URI">
- <section names="title">
- <title>
- Title
+ <reference refuri="http://uri">
+ Chained
+ \n\
+ <reference refuri="http://uri">
+ indirect hyperlink
+ reference.
"""],
["""\
-foo
----
+.. _external: http://uri
+.. _indirect: external_
+.. _internal:
-With legacy_ids = False, an explicit target _`foo` takes over the
-reference name and identifier of a homonymous implicit target.
+.. image:: picture.png
+ :target: external_
-The reference foo_ points to the explicit target.
-Referencing from an external document can be done
-using the matching fragment identifier "#foo".
+.. image:: picture.png
+ :target: indirect_
+
+.. image:: picture.png
+ :target: internal_
""",
"""\
<document source="test data">
- <section dupnames="foo">
- <title>
- foo
- <system_message backrefs="foo" level="1" line="5" source="test data" type="INFO">
- <paragraph>
- Target name overrides implicit target name "foo".
+ <target names="external" refuri="http://uri">
+ <target names="indirect" refuri="http://uri">
+ <target refid="internal">
+ <reference ids="internal" names="internal" refuri="http://uri">
+ <image uri="picture.png">
+ <reference refuri="http://uri">
+ <image uri="picture.png">
+ <reference refid="internal">
+ <image uri="picture.png">
+"""],
+["""\
+.. __: http://full
+__
+__ http://simplified
+.. _external: http://indirect.external
+__ external_
+__
+
+`Full syntax anonymous external hyperlink reference`__,
+`chained anonymous external reference`__,
+`simplified syntax anonymous external hyperlink reference`__,
+`indirect anonymous hyperlink reference`__,
+`internal anonymous hyperlink reference`__.
+""",
+"""\
+<document source="test data">
+ <target anonymous="1" refuri="http://full">
+ <target anonymous="1" refid="target-1">
+ <target anonymous="1" ids="target-1" refuri="http://simplified">
+ <target names="external" refuri="http://indirect.external">
+ <target anonymous="1" refuri="http://indirect.external">
+ <target anonymous="1" refid="target-2">
+ <paragraph ids="target-...
[truncated message content] |
|
From: <mi...@us...> - 2026-07-14 13:31:54
|
Revision: 10381
http://sourceforge.net/p/docutils/code/10381
Author: milde
Date: 2026-07-14 13:31:29 +0000 (Tue, 14 Jul 2026)
Log Message:
-----------
"lazy IDs": Generate "implicit" section IDs only if required.
Do not load/run the `SectionIDs` transform.
Keep it so that components/applications that want IDs on all sections
can easily add it to their `get_transforms_spec()` method.
+ Links from the ToC and "self-links" use the same ID
("explicit" ID, if available).
+ Less "noise" in the output document.
Full backwards compatibility can be achieved with setting "legacy_ids".
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/api/transforms.rst
trunk/docutils/docs/user/config.rst
trunk/docutils/docutils/parsers/__init__.py
trunk/docutils/docutils/readers/standalone.py
trunk/docutils/docutils/transforms/parts.py
trunk/docutils/docutils/transforms/references.py
trunk/docutils/docutils/writers/html5_polyglot/__init__.py
trunk/docutils/test/data/help/docutils.rst
trunk/docutils/test/data/help/rst2html.rst
trunk/docutils/test/data/help/rst2latex.rst
trunk/docutils/test/functional/expected/length_units_html5.html
trunk/docutils/test/functional/expected/misc_rst_html5.html
trunk/docutils/test/functional/expected/standalone_rst_html5.html
trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt
trunk/docutils/test/functional/expected/standalone_rst_xetex.tex
trunk/docutils/test/functional/tests/length_units_html5.py
trunk/docutils/test/test_transforms/test_contents.py
trunk/docutils/test/test_transforms/test_hyperlinks.py
trunk/docutils/test/test_transforms/test_sectnum.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/HISTORY.rst 2026-07-14 13:31:29 UTC (rev 10381)
@@ -51,6 +51,7 @@
* docutils/parsers/__init__.py
- Remove `recommonmark` from `PARSER_ALIASES`.
+ - Rename command line option ``--matching-ids`` to ``--lazy-ids``.
* docutils/parsers/commonmark_wrapper.py
@@ -87,11 +88,17 @@
- Update `Reader.get_transforms()` to load the three transforms
obsoleting `references.DanglingReferences` (see below).
+ - Do not load `transforms.references.SectionIDs`.
* docutils/transforms/__init__.py
- Remove `Transformer.unknown_reference_resolvers`.
+* docutils/transforms/parts.py:
+
+ - `Contents.build_contents()`: ensure sections have an ID and prefer
+ IDs from external targets with "lazy IDs" (`legacy_ids`_ False).
+
* docutils/transforms/references.py
- `IndirectHyperlinks.resolve_indirect_target()` no longer calls
@@ -100,6 +107,8 @@
and `ReportUnreferencedLinks` obsolete `DanglingReferences`.
- Add INFO system_message if a <target> cannot be propagated
to the next node.
+ - support "lazy IDs": Handle hyperlink targets without ID;
+ if required, generate and set one.
* docutils/transforms/universal.py
@@ -123,6 +132,7 @@
problems with other elements using "topic" as class value (e.g. a
docinfo item "topic" in Enhancement Reports).
- More robust handling of figure captions.
+ - Support "lazy IDs": ensure sections have an ID when adding a self-link.
* docutils/writers/latex2e/__init__.py
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-07-14 13:31:29 UTC (rev 10381)
@@ -220,6 +220,7 @@
- The legacy_column_widths_ setting now defaults to False.
- The initial_header_level_ setting default for the HTML5 writer
changed to "auto".
+ - Rename command line option ``--matching-ids`` to ``--lazy-ids``.
Command line interface:
- Option ``-o`` sets the `output file path <output_path_>`__
@@ -227,8 +228,14 @@
- Drop the ``<destination>`` positional argument.
Use ``-o <destination>`` or output redirection.
+standalone reader:
+ - Do not load the `SectionIDs` transform.
+
rST parser:
- Warn if a `"figure"`_ directive is missing both caption and legend.
+ - Generate identifiers for implicit targets (mainly sections) only if
+ there is a cross-link to the target [#cross-links]_ and no "explicit"
+ identifier (unless legacy_ids_ is True).
HTML5 writer:
- Use normal font size and colour for informal titles of type "rubric".
@@ -285,6 +292,9 @@
`writers.latex2e.SortableDict`
Not used and deprecated since Docutils 0.22.
+.. [#cross-links] This includes links from the table of contents_ and
+ "`section self-links <section_self_link_>`_" added by the HTML5
+ writer.
Release 0.23 (2026-05-27)
=========================
Modified: trunk/docutils/docs/api/transforms.rst
===================================================================
--- trunk/docutils/docs/api/transforms.rst 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/docs/api/transforms.rst 2026-07-14 13:31:29 UTC (rev 10381)
@@ -57,7 +57,7 @@
references_.Substitutions standalone_ (r), pep_ (r) _`220`
-references_.SectionIDs standalone_ (r), pep_ (r) _`240`
+references_.SectionIDs *not used* _`240`
references_.PropagateTargets standalone_ (r), pep_ (r) _`260`
Modified: trunk/docutils/docs/user/config.rst
===================================================================
--- trunk/docutils/docs/user/config.rst 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/docs/user/config.rst 2026-07-14 13:31:29 UTC (rev 10381)
@@ -798,16 +798,38 @@
Keep element identifiers_ compatible to Docutils ≤ 0.22.
-In case of a name conflict with an `implicit target`_ (section heading),
-identifiers_ may have a disambiguating number added to the normalized
-`reference name`_.
+If "legacy_ids" is False or with the command line option ``--lazy-ids``,
+the generation of identifiers_ from the `reference names`_ of
+`implicit targets`_ is done after parsing is complete and only
+if required by an internal cross-link [#cross-link]_.
+An existing identifier from an `explicit target`_ is re-used instead of
+generating an additional identifier for the "implicit" reference name.
-:Default: True; will change to False in Docutils 2.0.
-:Options: ``--legacy-ids``, ``--matching-ids``.
+* Less "noise" in generated output documents.
+* Less cluttered identifier namespace: `explicit targets`_ have a better
+ chance to get an identifier_ matching their `reference name`_. [#]_
-New in Docutils 0.23. Provisional.
+.. caution:: Changing this setting may alter IDs in the output document
+ and hence break incoming "deep" hyperlinks that use "implicit"
+ identifiers in their `URI fragment`_.
+:Default: True (will change to False in Docutils 2.0).
+:Options: ``--legacy-ids``,
+ ``--lazy-ids`` (name changed in Docutils 1.0).
+New in Docutils 0.23. Provisional.
+
+.. [#cross-link]
+ Internal cross-links include links from `hyperlink references`_,
+ the `table of contents`_, and "`self-links <section_self_link_>`_"
+ added by the HTML5 writer.
+.. [#]
+ Due to the `identifier normalization`_, different `reference names`_
+ may compete for the same identifier_, e.g. the reference names
+ ``"legacy ids"`` and ``"legacy-ids"`` would get the
+ identifiers ``"legacy-ids"`` and ``"legacy-ids-1"``.
+
+
raw_enabled
-----------
@@ -2634,6 +2656,8 @@
.. _"code": ../ref/rst/directives.html#code
.. _"csv-table": ../ref/rst/directives.html#csv-table
.. _"figure": ../ref/rst/directives.html#figure
+.. _identifier normalization:
+ ../ref/rst/directives.html#identifier-normalization
.. _images:
.. _"image": ../ref/rst/directives.html#image
.. _"include": ../ref/rst/directives.html#include
@@ -2662,12 +2686,15 @@
.. _citations: ../ref/rst/restructuredtext.html#citations
.. _document title: ../ref/rst/restructuredtext.html#document-title
.. _enumerated lists: ../ref/rst/restructuredtext.html#enumerated-lists
-.. _explicit target: ../ref/rst/restructuredtext.html#explicit-hyperlink-targets
+.. _explicit target:
+.. _explicit targets: ../ref/rst/restructuredtext.html#explicit-hyperlink-targets
+.. _explicit internal target: ../ref/rst/restructuredtext.html#internal-hyperlink-targets
.. _field lists: ../ref/rst/restructuredtext.html#field-lists
.. _field names: ../ref/rst/restructuredtext.html#field-names
.. _footnotes: ../ref/rst/restructuredtext.html#footnotes
.. _footnote references: ../ref/rst/restructuredtext.html#footnote-references
.. _hyperlink references: ../ref/rst/restructuredtext.html#hyperlink-references
+.. _implicit hyperlink targets:
.. _implicit target:
.. _implicit targets: ../ref/rst/restructuredtext.html#implicit-hyperlink-targets
.. _interpreted text role: ../ref/rst/restructuredtext.html#interpreted-text
@@ -2675,6 +2702,7 @@
../ref/rst/restructuredtext.html#inline-markup-recognition-rules
.. _literal blocks: ../ref/rst/restructuredtext.html#literal-blocks
.. _option lists: ../ref/rst/restructuredtext.html#option-lists
+.. _sections: ../ref/rst/restructuredtext.html#sections
.. _tables: ../ref/rst/restructuredtext.html#tables
.. _Docutils HTML writers: html.html
@@ -2701,3 +2729,5 @@
.. _standard encodings:
https://docs.python.org/3/library/codecs.html#standard-encodings
.. _inspecting_codecs: https://codeberg.org/milde/inspecting-codecs
+.. _URI fragment:
+ https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Fragment
Modified: trunk/docutils/docutils/parsers/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/__init__.py 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/docutils/parsers/__init__.py 2026-07-14 13:31:29 UTC (rev 10381)
@@ -47,12 +47,12 @@
['--line-length-limit'],
{'metavar': '<length>', 'type': 'int', 'default': 10_000,
'validator': frontend.validate_nonnegative_int}),
- ('Keep identifiers backwards compatible. (default)',
+ ('Keep IDs backwards compatible. (default)',
['--legacy-ids'],
{'action': 'store_true', 'default': True,
'validator': frontend.validate_boolean}),
- ('Explicit targets use identifiers matching the reference name.',
- ['--matching-ids'],
+ ('Generate IDs for implicit targets only if required.',
+ ['--lazy-ids'],
{'dest': 'legacy_ids', 'action': 'store_false'}),
('Validate the document tree after parsing.',
['--validate'],
Modified: trunk/docutils/docutils/readers/standalone.py
===================================================================
--- trunk/docutils/docutils/readers/standalone.py 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/docutils/readers/standalone.py 2026-07-14 13:31:29 UTC (rev 10381)
@@ -56,7 +56,6 @@
def get_transforms(self) -> list[type[Transform]]:
return super().get_transforms() + [
references.Substitutions,
- references.SectionIDs,
references.PropagateTargets,
frontmatter.DocTitle,
frontmatter.DocInfo,
Modified: trunk/docutils/docutils/transforms/parts.py
===================================================================
--- trunk/docutils/docutils/transforms/parts.py 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/docutils/transforms/parts.py 2026-07-14 13:31:29 UTC (rev 10381)
@@ -118,12 +118,16 @@
sections = [sect for sect in node if isinstance(sect, nodes.section)]
entries = []
depth = self.startnode.details.get('depth', sys.maxsize)
+ legacy_ids = getattr(self.document.settings, "legacy_ids", True)
for section in sections:
title = section[0]
auto = title.get('auto') # May be set by SectNum.
entrytext = self.copy_and_filter(title)
- reference = nodes.reference('', '', refid=section['ids'][0],
- *entrytext)
+ if legacy_ids: # get first (backwards compatible)
+ sect_id = section['ids'][0]
+ else: # ensure there is an ID, get last
+ sect_id = self.document.set_id(section)
+ reference = nodes.reference('', '', refid=sect_id, *entrytext)
ref_id = self.document.set_id(reference,
suggested_prefix='toc-entry')
entry = nodes.paragraph('', '', reference)
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-14 13:31:29 UTC (rev 10381)
@@ -20,19 +20,18 @@
"""
Add identifiers to sections.
- If the "legacy_ids" configuration setting is False, the rST parser
- does not generate identifiers for implicit targets (e.g. sections)
- in order to give explicit targets preferential access to identifiers
- matching their reference name.
+ Since Docutils 0.23, the rST parser does not generate identifiers for
+ implicit targets (e.g. sections) unless the "legacy_ids" configuration
+ setting is True.
- However, the `parts.Contents` transform and most writers
- expect sections to have an identifier, so this transform adds them.
+ Components that expect all sections to have an identifier can either
+ set "legacy_ids" or load this transform to add them.
"""
default_priority = 240
def apply(self) -> None:
if getattr(self.document.settings, "legacy_ids", True):
- return
+ return # IDs already generated by parser
for node in self.document.findall(nodes.section):
self.document.set_id(node)
@@ -89,8 +88,8 @@
next_node.expect_referenced_by_name = {}
if not hasattr(next_node, 'expect_referenced_by_id'):
next_node.expect_referenced_by_id = {}
+ # Update mappings:
for id in target['ids']:
- # Update IDs to node mapping.
self.document.ids[id] = next_node
# If next_node is referenced by id ``id``, this
# target shall be marked as referenced.
@@ -883,16 +882,21 @@
nodes.citation_reference)):
if node.resolved or 'refname' not in node:
continue
- identifier = self.document.nameids.get(node['refname'])
- if identifier:
- # target found, set refid
- node['refid'] = identifier
- self.document.ids[identifier].note_referenced_by(id=identifier)
- # If a transform is able to resolve the reference,
- # it should # also remove the 'refname' attribute and
- # mark the node as resolved:
- del node['refname']
- node.resolved = True
+ refname = node['refname']
+ target = self.document.names.get(refname)
+ if target is None: # "refname" is unknown or duplicate
+ continue
+ # target found, set refid
+ refid = self.document.nameids.get(refname)
+ if refid:
+ target.note_referenced_by(id=refid)
+ else:
+ refid = self.document.set_id(target)
+ target.note_referenced_by(name=refname)
+ node['refid'] = refid
+ # cleanup
+ del node['refname']
+ node.resolved = True
class CitationReferences(Transform):
Modified: trunk/docutils/docutils/writers/html5_polyglot/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/html5_polyglot/__init__.py 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/docutils/writers/html5_polyglot/__init__.py 2026-07-14 13:31:29 UTC (rev 10381)
@@ -347,6 +347,11 @@
# use the new HTML5 element <section>
def visit_section(self, node) -> None:
self.section_level += 1
+ # ensure the element has an ID if we want to add a self-link:
+ if (getattr(self.settings, 'section_self_link', None)
+ and not getattr(self.settings, 'legacy_ids', None)
+ and 'system-messages' not in node['classes']):
+ node.document.set_id(node)
self.body.append(self.starttag(node, 'section'))
def depart_section(self, node) -> None:
Modified: trunk/docutils/test/data/help/docutils.rst
===================================================================
--- trunk/docutils/test/data/help/docutils.rst 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/data/help/docutils.rst 2026-07-14 13:31:29 UTC (rev 10381)
@@ -89,9 +89,8 @@
--line-length-limit=<length>
Maximal number of characters in an input line.
(default 10 000)
---legacy-ids Keep identifiers backwards compatible. (default)
---matching-ids Explicit targets use identifiers matching the
- reference name.
+--legacy-ids Keep IDs backwards compatible. (default)
+--lazy-ids Generate IDs for implicit targets only if required.
--validate Validate the document tree after parsing.
--no-validation Do not validate the document tree. (default)
Modified: trunk/docutils/test/data/help/rst2html.rst
===================================================================
--- trunk/docutils/test/data/help/rst2html.rst 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/data/help/rst2html.rst 2026-07-14 13:31:29 UTC (rev 10381)
@@ -90,9 +90,8 @@
--line-length-limit=<length>
Maximal number of characters in an input line.
(default 10 000)
---legacy-ids Keep identifiers backwards compatible. (default)
---matching-ids Explicit targets use identifiers matching the
- reference name.
+--legacy-ids Keep IDs backwards compatible. (default)
+--lazy-ids Generate IDs for implicit targets only if required.
--validate Validate the document tree after parsing.
--no-validation Do not validate the document tree. (default)
Modified: trunk/docutils/test/data/help/rst2latex.rst
===================================================================
--- trunk/docutils/test/data/help/rst2latex.rst 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/data/help/rst2latex.rst 2026-07-14 13:31:29 UTC (rev 10381)
@@ -90,9 +90,8 @@
--line-length-limit=<length>
Maximal number of characters in an input line.
(default 10 000)
---legacy-ids Keep identifiers backwards compatible. (default)
---matching-ids Explicit targets use identifiers matching the
- reference name.
+--legacy-ids Keep IDs backwards compatible. (default)
+--lazy-ids Generate IDs for implicit targets only if required.
--validate Validate the document tree after parsing.
--no-validation Do not validate the document tree. (default)
Modified: trunk/docutils/test/functional/expected/length_units_html5.html
===================================================================
--- trunk/docutils/test/functional/expected/length_units_html5.html 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/functional/expected/length_units_html5.html 2026-07-14 13:31:29 UTC (rev 10381)
@@ -9,10 +9,10 @@
<link rel="stylesheet" href="../input/data/plain.css" type="text/css" />
</head>
<body>
-<main id="test-length-specifications">
+<main>
<h1 class="title">Test length specifications</h1>
-<section id="images-and-figures">
+<section>
<h2>Images and Figures</h2>
<figure>
<img alt="blue square" height="32" src="../input/data/blue%20square.png" width="32" />
@@ -129,13 +129,13 @@
</figcaption>
</figure>
</section>
-<section id="ch-em-and-rem-test1ch-test1em-test1rem">
+<section>
<h2>ch, em, and rem: <img alt="test1ch" src="../input/data/blue%20square.png" style="height: 1ch;" /> <img alt="test1em" src="../input/data/blue%20square.png" style="height: 1em;" /> <img alt="test1rem" src="../input/data/blue%20square.png" style="height: 1rem;" /></h2>
<p>Image height 1ch, 1em, and 1rem: <img alt="test1ch" src="../input/data/blue%20square.png" style="height: 1ch;" /> <img alt="test1em" src="../input/data/blue%20square.png" style="height: 1em;" /> <img alt="test1rem" src="../input/data/blue%20square.png" style="height: 1rem;" /></p>
<p>The units "em" and "ch" change with the current font size.
The unit "rem" is tied to the document root fontsize.</p>
</section>
-<section id="tables">
+<section>
<h2>Tables</h2>
<table>
<tbody>
Modified: trunk/docutils/test/functional/expected/misc_rst_html5.html
===================================================================
--- trunk/docutils/test/functional/expected/misc_rst_html5.html 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/functional/expected/misc_rst_html5.html 2026-07-14 13:31:29 UTC (rev 10381)
@@ -9,7 +9,7 @@
<link rel="stylesheet" href="../input/data/responsive.css" type="text/css" />
</head>
<body class="with-toc">
-<main id="additional-tests-with-html-5">
+<main>
<h1 class="title">Additional tests with HTML 5</h1>
<nav class="contents" id="contents" role="doc-toc">
Modified: trunk/docutils/test/functional/expected/standalone_rst_html5.html
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_html5.html 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/functional/expected/standalone_rst_html5.html 2026-07-14 13:31:29 UTC (rev 10381)
@@ -21,10 +21,9 @@
<header>
<p>Document header</p>
</header>
-<main id="restructuredtext-test-document">
-<span id="doctitle"></span>
+<main id="doctitle">
<h1 class="title">reStructuredText Test Document</h1>
-<p class="subtitle" id="examples-of-syntax-constructs"><span id="subtitle"></span>Examples of Syntax Constructs</p>
+<p class="subtitle" id="subtitle">Examples of Syntax Constructs</p>
<dl class="docinfo">
<dt class="author">Author<span class="colon">:</span></dt>
<dd class="author"><p>David Goodger</p></dd>
@@ -109,7 +108,7 @@
<li><p><a class="reference internal" href="#doctest-blocks" id="toc-entry-16"><span class="sectnum">2.10 </span>Doctest Blocks</a></p></li>
<li><p><a class="reference internal" href="#footnotes" id="toc-entry-17"><span class="sectnum">2.11 </span>Footnotes</a></p></li>
<li><p><a class="reference internal" href="#citations" id="toc-entry-18"><span class="sectnum">2.12 </span>Citations</a></p></li>
-<li><p><a class="reference internal" href="#targets" id="toc-entry-19"><span class="sectnum">2.13 </span>Targets</a></p>
+<li><p><a class="reference internal" href="#another-target" id="toc-entry-19"><span class="sectnum">2.13 </span>Targets</a></p>
<ul class="auto-toc">
<li><p><a class="reference internal" href="#duplicate-target-names-1" id="toc-entry-20"><span class="sectnum">2.13.1 </span>Duplicate Target Names</a></p></li>
<li><p><a class="reference internal" href="#duplicate-target-names-2" id="toc-entry-21"><span class="sectnum">2.13.2 </span>Duplicate Target Names</a></p></li>
@@ -165,7 +164,7 @@
<h2><a class="toc-backref" href="#toc-entry-1" role="doc-backlink"><span class="sectnum">1 </span>Structural Elements</a><a class="self-link" title="link to this section" href="#structural-elements"></a></h2>
<section id="section-title">
<h3><a class="toc-backref" href="#toc-entry-2" role="doc-backlink"><span class="sectnum">1.1 </span>Section Title</a><a class="self-link" title="link to this section" href="#section-title"></a></h3>
-<p class="section-subtitle" id="section-subtitle">Section Subtitle</p>
+<p class="section-subtitle">Section Subtitle</p>
<p>Lone subsections are converted to a section subtitle by a transform
activated with the <span class="docutils literal"><span class="pre">--section-subtitles</span></span> command line option or the
<span class="docutils literal"><span class="pre">sectsubtitle-xform</span></span> configuration value.</p>
@@ -198,7 +197,7 @@
<a class="brackets" href="#label" id="footnote-reference-3" role="doc-noteref"><span class="fn-bracket">[</span>2<span class="fn-bracket">]</span></a>, or symbolic <a class="brackets" href="#footnote-3" id="footnote-reference-4" role="doc-noteref"><span class="fn-bracket">[</span>*<span class="fn-bracket">]</span></a>), citation references (see <a class="citation-reference" href="#cit2002" id="citation-reference-1" role="doc-biblioref">[CIT2002]</a>),
substitution references (<img alt="EXAMPLE" src="../../../docs/user/rst/images/biohazard.png" /> &
a <em>trimmed heart</em> <span class="docutils literal">(U+2665):</span>♥), and <span class="target" id="inline-hyperlink-targets">inline hyperlink targets</span>
-(see <a class="reference internal" href="#targets">Targets</a> below for a reference back to here). Character-level
+(see <a class="reference internal" href="#another-target">Targets</a> below for a reference back to here). Character-level
inline markup is also possible (although exceedingly ugly!) in <em>re</em><span class="docutils literal">Structured</span><em>Text</em>. Problems are indicated by <a href="#system-message-1"><span class="problematic" id="problematic-1">|problematic|</span></a> text
(generated by processing errors; this one is intentional). Here is a
reference to the <a class="reference internal" href="#doctitle">doctitle</a> and the <a class="reference internal" href="#subtitle">subtitle</a>.</p>
@@ -530,18 +529,17 @@
<p>Here's a reference to the above, <a class="citation-reference" href="#cit2002" id="citation-reference-2" role="doc-biblioref">[CIT2002]</a>, and a <a href="#system-message-3"><span class="problematic" id="citation-reference-3">[nonexistent]_</span></a>
citation.</p>
</section>
-<section id="targets">
-<span id="another-target"></span>
+<section id="another-target">
<h3><a class="toc-backref" href="#toc-entry-19" role="doc-backlink"><span class="sectnum">2.13 </span>Targets</a><a class="self-link" title="link to this section" href="#another-target"></a></h3>
<p id="example">This paragraph is pointed to by the explicit "example" target. A
reference can be found under <a class="reference internal" href="#inline-markup">Inline Markup</a>, above. <a class="reference internal" href="#inline-hyperlink-targets">Inline
hyperlink targets</a> are also possible.</p>
<p>Section headers are implicit targets, referred to by name. See
-<a class="reference internal" href="#targets">Targets</a>, which is a subsection of <a class="reference internal" href="#body-elements">Body Elements</a>.</p>
+<a class="reference internal" href="#another-target">Targets</a>, which is a subsection of <a class="reference internal" href="#body-elements">Body Elements</a>.</p>
<p>Explicit external targets are interpolated into references such as
"<a class="reference external" href="http://www.python.org/">Python</a> <a class="brackets" href="#footnote-7" id="footnote-reference-19" role="doc-noteref"><span class="fn-bracket">[</span>7<span class="fn-bracket">]</span></a>".</p>
-<p>Targets may be indirect and anonymous. Thus <a class="reference internal" href="#targets">this phrase</a> may also
-refer to the <a class="reference internal" href="#targets">Targets</a> section.</p>
+<p>Targets may be indirect and anonymous. Thus <a class="reference internal" href="#another-target">this phrase</a> may also
+refer to the <a class="reference internal" href="#another-target">Targets</a> section.</p>
<p>Here's a <a href="#system-message-4"><span class="problematic" id="problematic-2">`hyperlink reference without a target`_</span></a>, which generates an
error.</p>
<section id="duplicate-target-names-1">
Modified: trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2026-07-14 13:31:29 UTC (rev 10381)
@@ -1,7 +1,7 @@
-<document ids="restructuredtext-test-document doctitle" names="restructuredtext\ test\ document doctitle" source="functional/input/standalone_rst_pseudoxml.rst" title="reStructuredText Test Document">
+<document ids="doctitle" names="restructuredtext\ test\ document doctitle" source="functional/input/standalone_rst_pseudoxml.rst" title="reStructuredText Test Document">
<title>
reStructuredText Test Document
- <subtitle ids="examples-of-syntax-constructs subtitle" names="examples\ of\ syntax\ constructs subtitle">
+ <subtitle ids="subtitle" names="examples\ of\ syntax\ constructs subtitle">
Examples of Syntax Constructs
<meta content="reStructuredText, test, parser" name="keywords">
<meta content="A test document, containing at least one example of each reStructuredText construct." lang="en" name="description">
@@ -204,7 +204,7 @@
Citations
<list_item>
<paragraph>
- <reference ids="toc-entry-19" refid="targets">
+ <reference ids="toc-entry-19" refid="another-target">
<generated classes="sectnum">
2.13
Targets
@@ -358,7 +358,7 @@
<generated classes="sectnum">
1.1
Section Title
- <subtitle ids="section-subtitle" names="section\ subtitle">
+ <subtitle names="section\ subtitle">
Section Subtitle
<paragraph>
Lone subsections are converted to a section subtitle by a transform
@@ -475,7 +475,7 @@
inline hyperlink targets
(see
- <reference refid="targets">
+ <reference refid="another-target">
Targets
below for a reference back to here). Character-level
inline markup is also possible (although exceedingly ugly!) in
@@ -1109,7 +1109,7 @@
citation.
<target refid="another-target">
- <section ids="targets another-target" names="targets another\ target">
+ <section ids="another-target" names="targets another\ target">
<title auto="1" refid="toc-entry-19">
<generated classes="sectnum">
2.13
@@ -1127,7 +1127,7 @@
are also possible.
<paragraph>
Section headers are implicit targets, referred to by name. See
- <reference refid="targets">
+ <reference refid="another-target">
Targets
, which is a subsection of
<reference refid="body-elements">
@@ -1145,14 +1145,14 @@
<target ids="python" names="python" refuri="http://www.python.org/">
<paragraph>
Targets may be indirect and anonymous. Thus
- <reference anonymous="1" refid="targets">
+ <reference anonymous="1" refid="another-target">
this phrase
may also
refer to the
- <reference refid="targets">
+ <reference refid="another-target">
Targets
section.
- <target anonymous="1" ids="target-4" refid="targets">
+ <target anonymous="1" ids="target-4" refid="another-target">
<paragraph>
Here's a
<problematic ids="problematic-2" refid="system-message-4">
@@ -2417,9 +2417,6 @@
<system_message level="1" line="159" source="functional/input/data/standard.rst" type="INFO">
<paragraph>
Hyperlink target "target" is not referenced.
- <system_message level="1" line="404" source="functional/input/data/standard.rst" type="INFO">
- <paragraph>
- Hyperlink target "another-target" is not referenced.
<system_message level="1" line="474" source="functional/input/data/standard.rst" type="INFO">
<paragraph>
Hyperlink target "image-target-1" is not referenced.
Modified: trunk/docutils/test/functional/expected/standalone_rst_xetex.tex
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_xetex.tex 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/functional/expected/standalone_rst_xetex.tex 2026-07-14 13:31:29 UTC (rev 10381)
@@ -188,7 +188,7 @@
\item \hyperref[citations]{2.12 Citations}
-\item \hyperref[targets]{2.13 Targets}
+\item \hyperref[another-target]{2.13 Targets}
\begin{DUclass}{auto-toc}
\begin{itemize}
@@ -325,7 +325,7 @@
substitution references (\includegraphics{../../../docs/user/rst/images/biohazard.png} \&
a \emph{trimmed heart} \texttt{(U+2665):}♥), and %
\phantomsection\label{inline-hyperlink-targets}inline hyperlink targets
-(see \hyperref[targets]{Targets} below for a reference back to here). Character-level
+(see \hyperref[another-target]{Targets} below for a reference back to here). Character-level
inline markup is also possible (although exceedingly ugly!) in \emph{re}\texttt{Structured}\emph{Text}. Problems are indicated by %
\raisebox{1em}{\hypertarget{problematic-1}{}}\hyperlink{system-message-1}{\textbf{\color{red}|problematic|}} text
(generated by processing errors; this one is intentional). Here is a
@@ -739,7 +739,6 @@
\subsection{2.13 Targets%
- \label{targets}%
\label{another-target}%
}
@@ -749,13 +748,13 @@
hyperlink targets} are also possible.
Section headers are implicit targets, referred to by name. See
-\hyperref[targets]{Targets}, which is a subsection of \hyperref[body-elements]{Body Elements}.
+\hyperref[another-target]{Targets}, which is a subsection of \hyperref[body-elements]{Body Elements}.
Explicit external targets are interpolated into references such as
“\href{http://www.python.org/}{Python}\DUfootnotemark{footnote-reference-11}{footnote-6}{5}”.
-Targets may be indirect and anonymous. Thus \hyperref[targets]{this phrase} may also
-refer to the \hyperref[targets]{Targets} section.
+Targets may be indirect and anonymous. Thus \hyperref[another-target]{this phrase} may also
+refer to the \hyperref[another-target]{Targets} section.
Here’s a %
\raisebox{1em}{\hypertarget{problematic-2}{}}\hyperlink{system-message-4}{\textbf{\color{red}`hyperlink reference without a target`\_}}, which generates an
Modified: trunk/docutils/test/functional/tests/length_units_html5.py
===================================================================
--- trunk/docutils/test/functional/tests/length_units_html5.py 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/functional/tests/length_units_html5.py 2026-07-14 13:31:29 UTC (rev 10381)
@@ -16,4 +16,5 @@
# location of stylesheets (relative to ``docutils/test/``)
'stylesheet_dirs': ('functional/input/data', ),
'section_self_link': False,
+ 'legacy_ids': False,
}
Modified: trunk/docutils/test/test_transforms/test_contents.py
===================================================================
--- trunk/docutils/test/test_transforms/test_contents.py 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/test_transforms/test_contents.py 2026-07-14 13:31:29 UTC (rev 10381)
@@ -20,7 +20,7 @@
from docutils.frontend import get_default_settings
from docutils.parsers.rst import Parser
-from docutils.transforms.references import SectionIDs, Substitutions
+from docutils.transforms.references import Substitutions
from docutils.transforms.universal import TestMessages
from docutils.utils import new_document
@@ -46,7 +46,7 @@
totest = {}
-totest['tables_of_contents'] = ((SectionIDs, Substitutions,), [
+totest['tables_of_contents'] = ((Substitutions,), [
["""\
.. contents::
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-14 13:31:29 UTC (rev 10381)
@@ -20,7 +20,7 @@
from docutils.frontend import get_default_settings
from docutils.parsers.rst import Parser
from docutils.transforms.references import (
- SectionIDs, PropagateTargets, AnonymousHyperlinks, IndirectHyperlinks,
+ PropagateTargets, AnonymousHyperlinks, IndirectHyperlinks,
ExternalTargets, InternalTargets, DanglingReferences, MatchReferences,
ReportDanglingReferences, ReportUnreferencedTargets)
from docutils.transforms.universal import TestMessages
@@ -33,7 +33,7 @@
transforms = (PropagateTargets, AnonymousHyperlinks, IndirectHyperlinks,
ExternalTargets, InternalTargets, MatchReferences,
ReportDanglingReferences, ReportUnreferencedTargets,
- SectionIDs, TestMessages)
+ TestMessages)
def test_transforms(self):
parser = Parser()
@@ -594,7 +594,7 @@
"""],
])
-totest['hyperlinks legacy'] = ({'legacy_ids': True}, [
+totest['explicit hyperlinks legacy'] = ({'legacy_ids': True}, [
["""\
.. _internal hyperlink:
@@ -1036,6 +1036,58 @@
to an image with target (sic!).
"""],
["""\
+Unknown reference_.
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Unknown \n\
+ <problematic ids="problematic-1" refid="system-message-1">
+ reference_
+ .
+ <system_message backrefs="problematic-1" ids="system-message-1" level="3" line="1" source="test data" type="ERROR">
+ <paragraph>
+ Unknown target name: "reference".
+"""],
+["""\
+Duplicate manual footnote labels, with reference ([1]_):
+
+.. [1] Footnote.
+
+.. [1] Footnote.
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate manual footnote labels, with reference (
+ <problematic ids="footnote-reference-1" refid="system-message-1">
+ [1]_
+ ):
+ <footnote dupnames="1" ids="footnote-1">
+ <label>
+ 1
+ <paragraph>
+ Footnote.
+ <footnote dupnames="1" ids="footnote-2">
+ <label>
+ 1
+ <system_message backrefs="footnote-2" level="2" line="5" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "1".
+ <paragraph>
+ Footnote.
+ <system_message backrefs="footnote-reference-1" ids="system-message-1" level="3" line="1" source="test data" type="ERROR">
+ <paragraph>
+ Duplicate target name, cannot be used as a unique reference: "1".
+"""],
+])
+
+totest['explicit hyperlinks'] = ({'legacy_ids': False},
+ # all samples compile as before
+ totest['explicit hyperlinks legacy'][1])
+
+totest['implicit hyperlinks legacy'] = ({'legacy_ids': True}, [
+["""\
.. contents:: Table of Contents
.. _indirect reference to the table of contents: `table of contents`_
@@ -1109,51 +1161,6 @@
Title
"""],
["""\
-Unknown reference_.
-""",
-"""\
-<document source="test data">
- <paragraph>
- Unknown \n\
- <problematic ids="problematic-1" refid="system-message-1">
- reference_
- .
- <system_message backrefs="problematic-1" ids="system-message-1" level="3" line="1" source="test data" type="ERROR">
- <paragraph>
- Unknown target name: "reference".
-"""],
-["""\
-Duplicate manual footnote labels, with reference ([1]_):
-
-.. [1] Footnote.
-
-.. [1] Footnote.
-""",
-"""\
-<document source="test data">
- <paragraph>
- Duplicate manual footnote labels, with reference (
- <problematic ids="footnote-reference-1" refid="system-message-1">
- [1]_
- ):
- <footnote dupnames="1" ids="footnote-1">
- <label>
- 1
- <paragraph>
- Footnote.
- <footnote dupnames="1" ids="footnote-2">
- <label>
- 1
- <system_message backrefs="footnote-2" level="2" line="5" source="test data" type="WARNING">
- <paragraph>
- Duplicate explicit target name: "1".
- <paragraph>
- Footnote.
- <system_message backrefs="footnote-reference-1" ids="system-message-1" level="3" line="1" source="test data" type="ERROR">
- <paragraph>
- Duplicate target name, cannot be used as a unique reference: "1".
-"""],
-["""\
An explicit target _`foo` overrides a homonymous implicit target.
foo
@@ -1213,10 +1220,84 @@
"""],
])
-totest['hyperlinks'] = ({'legacy_ids': False},
- # all but the last sample compile as before
- totest['hyperlinks legacy'][1][:-1] + [
+totest['implicit hyperlinks'] = ({'legacy_ids': False}, [
["""\
+.. contents:: Table of Contents
+.. _indirect reference to the table of contents: `table of contents`_
+
+Section
+=======
+
+Testing an `indirect reference to the table of contents`_.
+""",
+"""\
+<document source="test data">
+ <topic classes="contents" ids="table-of-contents" names="table\\ of\\ contents">
+ <title>
+ Table of Contents
+ <bullet_list>
+ <list_item>
+ <paragraph>
+ <reference ids="toc-entry-1" refid="section">
+ Section
+ <target ids="indirect-reference-to-the-table-of-contents" names="indirect\\ reference\\ to\\ the\\ table\\ of\\ contents" refid="table-of-contents">
+ <section ids="section" names="section">
+ <title refid="toc-entry-1">
+ Section
+ <paragraph>
+ Testing an \n\
+ <reference refid="table-of-contents">
+ indirect reference to the table of contents
+ .
+"""],
+["""\
+.. _explicit target:
+
+Title
+-----
+
+References to the section (title_) use the ID from the `explicit target`_.
+""",
+"""\
+<document source="test data">
+ <target refid="explicit-target">
+ <section ids="explicit-target" names="title explicit\\ target">
+ <title>
+ Title
+ <paragraph>
+ References to the section (
+ <reference refid="explicit-target">
+ title
+ ) use the ID from the \n\
+ <reference refid="explicit-target">
+ explicit target
+ .
+"""],
+["""\
+target1_ should refer to target2_, not the Title.
+
+.. _target1:
+.. _target2: URI
+
+Title
+=====
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ <reference refuri="URI">
+ target1
+ should refer to \n\
+ <reference refuri="URI">
+ target2
+ , not the Title.
+ <target refid="target1">
+ <target ids="target2 target1" names="target2 target1" refuri="URI">
+ <section names="title">
+ <title>
+ Title
+"""],
+["""\
foo
---
@@ -1229,7 +1310,7 @@
""",
"""\
<document source="test data">
- <section dupnames="foo" ids="foo-1">
+ <section dupnames="foo">
<title>
foo
<system_message backrefs="foo" level="1" line="5" source="test data" type="INFO">
Modified: trunk/docutils/test/test_transforms/test_sectnum.py
===================================================================
--- trunk/docutils/test/test_transforms/test_sectnum.py 2026-07-14 13:31:13 UTC (rev 10380)
+++ trunk/docutils/test/test_transforms/test_sectnum.py 2026-07-14 13:31:29 UTC (rev 10381)
@@ -20,7 +20,7 @@
from docutils.frontend import get_default_settings
from docutils.parsers.rst import Parser
-from docutils.transforms.references import SectionIDs, Substitutions
+from docutils.transforms.references import Substitutions
from docutils.transforms.universal import TestMessages
from docutils.utils import new_document
@@ -46,7 +46,7 @@
totest = {}
-totest['section_numbers'] = ((SectionIDs, Substitutions), [
+totest['section_numbers'] = ((Substitutions,), [
["""\
.. sectnum::
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-14 13:31:16
|
Revision: 10380
http://sourceforge.net/p/docutils/code/10380
Author: milde
Date: 2026-07-14 13:31:13 +0000 (Tue, 14 Jul 2026)
Log Message:
-----------
Small fixes.
Fix typos, improve wording and formatting at various places.
Remove obsolete change announcements.
Sort link targets.
Update comments and simplifiy conditional in nodes.py.
Update `document.names` after transferring names from explicit internal targets,
simplify conditional, and use `True` instead of 1 for boolean value
in transforms/references.py.
Format code in html5 writer. More precise condition in `section_title_tags()`.
Simplify CSS rule to highlight "targeted" elements,
also highlight target admonitions and topics.
No change to tested behaviour.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/ref/rst/restructuredtext.rst
trunk/docutils/docs/user/config.rst
trunk/docutils/docutils/nodes.py
trunk/docutils/docutils/transforms/references.py
trunk/docutils/docutils/writers/html5_polyglot/__init__.py
trunk/docutils/docutils/writers/html5_polyglot/responsive.css
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-07-14 13:31:00 UTC (rev 10379)
+++ trunk/docutils/HISTORY.rst 2026-07-14 13:31:13 UTC (rev 10380)
@@ -94,12 +94,10 @@
* docutils/transforms/references.py
- - Do not call `unknown_reference_resolvers` in
- `IndirectHyperlinks.resolve_indirect_target()`.
- - 3 new transforms, `references.MatchReferences`,
- `references.ReportDanglingReferences` and
- `references.ReportUnreferencedLinks`,
- obsolete `references.DanglingReferences`.
+ - `IndirectHyperlinks.resolve_indirect_target()` no longer calls
+ `unknown_reference_resolvers` and only sets IDs if required.
+ - 3 new transforms, `MatchReferences`, `ReportDanglingReferences`,
+ and `ReportUnreferencedLinks` obsolete `DanglingReferences`.
- Add INFO system_message if a <target> cannot be propagated
to the next node.
@@ -119,10 +117,11 @@
- Change the default value of the "section_self_link" setting to True.
- Add CSS rules for back-link and self-link symbols from
"responsive.css" also in "plain.css" and "tuftig.css".
- - Use normal font size and colour in CSS for informal titles of type "rubric".
+ - Use normal font size and colour in CSS for informal titles
+ of type "rubric".
- Use more specific CSS selectors for styling <aside> elements to avoid
- problems with other elements using "topic" as class value, e.g. a docinfo
- item "topic" in Enhancement Reports.
+ problems with other elements using "topic" as class value (e.g. a
+ docinfo item "topic" in Enhancement Reports).
- More robust handling of figure captions.
* docutils/writers/latex2e/__init__.py
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-07-14 13:31:00 UTC (rev 10379)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-07-14 13:31:13 UTC (rev 10380)
@@ -71,11 +71,6 @@
<substitution_definition>, and <target> elements when warning about
transitions at the start or end of the document or a section.
-* In case of name conflicts, an explicit target will not only override
- the "name" attribute of an implicit target but also its name-based "id".
- Use case: "sane" anchors for links from an external source to a fragment
- of the document. Cf. https://github.com/sphinx-doc/sphinx/issues/1961
-
Parsers
-------
@@ -101,12 +96,6 @@
* "html5" writer:
- - Prefer explicit reference names as base for an HTML element's ID
- in Docutils 1.0. No change for internal cross-references.
- Cf. `Sphinx issue #1961`__
-
- __ https://github.com/sphinx-doc/sphinx/issues/1961
-
- Move attribution behind the blockquote to comply with the
`"HTML living standard"`__ [#]_ and adapt CSS stylesheets
in Docutils 1.0.
@@ -1638,8 +1627,6 @@
.. _datestamp: docs/user/config.html#datestamp
.. _embed_images: docs/user/config.html#embed-images
.. _graphicx_option: docs/user/config.html#graphicx-option
-.. _legacy_class_functions: docs/user/config.html#legacy-class-functions
-.. _literal_block_env: docs/user/config.html#literal-block-env
.. _id_prefix: docs/user/config.html#id-prefix
.. _image_loading: docs/user/config.html#image-loading
.. _initial_header_level: docs/user/config.html#initial-header-level
@@ -1646,9 +1633,10 @@
.. _input_encoding: docs/user/config.html#input-encoding
.. _[latex writers]: docs/user/config.html#latex-writers
.. _latex_footnotes: docs/user/config.html#latex-footnotes
+.. _legacy_class_functions: docs/user/config.html#legacy-class-functions
.. _legacy_column_widths: docs/user/config.html#legacy-column-widths
.. _legacy_ids: docs/user/config.html#legacy-ids
-.. _text_references: docs/user/config.html#text-references
+.. _literal_block_env: docs/user/config.html#literal-block-env
.. _math_output: docs/user/config.html#math-output
.. _old-format configuration files:
docs/user/config.html#old-format-configuration-files
@@ -1660,6 +1648,7 @@
.. _section_self_link: docs/user/config.html#section-self-link
.. _SmartQuotes: docs/user/config.html#smart-quotes
.. _sources: docs/user/config.html#sources
+.. _text_references: docs/user/config.html#text-references
.. _use_latex_citations: docs/user/config.html#use-latex-citations
.. _validate: docs/user/config.html#validate
.. _"writer" setting: docs/user/config.html#writer-buildhtml-application
Modified: trunk/docutils/docs/ref/rst/restructuredtext.rst
===================================================================
--- trunk/docutils/docs/ref/rst/restructuredtext.rst 2026-07-14 13:31:00 UTC (rev 10379)
+++ trunk/docutils/docs/ref/rst/restructuredtext.rst 2026-07-14 13:31:13 UTC (rev 10380)
@@ -474,7 +474,7 @@
Hyperlink`_
Hyperlinks_, footnotes_, and citations_ all share the same namespace
-for reference names. [#substitution-text]_
+for `reference names`_. [#substitution-text]_
This means that a footnote defined as "``.. [#note]``" can be referred to
by the `footnote reference`_ ``[#note]_`` as well as a plain `hyperlink
reference`_ ``note_``. Of course, each type of reference (hyperlink,
@@ -629,8 +629,8 @@
established, sections must use that hierarchy. [#]_
Each section title automatically generates a hyperlink target pointing
-to the section. The text of the hyperlink target (the "reference
-name") is the same as that of the section title. See `Implicit
+to the section. The text of the hyperlink target (the `reference name`_)
+is the same as that of the section title. See `Implicit
Hyperlink Targets`_ for a complete description.
Sections may contain `body elements`_, transitions_, and nested
Modified: trunk/docutils/docs/user/config.rst
===================================================================
--- trunk/docutils/docs/user/config.rst 2026-07-14 13:31:00 UTC (rev 10379)
+++ trunk/docutils/docs/user/config.rst 2026-07-14 13:31:13 UTC (rev 10380)
@@ -255,10 +255,7 @@
:Default: "%" (use Doctree element name; changed from "id" in Docutils 0.18).
:Option: ``--auto-id-prefix`` (hidden, intended mainly for programmatic use).
-.. _identifier normalization:
- ../ref/rst/directives.html#identifier-normalization
-
datestamp
---------
@@ -806,7 +803,7 @@
`reference name`_.
:Default: True; will change to False in Docutils 2.0.
-:Option: ``--legacy-ids``, ``--matching-ids``.
+:Options: ``--legacy-ids``, ``--matching-ids``.
New in Docutils 0.23. Provisional.
@@ -2158,7 +2155,7 @@
.. _ODT Writer: odt.html
.. _OpenDocument: https://en.wikipedia.org/wiki/OpenDocument
-add-syntax_highlighting
+add_syntax_highlighting
~~~~~~~~~~~~~~~~~~~~~~~
Add syntax highlighting in literal code blocks.
See section "`Syntax highlighting`__" in the ODT Writer documentation
@@ -2610,6 +2607,8 @@
.. _Document Tree: ../ref/doctree.html
.. _Doctree: ../ref/doctree.html
.. _class attribute: ../ref/doctree.html#classes
+.. _identifier:
+.. _element identifiers:
.. _identifiers: ../ref/doctree.html#identifiers
.. _reference name:
.. _reference names: ../ref/doctree.html#reference-names
@@ -2670,7 +2669,7 @@
.. _footnote references: ../ref/rst/restructuredtext.html#footnote-references
.. _hyperlink references: ../ref/rst/restructuredtext.html#hyperlink-references
.. _implicit target:
-.. _implicit targets: ../ref/rst/restructuredtext.html#implicit-hyperlink-targets
+.. _implicit targets: ../ref/rst/restructuredtext.html#implicit-hyperlink-targets
.. _interpreted text role: ../ref/rst/restructuredtext.html#interpreted-text
.. _inline markup recognition rules:
../ref/rst/restructuredtext.html#inline-markup-recognition-rules
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-07-14 13:31:00 UTC (rev 10379)
+++ trunk/docutils/docutils/nodes.py 2026-07-14 13:31:13 UTC (rev 10380)
@@ -686,7 +686,7 @@
def __len__(self) -> int:
return len(self.children)
- def __contains__(self, key) -> bool:
+ def __contains__(self, key: str | Node) -> bool:
# Test for both, children and attributes with operator ``in``.
if isinstance(key, str):
return key in self.attributes
@@ -1209,17 +1209,13 @@
`name` or id `id`."""
self.referenced = True
# Element.expect_referenced_by_* dictionaries map names or ids
- # to nodes whose ``referenced`` attribute is set to true as
- # soon as this node is referenced by the given name or id.
- # Needed for target propagation.
- by_name = getattr(self, 'expect_referenced_by_name', {}).get(name)
- by_id = getattr(self, 'expect_referenced_by_id', {}).get(id)
- if by_name:
- assert name is not None
- by_name.referenced = True
- if by_id:
- assert id is not None
- by_id.referenced = True
+ # that were "propagated" to this element to the elements that
+ # had these attributes before. Mark them as ``referenced``
+ # when this node is referenced by the respective names or ids.
+ if relay := getattr(self, 'expect_referenced_by_name', {}).get(name):
+ relay.referenced = True
+ if relay := getattr(self, 'expect_referenced_by_id', {}).get(id):
+ relay.referenced = True
@classmethod
def is_not_list_attribute(cls, attr: str) -> bool:
@@ -1972,7 +1968,7 @@
Check/set identifiers of element `node`. Return last identifier.
Check `node`s identifiers for duplicates,
- create a new identifier if there are none.
+ create a new identifier if there are no identifiers.
Update `document.ids` and `document.nameids`.
Provisional.
@@ -2168,7 +2164,7 @@
self.nametypes.setdefault(name, explicit)
def has_name(self, name: str) -> bool:
- # TODO: deprecate? (use ``name in document.names``)
+ # TODO: deprecate in Docutils 2.0 (use ``name in document.names``)
return name in self.names
# "note" here is an imperative verb: "take note of".
@@ -2576,9 +2572,7 @@
(legend, '?'),
)
# (image, ((caption, legend?) | legend))
- # TODO: According to the DTD, a caption or legend is required
- # but rST allows "bare" figures which are formatted differently from
- # images (floating in LaTeX, nested in a <figure> in HTML). [bugs: #489]
+ # A caption or legend is required (cf. [bugs: #489]).
# Tables
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-07-14 13:31:00 UTC (rev 10379)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-14 13:31:13 UTC (rev 10380)
@@ -64,11 +64,11 @@
def apply(self) -> None:
for target in self.document.findall(nodes.target):
# Only block-level targets without reference (like ".. _target:"):
- if (isinstance(target.parent, nodes.TextElement)
- or (target.hasattr('refid') or target.hasattr('refuri')
- or target.hasattr('refname'))):
+ if (len(target) or isinstance(target.parent, nodes.TextElement)
+ or 'refid' in target
+ or 'refname' in target
+ or 'refuri' in target):
continue
- assert len(target) == 0, 'error: block-level target has children'
next_node = target.next_node(ascend=True)
# skip system messages (may be removed by universal.FilterMessages)
while isinstance(next_node, nodes.system_message):
@@ -96,6 +96,7 @@
# target shall be marked as referenced.
next_node.expect_referenced_by_id[id] = target
for name in target['names']:
+ self.document.names[name] = next_node
next_node.expect_referenced_by_name[name] = target
# If there are any expect_referenced_by_... attributes
# in target set, copy them to next_node.
@@ -264,12 +265,12 @@
if (isinstance(reftarget, nodes.target)
and not reftarget.resolved
and reftarget.hasattr('refname')):
- if hasattr(target, 'multiply_indirect'):
+ if hasattr(target, 'multiple_indirect'):
self.circular_indirect_reference(target)
return
- target.multiply_indirect = 1
- self.resolve_indirect_target(reftarget) # multiply indirect
- del target.multiply_indirect
+ target.multiple_indirect = True
+ self.resolve_indirect_target(reftarget) # multiple redirection
+ del target.multiple_indirect
if reftarget.hasattr('refuri'):
target['refuri'] = reftarget['refuri']
if 'refid' in target:
@@ -277,13 +278,12 @@
elif reftarget.hasattr('refid'):
target['refid'] = reftarget['refid']
self.document.note_refid(target)
+ elif reftarget['ids']:
+ target['refid'] = refid
+ self.document.note_refid(target)
else:
- if reftarget['ids']:
- target['refid'] = refid
- self.document.note_refid(target)
- else:
- self.nonexistent_indirect_target(target)
- return
+ self.nonexistent_indirect_target(target)
+ return
if refname is not None:
del target['refname']
target.resolved = True
@@ -403,7 +403,7 @@
def apply(self) -> None:
for target in self.document.findall(nodes.target):
- if not target.hasattr('refuri') and not target.hasattr('refid'):
+ if 'refid' not in target and 'refuri' not in target:
self.resolve_reference_ids(target)
def resolve_reference_ids(self, target) -> None:
@@ -809,7 +809,7 @@
nodelist = []
for target in self.document.findall(nodes.target):
# Only external targets.
- if not target.hasattr('refuri'):
+ if 'refuri' not in target:
continue
names = target['names']
refs = []
@@ -1050,7 +1050,7 @@
pass
def visit_reference(self, node) -> None:
- if node.resolved or not node.hasattr('refname'):
+ if node.resolved or 'refname' not in node:
return
refname = node['refname']
id = self.document.nameids.get(refname, '')
Modified: trunk/docutils/docutils/writers/html5_polyglot/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/html5_polyglot/__init__.py 2026-07-14 13:31:00 UTC (rev 10379)
+++ trunk/docutils/docutils/writers/html5_polyglot/__init__.py 2026-07-14 13:31:13 UTC (rev 10380)
@@ -347,8 +347,7 @@
# use the new HTML5 element <section>
def visit_section(self, node) -> None:
self.section_level += 1
- self.body.append(
- self.starttag(node, 'section'))
+ self.body.append(self.starttag(node, 'section'))
def depart_section(self, node) -> None:
self.section_level -= 1
@@ -356,8 +355,7 @@
# use the new HTML5 element <aside>
def visit_sidebar(self, node) -> None:
- self.body.append(
- self.starttag(node, 'aside', CLASS='sidebar'))
+ self.body.append(self.starttag(node, 'aside', CLASS='sidebar'))
self.in_sidebar = True
def depart_sidebar(self, node) -> None:
@@ -394,7 +392,7 @@
start_tag, close_tag = super().section_title_tags(node)
ids = node.parent['ids']
if (ids and getattr(self.settings, 'section_self_link', None)
- and not isinstance(node.parent, nodes.document)):
+ and isinstance(node.parent, nodes.section)):
self_link = ('<a class="self-link" title="link to this section"'
f' href="#{ids[-1]}"></a>')
close_tag = close_tag.replace('</h', self_link + '</h')
Modified: trunk/docutils/docutils/writers/html5_polyglot/responsive.css
===================================================================
--- trunk/docutils/docutils/writers/html5_polyglot/responsive.css 2026-07-14 13:31:00 UTC (rev 10379)
+++ trunk/docutils/docutils/writers/html5_polyglot/responsive.css 2026-07-14 13:31:13 UTC (rev 10380)
@@ -299,11 +299,9 @@
dt:target, span:target, p:target,
.contents :target,
.contents:target > .topic-title,
-aside.system-message:target,
+aside:target,
[role="doc-biblioentry"]:target,
[role="doc-biblioref"]:target,
-[role="note"]:target, /* Docutils 0.18 and 0.19 */
-[role="doc-footnote"]:target, /* Docutils >= 0.20 */
[role="doc-noteref"]:target {
background-color: #d2e6ec;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-14 13:31:03
|
Revision: 10379
http://sourceforge.net/p/docutils/code/10379
Author: milde
Date: 2026-07-14 13:31:00 +0000 (Tue, 14 Jul 2026)
Log Message:
-----------
Add test for the bug with anonymous links to images with a :target:.
Anonymous internal hyperlinks to "clickable" images currently link to the
wrapping `<reference>` instead of the `<image>`.
The reference is handled similar to an indirect target: the reference's
"refid" or "refuri" is transferred to the internal reference.
As a result, clicking the hyperlink reference to the image brings you
directly to the image's "target" (instead of the internal image).
Modified Paths:
--------------
trunk/docutils/test/test_transforms/test_hyperlinks.py
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-13 11:13:03 UTC (rev 10378)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-14 13:31:00 UTC (rev 10379)
@@ -937,7 +937,105 @@
<reference refid="internal">
<image uri="picture.png">
"""],
+# TODO: Anonymous links to a "clickable image should go
+# to the image, not the image's click-target!
["""\
+.. _img1:
+.. image:: pic1.png
+ :target: uri1.html
+__
+.. image:: pic2.png
+__
+.. image:: pic3.png
+ :target: uri3.html
+
+Named link to img1_ with target and anonymous links to
+the targetless img2__ and
+img3__ with target (sic!).
+""",
+"""\
+<document source="test data">
+ <target refid="img1">
+ <reference ids="img1" names="img1" refuri="uri1.html">
+ <image uri="pic1.png">
+ <target anonymous="1" refid="target-1">
+ <image ids="target-1" uri="pic2.png">
+ <target anonymous="1" refid="target-2">
+ <reference ids="target-2" refuri="uri3.html">
+ <image uri="pic3.png">
+ <paragraph>
+ Named link to \n\
+ <reference refid="img1">
+ img1
+ with target and anonymous links to
+ the targetless \n\
+ <reference anonymous="1" refid="target-1">
+ img2
+ and
+ <reference anonymous="1" refuri="uri3.html">
+ img3
+ with target (sic!).
+"""],
+["""\
+__
+__
+.. image:: pic1.png
+ :target: uri1.html
+
+Two anonymous__ links to an `image with target`__ (sic!).
+
+.. _named:
+__
+.. image:: pic2.png
+ :target: uri2.html
+
+Named_ and anonymous__ link to an image with target (sic!).
+
+__
+.. _named link:
+.. image:: pic3.png
+ :target: uri3.html
+
+Anonymous__ and `named link`_ to an image with target (sic!).
+""",
+"""\
+<document source="test data">
+ <target anonymous="1" refid="target-1">
+ <target anonymous="1" refid="target-2">
+ <reference ids="target-2 target-1" refuri="uri1.html">
+ <image uri="pic1.png">
+ <paragraph>
+ Two \n\
+ <reference anonymous="1" refuri="uri1.html">
+ anonymous
+ links to an \n\
+ <reference anonymous="1" refuri="uri1.html">
+ image with target
+ (sic!).
+ <target refid="named">
+ <target anonymous="1" refid="target-3">
+ <reference ids="target-3 named" names="named" refuri="uri2.html">
+ <image uri="pic2.png">
+ <paragraph>
+ <reference refid="named">
+ Named
+ and \n\
+ <reference anonymous="1" refuri="uri2.html">
+ anonymous
+ link to an image with target (sic!).
+ <target anonymous="1" refid="target-4">
+ <target refid="named-link">
+ <reference ids="named-link target-4" names="named\\ link" refuri="uri3.html">
+ <image uri="pic3.png">
+ <paragraph>
+ <reference anonymous="1" refuri="uri3.html">
+ Anonymous
+ and \n\
+ <reference refid="named-link">
+ named link
+ to an image with target (sic!).
+"""],
+["""\
.. contents:: Table of Contents
.. _indirect reference to the table of contents: `table of contents`_
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-07-13 11:13:06
|
Revision: 10378
http://sourceforge.net/p/docutils/code/10378
Author: milde
Date: 2026-07-13 11:13:03 +0000 (Mon, 13 Jul 2026)
Log Message:
-----------
Inform if a target cannot be propagated to the next element.
Add an INFO system_message if a `<target>` cannot be "propagated" because the
next element is invisible, a footnote, or a citation.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/transforms/references.py
trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt
trunk/docutils/test/test_transforms/test_hyperlinks.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-06-30 08:11:33 UTC (rev 10377)
+++ trunk/docutils/HISTORY.rst 2026-07-13 11:13:03 UTC (rev 10378)
@@ -100,6 +100,8 @@
`references.ReportDanglingReferences` and
`references.ReportUnreferencedLinks`,
obsolete `references.DanglingReferences`.
+ - Add INFO system_message if a <target> cannot be propagated
+ to the next node.
* docutils/transforms/universal.py
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-06-30 08:11:33 UTC (rev 10377)
+++ trunk/docutils/docutils/transforms/references.py 2026-07-13 11:13:03 UTC (rev 10378)
@@ -78,6 +78,9 @@
if (next_node is None
or isinstance(next_node, (nodes.Invisible, nodes.Targetable))
and not isinstance(next_node, nodes.target)):
+ self.document.reporter.info(
+ f'Cannot propagate target "{" ".join(target["names"])}" '
+ 'to next element', base_node=target)
continue
next_node['ids'].extend(target['ids'])
next_node['names'].extend(target['names'])
Modified: trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2026-06-30 08:11:33 UTC (rev 10377)
+++ trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2026-07-13 11:13:03 UTC (rev 10378)
@@ -2399,6 +2399,9 @@
<system_message backrefs="problematic-1" ids="system-message-1" level="3" line="99" source="functional/input/data/standard.rst" type="ERROR">
<paragraph>
Undefined substitution referenced: "problematic".
+ <system_message level="1" line="159" source="functional/input/data/standard.rst" type="INFO">
+ <paragraph>
+ Cannot propagate target "target" to next element
<system_message backrefs="footnote-reference-8" ids="system-message-2" level="3" line="390" source="functional/input/data/standard.rst" type="ERROR">
<paragraph>
Unknown target name: "5".
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-06-30 08:11:33 UTC (rev 10377)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-07-13 11:13:03 UTC (rev 10378)
@@ -569,6 +569,9 @@
Footnote; \n\
<reference refid="target">
target
+ <system_message level="1" line="1" source="test data" type="INFO">
+ <paragraph>
+ Cannot propagate target "target" to next element
"""],
["""\
.. _target:
@@ -585,6 +588,9 @@
Citation; \n\
<reference refid="target">
target
+ <system_message level="1" line="1" source="test data" type="INFO">
+ <paragraph>
+ Cannot propagate target "target" to next element
"""],
])
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-06-30 08:11:35
|
Revision: 10377
http://sourceforge.net/p/docutils/code/10377
Author: milde
Date: 2026-06-30 08:11:33 +0000 (Tue, 30 Jun 2026)
Log Message:
-----------
Make section-titles test sample less discombobulating.
The "section_titles.rst" functional test sample tests, among other things,
inline markup (including a reference) in a section title.
Move the sample refeference's target to a place where it makes some sense
instead of causing puzzlement. Adapt the tests using this sample.
Modified Paths:
--------------
trunk/docutils/test/functional/expected/latex_cornercases.tex
trunk/docutils/test/functional/expected/misc_rst_html4css1.html
trunk/docutils/test/functional/expected/misc_rst_html5.html
trunk/docutils/test/functional/input/data/section_titles.rst
Modified: trunk/docutils/test/functional/expected/latex_cornercases.tex
===================================================================
--- trunk/docutils/test/functional/expected/latex_cornercases.tex 2026-06-29 14:03:43 UTC (rev 10376)
+++ trunk/docutils/test/functional/expected/latex_cornercases.tex 2026-06-30 08:11:33 UTC (rev 10377)
@@ -227,9 +227,7 @@
Unsupported in ODT.
-\section{Section titles with inline markup%
- \label{references}%
-}
+\section{Section titles with inline markup}
\subsection{\emph{emphasized}, H\textsubscript{2}O, $x^2$, and \hyperref[references]{references}}
@@ -239,6 +237,7 @@
\label{substitutions-fail}%
}
+\phantomsection\label{references}
Note, that the \textquotedbl{}reference name\textquotedbl{} for this section is derived from the
content \emph{before} substitution. You can link to it with the \href{https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html\#hyperlink-references}{phrase
reference} \textquotedbl{}\hyperref[substitutions-fail]{substitutions fail}\textquotedbl{}.
Modified: trunk/docutils/test/functional/expected/misc_rst_html4css1.html
===================================================================
--- trunk/docutils/test/functional/expected/misc_rst_html4css1.html 2026-06-29 14:03:43 UTC (rev 10376)
+++ trunk/docutils/test/functional/expected/misc_rst_html4css1.html 2026-06-30 08:11:33 UTC (rev 10377)
@@ -50,7 +50,6 @@
</div>
</div>
<div class="section" id="section-titles-with-inline-markup">
-<span id="references"></span>
<h1>Section titles with inline markup</h1>
<div class="section" id="emphasized-h2o-x-2-and-references">
<h2><em>emphasized</em>, H<sub>2</sub>O, <span class="formula"><i>x</i><sup>2</sup></span>, and <a class="reference internal" href="#references">references</a></h2>
@@ -57,7 +56,7 @@
</div>
<div class="section" id="substitutions-fail">
<h2>Substitutions work</h2>
-<p>Note, that the "reference name" for this section is derived from the
+<p id="references">Note, that the "reference name" for this section is derived from the
content <em>before</em> substitution. You can link to it with the <a class="reference external" href="https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#hyperlink-references">phrase
reference</a> "<a class="reference internal" href="#substitutions-fail">substitutions fail</a>".
This behaviour may be exploited to get intelligible IDs after <a class="reference external" href="https://docutils.sourceforge.io/docs/ref/rst/directives.html#identifier-normalization">identifier
Modified: trunk/docutils/test/functional/expected/misc_rst_html5.html
===================================================================
--- trunk/docutils/test/functional/expected/misc_rst_html5.html 2026-06-29 14:03:43 UTC (rev 10376)
+++ trunk/docutils/test/functional/expected/misc_rst_html5.html 2026-06-30 08:11:33 UTC (rev 10377)
@@ -97,8 +97,7 @@
</section>
</section>
<section id="section-titles-with-inline-markup">
-<span id="references"></span>
-<h2><a class="toc-backref" href="#contents" role="doc-backlink">Section titles with inline markup</a><a class="self-link" title="link to this section" href="#references"></a></h2>
+<h2><a class="toc-backref" href="#contents" role="doc-backlink">Section titles with inline markup</a><a class="self-link" title="link to this section" href="#section-titles-with-inline-markup"></a></h2>
<section id="emphasized-h2o-x-2-and-references">
<h3><em>emphasized</em>, H<sub>2</sub>O, <math xmlns="http://www.w3.org/1998/Math/MathML">
<msup>
@@ -109,7 +108,7 @@
</section>
<section id="substitutions-fail">
<h3><a class="toc-backref" href="#contents" role="doc-backlink">Substitutions work</a><a class="self-link" title="link to this section" href="#substitutions-fail"></a></h3>
-<p>Note, that the “reference name” for this section is derived from the
+<p id="references">Note, that the “reference name” for this section is derived from the
content <em>before</em> substitution. You can link to it with the <a class="reference external" href="https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#hyperlink-references">phrase
reference</a> “<a class="reference internal" href="#substitutions-fail">substitutions fail</a>”.
This behaviour may be exploited to get intelligible IDs after <a class="reference external" href="https://docutils.sourceforge.io/docs/ref/rst/directives.html#identifier-normalization">identifier
Modified: trunk/docutils/test/functional/input/data/section_titles.rst
===================================================================
--- trunk/docutils/test/functional/input/data/section_titles.rst 2026-06-29 14:03:43 UTC (rev 10376)
+++ trunk/docutils/test/functional/input/data/section_titles.rst 2026-06-30 08:11:33 UTC (rev 10377)
@@ -34,7 +34,6 @@
<<<<<<<
Unsupported in ODT.
-.. _references:
Section titles with inline markup
==================================
@@ -46,6 +45,8 @@
--------------------
.. |fail| replace:: work
+.. _references:
+
Note, that the "reference name" for this section is derived from the
content *before* substitution. You can link to it with the `phrase
reference`_ "`substitutions fail`_".
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-06-29 14:03:46
|
Revision: 10376
http://sourceforge.net/p/docutils/code/10376
Author: milde
Date: 2026-06-29 14:03:43 +0000 (Mon, 29 Jun 2026)
Log Message:
-----------
Improve warning for figures without caption.
Move details to a separate paragraph (not shown in console output).
Add hint to cheat with an empty comment in place of the caption.
Note: When cheating with an empty comment, the `<figure>` element
remains invalid (but most writers can handle this).
Fixup for [r10370].
Modified Paths:
--------------
trunk/docutils/docutils/parsers/rst/directives/images.py
trunk/docutils/test/test_parsers/test_rst/test_directives/test_figures.py
trunk/docutils/test/test_writers/test_html4css1.py
trunk/docutils/test/test_writers/test_html5_polyglot.py
Modified: trunk/docutils/docutils/parsers/rst/directives/images.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/directives/images.py 2026-06-27 17:26:02 UTC (rev 10375)
+++ trunk/docutils/docutils/parsers/rst/directives/images.py 2026-06-29 14:03:43 UTC (rev 10376)
@@ -156,8 +156,10 @@
if align:
figure_node['align'] = align
if not self.content:
- msg = self.reporter.warning('Figure without caption and legend. '
- 'Use "image"?', line=self.lineno)
+ msg = self.reporter.warning('Figure without caption and legend.',
+ line=self.lineno)
+ msg.append(nodes.paragraph('', 'Try the "image" directive '
+ '(or cheat with an empty comment).'))
return [figure_node, msg]
else:
# optional caption (single paragraph or empty comment)
Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_figures.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_directives/test_figures.py 2026-06-27 17:26:02 UTC (rev 10375)
+++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_figures.py 2026-06-29 14:03:43 UTC (rev 10376)
@@ -51,7 +51,9 @@
<image uri="picture.png">
<system_message level="2" line="1" source="test data" type="WARNING">
<paragraph>
- Figure without caption and legend. Use "image"?
+ Figure without caption and legend.
+ <paragraph>
+ Try the "image" directive (or cheat with an empty comment).
"""],
["""\
.. figure:: picture.png
@@ -330,7 +332,9 @@
<image uri="picture.png">
<system_message level="2" line="15" source="test data" type="WARNING">
<paragraph>
- Figure without caption and legend. Use "image"?
+ Figure without caption and legend.
+ <paragraph>
+ Try the "image" directive (or cheat with an empty comment).
<figure>
<image uri="picture.png">
<figure>
@@ -347,7 +351,9 @@
<image uri="picture.png">
<system_message level="2" line="34" source="test data" type="WARNING">
<paragraph>
- Figure without caption and legend. Use "image"?
+ Figure without caption and legend.
+ <paragraph>
+ Try the "image" directive (or cheat with an empty comment).
"""],
]
Modified: trunk/docutils/test/test_writers/test_html4css1.py
===================================================================
--- trunk/docutils/test/test_writers/test_html4css1.py 2026-06-27 17:26:02 UTC (rev 10375)
+++ trunk/docutils/test/test_writers/test_html4css1.py 2026-06-29 14:03:43 UTC (rev 10376)
@@ -364,7 +364,9 @@
</div>
<div class="system-message">
<p class="system-message-title">System Message: WARNING/2 (<tt class="docutils"><string></tt>, line 1)</p>
-Figure without caption and legend. Use "image"?</div>
+<p>Figure without caption and legend.</p>
+<p>Try the "image" directive (or cheat with an empty comment).</p>
+</div>
<p>No caption nor legend.</p>
""",
],
Modified: trunk/docutils/test/test_writers/test_html5_polyglot.py
===================================================================
--- trunk/docutils/test/test_writers/test_html5_polyglot.py 2026-06-27 17:26:02 UTC (rev 10375)
+++ trunk/docutils/test/test_writers/test_html5_polyglot.py 2026-06-29 14:03:43 UTC (rev 10376)
@@ -391,7 +391,8 @@
</figure>
<aside class="system-message">
<p class="system-message-title">System Message: WARNING/2 (<span class="docutils literal"><string></span>, line 1)</p>
-<p>Figure without caption and legend. Use "image"?</p>
+<p>Figure without caption and legend.</p>
+<p>Try the "image" directive (or cheat with an empty comment).</p>
</aside>
<p>No caption nor legend.</p>
""",
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-06-27 17:26:05
|
Revision: 10375
http://sourceforge.net/p/docutils/code/10375
Author: milde
Date: 2026-06-27 17:26:02 +0000 (Sat, 27 Jun 2026)
Log Message:
-----------
Revise `SettingsSpec` definitions.
Use more consistent style.
A `frontend.validate_boolean` validator is required for boolean settings
(converts config file entries to True/False).
It does not need to be specified again in the "reverse-option" for the same
setting variable.
Modified Paths:
--------------
trunk/docutils/docutils/frontend.py
trunk/docutils/docutils/parsers/__init__.py
trunk/docutils/docutils/parsers/rst/__init__.py
trunk/docutils/docutils/writers/_html_base.py
trunk/docutils/docutils/writers/docutils_xml.py
trunk/docutils/docutils/writers/html5_polyglot/__init__.py
trunk/docutils/docutils/writers/latex2e/__init__.py
Modified: trunk/docutils/docutils/frontend.py
===================================================================
--- trunk/docutils/docutils/frontend.py 2026-06-27 17:25:52 UTC (rev 10374)
+++ trunk/docutils/docutils/frontend.py 2026-06-27 17:26:02 UTC (rev 10375)
@@ -686,32 +686,33 @@
'General Docutils Options',
None,
(('Output destination name. (default: stdout)',
- ['--output', '-o'], {'metavar': '<destination>',
- 'dest': 'output_path'}),
+ ['--output', '-o'],
+ {'dest': 'output_path', 'metavar': '<destination>'}),
('Specify the document title as metadata.',
['--title'], {'metavar': '<title>'}),
('Include a "Generated by Docutils" credit and link.',
- ['--generator', '-g'], {'action': 'store_true',
- 'validator': validate_boolean}),
+ ['--generator', '-g'],
+ {'action': 'store_true', 'validator': validate_boolean}),
('Do not include a generator credit.',
- ['--no-generator'], {'action': 'store_false', 'dest': 'generator'}),
+ ['--no-generator'],
+ {'dest': 'generator', 'action': 'store_false'}),
('Include the date at the end of the document (UTC).',
- ['--date', '-d'], {'action': 'store_const', 'const': '%Y-%m-%d',
- 'dest': 'datestamp'}),
+ ['--date', '-d'],
+ {'dest': 'datestamp', 'action': 'store_const', 'const': '%Y-%m-%d'}),
('Include the time & date (UTC).',
- ['--time', '-t'], {'action': 'store_const',
- 'const': '%Y-%m-%d %H:%M UTC',
- 'dest': 'datestamp'}),
+ ['--time', '-t'],
+ {'dest': 'datestamp', 'action': 'store_const',
+ 'const': '%Y-%m-%d %H:%M UTC'}),
('Do not include a datestamp of any kind.',
- ['--no-datestamp'], {'action': 'store_const', 'const': None,
- 'dest': 'datestamp'}),
+ ['--no-datestamp'],
+ {'dest': 'datestamp', 'action': 'store_const', 'const': None}),
('Base directory for absolute paths when reading '
'from the local filesystem. (default: "")',
['--root-prefix'],
{'default': '', 'metavar': '<path>'}),
('Include a "View document source" link.',
- ['--source-link', '-s'], {'action': 'store_true',
- 'validator': validate_boolean}),
+ ['--source-link', '-s'],
+ {'action': 'store_true', 'validator': validate_boolean}),
('Use <URL> for a source link; implies --source-link.',
['--source-url'], {'metavar': '<URL>'}),
('Do not include a "View document source" link.',
@@ -737,66 +738,69 @@
{'dest': 'footnote_backlinks', 'action': 'store_false'}),
('Enable section numbering by Docutils. (default)',
['--section-numbering'],
- {'action': 'store_true', 'dest': 'sectnum_xform',
+ {'dest': 'sectnum_xform', 'action': 'store_true',
'default': True, 'validator': validate_boolean}),
('Disable section numbering by Docutils.',
['--no-section-numbering'],
- {'action': 'store_false', 'dest': 'sectnum_xform'}),
+ {'dest': 'sectnum_xform', 'action': 'store_false'}),
('Remove comment elements from the document tree.',
['--strip-comments'],
{'action': 'store_true', 'validator': validate_boolean}),
('Leave comment elements in the document tree. (default)',
['--leave-comments'],
- {'action': 'store_false', 'dest': 'strip_comments'}),
+ {'dest': 'strip_comments', 'action': 'store_false'}),
('Remove all elements with classes="<class>" from the document tree. '
'Warning: potentially dangerous; use with caution. '
'(multiple-use option.)',
['--strip-elements-with-class'],
- {'action': 'append', 'dest': 'strip_elements_with_classes',
+ {'dest': 'strip_elements_with_classes', 'action': 'append',
'metavar': '<class>', 'validator': validate_strip_class}),
('Remove all classes="<class>" attributes from elements in the '
'document tree. Warning: potentially dangerous; use with caution. '
'(multiple-use option.)',
['--strip-class'],
- {'action': 'append', 'dest': 'strip_classes',
+ {'dest': 'strip_classes', 'action': 'append',
'metavar': '<class>', 'validator': validate_strip_class}),
('Report system messages at or higher than <level>: "info" or "1", '
'"warning"/"2" (default), "error"/"3", "severe"/"4", "none"/"5"',
- ['--report', '-r'], {'choices': threshold_choices, 'default': 2,
- 'dest': 'report_level', 'metavar': '<level>',
- 'validator': validate_threshold}),
+ ['--report', '-r'],
+ {'dest': 'report_level', 'choices': threshold_choices, 'default': 2,
+ 'metavar': '<level>', 'validator': validate_threshold}),
('Report all system messages. (Same as "--report=1".)',
- ['--verbose', '-v'], {'action': 'store_const', 'const': 1,
- 'dest': 'report_level'}),
+ ['--verbose', '-v'],
+ {'dest': 'report_level', 'action': 'store_const', 'const': 1}),
('Report no system messages. (Same as "--report=5".)',
- ['--quiet', '-q'], {'action': 'store_const', 'const': 5,
- 'dest': 'report_level'}),
+ ['--quiet', '-q'],
+ {'dest': 'report_level', 'action': 'store_const', 'const': 5}),
('Halt execution at system messages at or above <level>. '
'Levels as in --report. Default: 4 (severe).',
- ['--halt'], {'choices': threshold_choices, 'dest': 'halt_level',
- 'default': 4, 'metavar': '<level>',
- 'validator': validate_threshold}),
+ ['--halt'],
+ {'dest': 'halt_level', 'choices': threshold_choices, 'default': 4,
+ 'metavar': '<level>', 'validator': validate_threshold}),
('Halt at the slightest problem. Same as "--halt=info".',
- ['--strict'], {'action': 'store_const', 'const': 1,
- 'dest': 'halt_level'}),
+ ['--strict'],
+ {'dest': 'halt_level', 'action': 'store_const', 'const': 1}),
('Enable a non-zero exit status for non-halting system messages at '
'or above <level>. Default: 5 (disabled).',
- ['--exit-status'], {'choices': threshold_choices,
- 'dest': 'exit_status_level',
- 'default': 5, 'metavar': '<level>',
- 'validator': validate_threshold}),
+ ['--exit-status'],
+ {'dest': 'exit_status_level', 'choices': threshold_choices,
+ 'default': 5,
+ 'metavar': '<level>', 'validator': validate_threshold}),
('Enable debug-level system messages and diagnostics.',
- ['--debug'], {'action': 'store_true',
- 'validator': validate_boolean}),
+ ['--debug'],
+ {'action': 'store_true', 'validator': validate_boolean}),
('Disable debug output. (default)',
- ['--no-debug'], {'action': 'store_false', 'dest': 'debug'}),
+ ['--no-debug'],
+ {'dest': 'debug', 'action': 'store_false'}),
('Send the output of system messages to <file>.',
- ['--warnings'], {'dest': 'warning_stream', 'metavar': '<file>'}),
+ ['--warnings'],
+ {'dest': 'warning_stream', 'metavar': '<file>'}),
('Enable Python tracebacks when Docutils is halted.',
- ['--traceback'], {'action': 'store_true', 'default': None,
- 'validator': validate_boolean}),
+ ['--traceback'],
+ {'action': 'store_true', 'validator': validate_boolean}),
('Disable Python tracebacks. (default)',
- ['--no-traceback'], {'dest': 'traceback', 'action': 'store_false'}),
+ ['--no-traceback'],
+ {'dest': 'traceback', 'action': 'store_false'}),
('Specify the encoding and optionally the '
'error handler of input text. (default: utf-8)',
['--input-encoding'],
@@ -820,19 +824,22 @@
{'default': default_error_encoding_error_handler,
'validator': validate_encoding_error_handler}),
('Specify the language (as BCP 47 language tag). (default: en)',
- ['--language', '-l'], {'dest': 'language_code', 'default': 'en',
- 'metavar': '<tag>'}),
+ ['--language', '-l'],
+ {'dest': 'language_code', 'metavar': '<tag>', 'default': 'en'}),
('Write output file dependencies to <file>.',
['--record-dependencies'],
{'metavar': '<file>', 'validator': validate_dependency_file,
- 'default': None}), # default set in Values class
+ 'default': None}), # default file set in Values class
('Read configuration settings from <file>, if it exists.',
- ['--config'], {'metavar': '<file>', 'type': 'string',
- 'action': 'callback', 'callback': read_config_file}),
+ ['--config'],
+ {'metavar': '<file>', 'type': 'string',
+ 'action': 'callback', 'callback': read_config_file}),
("Show this program's version number and exit.",
- ['--version', '-V'], {'action': 'version'}),
+ ['--version', '-V'],
+ {'action': 'version'}),
('Show this help message and exit.',
- ['--help', '-h'], {'action': 'help'}),
+ ['--help', '-h'],
+ {'action': 'help'}),
# Typically not useful for non-programmatical use:
(SUPPRESS_HELP, ['--id-prefix'], {'default': ''}),
(SUPPRESS_HELP, ['--auto-id-prefix'], {'default': '%'}),
@@ -843,7 +850,7 @@
(SUPPRESS_HELP, ['--dump-transforms'], {'action': 'store_true'}),
(SUPPRESS_HELP, ['--dump-pseudo-xml'], {'action': 'store_true'}),
(SUPPRESS_HELP, ['--expose-internal-attribute'],
- {'action': 'append', 'dest': 'expose_internals',
+ {'dest': 'expose_internals', 'action': 'append',
'validator': validate_colon_separated_string_list}),
(SUPPRESS_HELP, ['--strict-visitor'], {'action': 'store_true'}),
))
Modified: trunk/docutils/docutils/parsers/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/__init__.py 2026-06-27 17:25:52 UTC (rev 10374)
+++ trunk/docutils/docutils/parsers/__init__.py 2026-06-27 17:26:02 UTC (rev 10375)
@@ -29,9 +29,8 @@
(('Disable directives that insert the contents of an external file; '
'replaced with a "warning" system message.',
['--no-file-insertion'],
- {'action': 'store_false', 'default': True,
- 'dest': 'file_insertion_enabled',
- 'validator': frontend.validate_boolean}),
+ {'dest': 'file_insertion_enabled', 'action': 'store_false',
+ 'default': True, 'validator': frontend.validate_boolean}),
('Enable directives that insert the contents '
'of an external file. (default)',
['--file-insertion-enabled'],
@@ -39,7 +38,7 @@
('Disable the "raw" directive; '
'replaced with a "warning" system message.',
['--no-raw'],
- {'action': 'store_false', 'default': True, 'dest': 'raw_enabled',
+ {'dest': 'raw_enabled', 'action': 'store_false', 'default': True,
'validator': frontend.validate_boolean}),
('Enable the "raw" directive. (default)',
['--raw-enabled'],
@@ -50,20 +49,17 @@
'validator': frontend.validate_nonnegative_int}),
('Keep identifiers backwards compatible. (default)',
['--legacy-ids'],
- {'action': 'store_true',
- 'validator': frontend.validate_boolean,
- 'default': True}),
+ {'action': 'store_true', 'default': True,
+ 'validator': frontend.validate_boolean}),
('Explicit targets use identifiers matching the reference name.',
['--matching-ids'],
- {'action': 'store_false',
- 'dest': 'legacy_ids'}),
+ {'dest': 'legacy_ids', 'action': 'store_false'}),
('Validate the document tree after parsing.',
['--validate'],
- {'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true', 'validator': frontend.validate_boolean}),
('Do not validate the document tree. (default)',
['--no-validation'],
- {'action': 'store_false', 'dest': 'validate'}),
+ {'dest': 'validate', 'action': 'store_false'}),
)
)
component_type: Final = 'parser'
Modified: trunk/docutils/docutils/parsers/rst/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/__init__.py 2026-06-27 17:25:52 UTC (rev 10374)
+++ trunk/docutils/docutils/parsers/rst/__init__.py 2026-06-27 17:26:02 UTC (rev 10375)
@@ -116,7 +116,7 @@
{'action': 'store_true', 'validator': frontend.validate_boolean}),
('Leave spaces before footnote references.',
['--leave-footnote-reference-space'],
- {'action': 'store_false', 'dest': 'trim_footnote_reference_space'}),
+ {'dest': 'trim_footnote_reference_space', 'action': 'store_false'}),
('Token name set for parsing code with Pygments: one of '
'"long", "short", or "none" (no parsing). (default: "long")',
['--syntax-highlight'],
@@ -137,13 +137,13 @@
'Force character-level inline markup recognition with '
'"\\ " (backslash + space). (default)',
['--word-level-inline-markup'],
- {'action': 'store_false', 'dest': 'character_level_inline_markup'}),
+ {'dest': 'character_level_inline_markup', 'action': 'store_false',
+ 'validator': frontend.validate_boolean}),
('Inline markup recognized anywhere, regardless of surrounding '
'characters. Backslash-escapes must be used to avoid unwanted '
'markup recognition. Useful for East Asian languages. ',
['--character-level-inline-markup'],
- {'action': 'store_true', 'default': False,
- 'dest': 'character_level_inline_markup'}),
+ {'action': 'store_true'}),
)
)
Modified: trunk/docutils/docutils/writers/_html_base.py
===================================================================
--- trunk/docutils/docutils/writers/_html_base.py 2026-06-27 17:25:52 UTC (rev 10374)
+++ trunk/docutils/docutils/writers/_html_base.py 2026-06-27 17:26:02 UTC (rev 10375)
@@ -128,8 +128,7 @@
'validator': frontend.validate_math_output}),
('Prepend an XML declaration. ',
['--xml-declaration'],
- {'default': False, 'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true', 'validator': frontend.validate_boolean}),
('Omit the XML declaration.',
['--no-xml-declaration'],
{'dest': 'xml_declaration', 'action': 'store_false'}),
Modified: trunk/docutils/docutils/writers/docutils_xml.py
===================================================================
--- trunk/docutils/docutils/writers/docutils_xml.py 2026-06-27 17:25:52 UTC (rev 10374)
+++ trunk/docutils/docutils/writers/docutils_xml.py 2026-06-27 17:26:02 UTC (rev 10375)
@@ -39,11 +39,11 @@
{'action': 'store_true', 'validator': frontend.validate_boolean}),
('Omit the XML declaration. Use with caution.',
['--no-xml-declaration'],
- {'dest': 'xml_declaration', 'default': 1, 'action': 'store_false',
+ {'dest': 'xml_declaration', 'default': True, 'action': 'store_false',
'validator': frontend.validate_boolean}),
('Omit the DOCTYPE declaration.',
['--no-doctype'],
- {'dest': 'doctype_declaration', 'default': 1,
+ {'dest': 'doctype_declaration', 'default': True,
'action': 'store_false', 'validator': frontend.validate_boolean}),))
settings_defaults = {'output_encoding_error_handler': 'xmlcharrefreplace'}
Modified: trunk/docutils/docutils/writers/html5_polyglot/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/html5_polyglot/__init__.py 2026-06-27 17:25:52 UTC (rev 10374)
+++ trunk/docutils/docutils/writers/html5_polyglot/__init__.py 2026-06-27 17:26:02 UTC (rev 10375)
@@ -99,7 +99,8 @@
}),
('Append a self-link to section headings. (default)',
['--section-self-link'],
- {'default': True, 'action': 'store_true'}),
+ {'default': True, 'action': 'store_true',
+ 'validator': frontend.validate_boolean}),
('Do not append a self-link to section headings.',
['--no-section-self-link'],
{'dest': 'section_self_link', 'action': 'store_false'}),
Modified: trunk/docutils/docutils/writers/latex2e/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/latex2e/__init__.py 2026-06-27 17:25:52 UTC (rev 10374)
+++ trunk/docutils/docutils/writers/latex2e/__init__.py 2026-06-27 17:26:02 UTC (rev 10375)
@@ -60,13 +60,12 @@
'overrides': 'trim_footnote_reference_space'}),
('Use \\cite command for citations. (default)',
['--use-latex-citations'],
- {'default': True, 'action': 'store_true',
+ {'action': 'store_true', 'default': True,
'validator': frontend.validate_boolean}),
('Use figure floats for citations '
'(might get mixed with real figures).',
['--figure-citations'],
- {'dest': 'use_latex_citations', 'action': 'store_false',
- 'validator': frontend.validate_boolean}),
+ {'dest': 'use_latex_citations', 'action': 'store_false'}),
('Format for block quote attributions: one of "dash" (em-dash '
'prefix), "parentheses"/"parens", or "none". (default: "dash")',
['--attribution'],
@@ -89,19 +88,18 @@
'validator': frontend.validate_comma_separated_list}),
('Link to the stylesheet(s) in the output file. (default)',
['--link-stylesheet'],
- {'dest': 'embed_stylesheet', 'action': 'store_false'}),
+ {'dest': 'embed_stylesheet', 'action': 'store_false',
+ 'validator': frontend.validate_boolean}),
('Embed the stylesheet(s) in the output file. '
'Stylesheets must be accessible during processing. ',
['--embed-stylesheet'],
- {'default': False, 'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true'}),
('Comma-separated list of directories where stylesheets are found. '
'Used by --stylesheet-path when expanding relative path arguments. '
'(default: ".")',
['--stylesheet-dirs'],
- {'metavar': '<dir[,dir,...]>',
- 'validator': frontend.validate_comma_separated_list,
- 'default': ['.']}),
+ {'metavar': '<dir[,dir,...]>', 'default': ['.'],
+ 'validator': frontend.validate_comma_separated_list}),
('Customization by LaTeX code in the preamble. '
'Default: select PDF standard fonts (Times, Helvetica, Courier).',
['--latex-preamble'],
@@ -111,16 +109,14 @@
{'default': default_template, 'metavar': '<file>'}),
('Table of contents by LaTeX. (default)',
['--use-latex-toc'],
- {'default': True, 'action': 'store_true',
+ {'action': 'store_true', 'default': True,
'validator': frontend.validate_boolean}),
('Table of contents by Docutils (without page numbers).',
['--use-docutils-toc'],
- {'dest': 'use_latex_toc', 'action': 'store_false',
- 'validator': frontend.validate_boolean}),
+ {'dest': 'use_latex_toc', 'action': 'store_false'}),
('Add parts on top of the section hierarchy.',
['--use-part-section'],
- {'default': False, 'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true', 'validator': frontend.validate_boolean}),
('Attach author and date to the document info table. (default)',
['--use-docutils-docinfo'],
{'dest': 'use_latex_docinfo', 'action': 'store_false',
@@ -127,8 +123,7 @@
'validator': frontend.validate_boolean}),
('Attach author and date to the document title.',
['--use-latex-docinfo'],
- {'default': False, 'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true'}),
("Typeset abstract as topic. (default)",
['--topic-abstract'],
{'dest': 'use_latex_abstract', 'action': 'store_false',
@@ -135,8 +130,7 @@
'validator': frontend.validate_boolean}),
("Use LaTeX abstract environment for the document's abstract.",
['--use-latex-abstract'],
- {'default': False, 'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true'}),
('Color of any hyperlinks embedded in text. '
'Default: "blue" (use "false" to disable).',
['--hyperlink-color'],
@@ -147,20 +141,18 @@
('Enable compound enumerators for nested enumerated lists '
'(e.g. "1.2.a.ii").',
['--compound-enumerators'],
- {'default': False, 'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true', 'validator': frontend.validate_boolean}),
('Disable compound enumerators for nested enumerated lists. '
'(default)',
['--no-compound-enumerators'],
- {'action': 'store_false', 'dest': 'compound_enumerators'}),
+ {'dest': 'compound_enumerators', 'action': 'store_false'}),
('Enable section ("." subsection ...) prefixes for compound '
'enumerators. This has no effect without --compound-enumerators.',
['--section-prefix-for-enumerators'],
- {'default': None, 'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true', 'validator': frontend.validate_boolean}),
('Disable section prefixes for compound enumerators. (default)',
['--no-section-prefix-for-enumerators'],
- {'action': 'store_false', 'dest': 'section_prefix_for_enumerators'}),
+ {'dest': 'section_prefix_for_enumerators', 'action': 'store_false'}),
('Set the separator between section number and enumerator '
'for compound enumerated lists. (default: "-")',
['--section-enumerator-separator'],
@@ -171,8 +163,7 @@
{'metavar': '<environment>', 'default': ''}),
(frontend.SUPPRESS_HELP, # deprecated legacy option
['--use-verbatim-when-possible'],
- {'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true', 'validator': frontend.validate_boolean}),
('Table style. "standard" with horizontal and vertical lines, '
'"booktabs" (LaTeX booktabs style) only horizontal lines '
'above and below the table and below the header, or "borderless". '
@@ -205,35 +196,24 @@
('Use legacy functions with class value list for '
'\\DUtitle and \\DUadmonition.',
['--legacy-class-functions'],
- {'default': False,
- 'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true', 'validator': frontend.validate_boolean}),
('Use \\DUrole and "DUclass" wrappers for class values. '
'Place admonition content in an environment. (default)',
['--new-class-functions'],
- {'dest': 'legacy_class_functions',
- 'action': 'store_false',
- 'validator': frontend.validate_boolean}),
+ {'dest': 'legacy_class_functions', 'action': 'store_false'}),
('Use legacy algorithm to determine table column widths. ',
['--legacy-column-widths'],
- {'default': False,
- 'action': 'store_true',
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true', 'validator': frontend.validate_boolean}),
('Use new algorithm to determine table column widths. (default)',
['--new-column-widths'],
- {'dest': 'legacy_column_widths',
- 'action': 'store_false',
- 'validator': frontend.validate_boolean}),
+ {'dest': 'legacy_column_widths', 'action': 'store_false'}),
('Footnotes with numbers/symbols by Docutils. (default)',
['--docutils-footnotes'],
- {'dest': 'latex_footnotes',
- 'action': 'store_false',
+ {'dest': 'latex_footnotes', 'action': 'store_false',
'validator': frontend.validate_boolean}),
('Footnotes with numbers by LaTeX.',
['--latex-footnotes'],
- {'action': 'store_true',
- 'default': False,
- 'validator': frontend.validate_boolean}),
+ {'action': 'store_true', 'default': False}),
),
)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-06-27 17:25:55
|
Revision: 10374
http://sourceforge.net/p/docutils/code/10374
Author: milde
Date: 2026-06-27 17:25:52 +0000 (Sat, 27 Jun 2026)
Log Message:
-----------
Update command-line help.
Use more consistent style.
After 10 years, character_level_inline_markup is no longer "experimental".
Modified Paths:
--------------
trunk/docutils/docutils/frontend.py
trunk/docutils/docutils/parsers/__init__.py
trunk/docutils/docutils/parsers/rst/__init__.py
trunk/docutils/docutils/writers/latex2e/__init__.py
trunk/docutils/test/data/help/docutils.rst
trunk/docutils/test/data/help/rst2html.rst
trunk/docutils/test/data/help/rst2latex.rst
Modified: trunk/docutils/docutils/frontend.py
===================================================================
--- trunk/docutils/docutils/frontend.py 2026-06-27 17:25:07 UTC (rev 10373)
+++ trunk/docutils/docutils/frontend.py 2026-06-27 17:25:52 UTC (rev 10374)
@@ -685,7 +685,7 @@
settings_spec = (
'General Docutils Options',
None,
- (('Output destination name. Default: None (stdout).',
+ (('Output destination name. (default: stdout)',
['--output', '-o'], {'metavar': '<destination>',
'dest': 'output_path'}),
('Specify the document title as metadata.',
@@ -706,7 +706,7 @@
['--no-datestamp'], {'action': 'store_const', 'const': None,
'dest': 'datestamp'}),
('Base directory for absolute paths when reading '
- 'from the local filesystem. Default "".',
+ 'from the local filesystem. (default: "")',
['--root-prefix'],
{'default': '', 'metavar': '<path>'}),
('Include a "View document source" link.',
@@ -750,13 +750,13 @@
{'action': 'store_false', 'dest': 'strip_comments'}),
('Remove all elements with classes="<class>" from the document tree. '
'Warning: potentially dangerous; use with caution. '
- '(Multiple-use option.)',
+ '(multiple-use option.)',
['--strip-elements-with-class'],
{'action': 'append', 'dest': 'strip_elements_with_classes',
'metavar': '<class>', 'validator': validate_strip_class}),
('Remove all classes="<class>" attributes from elements in the '
'document tree. Warning: potentially dangerous; use with caution. '
- '(Multiple-use option.)',
+ '(multiple-use option.)',
['--strip-class'],
{'action': 'append', 'dest': 'strip_classes',
'metavar': '<class>', 'validator': validate_strip_class}),
@@ -798,7 +798,7 @@
('Disable Python tracebacks. (default)',
['--no-traceback'], {'dest': 'traceback', 'action': 'store_false'}),
('Specify the encoding and optionally the '
- 'error handler of input text. Default: utf-8.',
+ 'error handler of input text. (default: utf-8)',
['--input-encoding'],
{'metavar': '<name[:handler]>', 'default': 'utf-8',
'validator': validate_encoding_and_error_handler}),
@@ -805,7 +805,7 @@
(SUPPRESS_HELP, ['--input-encoding-error-handler'],
{'default': 'strict', 'validator': validate_encoding_error_handler}),
('Specify the text encoding and optionally the error handler for '
- 'output. Default: utf-8.',
+ 'output. (default: utf-8)',
['--output-encoding'],
{'metavar': '<name[:handler]>', 'default': 'utf-8',
'validator': validate_encoding_and_error_handler}),
@@ -812,7 +812,7 @@
(SUPPRESS_HELP, ['--output-encoding-error-handler'],
{'default': 'strict', 'validator': validate_encoding_error_handler}),
('Specify text encoding and optionally the error handler'
- f' for error output. Default: {default_error_encoding}.',
+ f' for error output. (default: {default_error_encoding})',
['--error-encoding', '-e'],
{'metavar': '<name[:handler]>', 'default': default_error_encoding,
'validator': validate_encoding_and_error_handler}),
@@ -819,7 +819,7 @@
(SUPPRESS_HELP, ['--error-encoding-error-handler'],
{'default': default_error_encoding_error_handler,
'validator': validate_encoding_error_handler}),
- ('Specify the language (as BCP 47 language tag). Default: en.',
+ ('Specify the language (as BCP 47 language tag). (default: en)',
['--language', '-l'], {'dest': 'language_code', 'default': 'en',
'metavar': '<tag>'}),
('Write output file dependencies to <file>.',
Modified: trunk/docutils/docutils/parsers/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/__init__.py 2026-06-27 17:25:07 UTC (rev 10373)
+++ trunk/docutils/docutils/parsers/__init__.py 2026-06-27 17:25:52 UTC (rev 10374)
@@ -44,11 +44,11 @@
('Enable the "raw" directive. (default)',
['--raw-enabled'],
{'action': 'store_true'}),
- ('Maximal number of characters in an input line. Default 10 000.',
+ ('Maximal number of characters in an input line. (default 10 000)',
['--line-length-limit'],
{'metavar': '<length>', 'type': 'int', 'default': 10_000,
'validator': frontend.validate_nonnegative_int}),
- ('Keep identifiers backwards compatible. Default.',
+ ('Keep identifiers backwards compatible. (default)',
['--legacy-ids'],
{'action': 'store_true',
'validator': frontend.validate_boolean,
Modified: trunk/docutils/docutils/parsers/rst/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/__init__.py 2026-06-27 17:25:07 UTC (rev 10373)
+++ trunk/docutils/docutils/parsers/rst/__init__.py 2026-06-27 17:25:52 UTC (rev 10374)
@@ -118,12 +118,12 @@
['--leave-footnote-reference-space'],
{'action': 'store_false', 'dest': 'trim_footnote_reference_space'}),
('Token name set for parsing code with Pygments: one of '
- '"long", "short", or "none" (no parsing). Default is "long".',
+ '"long", "short", or "none" (no parsing). (default: "long")',
['--syntax-highlight'],
{'choices': ['long', 'short', 'none'],
'default': 'long', 'metavar': '<format>'}),
('Change straight quotation marks to typographic form: '
- 'one of "yes", "no", "alt[ernative]" (default "no").',
+ 'one of "yes", "no", "alt[ernative]". (default: "no")',
['--smart-quotes'],
{'default': False, 'metavar': '<yes/no/alt>',
'validator': frontend.validate_ternary}),
@@ -135,13 +135,12 @@
('Inline markup recognized at word boundaries only '
'(adjacent to punctuation or whitespace). '
'Force character-level inline markup recognition with '
- '"\\ " (backslash + space). Default.',
+ '"\\ " (backslash + space). (default)',
['--word-level-inline-markup'],
{'action': 'store_false', 'dest': 'character_level_inline_markup'}),
('Inline markup recognized anywhere, regardless of surrounding '
'characters. Backslash-escapes must be used to avoid unwanted '
- 'markup recognition. Useful for East Asian languages. '
- 'Experimental.',
+ 'markup recognition. Useful for East Asian languages. ',
['--character-level-inline-markup'],
{'action': 'store_true', 'default': False,
'dest': 'character_level_inline_markup'}),
Modified: trunk/docutils/docutils/writers/latex2e/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/latex2e/__init__.py 2026-06-27 17:25:07 UTC (rev 10373)
+++ trunk/docutils/docutils/writers/latex2e/__init__.py 2026-06-27 17:25:52 UTC (rev 10374)
@@ -45,15 +45,15 @@
settings_spec = (
'LaTeX-Specific Options',
None,
- (('Specify LaTeX documentclass. Default: "article".',
+ (('Specify LaTeX documentclass. (default: "article")',
['--documentclass'],
{'metavar': '<documentclass>', 'default': 'article'}),
('Specify document options. Multiple options can be given, '
- 'separated by commas. Default: "a4paper".',
+ 'separated by commas. (default: "a4paper")',
['--documentoptions'],
{'metavar': '<options>', 'default': 'a4paper'}),
('Format for footnote references: one of "superscript" or '
- '"brackets". Default: "superscript".',
+ '"brackets". (default: "superscript")',
['--footnote-references'],
{'choices': ['superscript', 'brackets'], 'default': 'superscript',
'metavar': '<format>',
@@ -68,7 +68,7 @@
{'dest': 'use_latex_citations', 'action': 'store_false',
'validator': frontend.validate_boolean}),
('Format for block quote attributions: one of "dash" (em-dash '
- 'prefix), "parentheses"/"parens", or "none". Default: "dash".',
+ 'prefix), "parentheses"/"parens", or "none". (default: "dash")',
['--attribution'],
{'choices': ['dash', 'parentheses', 'parens', 'none'],
'default': 'dash', 'metavar': '<format>'}),
@@ -96,8 +96,8 @@
{'default': False, 'action': 'store_true',
'validator': frontend.validate_boolean}),
('Comma-separated list of directories where stylesheets are found. '
- 'Used by --stylesheet-path when expanding relative path arguments. '
- 'Default: ".".',
+ 'Used by --stylesheet-path when expanding relative path arguments. '
+ '(default: ".")',
['--stylesheet-dirs'],
{'metavar': '<dir[,dir,...]>',
'validator': frontend.validate_comma_separated_list,
@@ -106,10 +106,10 @@
'Default: select PDF standard fonts (Times, Helvetica, Courier).',
['--latex-preamble'],
{'metavar': '<preamble>', 'default': default_preamble}),
- ('Specify the template file. Default: "%s".' % default_template,
+ (f'Specify the template file. (default: "{default_template}")',
['--template'],
{'default': default_template, 'metavar': '<file>'}),
- ('Table of contents by LaTeX. (default)',
+ ('Table of contents by LaTeX. (default)',
['--use-latex-toc'],
{'default': True, 'action': 'store_true',
'validator': frontend.validate_boolean}),
@@ -162,7 +162,7 @@
['--no-section-prefix-for-enumerators'],
{'action': 'store_false', 'dest': 'section_prefix_for_enumerators'}),
('Set the separator between section number and enumerator '
- 'for compound enumerated lists. Default: "-".',
+ 'for compound enumerated lists. (default: "-")',
['--section-enumerator-separator'],
{'default': '-', 'metavar': '<char>'}),
('When possible, use the specified environment for literal-blocks. '
@@ -175,8 +175,8 @@
'validator': frontend.validate_boolean}),
('Table style. "standard" with horizontal and vertical lines, '
'"booktabs" (LaTeX booktabs style) only horizontal lines '
- 'above and below the table and below the header, or "borderless". '
- 'Default: "standard"',
+ 'above and below the table and below the header, or "borderless". '
+ '(default: "standard")',
['--table-style'],
{'default': ['standard'],
'metavar': '<format>',
@@ -183,7 +183,7 @@
'action': 'append',
'validator': frontend.validate_comma_separated_list,
'choices': table_style_values}),
- ('LaTeX graphicx package option. Default: "".',
+ ('LaTeX graphicx package option. (default: "")',
['--graphicx-option'],
{'metavar': '<option>', 'default': ''}),
('LaTeX font encoding. '
Modified: trunk/docutils/test/data/help/docutils.rst
===================================================================
--- trunk/docutils/test/data/help/docutils.rst 2026-06-27 17:25:07 UTC (rev 10373)
+++ trunk/docutils/test/data/help/docutils.rst 2026-06-27 17:25:52 UTC (rev 10374)
@@ -12,7 +12,7 @@
General Docutils Options
------------------------
--output=<destination>, -o <destination>
- Output destination name. Default: None (stdout).
+ Output destination name. (default: stdout)
--title=<title> Specify the document title as metadata.
--generator, -g Include a "Generated by Docutils" credit and link.
--no-generator Do not include a generator credit.
@@ -20,7 +20,7 @@
--time, -t Include the time & date (UTC).
--no-datestamp Do not include a datestamp of any kind.
--root-prefix=<path> Base directory for absolute paths when reading from
- the local filesystem. Default "".
+ the local filesystem. (default: "")
--source-link, -s Include a "View document source" link.
--source-url=<URL> Use <URL> for a source link; implies --source-link.
--no-source-link Do not include a "View document source" link.
@@ -37,10 +37,10 @@
--strip-elements-with-class=<class>
Remove all elements with classes="<class>" from the
document tree. Warning: potentially dangerous; use
- with caution. (Multiple-use option.)
+ with caution. (multiple-use option.)
--strip-class=<class> Remove all classes="<class>" attributes from elements
in the document tree. Warning: potentially dangerous;
- use with caution. (Multiple-use option.)
+ use with caution. (multiple-use option.)
--report=<level>, -r <level>
Report system messages at or higher than <level>:
"info" or "1", "warning"/"2" (default), "error"/"3",
@@ -59,16 +59,16 @@
--no-traceback Disable Python tracebacks. (default)
--input-encoding=<name[:handler]>
Specify the encoding and optionally the error handler
- of input text. Default: utf-8.
+ of input text. (default: utf-8)
--output-encoding=<name[:handler]>
Specify the text encoding and optionally the error
- handler for output. Default: utf-8.
+ handler for output. (default: utf-8)
--error-encoding=<name[:handler]>, -e <name[:handler]>
Specify text encoding and optionally the error handler
- for error output. Default: utf-8.
+ for error output. (default: utf-8)
--language=<tag>, -l <tag>
Specify the language (as BCP 47 language tag).
- Default: en.
+ (default: en)
--record-dependencies=<file>
Write output file dependencies to <file>.
--config=<file> Read configuration settings from <file>, if it exists.
@@ -87,9 +87,9 @@
system message.
--raw-enabled Enable the "raw" directive. (default)
--line-length-limit=<length>
- Maximal number of characters in an input line. Default
- 10 000.
---legacy-ids Keep identifiers backwards compatible. Default.
+ Maximal number of characters in an input line.
+ (default 10 000)
+--legacy-ids Keep identifiers backwards compatible. (default)
--matching-ids Explicit targets use identifiers matching the
reference name.
--validate Validate the document tree after parsing.
@@ -115,11 +115,11 @@
Leave spaces before footnote references.
--syntax-highlight=<format>
Token name set for parsing code with Pygments: one of
- "long", "short", or "none" (no parsing). Default is
- "long".
+ "long", "short", or "none" (no parsing).
+ (default: "long")
--smart-quotes=<yes/no/alt>
Change straight quotation marks to typographic form:
- one of "yes", "no", "alt[ernative]" (default "no").
+ one of "yes", "no", "alt[ernative]". (default: "no")
--smartquotes-locales=<language:quotes[,language:quotes,...]>
Characters to use as "smart quotes" for <language>.
--word-level-inline-markup
@@ -126,12 +126,12 @@
Inline markup recognized at word boundaries only
(adjacent to punctuation or whitespace). Force
character-level inline markup recognition with "\ "
- (backslash + space). Default.
+ (backslash + space). (default)
--character-level-inline-markup
Inline markup recognized anywhere, regardless of
surrounding characters. Backslash-escapes must be used
to avoid unwanted markup recognition. Useful for East
- Asian languages. Experimental.
+ Asian languages.
Standalone Reader Options
-------------------------
Modified: trunk/docutils/test/data/help/rst2html.rst
===================================================================
--- trunk/docutils/test/data/help/rst2html.rst 2026-06-27 17:25:07 UTC (rev 10373)
+++ trunk/docutils/test/data/help/rst2html.rst 2026-06-27 17:25:52 UTC (rev 10374)
@@ -13,7 +13,7 @@
General Docutils Options
------------------------
--output=<destination>, -o <destination>
- Output destination name. Default: None (stdout).
+ Output destination name. (default: stdout)
--title=<title> Specify the document title as metadata.
--generator, -g Include a "Generated by Docutils" credit and link.
--no-generator Do not include a generator credit.
@@ -21,7 +21,7 @@
--time, -t Include the time & date (UTC).
--no-datestamp Do not include a datestamp of any kind.
--root-prefix=<path> Base directory for absolute paths when reading from
- the local filesystem. Default "".
+ the local filesystem. (default: "")
--source-link, -s Include a "View document source" link.
--source-url=<URL> Use <URL> for a source link; implies --source-link.
--no-source-link Do not include a "View document source" link.
@@ -38,10 +38,10 @@
--strip-elements-with-class=<class>
Remove all elements with classes="<class>" from the
document tree. Warning: potentially dangerous; use
- with caution. (Multiple-use option.)
+ with caution. (multiple-use option.)
--strip-class=<class> Remove all classes="<class>" attributes from elements
in the document tree. Warning: potentially dangerous;
- use with caution. (Multiple-use option.)
+ use with caution. (multiple-use option.)
--report=<level>, -r <level>
Report system messages at or higher than <level>:
"info" or "1", "warning"/"2" (default), "error"/"3",
@@ -60,16 +60,16 @@
--no-traceback Disable Python tracebacks. (default)
--input-encoding=<name[:handler]>
Specify the encoding and optionally the error handler
- of input text. Default: utf-8.
+ of input text. (default: utf-8)
--output-encoding=<name[:handler]>
Specify the text encoding and optionally the error
- handler for output. Default: utf-8.
+ handler for output. (default: utf-8)
--error-encoding=<name[:handler]>, -e <name[:handler]>
Specify text encoding and optionally the error handler
- for error output. Default: utf-8.
+ for error output. (default: utf-8)
--language=<tag>, -l <tag>
Specify the language (as BCP 47 language tag).
- Default: en.
+ (default: en)
--record-dependencies=<file>
Write output file dependencies to <file>.
--config=<file> Read configuration settings from <file>, if it exists.
@@ -88,9 +88,9 @@
system message.
--raw-enabled Enable the "raw" directive. (default)
--line-length-limit=<length>
- Maximal number of characters in an input line. Default
- 10 000.
---legacy-ids Keep identifiers backwards compatible. Default.
+ Maximal number of characters in an input line.
+ (default 10 000)
+--legacy-ids Keep identifiers backwards compatible. (default)
--matching-ids Explicit targets use identifiers matching the
reference name.
--validate Validate the document tree after parsing.
@@ -116,11 +116,11 @@
Leave spaces before footnote references.
--syntax-highlight=<format>
Token name set for parsing code with Pygments: one of
- "long", "short", or "none" (no parsing). Default is
- "long".
+ "long", "short", or "none" (no parsing).
+ (default: "long")
--smart-quotes=<yes/no/alt>
Change straight quotation marks to typographic form:
- one of "yes", "no", "alt[ernative]" (default "no").
+ one of "yes", "no", "alt[ernative]". (default: "no")
--smartquotes-locales=<language:quotes[,language:quotes,...]>
Characters to use as "smart quotes" for <language>.
--word-level-inline-markup
@@ -127,12 +127,12 @@
Inline markup recognized at word boundaries only
(adjacent to punctuation or whitespace). Force
character-level inline markup recognition with "\ "
- (backslash + space). Default.
+ (backslash + space). (default)
--character-level-inline-markup
Inline markup recognized anywhere, regardless of
surrounding characters. Backslash-escapes must be used
to avoid unwanted markup recognition. Useful for East
- Asian languages. Experimental.
+ Asian languages.
Standalone Reader Options
-------------------------
Modified: trunk/docutils/test/data/help/rst2latex.rst
===================================================================
--- trunk/docutils/test/data/help/rst2latex.rst 2026-06-27 17:25:07 UTC (rev 10373)
+++ trunk/docutils/test/data/help/rst2latex.rst 2026-06-27 17:25:52 UTC (rev 10374)
@@ -13,7 +13,7 @@
General Docutils Options
------------------------
--output=<destination>, -o <destination>
- Output destination name. Default: None (stdout).
+ Output destination name. (default: stdout)
--title=<title> Specify the document title as metadata.
--generator, -g Include a "Generated by Docutils" credit and link.
--no-generator Do not include a generator credit.
@@ -21,7 +21,7 @@
--time, -t Include the time & date (UTC).
--no-datestamp Do not include a datestamp of any kind.
--root-prefix=<path> Base directory for absolute paths when reading from
- the local filesystem. Default "".
+ the local filesystem. (default: "")
--source-link, -s Include a "View document source" link.
--source-url=<URL> Use <URL> for a source link; implies --source-link.
--no-source-link Do not include a "View document source" link.
@@ -38,10 +38,10 @@
--strip-elements-with-class=<class>
Remove all elements with classes="<class>" from the
document tree. Warning: potentially dangerous; use
- with caution. (Multiple-use option.)
+ with caution. (multiple-use option.)
--strip-class=<class> Remove all classes="<class>" attributes from elements
in the document tree. Warning: potentially dangerous;
- use with caution. (Multiple-use option.)
+ use with caution. (multiple-use option.)
--report=<level>, -r <level>
Report system messages at or higher than <level>:
"info" or "1", "warning"/"2" (default), "error"/"3",
@@ -60,16 +60,16 @@
--no-traceback Disable Python tracebacks. (default)
--input-encoding=<name[:handler]>
Specify the encoding and optionally the error handler
- of input text. Default: utf-8.
+ of input text. (default: utf-8)
--output-encoding=<name[:handler]>
Specify the text encoding and optionally the error
- handler for output. Default: utf-8.
+ handler for output. (default: utf-8)
--error-encoding=<name[:handler]>, -e <name[:handler]>
Specify text encoding and optionally the error handler
- for error output. Default: utf-8.
+ for error output. (default: utf-8)
--language=<tag>, -l <tag>
Specify the language (as BCP 47 language tag).
- Default: en.
+ (default: en)
--record-dependencies=<file>
Write output file dependencies to <file>.
--config=<file> Read configuration settings from <file>, if it exists.
@@ -88,9 +88,9 @@
system message.
--raw-enabled Enable the "raw" directive. (default)
--line-length-limit=<length>
- Maximal number of characters in an input line. Default
- 10 000.
---legacy-ids Keep identifiers backwards compatible. Default.
+ Maximal number of characters in an input line.
+ (default 10 000)
+--legacy-ids Keep identifiers backwards compatible. (default)
--matching-ids Explicit targets use identifiers matching the
reference name.
--validate Validate the document tree after parsing.
@@ -116,11 +116,11 @@
Leave spaces before footnote references.
--syntax-highlight=<format>
Token name set for parsing code with Pygments: one of
- "long", "short", or "none" (no parsing). Default is
- "long".
+ "long", "short", or "none" (no parsing).
+ (default: "long")
--smart-quotes=<yes/no/alt>
Change straight quotation marks to typographic form:
- one of "yes", "no", "alt[ernative]" (default "no").
+ one of "yes", "no", "alt[ernative]". (default: "no")
--smartquotes-locales=<language:quotes[,language:quotes,...]>
Characters to use as "smart quotes" for <language>.
--word-level-inline-markup
@@ -127,12 +127,12 @@
Inline markup recognized at word boundaries only
(adjacent to punctuation or whitespace). Force
character-level inline markup recognition with "\ "
- (backslash + space). Default.
+ (backslash + space). (default)
--character-level-inline-markup
Inline markup recognized anywhere, regardless of
surrounding characters. Backslash-escapes must be used
to avoid unwanted markup recognition. Useful for East
- Asian languages. Experimental.
+ Asian languages.
Standalone Reader Options
-------------------------
@@ -148,19 +148,19 @@
LaTeX-Specific Options
----------------------
--documentclass=<documentclass>
- Specify LaTeX documentclass. Default: "article".
+ Specify LaTeX documentclass. (default: "article")
--documentoptions=<options>
Specify document options. Multiple options can be
- given, separated by commas. Default: "a4paper".
+ given, separated by commas. (default: "a4paper")
--footnote-references=<format>
Format for footnote references: one of "superscript"
- or "brackets". Default: "superscript".
+ or "brackets". (default: "superscript")
--use-latex-citations Use \cite command for citations. (default)
--figure-citations Use figure floats for citations (might get mixed with
real figures).
--attribution=<format> Format for block quote attributions: one of "dash"
(em-dash prefix), "parentheses"/"parens", or "none".
- Default: "dash".
+ (default: "dash")
--stylesheet=<file[,file,...]>
Specify LaTeX packages/stylesheets. A style is
referenced with "\usepackage" if extension is ".sty"
@@ -179,12 +179,12 @@
--stylesheet-dirs=<dir[,dir,...]>
Comma-separated list of directories where stylesheets
are found. Used by --stylesheet-path when expanding
- relative path arguments. Default: ".".
+ relative path arguments. (default: ".")
--latex-preamble=<preamble>
Customization by LaTeX code in the preamble. Default:
select PDF standard fonts (Times, Helvetica, Courier).
---template=<file> Specify the template file. Default: "default.tex".
---use-latex-toc Table of contents by LaTeX. (default)
+--template=<file> Specify the template file. (default: "default.tex")
+--use-latex-toc Table of contents by LaTeX. (default)
--use-docutils-toc Table of contents by Docutils (without page numbers).
--use-part-section Add parts on top of the section hierarchy.
--use-docutils-docinfo Attach author and date to the document info table.
@@ -212,8 +212,8 @@
(default)
--section-enumerator-separator=<char>
Set the separator between section number and
- enumerator for compound enumerated lists. Default:
- "-".
+ enumerator for compound enumerated lists.
+ (default: "-")
--literal-block-env=<environment>
When possible, use the specified environment for
literal-blocks. Default: "" (fall back to "alltt").
@@ -220,9 +220,9 @@
--table-style=<format> Table style. "standard" with horizontal and vertical
lines, "booktabs" (LaTeX booktabs style) only
horizontal lines above and below the table and below
- the header, or "borderless". Default: "standard"
+ the header, or "borderless". (default: "standard")
--graphicx-option=<option>
- LaTeX graphicx package option. Default: "".
+ LaTeX graphicx package option. (default: "")
--font-encoding=<encoding>
LaTeX font encoding. Possible values are "", "T1"
(default), "OT1", "LGR,T1" or any other combination of
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|