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
(5) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <mi...@us...> - 2026-04-29 15:15:51
|
Revision: 10313
http://sourceforge.net/p/docutils/code/10313
Author: milde
Date: 2026-04-29 15:15:49 +0000 (Wed, 29 Apr 2026)
Log Message:
-----------
Documentation update.
Reword description of LaTeX writer changes.
Reword description of doctree element attributes.
doctree doc: Solve ID conflict of "footnote references" section
vs. "footnote_references" configuration setting.
Fix documentation of "raw_enabled" and "file_insertion_enabled" settings.
Remove non-working footnote styling example from LaTeX writer documentation.
Fix another non-working example.
Update "Citations" problem description in LaTeX writer documentation --
footnotes stopped using "figure floats" years ago.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/ref/doctree.rst
trunk/docutils/docs/ref/rst/restructuredtext.rst
trunk/docutils/docs/user/config.rst
trunk/docutils/docs/user/latex.rst
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-04-17 17:54:14 UTC (rev 10312)
+++ trunk/docutils/HISTORY.rst 2026-04-29 15:15:49 UTC (rev 10313)
@@ -88,8 +88,10 @@
* docutils/writers/latex2e/*
- - Default styling for "semantic inline markup roles" from the
- ``html-roles.txt`` standard definition file.
+ - Do not write ``\label`` commands for section titles and other
+ implicit targets if there is no matching reference in the document.
+ - Default styling for "semantic inline markup roles"
+ (cf. ``html-roles.txt`` standard definition file).
Release 0.22.4 (2025-12-18)
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-04-17 17:54:14 UTC (rev 10312)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-04-29 15:15:49 UTC (rev 10313)
@@ -305,11 +305,9 @@
__ docs/ref/rst/restructuredtext.html#explicit-hyperlink-targets
LaTeX writer:
- - Only write ``\label`` commands for explicit IDs and IDs that are
- referenced in the current document (i.e. not for un-referenced
- section titles).
- - Support the "semantic inline markup roles" from the ``html-roles.txt``
- `standard definition file`_.
+ - Do not write ``\label`` commands for section titles and other
+ implicit targets if there is no matching reference in the document.
+ - Support `semantic inline markup roles`_.
Configuration changes
- New setting `legacy_ids`_.
@@ -1617,6 +1615,8 @@
.. _"code" role: docs/ref/rst/roles.html#code
.. _standard definition file:
.. _standard definition files: docs/ref/rst/definitions.html
+.. _semantic inline markup roles:
+ docs/ref/rst/definitions.html#semantic-inline-markup-roles
.. _LaTeX syntax for mathematics: docs/ref/rst/mathematics.html
.. _configuration settings: docs/user/config.html
Modified: trunk/docutils/docs/ref/doctree.rst
===================================================================
--- trunk/docutils/docs/ref/doctree.rst 2026-04-17 17:54:14 UTC (rev 10312)
+++ trunk/docutils/docs/ref/doctree.rst 2026-04-29 15:15:49 UTC (rev 10313)
@@ -4541,11 +4541,13 @@
Python data type: ``bool``.
+.. _common attribute:
+
Common Attributes
=================
Through the `%basic.atts`_ parameter entity, all elements except `\<meta>`_
-support the attributes ids_, names_ or dupnames_, source_, and classes_.
+support the attributes classes_, dupnames_, ids_, names_, and source_.
---------------------
@@ -4760,9 +4762,9 @@
Attribute type: `%refnames.type`_. Default value: none.
-``dupnames`` replaces the `names`_ attribute when there has been
-a naming conflict.
-It is one of the `common attributes`_, shared by all Docutils elements.
+``dupnames`` is a `common attribute`_, shared by all Docutils elements.
+`Reference names`_ are moved from the `names`_ attribute to ``dupnames``
+in case of a naming conflict.
``enumtype``
@@ -4819,9 +4821,10 @@
Attribute type: `%ids.type`_. Default value: none.
-The ``ids`` attribute is a space separated list containing one or more
-unique `identifiers`_, typically assigned by the system.
-It is one of the `common attributes`_, shared by all Docutils elements.
+``ids`` is one of *two* attributes for element identification (the
+other is names_). It is a space separated list containing one or
+more unique `identifiers`_, typically assigned by the system.
+``ids`` is a `common attribute`_, shared by all Docutils elements.
An XPath_ expression to select the element with identifier `test` is ::
@@ -4935,23 +4938,22 @@
Attribute type: `%refnames.type`_. Default value: none.
-The ``names`` attribute is a space-separated list containing `reference
+``names`` is one of *two* attributes for element identification (the
+other is ids_). It is a space-separated list containing `reference
names`_ of an element (spaces inside a name are backslash-escaped).
-It is one of the `common attributes`_, shared by all Docutils elements.
+``names`` is a `common attribute`_, shared by all Docutils elements.
.. _reference name removal:
Each reference name must be unique in its namespace_;
-if there are name conflicts (two or more elements want to use the same
-name), the affected name will be transferred to the `dupnames`_ attribute on
-the duplicate element(s). The element can no longer be used as hyperlink
-target. [#]_
+if two or more elements want to use the same name, the affected name
+will be transferred to the `dupnames`_ attribute on the duplicate
+element(s) [#]_ and can no longer be used in hyperlinks. [#]_
-An element may have both ``names`` and ``dupnames`` attributes,
-if the ``dupnames`` are from conflicting `implicit hyperlink targets`_
-and the ``names`` from `explicit hyperlink targets`_ or a directive's
-`name option`_.
-
+.. [#] An element may have both ``names`` and ``dupnames`` attributes,
+ if the ``dupnames`` are from conflicting `implicit hyperlink targets`_
+ and the ``names`` from `explicit hyperlink targets`_ or a directive's
+ `name option`_.
.. [#] See `Implicit Hyperlink Targets`_ for details of conflict resolution.
Modified: trunk/docutils/docs/ref/rst/restructuredtext.rst
===================================================================
--- trunk/docutils/docs/ref/rst/restructuredtext.rst 2026-04-17 17:54:14 UTC (rev 10312)
+++ trunk/docutils/docs/ref/rst/restructuredtext.rst 2026-04-29 15:15:49 UTC (rev 10313)
@@ -1731,7 +1731,7 @@
`````````
:Doctree elements: `\<footnote>`_, `\<label>`_
-:Config settings: footnote_references_
+:Config settings: `footnote_references <footnote_references setting_>`__
:See also: `footnote references`_
Each footnote consists of an explicit markup start (:literal:`.. \ `),
@@ -2993,7 +2993,7 @@
:Doctree element: `\<footnote_reference>`_
:Start/End string: ``[`` ``]_``
-:Config settings: footnote_references_,
+:Config settings: `footnote_references <footnote_references setting_>`__
trim_footnote_reference_space_
:See also: footnotes_
@@ -3011,8 +3011,8 @@
footnote reference. To remove the whitespace from the output, use an
escaped whitespace character (see `Escaping Mechanism`_) or set the
trim_footnote_reference_space_ configuration setting.
-Leading whitespace is removed by default, if the footnote_references_
-setting is "superscript".
+Leading whitespace is removed by default, if the `footnote_references
+setting`_ is "superscript".
Citation References
@@ -3259,7 +3259,7 @@
.. _character_level_inline_markup:
../../user/config.html#character-level-inline-markup
-.. _footnote_references:
+.. _footnote_references setting:
../../user/config.html#footnote-references
.. _language_code: ../../user/config.html#language-code
.. _output encoding error handler:
Modified: trunk/docutils/docs/user/config.rst
===================================================================
--- trunk/docutils/docs/user/config.rst 2026-04-17 17:54:14 UTC (rev 10312)
+++ trunk/docutils/docs/user/config.rst 2026-04-29 15:15:49 UTC (rev 10313)
@@ -772,10 +772,12 @@
Enable directives inserting the contents of external files,
such as `"include"`_ directive or the `"raw"`_ and `"csv-table"`_
directives with option "url" or "file".
-A "warning" system message (including the directive text) is inserted
-instead. (See also raw_enabled_ for another security-relevant setting.)
-:Default: True.
+If disabled, a "warning" system message (including the directive text) is
+inserted instead. (See also raw_enabled_ for another security-relevant
+setting.)
+
+:Default: True (enabled).
:Options: ``--file-insertion-enabled``, ``--no-file-insertion``.
@@ -795,6 +797,7 @@
legacy_ids
----------
+
Keep element identifiers_ compatible to Docutils ≤ 0.22.
In case of a name conflict with an `implicit target`_ (section heading),
@@ -810,13 +813,16 @@
raw_enabled
-----------
-Enable the `"raw" directive`_. A "warning" system message
-(including the directive text) is inserted instead. See also
-file_insertion_enabled_ for another security-relevant setting.
+Enable the `"raw" directive`_.
-*Default*: True. *Options*: ``--raw-enabled``, ``--no-raw``.
+If disabled, a "warning" system message (including the directive text) is
+inserted instead. See also file_insertion_enabled_ for another
+security-relevant setting.
+:Default: True (enabled).
+:Options: ``--raw-enabled``, ``--no-raw``.
+
validate
--------
@@ -2040,6 +2046,7 @@
__ latex.html#document-title
__ latex.html#document-info
+
use_latex_toc
~~~~~~~~~~~~~
Let LaTeX generate the `table of contents`_. Generates a ToC with page numbers.
Modified: trunk/docutils/docs/user/latex.rst
===================================================================
--- trunk/docutils/docs/user/latex.rst 2026-04-17 17:54:14 UTC (rev 10312)
+++ trunk/docutils/docs/user/latex.rst 2026-04-29 15:15:49 UTC (rev 10313)
@@ -1096,19 +1096,6 @@
(play with the ``\footnotemargin`` setting),
- * redefine ``\DUfootnotetext`` inserting `\hangindent`::
-
- \newcommand{\DUfootnotetext}[4]{%
- \begingroup%
- \renewcommand{\thefootnote}{%
- \protect\raisebox{1em}{\protect\hypertarget{#1}{}}%
- \protect\hyperlink{#2}{#3}}%
- \footnotetext{\hangindent=2em #4}%
- \endgroup%
- }
-
- (adapt the ``\hangindent`` value).
-
Example 2:
Footnote marks in normal font size, not superscript::
@@ -1120,12 +1107,11 @@
Example 3:
Place the footnote text where it appears in the source document (instead
of at the page bottom). This can be used to get the effect of endnotes
- (needs the hanging_ package)::
+ (requires the hanging_ package)::
\usepackage{hanging}
\newcommand{\DUfootnotetext}[4]{%
- \par\noindent\raisebox{1em}{\hypertarget{#1}{}}%
- \hyperlink{#2}{#3}%
+ \par\noindent\phantomsection\label{#1}\hyperlink{#2}{#3}
\hangpara{\parindent}{1}#4%
}
@@ -2199,21 +2185,20 @@
.. _SourceForge Bug Tracker: https://sourceforge.net/p/docutils/bugs/
-Footnotes and citations
-```````````````````````
+Citations
+`````````
-Initially both were implemented using figure floats, because hyperlinking
+Initially citations were implemented using figure floats, because hyperlinking
back and forth seemed to be impossible. Later the `figure directive`_ was
added that puts images into figure floats.
-This results in footnotes, citations, and figures possibly being mixed at
-page foot.
+This results in citations and figures possibly being mixed at page foot.
-Workaround:
+Solution:
Select citation handling with the use_latex_citations_ setting.
-If ``use-latex-citations`` is used, a bibliography is inserted right at
-the end of the document. *This should be customizable*.
+If ``use_latex_citations`` is True, a bibliography is inserted right at
+the end of the document. *TODO: This should be customizable*.
If ``use-latex-citations`` is used adjacent citation references (separated
only by a single space or a newline) are combined to a single citation
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-04-17 17:54:16
|
Revision: 10312
http://sourceforge.net/p/docutils/code/10312
Author: milde
Date: 2026-04-17 17:54:14 +0000 (Fri, 17 Apr 2026)
Log Message:
-----------
Ensure and test backwards compatible auto-id-prefix behaviour.
Only derive IDs from duplicate names if the setting
"auto_id_prefix" ends in "%".
Sphinx still forces `auto_id_prefix = 'id"` and
`tests/test_intl/test_intl.py::test_xml_label_targets` failed
because an ID changed from "id1" to "explicit-target".
Add test cases for `auto_id_prefix = 'id"` and `legacy_ids = True`.
Modified Paths:
--------------
trunk/docutils/docutils/nodes.py
trunk/docutils/test/test_parsers/test_rst/test_targets.py
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-04-10 07:39:10 UTC (rev 10311)
+++ trunk/docutils/docutils/nodes.py 2026-04-17 17:54:14 UTC (rev 10312)
@@ -2023,7 +2023,8 @@
# disambiguate name-derived ID
# TODO: remove second condition after announcing change
prefix = id + '-'
- elif node['dupnames'] and make_id(node['dupnames'][0]):
+ elif (node['dupnames'] and auto_id_prefix.endswith('%')
+ and make_id(node['dupnames'][0])):
prefix = make_id(node['dupnames'][0]) + '-'
else:
prefix = id_prefix + auto_id_prefix
Modified: trunk/docutils/test/test_parsers/test_rst/test_targets.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-04-10 07:39:10 UTC (rev 10311)
+++ trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-04-17 17:54:14 UTC (rev 10312)
@@ -25,16 +25,19 @@
class ParserTestCase(unittest.TestCase):
maxDiff = None
+ mysettings = get_default_settings(Parser)
+ mysettings.legacy_ids = False # will become default in 2.0
+ mysettings.warning_stream = ''
def test_parser(self):
parser = Parser()
- settings = get_default_settings(Parser)
- settings.legacy_ids = False
- settings.warning_stream = ''
- for name, cases in totest.items():
+ for name, (settings_overrides, cases) in totest.items():
+ settings = self.mysettings.copy()
+ for k, v in settings_overrides.items():
+ setattr(settings, k, v)
for casenum, (case_input, case_expected) in enumerate(cases):
with self.subTest(id=f'totest[{name!r}][{casenum}]'):
- document = new_document('test data', settings.copy())
+ document = new_document('test data', settings)
parser.parse(case_input, document)
output = document.pformat()
self.assertEqual(case_expected, output)
@@ -42,7 +45,7 @@
totest = {}
-totest['targets'] = [
+totest['targets'] = ({}, [
["""\
.. _target:
@@ -523,10 +526,240 @@
<target ids="escaped-colon" names="escaped\\ colon:" refuri="OK">
<target ids="unescaped-colon-quoted" names="unescaped\\ colon,\\ quoted:" refuri="OK">
"""],
-]
+])
-totest['anonymous_targets'] = [
+
+# Backwards compatibiltiy IDs (default up to Docutils 2.0):
+totest['legacy-ids'] = ({'legacy_ids': True}, [
["""\
+Duplicate external targets (embedded/explicit, same URIs):
+
+See the `example <example.rst>`_
+
+See the example_
+
+.. _example: example.rst
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate external targets (embedded/explicit, same URIs):
+ <paragraph>
+ See the \n\
+ <reference name="example" refuri="example.rst">
+ example
+ <target ids="example" names="example" refuri="example.rst">
+ <paragraph>
+ See the \n\
+ <reference name="example" refname="example">
+ example
+ <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">
+"""],
+["""\
+Duplicate implicit targets.
+
+Title
+=====
+
+Paragraph.
+
+Title
+=====
+
+Paragraph.
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate implicit targets.
+ <section dupnames="title" ids="title">
+ <title>
+ Title
+ <paragraph>
+ Paragraph.
+ <section dupnames="title" ids="title-1">
+ <title>
+ Title
+ <system_message backrefs="title-1" level="1" line="9" source="test data" type="INFO">
+ <paragraph>
+ Duplicate implicit target name: "title".
+ <paragraph>
+ Paragraph.
+"""],
+["""\
+Duplicate implicit/explicit targets.
+
+Title
+=====
+
+.. _title:
+
+Paragraph.
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate implicit/explicit targets.
+ <section dupnames="title" ids="title">
+ <title>
+ Title
+ <system_message level="1" line="6" source="test data" type="INFO">
+ <paragraph>
+ Target name overrides implicit target name "title".
+ <target ids="title-1" names="title">
+ <paragraph>
+ Paragraph.
+"""],
+["""\
+Duplicate implicit/directive targets.
+
+Title
+=====
+
+.. note:: remember remember
+ :name: title
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate implicit/directive targets.
+ <section dupnames="title" ids="title">
+ <title>
+ Title
+ <note ids="title-1" names="title">
+ <system_message backrefs="title-1" level="1" line="7" source="test data" type="INFO">
+ <paragraph>
+ Target name overrides implicit target name "title".
+ <paragraph>
+ remember remember
+"""],
+["""\
+Duplicate explicit targets.
+
+.. _title:
+
+First.
+
+.. _title:
+
+Second.
+
+.. _title:
+
+Third.
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate explicit targets.
+ <target dupnames="title" ids="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">
+ <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">
+ <paragraph>
+ Third.
+"""],
+["""\
+Duplicate targets:
+
+Target
+======
+
+Implicit section header target.
+
+.. [TARGET] Citation target.
+
+.. [#target] Autonumber-labeled footnote target.
+
+.. _target:
+
+Explicit internal target.
+
+.. _target: Explicit_external_target
+
+| Do not insert <system_message> element for duplicate
+| _`target`, if this results in an invalid doctree.
+
+.. rubric:: directive with target
+ :name: Target
+
+:field list: with
+:_`target`: in a field name
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate targets:
+ <section dupnames="target" ids="target">
+ <title>
+ Target
+ <paragraph>
+ Implicit section header target.
+ <citation dupnames="target" ids="target-1">
+ <label>
+ TARGET
+ <system_message backrefs="target-1" level="1" line="8" source="test data" type="INFO">
+ <paragraph>
+ Target name overrides implicit target name "target".
+ <paragraph>
+ Citation target.
+ <footnote auto="1" dupnames="target" ids="target-2">
+ <system_message backrefs="target-2" level="2" line="10" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "target".
+ <paragraph>
+ Autonumber-labeled footnote target.
+ <system_message level="2" line="12" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "target".
+ <target dupnames="target" ids="target-3">
+ <paragraph>
+ Explicit internal target.
+ <system_message level="2" line="16" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "target".
+ <target dupnames="target" ids="target-4" refuri="Explicit_external_target">
+ <line_block>
+ <line>
+ Do not insert <system_message> element for duplicate
+ <line>
+ <target dupnames="target" ids="target-5">
+ target
+ , if this results in an invalid doctree.
+ <rubric dupnames="target" ids="target-6">
+ directive with target
+ <field_list>
+ <field>
+ <field_name>
+ field list
+ <field_body>
+ <paragraph>
+ with
+ <field>
+ <field_name>
+ <target dupnames="target" ids="target-7">
+ target
+ <field_body>
+ <paragraph>
+ in a field name
+"""],
+])
+
+
+totest['anonymous_targets'] = ({}, [
+["""\
Anonymous external hyperlink target:
.. __: http://w3c.org/
@@ -633,8 +866,346 @@
<comment xml:space="preserve">
_
"""],
-]
+])
+# keep stable IDs with legacy auto-ID setting (still default in Sphinx)
+totest['legacy auto-id prefix'] = ({'auto_id_prefix': 'id',
+ 'legacy_ids': True}, [
+["""\
+Duplicate external targets (different URIs):
+
+.. _target: first
+
+.. _target: second
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate external targets (different URIs):
+ <target dupnames="target" ids="target" refuri="first">
+ <system_message level="2" line="5" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "target".
+ <target dupnames="target" ids="id1" refuri="second">
+"""],
+["""\
+Duplicate external targets (same URIs):
+
+.. _target: first
+
+.. _target: first
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate external targets (same URIs):
+ <target ids="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="id1" refuri="first">
+"""],
+["""\
+Duplicate external targets (embedded/explicit, same URIs):
+
+See the `example <example.rst>`_
+
+See the example_
+
+.. _example: example.rst
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate external targets (embedded/explicit, same URIs):
+ <paragraph>
+ See the \n\
+ <reference name="example" refuri="example.rst">
+ example
+ <target ids="example" names="example" refuri="example.rst">
+ <paragraph>
+ See the \n\
+ <reference name="example" refname="example">
+ example
+ <system_message level="1" line="7" source="test data" type="INFO">
+ <paragraph>
+ Duplicate name "example" for external target "example.rst".
+ <target dupnames="example" ids="id1" refuri="example.rst">
+"""],
+["""\
+Duplicate indirect _`targets` (same refname):
+
+.. _link: targets_
+
+.. _link: targets_
+
+do not conflict. The reference name can be used in a link_.
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate indirect \n\
+ <target ids="targets" names="targets">
+ targets
+ (same refname):
+ <target ids="link" 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="id1" refname="targets">
+ <paragraph>
+ do not conflict. The reference name can be used in a \n\
+ <reference name="link" refname="link">
+ link
+ .
+"""],
+["""\
+Duplicate implicit targets.
+
+Title
+=====
+
+Paragraph.
+
+Title
+=====
+
+Paragraph.
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate implicit targets.
+ <section dupnames="title" ids="title">
+ <title>
+ Title
+ <paragraph>
+ Paragraph.
+ <section dupnames="title" ids="id1">
+ <title>
+ Title
+ <system_message backrefs="id1" level="1" line="9" source="test data" type="INFO">
+ <paragraph>
+ Duplicate implicit target name: "title".
+ <paragraph>
+ Paragraph.
+"""],
+["""\
+Duplicate implicit/explicit targets.
+
+Title
+=====
+
+.. _title:
+
+Paragraph.
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate implicit/explicit targets.
+ <section dupnames="title" ids="title">
+ <title>
+ Title
+ <system_message level="1" line="6" source="test data" type="INFO">
+ <paragraph>
+ Target name overrides implicit target name "title".
+ <target ids="id1" names="title">
+ <paragraph>
+ Paragraph.
+"""],
+["""\
+Duplicate implicit/directive targets.
+
+Title
+=====
+
+.. note:: remember remember
+ :name: title
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate implicit/directive targets.
+ <section dupnames="title" ids="title">
+ <title>
+ Title
+ <note ids="id1" names="title">
+ <system_message backrefs="id1" level="1" line="7" source="test data" type="INFO">
+ <paragraph>
+ Target name overrides implicit target name "title".
+ <paragraph>
+ remember remember
+"""],
+["""\
+Duplicate explicit targets.
+
+.. _title:
+
+First.
+
+.. _title:
+
+Second.
+
+.. _title:
+
+Third.
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate explicit targets.
+ <target dupnames="title" ids="title">
+ <paragraph>
+ First.
+ <system_message level="2" line="7" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "title".
+ <target dupnames="title" ids="id1">
+ <paragraph>
+ Second.
+ <system_message level="2" line="11" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "title".
+ <target dupnames="title" ids="id2">
+ <paragraph>
+ Third.
+"""],
+["""\
+Duplicate explicit/directive targets.
+
+.. _title:
+
+First.
+
+.. rubric:: this is a title too
+ :name: title
+
+The system message is left dangling
+(to be handled by the "universal.Messages" transform).
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate explicit/directive targets.
+ <target dupnames="title" ids="title">
+ <paragraph>
+ First.
+ <rubric dupnames="title" ids="id1">
+ this is a title too
+ <paragraph>
+ The system message is left dangling
+ (to be handled by the "universal.Messages" transform).
+"""],
+["""\
+Duplicate targets:
+
+Target
+======
+
+Implicit section header target.
+
+.. [TARGET] Citation target.
+
+.. [#target] Autonumber-labeled footnote target.
+
+.. _target:
+
+Explicit internal target.
+
+.. _target: Explicit_external_target
+
+| Do not insert <system_message> element for duplicate
+| _`target`, if this results in an invalid doctree.
+
+.. rubric:: directive with target
+ :name: Target
+
+:field list: with
+:_`target`: in a field name
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Duplicate targets:
+ <section dupnames="target" ids="target">
+ <title>
+ Target
+ <paragraph>
+ Implicit section header target.
+ <citation dupnames="target" ids="id1">
+ <label>
+ TARGET
+ <system_message backrefs="id1" level="1" line="8" source="test data" type="INFO">
+ <paragraph>
+ Target name overrides implicit target name "target".
+ <paragraph>
+ Citation target.
+ <footnote auto="1" dupnames="target" ids="id2">
+ <system_message backrefs="id2" level="2" line="10" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "target".
+ <paragraph>
+ Autonumber-labeled footnote target.
+ <system_message level="2" line="12" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "target".
+ <target dupnames="target" ids="id3">
+ <paragraph>
+ Explicit internal target.
+ <system_message level="2" line="16" source="test data" type="WARNING">
+ <paragraph>
+ Duplicate explicit target name: "target".
+ <target dupnames="target" ids="id4" refuri="Explicit_external_target">
+ <line_block>
+ <line>
+ Do not insert <system_message> element for duplicate
+ <line>
+ <target dupnames="target" ids="id5">
+ target
+ , if this results in an invalid doctree.
+ <rubric dupnames="target" ids="id6">
+ directive with target
+ <field_list>
+ <field>
+ <field_name>
+ field list
+ <field_body>
+ <paragraph>
+ with
+ <field>
+ <field_name>
+ <target dupnames="target" ids="id7">
+ target
+ <field_body>
+ <paragraph>
+ in a field name
+"""],
+["""\
+Anonymous external hyperlink target:
+
+__ http://w3c.org/
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Anonymous external hyperlink target:
+ <target anonymous="1" ids="id1" refuri="http://w3c.org/">
+"""],
+["""\
+Anonymous indirect hyperlink target:
+
+.. __: reference_
+""",
+"""\
+<document source="test data">
+ <paragraph>
+ Anonymous indirect hyperlink target:
+ <target anonymous="1" ids="id1" refname="reference">
+"""],
+])
+
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-04-10 07:39:11
|
Revision: 10311
http://sourceforge.net/p/docutils/code/10311
Author: milde
Date: 2026-04-10 07:39:10 +0000 (Fri, 10 Apr 2026)
Log Message:
-----------
Small documentation fixes.
Add an example for "auto-id-prefix" setting.
Decrease nesting level in section "Rejected Ideas" of EP 10.
Modified Paths:
--------------
trunk/docutils/docs/eps/ep-010.rst
trunk/docutils/docs/user/config.rst
Modified: trunk/docutils/docs/eps/ep-010.rst
===================================================================
--- trunk/docutils/docs/eps/ep-010.rst 2026-04-10 06:56:05 UTC (rev 10310)
+++ trunk/docutils/docs/eps/ep-010.rst 2026-04-10 07:39:10 UTC (rev 10311)
@@ -198,29 +198,29 @@
.. Why certain ideas that were brought while discussing this proposal were not
ultimately pursued.
-* Use type annotations as an indication of status in the public API.
+Use type annotations as an indication of status in the public API.
- - There is no known precedence for this approach.
- - Type annotations may be helpful also for non-public code.
+- There is no known precedence for this approach.
+- Type annotations may be helpful also for non-public code.
-* Use Calendar Versioning (CalVer).
+Use Calendar Versioning (CalVer).
- - Would be a break from current versioning without clear advantages.
+- Would be a break from current versioning without clear advantages.
-* Allow breaking API changes in *minor* versions after prior announcement
- and a deprecation period.
+Allow breaking API changes in *minor* versions after prior announcement
+and a deprecation period.
- - Breaks the principle of least surprise.
+- Breaks the principle of least surprise.
-* Mark all internal objects with a prefix underscore.
+Mark all internal objects with a prefix underscore.
- - May needlessly break applications using internal objects.
+- May needlessly break applications using internal objects.
-* Use the ``__all__`` attribute to declare modules, classes, and
- functions that form the public API.
+Use the ``__all__`` attribute to declare modules, classes, and
+functions that form the public API.
- - This may be done later to improve "pydoc" output, but should not hold
- up the declaration of a Backwards Compatibility Policy.
+- This may be done later to improve "pydoc" output, but should not hold
+ up the declaration of a Backwards Compatibility Policy.
Open Issues
Modified: trunk/docutils/docs/user/config.rst
===================================================================
--- trunk/docutils/docs/user/config.rst 2026-04-10 06:56:05 UTC (rev 10310)
+++ trunk/docutils/docs/user/config.rst 2026-04-10 07:39:10 UTC (rev 10311)
@@ -244,15 +244,15 @@
--------------
Prefix for identifiers_ of elements without a `reference name`_
-(after an eventual id_prefix_). The value is not subjected to
-the `identifier normalization`_ so users must ensure it conforms
-to the restrictions on identifiers in the output format.
+(after an eventual id_prefix_).
-A trailing "%" is replaced with the `Doctree element name`_;
-a number is added for disambiguation.
+The value is not subjected to the `identifier normalization`_ so users
+must ensure it conforms to the restrictions on identifiers in the output
+format. A trailing "%" is replaced with the Doctree_ element name;
+a number is added for disambiguation. With the default, the third
+`anonymous hyperlink target`_, for example, would get the ID "target-3".
-
-:Default: "%" (changed from "id" in Docutils 0.18).
+:Default: "%" (use Doctree element name; changed from "id" in Docutils 0.18).
:Option: ``--auto-id-prefix`` (hidden, intended mainly for programmatic use).
.. _identifier normalization:
@@ -2648,7 +2648,7 @@
.. _Docutils Document Tree:
.. _Docutils Generic document type definition:
.. _Document Tree: ../ref/doctree.html
-.. _Doctree element name: ../ref/doctree.html#element-reference
+.. _Doctree: ../ref/doctree.html
.. _class attribute: ../ref/doctree.html#classes
.. _identifiers: ../ref/doctree.html#identifiers
.. _reference name:
@@ -2690,6 +2690,8 @@
.. _table of contents: ../ref/rst/directives.html#table-of-contents
.. RestructuredText Markup Specification
+.. _anonymous hyperlink target:
+ ../ref/rst/restructuredtext.html#anonymous-hyperlinks
.. _auto-symbol footnotes:
../ref/rst/restructuredtext.html#auto-symbol-footnotes
.. _abstract:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-04-10 06:56:08
|
Revision: 10310
http://sourceforge.net/p/docutils/code/10310
Author: milde
Date: 2026-04-10 06:56:05 +0000 (Fri, 10 Apr 2026)
Log Message:
-----------
Amend documentation of the "identifier normalization".
Cf. [bugs:#518]
Modified Paths:
--------------
trunk/docutils/docs/ref/doctree.rst
trunk/docutils/docs/ref/rst/directives.rst
trunk/docutils/docs/user/config.rst
Modified: trunk/docutils/docs/ref/doctree.rst
===================================================================
--- trunk/docutils/docs/ref/doctree.rst 2026-04-09 14:35:52 UTC (rev 10309)
+++ trunk/docutils/docs/ref/doctree.rst 2026-04-10 06:56:05 UTC (rev 10310)
@@ -5759,29 +5759,17 @@
Identifiers are used in the ids_, refid_, and backrefs_ attributes
(`%ids.type`_, `%idref.type`_, or `%idrefs.type`_) [#id-vc]_.
- Docutils employs the `identifier normalization`_ to comply with
- restrictions in the supported output formats (HTML4.1__, HTML5__,
- `polyglot HTML`__, LaTeX__, ODT__, manpage, XML__).
-
Identifiers cannot be specified directly in reStructuredText.
- Docutils generates them from `reference names`_ or from the
- `"auto_id_prefix"`_ (prepending the `"id_prefix"`_ and
- appending numbers for disambiguation if required).
+ Docutils generates them from `reference names`_ (applying the
+ `identifier normalization`_ to comply with restrictions in the
+ supported output formats) or the `"auto_id_prefix"`_.
+ If specified, Docutils prepends the `"id_prefix"`_.
+ Numbers may be appended for disambiguation if required.
.. [#id-vc] The `Docutils Generic DTD`_ cannot use the ID, IDREF,
and IDREFS standard types because elements do not adhere
to the `One ID per Element Type`_ validity constraint.
- __ https://www.w3.org/TR/html401/types.html#type-name
- __ https://html.spec.whatwg.org/multipage/dom.html
- #global-attributes:the-id-attribute-2
- __ https://www.w3.org/TR/html-polyglot/#id-attribute
- __ https://tex.stackexchange.com/questions/18311/
- what-are-the-valid-names-as-labels
- __ https://help.libreoffice.org/6.3/en-US/text/swriter/01/04040000.html
- ?DbPAR=WRITER#bm_id4974211
- __ `XML attribute types`_
-
_`Phrasing content`
is text data that may be intermixed with `inline elements`_
(cf. the `%text.model`_ parameter entity).
@@ -5815,14 +5803,20 @@
.. _reference name:
_`Reference names`
- are identifiers assigned in the markup.
+ are assigned in the markup and used for internal cross-references and
+ as base of element identifiers_.
Reference names are used in the name_, names_, refname_, and dupnames_
attributes (`%refname.type`_ or `%refnames.type`_).
- Reference names may consist of any text.
- Whitespace is normalized. [#whitespace-normalization]_
+ Reference names may consist of any text,
+ whitespace is normalized. [#whitespace-normalization]_
+ (Identifiers_ have additional constraints.)
+ In reStructuredText, `reference names <rST reference names_>`__
+ originate from `internal hyperlink targets`_, a directive's `name
+ option`_, or the element's title or content.
+
.. _namespace:
Almost all elements in a document share a common *namespace*
@@ -5831,11 +5825,6 @@
elements use a distinct namespace with `case-sensitive but forgiving`_
matching of reference names.
- In reStructuredText, `reference names <rST reference names_>`__
- originate from `internal hyperlink targets`_, a directive's `name
- option`_, or the element's title or content and are used for internal
- cross-references.
-
.. [#whitespace-normalization] Adjacent spaces, horizontal or vertical
tabs, newlines, carriage returns, or form feeds, are replaced by a
single space. Leading and trailing whitespace is removed.
Modified: trunk/docutils/docs/ref/rst/directives.rst
===================================================================
--- trunk/docutils/docs/ref/rst/directives.rst 2026-04-09 14:35:52 UTC (rev 10309)
+++ trunk/docutils/docs/ref/rst/directives.rst 2026-04-10 06:56:05 UTC (rev 10310)
@@ -1910,11 +1910,13 @@
* trailing hyphens.
For example ``"Rot.Gelb&Grün::2008+"`` becomes ``"rot-gelb-grun-2008"`` and
-``"1000_Steps!"`` becomes ``"steps"``.
+``"1000_Steps!"`` becomes ``"steps"`` while both ``"2026-04-04"`` and
+``"λογος"`` become the empty string ``""`` (identifiers_ will use an
+auto-generated string instead).
.. topic:: Rationale:
- Identifier keys must be valid in all supported output formats.
+ Identifier keys must be valid in all supported output formats. [#]_
For HTML 4.1 + CSS1 compatibility, identifiers should have no
underscores, colons, or periods. Hyphens may be used.
@@ -1928,7 +1930,7 @@
-- https://www.w3.org/TR/html401/types.html#type-name
- - The `CSS1 spec`_ defines identifiers based on the "name" token
+ - The CSS1_ spec defines identifiers based on the "name" token
("flex" tokenizer notation below)::
unicode \\[0-9a-f]{1,4}
@@ -1946,6 +1948,19 @@
``[A-Za-z][-A-Za-z0-9]*``. Docutils adds a normalization by
downcasing and merge of consecutive hyphens.
+ .. [#] HTML4.1__, CSS1_, HTML5__, `polyglot HTML`__, LaTeX__, ODT__,
+ manpage, and XML__.
+
+ __ https://www.w3.org/TR/html401/types.html#type-name
+ __ https://html.spec.whatwg.org/multipage/dom.html
+ #global-attributes:the-id-attribute-2
+ __ https://www.w3.org/TR/html-polyglot/#id-attribute
+ __ https://tex.stackexchange.com/questions/18311/
+ what-are-the-valid-names-as-labels
+ __ https://help.libreoffice.org/6.3/en-US/text/swriter/01/04040000.html
+ ?DbPAR=WRITER#bm_id4974211
+ __ https://www.w3.org/TR/REC-xml/#sec-attribute-types
+
.. [#] CSS identifiers may use underscores ("_") directly in
`CSS Level 1`__, `CSS2.1`__, CSS2.2__, and CSS3__.
@@ -1955,7 +1970,7 @@
__ https://www.w3.org/TR/css-syntax-3/#typedef-ident-token
.. _HTML 4.01 spec: https://www.w3.org/TR/html401/
- .. _CSS1 spec: https://www.w3.org/TR/REC-CSS1
+ .. _CSS1: https://www.w3.org/TR/REC-CSS1
.. _role:
Modified: trunk/docutils/docs/user/config.rst
===================================================================
--- trunk/docutils/docs/user/config.rst 2026-04-09 14:35:52 UTC (rev 10309)
+++ trunk/docutils/docs/user/config.rst 2026-04-10 06:56:05 UTC (rev 10310)
@@ -243,13 +243,15 @@
auto_id_prefix
--------------
-Prefix prepended to all auto-generated `identifier keys` generated within
-the document, after id_prefix_. Ensure the value conforms to the
-restrictions on identifiers in the output format, as it is not subjected to
-the `identifier normalization`_.
+Prefix for identifiers_ of elements without a `reference name`_
+(after an eventual id_prefix_). The value is not subjected to
+the `identifier normalization`_ so users must ensure it conforms
+to the restrictions on identifiers in the output format.
-A trailing "%" is replaced with the tag name (new in Docutils 0.16).
+A trailing "%" is replaced with the `Doctree element name`_;
+a number is added for disambiguation.
+
:Default: "%" (changed from "id" in Docutils 0.18).
:Option: ``--auto-id-prefix`` (hidden, intended mainly for programmatic use).
@@ -409,11 +411,15 @@
id_prefix
---------
-Prefix prepended to all identifier keys generated within the document.
-Ensure the value conforms to the restrictions on identifiers in the output
-format, as it is not subjected to the `identifier normalization`_.
-See also auto_id_prefix_.
+Prefix prepended to all identifiers_. See also auto_id_prefix_.
+Use cases include tagging of all Docutils-generated element IDs and
+enabling leading numerals in `reference names`_ to pass the
+`identifier normalization`_.
+
+Users must ensure the value conforms to the restrictions on identifiers in
+the output format, as it is not subjected to the `identifier normalization`_.
+
:Default: "" (no prefix).
:Option: ``--id-prefix`` (hidden, intended mainly for programmatic use).
@@ -438,7 +444,7 @@
Raise an exception in case of an encoding error.
replace
Replace malformed data with the official Unicode replacement
- character, U+FFFD.
+ character � (U+FFFD).
ignore
Ignore malformed data and continue without further notice.
@@ -852,8 +858,6 @@
:Default: False.
:Options: ``--character-level-inline-markup``, ``--word-level-inline-markup``.
-New in Docutils 0.13.
-
pep_references
~~~~~~~~~~~~~~
Recognize and link to standalone PEP references (like "PEP 258").
@@ -930,8 +934,6 @@
:Default: SmartQuotes' `pre-defined quote sets`_.
:Option: ``--smartquotes-locales``.
-New in Docutils 0.14.
-
.. [#] If more than one character per quote is required (e.g. padding in
French quotes), a colon-separated list may be used for the quote set.
@@ -1497,8 +1499,6 @@
It shares all settings defined in the `[html writers]`_
`configuration section`_.
-New in Docutils 0.13.
-
.. _HTML5 Writer: html.html#html5-polyglot
.. _HTML5: https://www.w3.org/TR/2014/REC-html5-20141028/
@@ -2648,8 +2648,11 @@
.. _Docutils Document Tree:
.. _Docutils Generic document type definition:
.. _Document Tree: ../ref/doctree.html
+.. _Doctree element name: ../ref/doctree.html#element-reference
.. _class attribute: ../ref/doctree.html#classes
.. _identifiers: ../ref/doctree.html#identifiers
+.. _reference name:
+.. _reference names: ../ref/doctree.html#reference-names
.. _title attribute: ../ref/doctree.html#title-attribute
.. _"uri" attribute: ../ref/doctree.html#uri
@@ -2711,7 +2714,6 @@
../ref/rst/restructuredtext.html#inline-markup-recognition-rules
.. _literal blocks: ../ref/rst/restructuredtext.html#literal-blocks
.. _option lists: ../ref/rst/restructuredtext.html#option-lists
-.. _reference name: ../ref/rst/restructuredtext.html#reference-names
.. _tables: ../ref/rst/restructuredtext.html#tables
.. _Docutils HTML writers: html.html
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-04-09 14:35:54
|
Revision: 10309
http://sourceforge.net/p/docutils/code/10309
Author: milde
Date: 2026-04-09 14:35:52 +0000 (Thu, 09 Apr 2026)
Log Message:
-----------
Dcumentation update.
Update Public API and Backwards Compatibility Policy proposal.
Add link to EP Purpose and Guidelines to documentation overview.
Refactor PEP links: main link to upstream PEP, local copy in brackets.
Move "stalled" PEP 256 to the "suspended projects" list.
Build Docutils documentation with "legacy_ids: False".
Update `Contents` transfrom docstring.
Modified Paths:
--------------
trunk/docutils/docs/eps/ep-010.rst
trunk/docutils/docs/index.rst
trunk/docutils/docutils/transforms/parts.py
trunk/docutils/docutils.conf
Modified: trunk/docutils/docs/eps/ep-010.rst
===================================================================
--- trunk/docutils/docs/eps/ep-010.rst 2026-03-28 18:54:25 UTC (rev 10308)
+++ trunk/docutils/docs/eps/ep-010.rst 2026-04-09 14:35:52 UTC (rev 10309)
@@ -9,9 +9,10 @@
:Status: Draft
:Type: Process
:Created: 2025-04-22
-:Docutils-Version: 1.0
+:Docutils-Version: 0.23
+
:Abstract:
- This document suggests a definition of the public APIs provided by the
+ This document suggests a definition of the public API provided by the
Docutils project and the backwards compatibility policy.
.. contents::
@@ -53,7 +54,7 @@
writing or maintaining reStructuredText documents.
End-Users
- of Docutils native `front-end tools`_ (optionally with 3rd-party
+ of the `Docutils front-end tools`_ (optionally with 3rd-party
drop-in extensions) or alternative tools using Docutils either as a
library (Sphinx_, …) or via the command line interface
(build systems, Makefiles, scripts in other languages).
@@ -67,7 +68,7 @@
- alternative front-end tools,
- custom stylesheets (CSS style sheets, LaTeX styles, ODT styles),
or
- - re-implementations of the `reStructuredText specification`_,
+ - re-implementations of the `reStructuredText Markup Specification`_,
e.g. Pandoc_ or Text-Restructured_ (prest).
A person may belong to more than one of these categories.
@@ -87,29 +88,32 @@
.. _Text-Restructured: https://metacpan.org/dist/Text-Restructured
-Specification
-=============
+.. _specification:
+Public API
+==========
+
.. Describe the syntax and semantics of any new feature.
-Docutils public APIs are:
+Docutils' public API includes:
-* the `reStructuredText specification`_,
+* the `reStructuredText Markup Specification` [restructuredtext]_,
-* the `Docutils document structure`_ (`Docutils Document Tree`),
+* `the Docutils Document Tree` [doctree]_
+ and the `Docutils Generic Document Type Definition` [docutils.dtd]_,
* names, command-line arguments and behaviour of
- the `"console_scripts" entry points`_ (`Front-end Tools`),
+ the *"console_scripts" entry points* [tools]_ [settings]_,
* the core ``docutils`` Python package API:
- - the `Docutils Publisher`_ interface for programmatic use,
+ - the "publisher" interface for programmatic use [publisher]_,
- component interfaces as defined by the abstract base classes
- `docutils.reader.Reader`, `docutils.writer.Writer`, and
- `docutils.transform.Transform`,
+ `docutils.readers.Reader`, `docutils.parsers.Parser`,
+ `docutils.writer.Writer`, and `docutils.transform.Transform`,
-* behaviour and names of all *documented Python objects*, [#]_
+* behaviour and names of *documented Python objects*,
* *output templates* and *style sheets* provided with the writers,
@@ -120,18 +124,17 @@
used by writers to represent Doctree_ nodes in the output format.
Exemptions:
- Python objects, stylesheets and templates can explicitly "opt-out" of
- the public API with a docstring noting that the object is provisional_
- or internal.
- All undocumented objects should be assumed to be internal. [#]_
+* Python objects, stylesheets, and templates can "opt-out" of
+ the public API with a docstring noting that the object is
+ |provisional|_ or *internal*.
+* All **undocumented** objects should be assumed to be internal. [#]_
-See also the `API Reference Material for Client-Developers`_.
+.. [#] Cf. `Backwards Compatibility Rules`_ in :PEP:`387` and
+ `Public and Internal Interfaces`_ in :PEP:`8`.
+.. |provisional| replace:: *provisional*
-.. [#] Cf. `PEP 387: Backwards Compatibility Rules`_
-.. [#] Cf. `PEP 008: Public and Internal Interfaces`_
-
Backwards Compatibility
=======================
@@ -156,27 +159,22 @@
.. How to teach users, new and experienced,
how to apply the proposal to their work.
-* Move the API specification_ and the backwards compatibility declaration
- to the `Docutils Project Policies`_.
+* Copy the backwards compatibility declaration to the `Docutils Project
+ Policies`_. Link back to the `public API`_ specification in this document.
* Complete the API documentation and keep it up to date.
-* Generate "docutils" package API documentation from the docstrings:
+ - maintain and extend the `API Reference Material for Client-Developers`_
- Fix/enhance/add docstrings to improve the output of `pydoc`_.
- - Generate API documentation with Sphinx:
-
- - nicely format rST docstrings
- - include attribute docstrings (ignored by pydoc_).
-
* Put the following text at a suitable place in the documentation:
To find out if an object from the "docutils" package is safe to use,
look up its docstring and the docstring of its parent(s) [#]_.
- If there is no documentation or the documentation says "provisional" or
- "internal", the name, behaviour, and existence of the object is not
+ If there is no documentation or the documentation says *provisional* or
+ *internal*, the name, behaviour, and existence of the object is not
guaranteed to be stable.
Code relying on non-public objects should be made robust using
@@ -214,15 +212,17 @@
- Breaks the principle of least surprise.
-* Enumerate all modules, classes, and functions that form the public API.
+* Mark all internal objects with a prefix underscore.
-* Mark all private objects with a prefix underscore.
+ - May needlessly break applications using internal objects.
- - May needlessly break applications that use "internal" objects by the
- current name.
- - Too much work.
+* Use the ``__all__`` attribute to declare modules, classes, and
+ functions that form the public API.
+ - This may be done later to improve "pydoc" output, but should not hold
+ up the declaration of a Backwards Compatibility Policy.
+
Open Issues
===========
@@ -230,6 +230,9 @@
* Differentiate between "core API" and "extended API"?
+ There are many objects that were not intended for public use but are
+ still used by downstream projects.
+
Cf. the `Docutils Project Policies`_
When Docutils reaches version 1.0, the major APIs will be considered
@@ -238,46 +241,45 @@
The major number [...] may be incremented later if there is a major
change in the design or API.
+* Define a minimum deprecation time similar to DocBook?
-* Formalise the wording for docstrings for public/private/provisional
- (ideally this would be a single regex pattern)?
+ A "major" release […] may contain backward-incompatible changes if:
- * The keyword provisional_ is well defined. ✓
- * Use "private" or "internal"?
+ * the change was announced in the release notes for the previous
+ version (major or minor) and
+ * the change was announced in a release that occurred at least six
+ months previously.
-* Declare only objects included in the ``__all__`` attribute of their
- parent objects as public resp. explicitly list all public objects in
- ``__all__`` attribute of their parents?
+ By these rules, the technical committee can announce, in 5.1,
+ for example, plans to make a backward-incompatible change in 6.0.
+ Then, in 6.0, if it’s been at least six months since 5.1 was
+ released, they can make that change.
- This would hide private objects from `pydoc` help on the parent objects.
+ --- https://tdg.docbook.org/tdg/5.1/ch01.html#bwcompat
-* Define a minimum deprecation time similar to DocBook__? E.g.
+* Generate API documentation with Sphinx?
- * A "major" release may contain backward-incompatible changes if:
+ - nicely format rST docstrings
+ - include attribute docstrings (ignored by pydoc_).
- * the change was announced in the release notes for the previous
- version (major or minor) and
- * the change was announced in a release that occurred at least six
- months previously.
- By these rules, Docutils developers can announce, in release 5.1, for
- example, its plans to make a backward-incompatible change in release 6.0.
- Then, in 6.0, if it’s been at least six months since 5.1 was
- released, they can make that change.
-
- __ https://tdg.docbook.org/tdg/5.1/ch01.html#bwcompat
-
-
References
==========
.. A collection of URLs used as references through the proposal.
+
+.. [doctree] `The Docutils Document Tree <../ref/doctree.html>`_
+.. [docutils.dtd] `Docutils Generic DTD <../ref/docutils.dtd>`_
+.. [publisher] `The Docutils Publisher <../api/publisher.html>`_
+.. [tools] `Docutils Front-End Tools <../user/tools.html>`_
+.. [restructuredtext] `reStructuredText Markup Specification
+ <../ref/rst/restructuredtext.html>`_
+.. [settings] `Docutils Runtime Settings <../api/runtime-settings.html>`_
+.. [transforms] `Docutils Transforms <../api/transforms.html>`_
+
.. _API Reference Material for Client-Developers:
../index.html#api-reference-material-for-client-developers
-.. _doctree:
-.. _Docutils document structure: ../ref/doctree.html
-.. _docutils.dtd: ../ref/docutils.dtd
.. _Docutils Design Specification: ../peps/pep-0258.html
.. _Docutils Project Policies: ../dev/policies.html
.. _version specifier:
@@ -285,20 +287,15 @@
../dev/policies.html#version-identification
.. _backwards compatibility policy:
../dev/policies.html#backwards-compatibility-policy
-.. _"console_scripts" entry points:
-.. _front-end tools: ../user/tools.html
-.. _Docutils Publisher: ../api/publisher.html
-.. _Docutils Transforms: ../ref/transforms.html
.. _HISTORY: ../docutils/HISTORY.html
.. _RELEASE-NOTES: ../docutils/RELEASE-NOTES.html
-.. _reStructuredText specification:
- ../ref/rst/restructuredtext.html
-.. _`PEP 387: backwards compatibility rules`:
+.. _`Backwards Compatibility Rules`:
https://peps.python.org/pep-0387/#backwards-compatibility-rules
-.. _`PEP 008: Public and Internal Interfaces`:
+.. _`Public and Internal Interfaces`:
https://peps.python.org/pep-0008/#public-and-internal-interfaces
.. _provisional: https://docs.python.org/3/glossary.html#term-provisional-API
+
.. _Semantic Versioning: https://semver.org/
Modified: trunk/docutils/docs/index.rst
===================================================================
--- trunk/docutils/docs/index.rst 2026-03-28 18:54:25 UTC (rev 10308)
+++ trunk/docutils/docs/index.rst 2026-04-09 14:35:52 UTC (rev 10309)
@@ -130,7 +130,7 @@
* `Docutils Generic DTD <ref/docutils.dtd>`__
* `OASIS XML Exchange Table Model Declaration Module
<ref/soextblx.dtd>`__ (CALS tables DTD module)
- * `Docutils Design Specification`_ (PEP 258)
+ * `Docutils Design Specification <peps/pep-0258.html>`_ (PEP 258)
reStructuredText_:
* `An Introduction to reStructuredText <ref/rst/introduction.html>`__
@@ -148,33 +148,18 @@
.. _peps:
Python Enhancement Proposals
- * `PEP 256: Docstring Processing System Framework`__ is a high-level
- generic proposal. [:PEP:`256` in the `master repository`_]
- * `PEP 257: Docstring Conventions`__ addresses docstring style and
- touches on content. [:PEP:`257` in the `master repository`_]
- * `PEP 258: Docutils Design Specification`__ is an overview of the
- architecture of Docutils. It documents design issues and
- implementation details. [:PEP:`258` in the `master repository`_]
- * `PEP 287: reStructuredText Docstring Format`__ proposes a standard
- markup syntax. [:PEP:`287` in the `master repository`_]
+ * :PEP:`258` `Docutils Design Specification` is an overview of
+ the architecture of Docutils. It documents design issues and
+ implementation details. (`local copy <peps/pep-0258.html>`__)
+ * :PEP:`257` `Docstring Conventions` addresses docstring style and
+ touches on content (`local copy <peps/pep-0257.html>`__)
+ * :PEP:`287` `reStructuredText Docstring Format`
+ proposes a standard markup syntax (`local copy <peps/pep-0287.html>`__)
- Please note that PEPs in the `master repository`_ developed
- independent from the local versions after submission.
+ Please note that, after submission, the submitted PEPs developed
+ independent from the local versions.
- __ peps/pep-0256.html
- __ peps/pep-0257.html
- .. _PEP 258:
- .. _Docutils Design Specification:
- __ peps/pep-0258.html
- __ peps/pep-0287.html
- .. _master repository: https://peps.python.org
-Prehistoric:
- `Setext Documents Mirror`__
-
- __ https://docutils.sourceforge.io/mirror/setext.html
-
-
.. _api:
API Reference Material for Client-Developers
@@ -191,12 +176,6 @@
Docutils developer.
-Docutils Enhancement Proposals
-==============================
-
-* `Enhancement Proposal Index <eps/index.html>`__
-
-
.. _howto:
Instructions for Developers
@@ -213,6 +192,14 @@
<howto/rst-roles.html>`__
+Docutils Enhancement Proposals
+==============================
+
+`Index <eps/index.html>`__
+
+| EP 1 — `Docutils EP Purpose and Guidelines <eps/ep-001.html>`_
+| EP 10 — `Public API and Backwards Compatibility Policy <eps/ep-010.html>`_
+
.. _dev:
Development Notes and Plans for Core-Developers
@@ -234,6 +221,8 @@
* `Problems With StructuredText <dev/rst/problems.html>`__
Suspended projects and plans:
+ * :PEP:`256` `Docstring Processing System Framework`
+ (`local copy <peps/pep-0256.html>`__)
* `Docstring Semantics <dev/semantics.html>`__ (incomplete)
* `Python Source Reader <dev/pysource.html>`_ (incomplete)
* `Docutils Python DTD <dev/pysource.dtd>`_
@@ -240,6 +229,12 @@
* `Plan for Enthought API Documentation Tool <dev/enthought-plan.html>`_
* `Enthought API Documentation Tool RFP <dev/enthought-rfp.html>`_
+Prehistoric:
+ `Setext Documents Mirror`__
+
+ __ https://docutils.sourceforge.io/mirror/setext.html
+
+
.. Emacs settings
Local Variables:
Modified: trunk/docutils/docutils/transforms/parts.py
===================================================================
--- trunk/docutils/docutils/transforms/parts.py 2026-03-28 18:54:25 UTC (rev 10308)
+++ trunk/docutils/docutils/transforms/parts.py 2026-04-09 14:35:52 UTC (rev 10309)
@@ -68,25 +68,26 @@
class Contents(Transform):
+ """
+ Generate a table of contents (ToC)
- """
This transform generates a table of contents from the entire document tree
- or from a single branch. It locates "section" elements and builds them
- into a nested bullet list, which is placed within a "topic" created by the
+ or from a single branch. It locates <section> elements and builds them
+ into a nested bullet list, which is placed within a <topic> created by the
contents directive. A title is either explicitly specified, taken from
the appropriate language module, or omitted (local table of contents).
The depth may be specified. Two-way references between the table of
contents and section titles are generated (requires Writer support).
- This transform requires a startnode, a "pending" element which contains
+ This transform requires a startnode, a <pending> element which contains
generation options and provides the location for the generated ToC (the
- startnode is replaced by the table of contents "bullet-list").
+ startnode is replaced by the table of contents <bullet_list>).
"""
default_priority = 720
def apply(self) -> None:
- # ensure the "ToC topic" wrapper element has an identifier:
+ # ensure the <topic> containing the ToC has a registered ID
self.toc_id = self.document.set_id(self.startnode.parent)
# let the writer (or output software) build the contents list?
toc_by_writer = getattr(self.document.settings, 'use_latex_toc', False)
@@ -96,9 +97,9 @@
details = self.startnode.details
if 'local' in details:
+ # find the ToC root: a direct ancestor of startnode
startnode = self.startnode.parent.parent
while not isinstance(startnode, (nodes.section, nodes.document)):
- # find the ToC root: a direct ancestor of startnode
startnode = startnode.parent
else:
startnode = self.document
Modified: trunk/docutils/docutils.conf
===================================================================
--- trunk/docutils/docutils.conf 2026-03-28 18:54:25 UTC (rev 10308)
+++ trunk/docutils/docutils.conf 2026-04-09 14:35:52 UTC (rev 10309)
@@ -3,6 +3,7 @@
source-link: yes
datestamp: %Y-%m-%d %H:%M UTC
generator: on
+legacy_ids: false
# These entries affect HTML output:
[html writers]
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-03-28 18:54:27
|
Revision: 10308
http://sourceforge.net/p/docutils/code/10308
Author: milde
Date: 2026-03-28 18:54:25 +0000 (Sat, 28 Mar 2026)
Log Message:
-----------
More tests with "legacy_ids = False".
After parsing:
* the ToC, a subtitle, the document and sections with unique name
have no identifier (added later in "transforms"),
Exception: sections with duplicate names get an identifier
(normalized dupname + number) for the system-message backlink.
* references with embedded URI or alias have no identifier.
Modified Paths:
--------------
trunk/docutils/test/test_parsers/test_rst/test_directives/test_contents.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_nested_parsing.py
trunk/docutils/test/test_parsers/test_rst/test_section_headers.py
trunk/docutils/test/test_parsers/test_rst/test_targets.py
trunk/docutils/test/test_parsers/test_rst/test_transitions.py
trunk/docutils/test/test_transforms/test_doctitle.py
trunk/docutils/test/test_transforms/test_transitions.py
Modified: trunk/docutils/test/test_parsers/test_rst/test_directives/test_contents.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_directives/test_contents.py 2026-03-28 18:54:14 UTC (rev 10307)
+++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_contents.py 2026-03-28 18:54:25 UTC (rev 10308)
@@ -27,6 +27,7 @@
parser = Parser()
settings = get_default_settings(Parser)
settings.warning_stream = ''
+ settings.legacy_ids = False
for name, cases in totest.items():
for casenum, (case_input, case_expected) in enumerate(cases):
with self.subTest(id=f'totest[{name!r}][{casenum}]'):
@@ -51,7 +52,7 @@
""",
"""\
<document source="test data">
- <topic classes="contents" ids="contents" names="contents">
+ <topic classes="contents" names="contents">
<title>
Contents
<pending>
@@ -64,7 +65,7 @@
""",
"""\
<document source="test data">
- <topic classes="contents" ids="table-of-contents" names="table\\ of\\ contents">
+ <topic classes="contents" names="table\\ of\\ contents">
<title>
Table of Contents
<pending>
@@ -78,7 +79,7 @@
""",
"""\
<document source="test data">
- <topic classes="contents" ids="table-of-contents" names="table\\ of\\ contents">
+ <topic classes="contents" names="table\\ of\\ contents">
<title>
Table of Contents
<pending>
@@ -93,7 +94,7 @@
""",
"""\
<document source="test data">
- <topic classes="contents" ids="table-of-contents" names="table\\ of\\ contents">
+ <topic classes="contents" names="table\\ of\\ contents">
<title>
Table
of
@@ -108,7 +109,7 @@
""",
"""\
<document source="test data">
- <topic classes="contents" ids="table-of-contents" names="table\\ of\\ contents">
+ <topic classes="contents" names="table\\ of\\ contents">
<title>
<emphasis>
Table
@@ -127,7 +128,7 @@
""",
"""\
<document source="test data">
- <topic classes="contents local" ids="contents" names="contents">
+ <topic classes="contents local" names="contents">
<pending>
.. internal attributes:
.transform: docutils.transforms.parts.Contents
@@ -158,7 +159,7 @@
""",
"""\
<document source="test data">
- <topic classes="contents local" ids="table-of-contents" names="table\\ of\\ contents">
+ <topic classes="contents local" names="table\\ of\\ contents">
<title>
Table of Contents
<pending>
@@ -251,7 +252,7 @@
<sidebar>
<title>
containing contents
- <topic classes="contents" ids="contents" names="contents">
+ <topic classes="contents" names="contents">
<title>
Contents
<pending>
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-03-28 18:54:14 UTC (rev 10307)
+++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2026-03-28 18:54:25 UTC (rev 10308)
@@ -44,6 +44,7 @@
settings = get_default_settings(Parser)
settings.warning_stream = ''
settings.halt_level = 5
+ settings.legacy_ids = False
for name, cases in totest.items():
if name == 'with transforms':
continue # see test_publish() below
@@ -146,10 +147,10 @@
""",
"""\
<document source="test data">
- <section ids="include-test" names="include\\ test">
+ <section names="include\\ test">
<title>
Include Test
- <section ids="inclusion-1" names="inclusion\\ 1">
+ <section names="inclusion\\ 1">
<title>
Inclusion 1
<paragraph>
@@ -173,7 +174,7 @@
""",
f"""\
<document source="test data">
- <section ids="include-test" names="include\\ test">
+ <section names="include\\ test">
<title>
Include Test
<literal_block classes="test" ids="my-name" names="my\\ name" source="{include1}" xml:space="preserve">
@@ -332,7 +333,7 @@
""",
"""\
<document source="test data">
- <section ids="include-test" names="include\\ test">
+ <section names="include\\ test">
<title>
Include Test
<system_message level="3" line="4" source="test data" type="ERROR">
@@ -356,10 +357,10 @@
""",
f"""\
<document source="test data">
- <section ids="include-test" names="include\\ test">
+ <section names="include\\ test">
<title>
Include Test
- <section dupnames="inclusion\\ 1" ids="inclusion-1">
+ <section dupnames="inclusion\\ 1" ids="inclusion-1-1">
<title>
Inclusion 1
<paragraph>
@@ -367,10 +368,10 @@
<literal>
test_include.py
.
- <section dupnames="inclusion\\ 1" ids="inclusion-1-1">
+ <section dupnames="inclusion\\ 1" ids="inclusion-1-2">
<title>
Inclusion 1
- <system_message backrefs="inclusion-1-1" level="1" line="2" source="{include1}" type="INFO">
+ <system_message backrefs="inclusion-1-2" level="1" line="2" source="{include1}" type="INFO">
<paragraph>
Duplicate implicit target name: "inclusion 1".
<paragraph>
@@ -395,10 +396,10 @@
""",
f"""\
<document source="test data">
- <section ids="include-test" names="include\\ test">
+ <section names="include\\ test">
<title>
Include Test
- <section dupnames="inclusion\\ 1" ids="inclusion-1">
+ <section dupnames="inclusion\\ 1" ids="inclusion-1-1">
<title>
Inclusion 1
<paragraph>
@@ -407,10 +408,10 @@
test_include.py
.
<transition>
- <section dupnames="inclusion\\ 1" ids="inclusion-1-1">
+ <section dupnames="inclusion\\ 1" ids="inclusion-1-2">
<title>
Inclusion 1
- <system_message backrefs="inclusion-1-1" level="1" line="2" source="{include1}" type="INFO">
+ <system_message backrefs="inclusion-1-2" level="1" line="2" source="{include1}" type="INFO">
<paragraph>
Duplicate implicit target name: "inclusion 1".
<paragraph>
@@ -516,7 +517,7 @@
<document source="test data">
<paragraph>
In test data
- <section ids="section" names="section">
+ <section names="section">
<title>
Section
<paragraph>
@@ -637,7 +638,7 @@
Substitution definition "bad" empty or invalid.
<literal_block xml:space="preserve">
.. |bad| unicode:: 0x11111111
- <section dupnames="hi" ids="hi">
+ <section dupnames="hi" ids="hi-1">
<title>
hi
<block_quote>
@@ -648,10 +649,10 @@
Block quote ends without a blank line; unexpected unindent.
<paragraph>
error
- <section dupnames="hi" ids="hi-1">
+ <section dupnames="hi" ids="hi-2">
<title>
hi
- <system_message backrefs="hi-1" level="1" line="10" source="{include10}" type="INFO">
+ <system_message backrefs="hi-2" level="1" line="10" source="{include10}" type="INFO">
<paragraph>
Duplicate implicit target name: "hi".
<system_message level="3" line="12" source="{include10}" type="ERROR">
@@ -708,7 +709,7 @@
.. admonition::
\n\
without title and content following a blank line
- <section ids="section-underline-too-short" names="section\\ underline\\ too\\ short">
+ <section names="section\\ underline\\ too\\ short">
<title>
section underline too short
<system_message level="2" line="36" source="{include10}" type="WARNING">
@@ -877,15 +878,15 @@
""",
f"""\
<document source="test data">
- <section dupnames="inclusion\\ 1" ids="inclusion-1">
+ <section dupnames="inclusion\\ 1" ids="inclusion-1-1">
<title>
Inclusion 1
<paragraph>
Name clash: The included file uses the same section title.
- <section dupnames="inclusion\\ 1" ids="inclusion-1-1">
+ <section dupnames="inclusion\\ 1" ids="inclusion-1-2">
<title>
Inclusion 1
- <system_message backrefs="inclusion-1-1" level="1" line="2" source="{include1}" type="INFO">
+ <system_message backrefs="inclusion-1-2" level="1" line="2" source="{include1}" type="INFO">
<paragraph>
Duplicate implicit target name: "inclusion 1".
<paragraph>
@@ -1567,7 +1568,7 @@
<document source="test data">
<paragraph>
Include Markdown source.
- <section depth="1" ids="section-1">
+ <section depth="1">
<title>
Title 1
<paragraph>
Modified: trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py 2026-03-28 18:54:14 UTC (rev 10307)
+++ trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py 2026-03-28 18:54:25 UTC (rev 10308)
@@ -29,6 +29,7 @@
parser = Parser()
settings = get_default_settings(Parser)
settings.warning_stream = ''
+ settings.legacy_ids = False
for name, cases in totest.items():
for casenum, (case_input, case_expected) in enumerate(cases):
with self.subTest(id=f'totest[{name!r}][{casenum}]'):
@@ -991,7 +992,7 @@
<paragraph>
<reference name="phrase reference" refuri="http://example.com">
phrase reference
- <target ids="phrase-reference" names="phrase\\ reference" refuri="http://example.com">
+ <target names="phrase\\ reference" refuri="http://example.com">
"""],
["""\
`anonymous reference <http://example.com>`__
@@ -1111,7 +1112,7 @@
<paragraph>
<reference name="reference" refuri="reference">
reference
- <target ids="reference" names="reference" refuri="reference">
+ <target names="reference" refuri="reference">
<paragraph>
<reference name="anonymous" refuri="anonymous">
anonymous
@@ -1130,7 +1131,7 @@
<paragraph>
<reference name="reference_" refuri="reference_">
reference_
- <target ids="reference" names="reference_" refuri="reference_">
+ <target names="reference_" refuri="reference_">
<paragraph>
<reference name="anonymous_" refuri="anonymous_">
anonymous_
@@ -1149,7 +1150,7 @@
<paragraph>
<reference name="reference:1" refuri="reference:1">
reference:1
- <target ids="reference-1" names="reference:1" refuri="reference:1">
+ <target names="reference:1" refuri="reference:1">
<paragraph>
<reference name="anonymouscall" refuri="anonymouscall">
anonymouscall
@@ -1180,7 +1181,7 @@
Embedded URI: named \n\
<reference name="file.txt" refuri="file.txt">
file.txt
- <target dupnames="file.txt" ids="file-txt-1" refuri="file.txt">
+ <target dupnames="file.txt" refuri="file.txt">
and anonymous \n\
<reference name="file.html" refuri="file.html">
file.html
@@ -1197,7 +1198,7 @@
<paragraph>
<reference name="phrase reference" refname="alias">
phrase reference
- <target ids="phrase-reference" names="phrase\\ reference" refname="alias">
+ <target names="phrase\\ reference" refname="alias">
"""],
["""\
`anonymous reference <alias_>`__
@@ -1307,11 +1308,11 @@
References with embedded alias: \n\
<reference name="link" refname="tg1">
link
- <target dupnames="link" ids="link" refname="tg1">
+ <target dupnames="link" ids="link-1" refname="tg1">
and \n\
<reference name="link" refname="tg2">
link
- <target dupnames="link" ids="link-1" refname="tg2">
+ <target dupnames="link" refname="tg2">
.
<paragraph>
No clash with anonymous reference \n\
Modified: trunk/docutils/test/test_parsers/test_rst/test_nested_parsing.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_nested_parsing.py 2026-03-28 18:54:14 UTC (rev 10307)
+++ trunk/docutils/test/test_parsers/test_rst/test_nested_parsing.py 2026-03-28 18:54:25 UTC (rev 10308)
@@ -150,6 +150,7 @@
register_directive('fresh-current', FreshParseIntoCurrentNode)
parser = rst.Parser()
settings = get_default_settings(rst.Parser)
+ settings.legacy_ids = False
settings.warning_stream = ''
settings.halt_level = 5
for name, cases in totest.items():
@@ -202,19 +203,19 @@
""",
"""\
<document source="test data">
- <section ids="sec1" names="sec1">
+ <section names="sec1">
<title>
sec1
- <section ids="sec1-1" names="sec1.1">
+ <section names="sec1.1">
<title>
sec1.1
- <section ids="nested1-1-1" names="nested1.1.1">
+ <section names="nested1.1.1">
<title>
nested1.1.1
- <section ids="nested1-1-1-1" names="nested1.1.1.1">
+ <section names="nested1.1.1.1">
<title>
nested1.1.1.1
- <section ids="sec2" names="sec2">
+ <section names="sec2">
<title>
sec2
<system_message level="3" line="16" source="test data" type="ERROR">
@@ -225,10 +226,10 @@
***********
<paragraph>
Established title styles: = - * ~
- <section ids="nested2-1" names="nested2.1">
+ <section names="nested2.1">
<title>
nested2.1
- <section ids="nested2-2" names="nested2.2">
+ <section names="nested2.2">
<title>
nested2.2
<system_message level="3" line="22" source="test data" type="ERROR">
@@ -243,7 +244,7 @@
The parent of level 1 sections cannot be reached. The parser is at section level 2 but the current node has only 1 parent section(s).
One reason may be a high level section used in a directive that parses its content into a base node not attached to the document
(up to Docutils 0.21, these sections were silently dropped).
- <section ids="sec2-2" names="sec2.2">
+ <section names="sec2.2">
<title>
sec2.2
<system_message level="3" line="27" source="test data" type="ERROR">
@@ -271,13 +272,13 @@
""",
"""\
<document source="test data">
- <section ids="nested1" names="nested1">
+ <section names="nested1">
<title>
nested1
- <section ids="nested2" names="nested2">
+ <section names="nested2">
<title>
nested2
- <section ids="nested2-1" names="nested2.1">
+ <section names="nested2.1">
<title>
nested2.1
<paragraph>
@@ -299,10 +300,10 @@
<note>
<paragraph>
The next directive is parsed with "nested_list_parse()".
- <section ids="nested1" names="nested1">
+ <section names="nested1">
<title>
nested1
- <section ids="nested1-1" names="nested1.1">
+ <section names="nested1.1">
<title>
nested1.1
<paragraph>
@@ -348,25 +349,25 @@
""",
"""\
<document source="test data">
- <section ids="sec1" names="sec1">
+ <section names="sec1">
<title>
sec1
- <section ids="sec1-1" names="sec1.1">
+ <section names="sec1.1">
<title>
sec1.1
<note>
<paragraph>
The next directive is parsed with "nested_list_parse()".
- <section ids="nc1-1-1" names="nc1.1.1">
+ <section names="nc1.1.1">
<title>
nc1.1.1
- <section ids="nc1-2" names="nc1.2">
+ <section names="nc1.2">
<title>
nc1.2
- <section ids="nc2" names="nc2">
+ <section names="nc2">
<title>
nc2
- <section ids="sec2-2" names="sec2.2">
+ <section names="sec2.2">
<title>
sec2.2
"""],
@@ -388,23 +389,23 @@
""",
"""\
<document source="test data">
- <section ids="sec1" names="sec1">
+ <section names="sec1">
<title>
sec1
- <section ids="sec1-1" names="sec1.1">
+ <section names="sec1.1">
<title>
sec1.1
- <section ids="nested-section1-1-1" names="nested-section1.1.1">
+ <section names="nested-section1.1.1">
<title>
nested-section1.1.1
<paragraph>
This paragraph belongs to the last nested section (sic!).
- <section ids="sec2" names="sec2">
+ <section names="sec2">
<title>
sec2
<system_message level="2" line="10" source="test data" type="WARNING">
<paragraph>
- Element <section ids="sec1-1" names="sec1.1"> invalid:
+ Element <section names="sec1.1"> invalid:
Child element <paragraph> not allowed at this position.
"""],
# Even if the base node is a <section>, it does not show up in
@@ -421,7 +422,7 @@
""",
"""\
<document source="test data">
- <section ids="sec1" names="sec1">
+ <section names="sec1">
<title>
sec1
<system_message level="3" line="5" source="test data" type="ERROR">
@@ -479,13 +480,13 @@
============
<paragraph>
The <section> base node is discarded.
- <section ids="invalid-section-sic" names="invalid\\ section\\ (sic!)">
+ <section names="invalid\\ section\\ (sic!)">
<title>
invalid section (sic!)
<system_message level="2" line="1" source="test data" type="WARNING">
<paragraph>
Element <block_quote> invalid:
- Child element <section ids="invalid-section-sic" names="invalid\\ section\\ (sic!)"> not allowed at this position.
+ Child element <section names="invalid\\ section\\ (sic!)"> not allowed at this position.
"""],
# Nested parsing with new title style hierarchy
["""\
@@ -526,48 +527,48 @@
""",
"""\
<document source="test data">
- <section ids="sec1" names="sec1">
+ <section names="sec1">
<title>
sec1
- <section ids="sec1-1" names="sec1.1">
+ <section names="sec1.1">
<title>
sec1.1
- <section ids="fresh1-1-1" names="fresh1.1.1">
+ <section names="fresh1.1.1">
<title>
fresh1.1.1
- <section ids="fresh1-1-1-1" names="fresh1.1.1.1">
+ <section names="fresh1.1.1.1">
<title>
fresh1.1.1.1
- <section ids="sec2" names="sec2">
+ <section names="sec2">
<title>
sec2
- <section ids="fresh2-1" names="fresh2.1">
+ <section names="fresh2.1">
<title>
fresh2.1
<paragraph>
New title styles with every directive.
- <section ids="fresh2-1-1" names="fresh2.1.1">
+ <section names="fresh2.1.1">
<title>
fresh2.1.1
- <section ids="fresh2-1-2" names="fresh2.1.2">
+ <section names="fresh2.1.2">
<title>
fresh2.1.2
- <section ids="fresh2-1-2-1" names="fresh2.1.2.1">
+ <section names="fresh2.1.2.1">
<title>
fresh2.1.2.1
<paragraph>
This text belongs into the last nested section (sic!).
- <section ids="sec2-2" names="sec2.2">
+ <section names="sec2.2">
<title>
sec2.2
<paragraph>
Document-wide title styles unchanged
- <section ids="sec2-2-1" names="sec2.2.1">
+ <section names="sec2.2.1">
<title>
sec2.2.1
<system_message level="2" line="27" source="test data" type="WARNING">
<paragraph>
- Element <section ids="sec2" names="sec2"> invalid:
+ Element <section names="sec2"> invalid:
Child element <paragraph> not allowed at this position.
"""],
# Nested parsing into current node with new title style hierarchy
@@ -592,24 +593,24 @@
""",
"""\
<document source="test data">
- <section ids="sec1" names="sec1">
+ <section names="sec1">
<title>
sec1
- <section ids="sec1-1" names="sec1.1">
+ <section names="sec1.1">
<title>
sec1.1
- <section ids="fc1-1-1" names="fc1.1.1">
+ <section names="fc1.1.1">
<title>
fc1.1.1
- <section ids="fc1-1-2" names="fc1.1.2">
+ <section names="fc1.1.2">
<title>
fc1.1.2
- <section ids="fc1-1-2-1" names="fc1.1.2.1">
+ <section names="fc1.1.2.1">
<title>
fc1.1.2.1
<paragraph>
This text belongs into the last nested section.
- <section ids="sec1-2" names="sec1.2">
+ <section names="sec1.2">
<title>
sec1.2
"""],
Modified: trunk/docutils/test/test_parsers/test_rst/test_section_headers.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_section_headers.py 2026-03-28 18:54:14 UTC (rev 10307)
+++ trunk/docutils/test/test_parsers/test_rst/test_section_headers.py 2026-03-28 18:54:25 UTC (rev 10308)
@@ -28,6 +28,7 @@
def test_parser(self):
parser = Parser()
settings = get_default_settings(Parser)
+ settings.legacy_ids = False
settings.warning_stream = ''
settings.halt_level = 5
for name, cases in totest.items():
@@ -50,7 +51,7 @@
""",
"""\
<document source="test data">
- <section ids="title" names="title">
+ <section names="title">
<title>
Title
<paragraph>
@@ -63,7 +64,7 @@
""",
"""\
<document source="test data">
- <section ids="title" names="title">
+ <section names="title">
<title>
Title
<paragraph>
@@ -81,7 +82,7 @@
<document source="test data">
<paragraph>
Paragraph.
- <section ids="title" names="title">
+ <section names="title">
<title>
Title
<paragraph>
@@ -134,7 +135,7 @@
""",
"""\
<document source="test data">
- <section ids="title" names="title">
+ <section names="title">
<title>
Title
<system_message level="2" line="2" source="test data" type="WARNING">
@@ -154,7 +155,7 @@
""",
"""\
<document source="test data">
- <section ids="a-with-combining-varia" names="a\u0300\\ with\\ combining\\ varia">
+ <section names="a\u0300\\ with\\ combining\\ varia">
<title>
à with combining varia
<paragraph>
@@ -169,7 +170,7 @@
""",
"""\
<document source="test data">
- <section ids="title" names="title">
+ <section names="title">
<title>
Title
<paragraph>
@@ -184,7 +185,7 @@
""",
"""\
<document source="test data">
- <section ids="title" names="title">
+ <section names="title">
<title>
Title
<paragraph>
@@ -243,7 +244,7 @@
""",
"""\
<document source="test data">
- <section ids="long-title" names="long\\ title">
+ <section names="long\\ title">
<title>
Long Title
<system_message level="2" line="1" source="test data" type="WARNING">
@@ -344,22 +345,22 @@
<document source="test data">
<comment xml:space="preserve">
Test return to existing, highest-level section (Title 3).
- <section ids="title-1" names="title\\ 1">
+ <section names="title\\ 1">
<title>
Title 1
<paragraph>
Paragraph 1.
- <section ids="title-2" names="title\\ 2">
+ <section names="title\\ 2">
<title>
Title 2
<paragraph>
Paragraph 2.
- <section ids="title-3" names="title\\ 3">
+ <section names="title\\ 3">
<title>
Title 3
<paragraph>
Paragraph 3.
- <section ids="title-4" names="title\\ 4">
+ <section names="title\\ 4">
<title>
Title 4
<paragraph>
@@ -392,22 +393,22 @@
<document source="test data">
<paragraph>
Test return to existing, highest-level section (Title 3, with overlines).
- <section ids="title-1" names="title\\ 1">
+ <section names="title\\ 1">
<title>
Title 1
<paragraph>
Paragraph 1.
- <section ids="title-2" names="title\\ 2">
+ <section names="title\\ 2">
<title>
Title 2
<paragraph>
Paragraph 2.
- <section ids="title-3" names="title\\ 3">
+ <section names="title\\ 3">
<title>
Title 3
<paragraph>
Paragraph 3.
- <section ids="title-4" names="title\\ 4">
+ <section names="title\\ 4">
<title>
Title 4
<paragraph>
@@ -436,22 +437,22 @@
<document source="test data">
<paragraph>
Test return to existing, higher-level section (Title 4).
- <section ids="title-1" names="title\\ 1">
+ <section names="title\\ 1">
<title>
Title 1
<paragraph>
Paragraph 1.
- <section ids="title-2" names="title\\ 2">
+ <section names="title\\ 2">
<title>
Title 2
<paragraph>
Paragraph 2.
- <section ids="title-3" names="title\\ 3">
+ <section names="title\\ 3">
<title>
Title 3
<paragraph>
Paragraph 3.
- <section ids="title-4" names="title\\ 4">
+ <section names="title\\ 4">
<title>
Title 4
<paragraph>
@@ -480,17 +481,17 @@
<document source="test data">
<paragraph>
Test bad subsection order (Title 4).
- <section ids="title-1" names="title\\ 1">
+ <section names="title\\ 1">
<title>
Title 1
<paragraph>
Paragraph 1.
- <section ids="title-2" names="title\\ 2">
+ <section names="title\\ 2">
<title>
Title 2
<paragraph>
Paragraph 2.
- <section ids="title-3" names="title\\ 3">
+ <section names="title\\ 3">
<title>
Title 3
<paragraph>
@@ -533,17 +534,17 @@
<document source="test data">
<paragraph>
Test bad subsection order (Title 4, with overlines).
- <section ids="title-1" names="title\\ 1">
+ <section names="title\\ 1">
<title>
Title 1
<paragraph>
Paragraph 1.
- <section ids="title-2" names="title\\ 2">
+ <section names="title\\ 2">
<title>
Title 2
<paragraph>
Paragraph 2.
- <section ids="title-3" names="title\\ 3">
+ <section names="title\\ 3">
<title>
Title 3
<paragraph>
@@ -568,7 +569,7 @@
""",
"""\
<document source="test data">
- <section ids="title-containing-inline-markup" names="title\\ containing\\ inline\\ markup">
+ <section names="title\\ containing\\ inline\\ markup">
<title>
Title containing \n\
<emphasis>
@@ -587,7 +588,7 @@
""",
"""\
<document source="test data">
- <section ids="numbered-title" names="1.\\ numbered\\ title">
+ <section names="1.\\ numbered\\ title">
<title>
1. Numbered Title
<paragraph>
@@ -613,7 +614,7 @@
<system_message level="2" line="3" source="test data" type="WARNING">
<paragraph>
Enumerated list ends without a blank line; unexpected unindent.
- <section ids="numbered-title" names="3.\\ numbered\\ title">
+ <section names="3.\\ numbered\\ title">
<title>
3. Numbered Title
<paragraph>
@@ -627,7 +628,7 @@
""",
"""\
<document source="test data">
- <section ids="abc" names="abc">
+ <section names="abc">
<title>
ABC
<paragraph>
@@ -873,10 +874,10 @@
<system_message level="2" line="2" source="test data" type="WARNING">
<paragraph>
Explicit markup ends without a blank line; unexpected unindent.
- <section ids="hi" names="hi">
+ <section names="hi">
<title>
Hi
- <section ids="yo" names="yo">
+ <section names="yo">
<title>
Yo
<paragraph>
@@ -888,7 +889,7 @@
""",
"""\
<document source="test data">
- <section ids="empty-section" names="empty\\ section">
+ <section names="empty\\ section">
<title>
Empty Section
"""],
@@ -909,13 +910,13 @@
""",
"""\
<document source="test data">
- <section ids="one" names="one">
+ <section names="one">
<title>
One
<paragraph>
The bubble-up parser strategy conflicts with short titles
(<= 3 char-long over- & underlines).
- <section ids="two" names="two">
+ <section names="two">
<title>
Two
<paragraph>
Modified: trunk/docutils/test/test_parsers/test_rst/test_targets.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-03-28 18:54:14 UTC (rev 10307)
+++ trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-03-28 18:54:25 UTC (rev 10308)
@@ -29,6 +29,7 @@
def test_parser(self):
parser = Parser()
settings = get_default_settings(Parser)
+ settings.legacy_ids = False
settings.warning_stream = ''
for name, cases in totest.items():
for casenum, (case_input, case_expected) in enumerate(cases):
@@ -238,7 +239,7 @@
See the \n\
<reference name="example" refuri="example.rst">
example
- <target ids="example" names="example" refuri="example.rst">
+ <target names="example" refuri="example.rst">
<paragraph>
See the \n\
<reference name="example" refname="example">
@@ -292,15 +293,15 @@
<document source="test data">
<paragraph>
Duplicate implicit targets.
- <section dupnames="title" ids="title">
+ <section dupnames="title" ids="title-1">
<title>
Title
<paragraph>
Paragraph.
- <section dupnames="title" ids="title-1">
+ <section dupnames="title" ids="title-2">
<title>
Title
- <system_message backrefs="title-1" level="1" line="9" source="test data" type="INFO">
+ <system_message backrefs="title-2" level="1" line="9" source="test data" type="INFO">
<paragraph>
Duplicate implicit target name: "title".
<paragraph>
@@ -320,13 +321,13 @@
<document source="test data">
<paragraph>
Duplicate implicit/explicit targets.
- <section dupnames="title" ids="title">
+ <section dupnames="title">
<title>
Title
<system_message level="1" line="6" source="test data" type="INFO">
<paragraph>
Target name overrides implicit target name "title".
- <target ids="title-1" names="title">
+ <target ids="title" names="title">
<paragraph>
Paragraph.
"""],
@@ -343,11 +344,11 @@
<document source="test data">
<paragraph>
Duplicate implicit/directive targets.
- <section dupnames="title" ids="title">
+ <section dupnames="title">
<title>
Title
- <note ids="title-1" names="title">
- <system_message backrefs="title-1" level="1" line="7" source="test data" type="INFO">
+ <note ids="title" names="title">
+ <system_message backrefs="title" level="1" line="7" source="test data" type="INFO">
<paragraph>
Target name overrides implicit target name "title".
<paragraph>
@@ -445,21 +446,21 @@
<document source="test data">
<paragraph>
Duplicate targets:
- <section dupnames="target" ids="target">
+ <section dupnames="target">
<title>
Target
<paragraph>
Implicit section header target.
- <citation dupnames="target" ids="target-1">
+ <citation dupnames="target" ids="target">
<label>
TARGET
- <system_message backrefs="target-1" level="1" line="8" source="test data" type="INFO">
+ <system_message backrefs="target" level="1" line="8" source="test data" type="INFO">
<paragraph>
Target name overrides implicit target name "target".
<paragraph>
Citation target.
- <footnote auto="1" dupnames="target" ids="target-2">
- <system_message backrefs="target-2" level="2" line="10" source="test data" type="WARNING">
+ <footnote auto="1" dupnames="target" ids="target-1">
+ <system_message backrefs="target-1" level="2" line="10" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "target".
<paragraph>
@@ -467,21 +468,21 @@
<system_message level="2" line="12" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "target".
- <target dupnames="target" ids="target-3">
+ <target dupnames="target" ids="target-2">
<paragraph>
Explicit internal target.
<system_message level="2" line="16" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "target".
- <target dupnames="target" ids="target-4" refuri="Explicit_external_target">
+ <target dupnames="target" ids="target-3" refuri="Explicit_external_target">
<line_block>
<line>
Do not insert <system_message> element for duplicate
<line>
- <target dupnames="target" ids="target-5">
+ <target dupnames="target" ids="target-4">
target
, if this results in an invalid doctree.
- <rubric dupnames="target" ids="target-6">
+ <rubric dupnames="target" ids="target-5">
directive with target
<field_list>
<field>
@@ -492,7 +493,7 @@
with
<field>
<field_name>
- <target dupnames="target" ids="target-7">
+ <target dupnames="target" ids="target-6">
target
<field_body>
<paragraph>
Modified: trunk/docutils/test/test_parsers/test_rst/test_transitions.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_transitions.py 2026-03-28 18:54:14 UTC (rev 10307)
+++ trunk/docutils/test/test_parsers/test_rst/test_transitions.py 2026-03-28 18:54:25 UTC (rev 10308)
@@ -28,6 +28,7 @@
def test_parser(self):
parser = Parser()
settings = get_default_settings(Parser)
+ settings.legacy_ids = False
settings.warning_stream = ''
settings.halt_level = 5
for name, cases in totest.items():
@@ -74,7 +75,7 @@
""",
"""\
<document source="test data">
- <section ids="section-1" names="section\\ 1">
+ <section names="section\\ 1">
<title>
Section 1
<paragraph>
@@ -82,7 +83,7 @@
<transition>
<paragraph>
Second text division of section 1.
- <section ids="section-2" names="section\\ 2">
+ <section names="section\\ 2">
<title>
Section 2
<paragraph>
@@ -193,7 +194,7 @@
<document source="test data">
<paragraph>
Sections with transitions at beginning and end.
- <section ids="section-1" names="section\\ 1">
+ <section names="section\\ 1">
<title>
Section 1
<transition>
@@ -200,7 +201,7 @@
<paragraph>
The next transition is legal:
<transition>
- <section ids="section-2" names="section\\ 2">
+ <section names="section\\ 2">
<title>
Section 2
<transition>
@@ -263,16 +264,16 @@
""",
"""\
<document source="test data">
- <section ids="section-1" names="section\\ 1">
+ <section names="section\\ 1">
<title>
Section 1
- <section ids="subsection-1" names="subsection\\ 1">
+ <section names="subsection\\ 1">
<title>
Subsection 1
<paragraph>
Some text.
<transition>
- <section ids="section-2" names="section\\ 2">
+ <section names="section\\ 2">
<title>
Section 2
<paragraph>
@@ -295,13 +296,13 @@
""",
"""\
<document source="test data">
- <section ids="section-1" names="section\\ 1">
+ <section names="section\\ 1">
<title>
Section 1
<transition>
<transition>
<transition>
- <section ids="section-2" names="section\\ 2">
+ <section names="section\\ 2">
<title>
Section 2
<paragraph>
Modified: trunk/docutils/test/test_transforms/test_doctitle.py
===================================================================
--- trunk/docutils/test/test_transforms/test_doctitle.py 2026-03-28 18:54:14 UTC (rev 10307)
+++ trunk/docutils/test/test_transforms/test_doctitle.py 2026-03-28 18:54:25 UTC (rev 10308)
@@ -46,6 +46,7 @@
def test_transforms(self):
parser = Parser()
settings = get_default_settings(Parser)
+ settings.legacy_ids = False
settings.warning_stream = ''
register_directive('add-name-to-title', AddNameToDocumentTitle)
for name, (transforms, cases) in totest.items():
@@ -74,7 +75,7 @@
Paragraph.
""",
"""\
-<document ids="title" names="title" source="test data" title="Title">
+<document names="title" source="test data" title="Title">
<title>
Title
<comment xml:space="preserve">
@@ -88,7 +89,7 @@
Paragraph (no blank line).
""",
"""\
-<document ids="title" names="title" source="test data" title="Title">
+<document names="title" source="test data" title="Title">
<title>
Title
<paragraph>
@@ -106,7 +107,7 @@
<document source="test data">
<paragraph>
Paragraph.
- <section ids="title" names="title">
+ <section names="title">
<title>
Title
<paragraph>
@@ -124,10 +125,10 @@
Test title, subtitle, and title metadata.
""",
"""\
-<document ids="title" names="title" source="test data" title="Another Title">
+<document names="title" source="test data" title="Another Title">
<title>
Title
- <subtitle ids="subtitle" names="subtitle">
+ <subtitle names="subtitle">
Subtitle
<paragraph>
Test title, subtitle, and title metadata.
@@ -139,7 +140,7 @@
Test short underline.
""",
"""\
-<document ids="title" names="title" source="test data" title="Title">
+<document names="title" source="test data" title="Title">
<title>
Title
<system_message level="2" line="2" source="test data" type="WARNING">
@@ -161,7 +162,7 @@
(it was before the beginning of the section).
""",
"""\
-<document ids="long-title" names="long\\ title" source="test data" title="Long Title">
+<document names="long\\ title" source="test data" title="Long Title">
<title>
Long Title
<system_message level="2" line="1" source="test data" type="WARNING">
@@ -192,7 +193,7 @@
Paragraph 3.
""",
"""\
-<document ids="title-1" names="title\\ 1" source="test data" title="Title 1">
+<document names="title\\ 1" source="test data" title="Title 1">
<title>
Title 1
<comment xml:space="preserve">
@@ -199,12 +200,12 @@
Test multiple second-level titles.
<paragraph>
Paragraph 1.
- <section ids="title-2" names="title\\ 2">
+ <section names="title\\ 2">
<title>
Title 2
<paragraph>
Paragraph 2.
- <section ids="title-3" names="title\\ 3">
+ <section names="title\\ 3">
<title>
Title 3
<paragraph>
@@ -221,7 +222,7 @@
substitution_definition.
""",
"""\
-<document ids="title" names="title" source="test data" title="Title">
+<document names="title" source="test data" title="Title">
<title>
Title
<substitution_definition names="foo">
@@ -253,15 +254,15 @@
<document source="test data">
<paragraph>
(Because of this paragraph, the following is not a doc title.)
- <section ids="section-title" names="section\\ title">
+ <section names="section\\ title">
<title>
Section Title
- <subtitle ids="subtitle" names="subtitle">
+ <subtitle names="subtitle">
Subtitle
- <section ids="another-section" names="another\\ section">
+ <section names="another\\ section">
<title>
Another Section
- <subtitle ids="another-subtitle" names="another\\ subtitle">
+ <subtitle names="another\\ subtitle">
Another Subtitle
"""],
["""\
@@ -276,7 +277,7 @@
""",
"""\
-<document ids="title" names="Name title" source="test data" title="Title">
+<document names="Name title" source="test data" title="Title">
<title>
Title
<paragraph>
Modified: trunk/docutils/test/test_transforms/test_transitions.py
===================================================================
--- trunk/docutils/test/test_transforms/test_transitions.py 2026-03-28 18:54:14 UTC (rev 10307)
+++ trunk/docutils/test/test_transforms/test_transitions.py 2026-03-28 18:54:25 UTC (rev 10308)
@@ -31,6 +31,7 @@
def test_transforms(self):
parser = rst.Parser()
settings = get_default_settings(rst.Parser)
+ settings.legacy_ids = False
settings.warning_stream = ''
for name, (transforms, cases) in totest.items():
for casenum, (case_input, case_expected) in enumerate(cases):
@@ -87,16 +88,16 @@
""",
"""\
<document source="test data">
- <section ids="section-1" names="section\\ 1">
+ <section names="section\\ 1">
<title>
Section 1
- <section ids="subsection-1" names="subsection\\ 1">
+ <section names="subsection\\ 1">
<title>
Subsection 1
<paragraph>
A transition at the end of a section is moved behind the section.
<transition>
- <section ids="section-2" names="section\\ 2">
+ <section names="section\\ 2">
<title>
Section 2
<paragraph>
@@ -117,7 +118,7 @@
<paragraph>
A paragraph.
<transition>
- <section ids="section-1" names="section\\ 1">
+ <section names="section\\ 1">
<title>
Section 1
<paragraph>
@@ -222,7 +223,7 @@
<document source="test data">
<paragraph>
Sections with transitions at beginning and end.
- <section ids="section-1" names="section\\ 1">
+ <section names="section\\ 1">
<title>
Section 1
<transition>
@@ -231,7 +232,7 @@
Transition at the start of the section.
<comment xml:space="preserve">
Comment after transition.
- <section ids="section-2" names="section\\ 2">
+ <section names="section\\ 2">
<title>
Section 2
<paragraph>
@@ -341,7 +342,7 @@
""",
"""\
<document source="test data">
- <section ids="section-1" names="section\\ 1">
+ <section names="section\\ 1">
<title>
Section 1
<transition>
@@ -353,7 +354,7 @@
<system_message level="2" line="8" source="test data" type="WARNING">
<paragraph>
At least one body element should separate transitions.
- <section ids="section-2" names="section\\ 2">
+ <section names="section\\ 2">
<title>
Section 2
"""],
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-03-28 18:54:17
|
Revision: 10307
http://sourceforge.net/p/docutils/code/10307
Author: milde
Date: 2026-03-28 18:54:14 +0000 (Sat, 28 Mar 2026)
Log Message:
-----------
Add "SectionIDs" transform in standalone reader.
Add "SectionIDs" together with other transforms from `transforms.references`.
The change in `nodes.document.note_implicit_target()` affects all parsers,
so "SectionIDs" transform should be loaded by default for all parsers.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docs/api/transforms.rst
trunk/docutils/docutils/parsers/rst/__init__.py
trunk/docutils/docutils/readers/standalone.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-03-28 18:54:04 UTC (rev 10306)
+++ trunk/docutils/HISTORY.rst 2026-03-28 18:54:14 UTC (rev 10307)
@@ -42,7 +42,7 @@
- New configuration setting `legacy_ids`_.
-* docutils/parsers/rst/__init__.py
+* docutils/readers/standalone.py
- Load new transform `references.SectionIDs`.
Modified: trunk/docutils/docs/api/transforms.rst
===================================================================
--- trunk/docutils/docs/api/transforms.rst 2026-03-28 18:54:04 UTC (rev 10306)
+++ trunk/docutils/docs/api/transforms.rst 2026-03-28 18:54:14 UTC (rev 10307)
@@ -57,7 +57,7 @@
references_.Substitutions standalone_ (r), pep_ (r) _`220`
-references_.SectionIDs rst_ (p) _`240`
+references_.SectionIDs standalone_ (r), pep_ (r) _`240`
references_.PropagateTargets standalone_ (r), pep_ (r) _`260`
@@ -186,6 +186,7 @@
readers.standalone.Reader:
| references.Substitutions (220_)
+ | references.SectionIDs (240_)
| references.PropagateTargets (260_)
| frontmatter.\ DocTitle_ (320_)
| frontmatter.\ DocInfo_ (340_)
@@ -202,6 +203,7 @@
readers.pep.Reader:
| references.Substitutions (220_)
+ | references.SectionIDs (240_)
| references.PropagateTargets (260_)
| peps.Headers (360_)
| peps.Contents (380_)
@@ -222,7 +224,6 @@
.. _rst:
parsers.rst.Parser
- | references.SectionIDs (240_)
| universal.SmartQuotes (855_)
.. _writers:
Modified: trunk/docutils/docutils/parsers/rst/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/__init__.py 2026-03-28 18:54:04 UTC (rev 10306)
+++ trunk/docutils/docutils/parsers/rst/__init__.py 2026-03-28 18:54:14 UTC (rev 10307)
@@ -75,7 +75,7 @@
import docutils.statemachine
from docutils.parsers.rst import roles, states
from docutils import frontend, nodes
-from docutils.transforms import references, universal
+from docutils.transforms import universal
class Parser(docutils.parsers.Parser):
@@ -160,8 +160,7 @@
self.inliner = inliner
def get_transforms(self):
- return [*super().get_transforms(),
- references.SectionIDs, universal.SmartQuotes]
+ return super().get_transforms() + [universal.SmartQuotes]
def parse(self, inputstring, document) -> None:
"""Parse `inputstring` and populate `document`, a document tree."""
Modified: trunk/docutils/docutils/readers/standalone.py
===================================================================
--- trunk/docutils/docutils/readers/standalone.py 2026-03-28 18:54:04 UTC (rev 10306)
+++ trunk/docutils/docutils/readers/standalone.py 2026-03-28 18:54:14 UTC (rev 10307)
@@ -6,13 +6,18 @@
Standalone file Reader for the reStructuredText markup syntax.
"""
+from __future__ import annotations
+
__docformat__ = 'reStructuredText'
-
from docutils import frontend, readers
from docutils.transforms import frontmatter, references, misc
+TYPE_CHECKING = False
+if TYPE_CHECKING:
+ from docutils.transforms import Transform
+
class Reader(readers.Reader):
supported = ('standalone',)
@@ -48,9 +53,10 @@
config_section = 'standalone reader'
config_section_dependencies = ('readers',)
- def get_transforms(self):
+ def get_transforms(self) -> list[type[Transform]]:
return super().get_transforms() + [
references.Substitutions,
+ references.SectionIDs,
references.PropagateTargets,
frontmatter.DocTitle,
frontmatter.SectionSubTitle,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-03-28 18:54:07
|
Revision: 10306
http://sourceforge.net/p/docutils/code/10306
Author: milde
Date: 2026-03-28 18:54:04 +0000 (Sat, 28 Mar 2026)
Log Message:
-----------
Move "legacy_ids" setting to generic [parsers] config section.
The change in `nodes.document.note_implicit_target()` affects all parsers,
so the setting should be available to alternative parsers, too.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docs/user/config.rst
trunk/docutils/docutils/parsers/__init__.py
trunk/docutils/docutils/parsers/rst/__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/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-03-27 21:45:52 UTC (rev 10305)
+++ trunk/docutils/HISTORY.rst 2026-03-28 18:54:04 UTC (rev 10306)
@@ -38,9 +38,12 @@
- `document.set_id()` also updates the `document.nameids` map.
- `document.set_duplicate_name()` replaces `set_duplicate_name_id()`.
+* docutils/parsers/__init__.py
+
+ - New configuration setting `legacy_ids`_.
+
* docutils/parsers/rst/__init__.py
- - New configuration setting `legacy_ids`_.
- Load new transform `references.SectionIDs`.
* docutils/parsers/rst/directives/body.py
Modified: trunk/docutils/docs/user/config.rst
===================================================================
--- trunk/docutils/docs/user/config.rst 2026-03-27 21:45:52 UTC (rev 10305)
+++ trunk/docutils/docs/user/config.rst 2026-03-28 18:54:04 UTC (rev 10306)
@@ -787,6 +787,20 @@
New in Docutils 0.17.
+legacy_ids
+----------
+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`_.
+
+:Default: True; will change to False in Docutils 2.0.
+:Option: ``--legacy-ids``, ``--matching-ids``.
+
+New in Docutils 0.23.
+
+
raw_enabled
-----------
@@ -840,19 +854,6 @@
New in Docutils 0.13.
-legacy_ids
-~~~~~~~~~~
-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`_.
-
-:Default: True; will change to False in Docutils 2.0.
-:Option: ``--legacy-ids``, ``--matching-ids``.
-
-New in Docutils 0.23.
-
pep_references
~~~~~~~~~~~~~~
Recognize and link to standalone PEP references (like "PEP 258").
Modified: trunk/docutils/docutils/parsers/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/__init__.py 2026-03-27 21:45:52 UTC (rev 10305)
+++ trunk/docutils/docutils/parsers/__init__.py 2026-03-28 18:54:04 UTC (rev 10306)
@@ -48,6 +48,15 @@
['--line-length-limit'],
{'metavar': '<length>', 'type': 'int', 'default': 10_000,
'validator': frontend.validate_nonnegative_int}),
+ ('Keep identifiers backwards compatible. Default.',
+ ['--legacy-ids'],
+ {'action': 'store_true',
+ 'validator': frontend.validate_boolean,
+ 'default': True}),
+ ('Explicit targets use identifiers matching the reference name.',
+ ['--matching-ids'],
+ {'action': 'store_false',
+ 'dest': 'legacy_ids'}),
('Validate the document tree after parsing.',
['--validate'],
{'action': 'store_true',
Modified: trunk/docutils/docutils/parsers/rst/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/__init__.py 2026-03-27 21:45:52 UTC (rev 10305)
+++ trunk/docutils/docutils/parsers/rst/__init__.py 2026-03-28 18:54:04 UTC (rev 10306)
@@ -88,16 +88,7 @@
settings_spec = docutils.parsers.Parser.settings_spec + (
'reStructuredText Parser Options',
None,
- (('Keep identifiers backwards compatible. Default.',
- ['--legacy-ids'],
- {'action': 'store_true',
- 'validator': frontend.validate_boolean,
- 'default': True}),
- ('Explicit targets use identifiers matching the reference name.',
- ['--matching-ids'],
- {'action': 'store_false',
- 'dest': 'legacy_ids'}),
- ('Recognize and link to standalone PEP references (like "PEP 258").',
+ (('Recognize and link to standalone PEP references (like "PEP 258").',
['--pep-references'],
{'action': 'store_true', 'validator': frontend.validate_boolean}),
('Base URL for PEP references '
Modified: trunk/docutils/test/data/help/docutils.rst
===================================================================
--- trunk/docutils/test/data/help/docutils.rst 2026-03-27 21:45:52 UTC (rev 10305)
+++ trunk/docutils/test/data/help/docutils.rst 2026-03-28 18:54:04 UTC (rev 10306)
@@ -90,14 +90,14 @@
--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.
--validate Validate the document tree after parsing.
--no-validation Do not validate the document tree. (default)
reStructuredText Parser Options
-------------------------------
---legacy-ids Keep identifiers backwards compatible. Default.
---matching-ids Explicit targets use identifiers matching the
- reference name.
--pep-references Recognize and link to standalone PEP references (like
"PEP 258").
--pep-base-url=<URL> Base URL for PEP references (default
Modified: trunk/docutils/test/data/help/rst2html.rst
===================================================================
--- trunk/docutils/test/data/help/rst2html.rst 2026-03-27 21:45:52 UTC (rev 10305)
+++ trunk/docutils/test/data/help/rst2html.rst 2026-03-28 18:54:04 UTC (rev 10306)
@@ -91,14 +91,14 @@
--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.
--validate Validate the document tree after parsing.
--no-validation Do not validate the document tree. (default)
reStructuredText Parser Options
-------------------------------
---legacy-ids Keep identifiers backwards compatible. Default.
---matching-ids Explicit targets use identifiers matching the
- reference name.
--pep-references Recognize and link to standalone PEP references (like
"PEP 258").
--pep-base-url=<URL> Base URL for PEP references (default
Modified: trunk/docutils/test/data/help/rst2latex.rst
===================================================================
--- trunk/docutils/test/data/help/rst2latex.rst 2026-03-27 21:45:52 UTC (rev 10305)
+++ trunk/docutils/test/data/help/rst2latex.rst 2026-03-28 18:54:04 UTC (rev 10306)
@@ -91,14 +91,14 @@
--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.
--validate Validate the document tree after parsing.
--no-validation Do not validate the document tree. (default)
reStructuredText Parser Options
-------------------------------
---legacy-ids Keep identifiers backwards compatible. Default.
---matching-ids Explicit targets use identifiers matching the
- reference name.
--pep-references Recognize and link to standalone PEP references (like
"PEP 258").
--pep-base-url=<URL> Base URL for PEP references (default
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-03-27 21:45:55
|
Revision: 10305
http://sourceforge.net/p/docutils/code/10305
Author: milde
Date: 2026-03-27 21:45:52 +0000 (Fri, 27 Mar 2026)
Log Message:
-----------
Drop spurious back references from system messages.
Fix the conditional deciding whether to add a "backrefs" attribute to
a system message.
The test for empty `<target>`s (which are not shown in the output document)
now also catches indirect targets with a "refid" but no children.
Modified Paths:
--------------
trunk/docutils/docutils/nodes.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_hyperlinks.py
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-03-27 08:41:24 UTC (rev 10304)
+++ trunk/docutils/docutils/nodes.py 2026-03-27 21:45:52 UTC (rev 10305)
@@ -2144,7 +2144,7 @@
self.set_id(old_node) # set id to get running numbers right
if level:
# don't add backref id for empty targets (not shown in output)
- if isinstance(node, target) and 'refuri' in node:
+ if isinstance(node, target) and not node.children:
backrefs = []
else:
backrefs = [self.set_id(node)]
Modified: trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py 2026-03-27 08:41:24 UTC (rev 10304)
+++ trunk/docutils/test/test_parsers/test_rst/test_inline_markup.py 2026-03-27 21:45:52 UTC (rev 10305)
@@ -1300,7 +1300,7 @@
<target ids="tg2" names="tg2">
tg2
.
- <system_message backrefs="link-1" level="1" line="6" source="test data" type="INFO">
+ <system_message level="1" line="6" source="test data" type="INFO">
<paragraph>
Duplicate implicit target name: "link".
<paragraph>
Modified: trunk/docutils/test/test_parsers/test_rst/test_targets.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-03-27 08:41:24 UTC (rev 10304)
+++ trunk/docutils/test/test_parsers/test_rst/test_targets.py 2026-03-27 21:45:52 UTC (rev 10305)
@@ -265,7 +265,7 @@
targets
(same refname):
<target ids="link" names="link" refname="targets">
- <system_message backrefs="link-1" level="1" line="5" source="test data" type="INFO">
+ <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">
@@ -323,7 +323,7 @@
<section dupnames="title" ids="title">
<title>
Title
- <system_message backrefs="title-1" level="1" line="6" source="test data" type="INFO">
+ <system_message level="1" line="6" source="test data" type="INFO">
<paragraph>
Target name overrides implicit target name "title".
<target ids="title-1" names="title">
@@ -375,13 +375,13 @@
<target dupnames="title" ids="title">
<paragraph>
First.
- <system_message backrefs="title-1" level="2" line="7" source="test data" type="WARNING">
+ <system_message level="2" line="7" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "title".
<target dupnames="title" ids="title-1">
<paragraph>
Second.
- <system_message backrefs="title-2" level="2" line="11" source="test data" type="WARNING">
+ <system_message level="2" line="11" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "title".
<target dupnames="title" ids="title-2">
@@ -464,7 +464,7 @@
Duplicate explicit target name: "target".
<paragraph>
Autonumber-labeled footnote target.
- <system_message backrefs="target-3" level="2" line="12" source="test data" type="WARNING">
+ <system_message level="2" line="12" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "target".
<target dupnames="target" ids="target-3">
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-03-27 08:41:24 UTC (rev 10304)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-03-27 21:45:52 UTC (rev 10305)
@@ -292,7 +292,7 @@
<target dupnames="ztarget" refid="ztarget">
<paragraph ids="ztarget">
First
- <system_message backrefs="ztarget-1" level="2" line="5" source="test data" type="WARNING">
+ <system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
Duplicate explicit target name: "ztarget".
<target dupnames="ztarget" refid="ztarget-1">
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-03-27 08:41:27
|
Revision: 10304
http://sourceforge.net/p/docutils/code/10304
Author: milde
Date: 2026-03-27 08:41:24 +0000 (Fri, 27 Mar 2026)
Log Message:
-----------
Use "matching identifiers" in some functional tests.
Modified Paths:
--------------
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/latex_memoir.py
trunk/docutils/test/functional/tests/misc_rst_html5.py
trunk/docutils/test/functional/tests/standalone_rst_html4css1.py
trunk/docutils/test/functional/tests/standalone_rst_html5.py
trunk/docutils/test/functional/tests/standalone_rst_pseudoxml.py
trunk/docutils/test/functional/tests/standalone_rst_xetex.py
Modified: trunk/docutils/test/functional/expected/standalone_rst_html5.html
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_html5.html 2026-03-27 08:41:10 UTC (rev 10303)
+++ trunk/docutils/test/functional/expected/standalone_rst_html5.html 2026-03-27 08:41:24 UTC (rev 10304)
@@ -111,8 +111,8 @@
<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>
<ul class="auto-toc">
-<li><p><a class="reference internal" href="#duplicate-target-names" 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-1" id="toc-entry-21"><span class="sectnum">2.13.2 </span>Duplicate Target Names</a></p></li>
+<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>
</ul>
</li>
<li><p><a class="reference internal" href="#directives" id="toc-entry-22"><span class="sectnum">2.14 </span>Directives</a></p>
@@ -543,13 +543,13 @@
refer to the <a class="reference internal" href="#targets">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">
+<section id="duplicate-target-names-1">
<h4><a class="toc-backref" href="#toc-entry-20" role="doc-backlink"><span class="sectnum">2.13.1 </span>Duplicate Target Names</a></h4>
<p>Duplicate names in section headers or other implicit targets will
generate "info" (level-1) system messages. Duplicate names in
explicit targets will generate "warning" (level-2) system messages.</p>
</section>
-<section id="duplicate-target-names-1">
+<section id="duplicate-target-names-2">
<h4><a class="toc-backref" href="#toc-entry-21" role="doc-backlink"><span class="sectnum">2.13.2 </span>Duplicate Target Names</a></h4>
<p>Since there are two "Duplicate Target Names" section headers, we
cannot uniquely refer to either of them by name. If we try to (like
Modified: trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2026-03-27 08:41:10 UTC (rev 10303)
+++ trunk/docutils/test/functional/expected/standalone_rst_pseudoxml.txt 2026-03-27 08:41:24 UTC (rev 10304)
@@ -211,13 +211,13 @@
<bullet_list classes="auto-toc">
<list_item>
<paragraph>
- <reference ids="toc-entry-20" refid="duplicate-target-names">
+ <reference ids="toc-entry-20" refid="duplicate-target-names-1">
<generated classes="sectnum">
2.13.1
Duplicate Target Names
<list_item>
<paragraph>
- <reference ids="toc-entry-21" refid="duplicate-target-names-1">
+ <reference ids="toc-entry-21" refid="duplicate-target-names-2">
<generated classes="sectnum">
2.13.2
Duplicate Target Names
@@ -1159,7 +1159,7 @@
`hyperlink reference without a target`_
, which generates an
error.
- <section dupnames="duplicate\ target\ names" ids="duplicate-target-names">
+ <section dupnames="duplicate\ target\ names" ids="duplicate-target-names-1">
<title auto="1" refid="toc-entry-20">
<generated classes="sectnum">
2.13.1
@@ -1168,12 +1168,12 @@
Duplicate names in section headers or other implicit targets will
generate "info" (level-1) system messages. Duplicate names in
explicit targets will generate "warning" (level-2) system messages.
- <section dupnames="duplicate\ target\ names" ids="duplicate-target-names-1">
+ <section dupnames="duplicate\ target\ names" ids="duplicate-target-names-2">
<title auto="1" refid="toc-entry-21">
<generated classes="sectnum">
2.13.2
Duplicate Target Names
- <system_message backrefs="duplicate-target-names-1" level="1" line="437" source="functional/input/data/standard.rst" type="INFO">
+ <system_message backrefs="duplicate-target-names-2" level="1" line="437" source="functional/input/data/standard.rst" type="INFO">
<paragraph>
Duplicate implicit target name: "duplicate target names".
<paragraph>
@@ -1925,7 +1925,7 @@
, and
<reference name="references" refuri="http://www.python.org/">
references
- <target ids="references" names="references" refuri="http://www.python.org/">
+ <target names="references" refuri="http://www.python.org/">
.
<section ids="code" names="code">
<title auto="1" refid="toc-entry-52">
Modified: trunk/docutils/test/functional/expected/standalone_rst_xetex.tex
===================================================================
--- trunk/docutils/test/functional/expected/standalone_rst_xetex.tex 2026-03-27 08:41:10 UTC (rev 10303)
+++ trunk/docutils/test/functional/expected/standalone_rst_xetex.tex 2026-03-27 08:41:24 UTC (rev 10304)
@@ -192,9 +192,9 @@
\begin{DUclass}{auto-toc}
\begin{itemize}
-\item \hyperref[duplicate-target-names]{2.13.1 Duplicate Target Names}
+\item \hyperref[duplicate-target-names-1]{2.13.1 Duplicate Target Names}
-\item \hyperref[duplicate-target-names-1]{2.13.2 Duplicate Target Names}
+\item \hyperref[duplicate-target-names-2]{2.13.2 Duplicate Target Names}
\end{itemize}
\end{DUclass}
@@ -763,7 +763,7 @@
\subsubsection{2.13.1 Duplicate Target Names%
- \label{duplicate-target-names}%
+ \label{duplicate-target-names-1}%
}
Duplicate names in section headers or other implicit targets will
@@ -772,7 +772,7 @@
\subsubsection{2.13.2 Duplicate Target Names%
- \label{duplicate-target-names-1}%
+ \label{duplicate-target-names-2}%
}
Since there are two “Duplicate Target Names” section headers, we
Modified: trunk/docutils/test/functional/tests/latex_memoir.py
===================================================================
--- trunk/docutils/test/functional/tests/latex_memoir.py 2026-03-27 08:41:10 UTC (rev 10303)
+++ trunk/docutils/test/functional/tests/latex_memoir.py 2026-03-27 08:41:24 UTC (rev 10304)
@@ -8,6 +8,7 @@
'use_latex_docinfo': 1,
'documentclass': "memoir",
'template': "titlingpage.tex",
+ 'legacy_ids': True,
# test the legacy class functions (since 0.18 default is False )
'legacy_class_functions': True,
'legacy_column_widths': True,
Modified: trunk/docutils/test/functional/tests/misc_rst_html5.py
===================================================================
--- trunk/docutils/test/functional/tests/misc_rst_html5.py 2026-03-27 08:41:10 UTC (rev 10303)
+++ trunk/docutils/test/functional/tests/misc_rst_html5.py 2026-03-27 08:41:24 UTC (rev 10304)
@@ -8,6 +8,7 @@
# location of stylesheets (relative to ``docutils/test/``)
'stylesheet_dirs': ('functional/input/data', ),
'stylesheet_path': 'minimal.css,responsive.css',
+ 'legacy_ids': False,
'smart_quotes': 'yes',
'image_loading': 'embed',
'toc_backlinks': 'top',
Modified: trunk/docutils/test/functional/tests/standalone_rst_html4css1.py
===================================================================
--- trunk/docutils/test/functional/tests/standalone_rst_html4css1.py 2026-03-27 08:41:10 UTC (rev 10303)
+++ trunk/docutils/test/functional/tests/standalone_rst_html4css1.py 2026-03-27 08:41:24 UTC (rev 10304)
@@ -6,6 +6,7 @@
writer = "html4css1"
settings_overrides = {
'sectsubtitle_xform': True,
+ 'legacy_ids': True,
# location of stylesheets (relative to ``docutils/test/``)
'stylesheet_dirs': ('functional/input/data', ),
}
Modified: trunk/docutils/test/functional/tests/standalone_rst_html5.py
===================================================================
--- trunk/docutils/test/functional/tests/standalone_rst_html5.py 2026-03-27 08:41:10 UTC (rev 10303)
+++ trunk/docutils/test/functional/tests/standalone_rst_html5.py 2026-03-27 08:41:24 UTC (rev 10304)
@@ -6,6 +6,7 @@
writer = "html5"
settings_overrides = {
'sectsubtitle_xform': True,
+ 'legacy_ids': False,
# "smart" quotes:
# 'smart_quotes': 'yes',
# location of stylesheets (relative to ``docutils/test/``)
Modified: trunk/docutils/test/functional/tests/standalone_rst_pseudoxml.py
===================================================================
--- trunk/docutils/test/functional/tests/standalone_rst_pseudoxml.py 2026-03-27 08:41:10 UTC (rev 10303)
+++ trunk/docutils/test/functional/tests/standalone_rst_pseudoxml.py 2026-03-27 08:41:24 UTC (rev 10304)
@@ -6,6 +6,7 @@
writer = "pseudoxml"
settings_overrides = {
'sectsubtitle_xform': True,
+ 'legacy_ids': False,
# enable INFO-level system messages in this test:
'report_level': 1,
}
Modified: trunk/docutils/test/functional/tests/standalone_rst_xetex.py
===================================================================
--- trunk/docutils/test/functional/tests/standalone_rst_xetex.py 2026-03-27 08:41:10 UTC (rev 10303)
+++ trunk/docutils/test/functional/tests/standalone_rst_xetex.py 2026-03-27 08:41:24 UTC (rev 10304)
@@ -6,6 +6,7 @@
writer = "xetex"
settings_overrides = {
'sectsubtitle_xform': True,
+ 'legacy_ids': False,
# use "smartquotes" transition:
'smart_quotes': True,
# use docutils.sty and up-to-date class functions:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-03-27 08:41:13
|
Revision: 10303
http://sourceforge.net/p/docutils/code/10303
Author: milde
Date: 2026-03-27 08:41:10 +0000 (Fri, 27 Mar 2026)
Log Message:
-----------
Generate identifiers for sections and ToC in transforms.
If the setting "legacy_ids" is False, the rST parser does not generate
IDs for implicit targets. OTOH, writers and the `parts.Contents` transform
rely on section IDs. `transforms.parts.Contents` also expects an identifier
for the `<topic>` containing the table of contents.
New and changed transforms:
`references.SectionIDs`
new, ensures all sections have an identifier.
`references.IndirectHyperlinks?
don't break, if the "relay target" points to an element with
reference-name but no identifier.
`parts.Contents`
sets an identifier for the table of contents.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/api/transforms.rst
trunk/docutils/docutils/parsers/rst/__init__.py
trunk/docutils/docutils/transforms/parts.py
trunk/docutils/docutils/transforms/references.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-03-27 08:40:56 UTC (rev 10302)
+++ trunk/docutils/HISTORY.rst 2026-03-27 08:41:10 UTC (rev 10303)
@@ -41,6 +41,7 @@
* docutils/parsers/rst/__init__.py
- New configuration setting `legacy_ids`_.
+ - Load new transform `references.SectionIDs`.
* docutils/parsers/rst/directives/body.py
@@ -74,6 +75,10 @@
- Use `nodes.transition.validate_position()` to warn about transitions
at the beginning or end of the document or a section.
+* docutils/transforms/references.py:
+
+ - New transform `SectionIDs`: ensure all sections have an "identifier".
+
* docutils/writers/html5_polyglot/__init__.py
- Use a section's last "ids" attribute for the "section-self-link".
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-03-27 08:40:56 UTC (rev 10302)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-03-27 08:41:10 UTC (rev 10303)
@@ -323,6 +323,8 @@
`nodes.document.set_duplicate_name()`
Called by `nodes.document.note_names()` to handle duplicate names.
Provisional.
+ `transforms.SectionIDs`:
+ Ensure all sections have an identifier_.
Removed objects
`parsers.rst.directives.tables.CSVTable.check_requirements()`
@@ -1595,6 +1597,7 @@
.. _Docutils Document Model:
.. _Docutils XML: docs/ref/doctree.html
.. _"colwidth" attribute: docs/ref/doctree.html#colwidth
+.. _identifier: docs/ref/doctree.html#identifiers
.. _<doctest_block>: docs/ref/doctree.html#doctest-block
.. _reference names: docs/ref/doctree.html#reference-names
.. _<target>: docs/ref/doctree.html#target
Modified: trunk/docutils/docs/api/transforms.rst
===================================================================
--- trunk/docutils/docs/api/transforms.rst 2026-03-27 08:40:56 UTC (rev 10302)
+++ trunk/docutils/docs/api/transforms.rst 2026-03-27 08:41:10 UTC (rev 10303)
@@ -57,6 +57,8 @@
references_.Substitutions standalone_ (r), pep_ (r) _`220`
+references_.SectionIDs rst_ (p) _`240`
+
references_.PropagateTargets standalone_ (r), pep_ (r) _`260`
frontmatter.\ DocTitle_ standalone_ (r) _`320`
@@ -220,7 +222,8 @@
.. _rst:
parsers.rst.Parser
- universal.SmartQuotes (855_)
+ | references.SectionIDs (240_)
+ | universal.SmartQuotes (855_)
.. _writers:
Modified: trunk/docutils/docutils/parsers/rst/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/__init__.py 2026-03-27 08:40:56 UTC (rev 10302)
+++ trunk/docutils/docutils/parsers/rst/__init__.py 2026-03-27 08:41:10 UTC (rev 10303)
@@ -75,7 +75,7 @@
import docutils.statemachine
from docutils.parsers.rst import roles, states
from docutils import frontend, nodes
-from docutils.transforms import universal
+from docutils.transforms import references, universal
class Parser(docutils.parsers.Parser):
@@ -169,7 +169,8 @@
self.inliner = inliner
def get_transforms(self):
- return super().get_transforms() + [universal.SmartQuotes]
+ return [*super().get_transforms(),
+ references.SectionIDs, universal.SmartQuotes]
def parse(self, inputstring, document) -> None:
"""Parse `inputstring` and populate `document`, a document tree."""
Modified: trunk/docutils/docutils/transforms/parts.py
===================================================================
--- trunk/docutils/docutils/transforms/parts.py 2026-03-27 08:40:56 UTC (rev 10302)
+++ trunk/docutils/docutils/transforms/parts.py 2026-03-27 08:41:10 UTC (rev 10303)
@@ -86,6 +86,8 @@
default_priority = 720
def apply(self) -> None:
+ # ensure the "ToC topic" wrapper element has an identifier:
+ self.toc_id = self.document.set_id(self.startnode.parent)
# let the writer (or output software) build the contents list?
toc_by_writer = getattr(self.document.settings, 'use_latex_toc', False)
# TODO: handle "generate_oowriter_toc" setting of the "ODT" writer.
@@ -100,7 +102,6 @@
startnode = startnode.parent
else:
startnode = self.document
- self.toc_id = self.startnode.parent['ids'][0]
if 'backlinks' in details:
self.backlinks = details['backlinks']
else:
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-03-27 08:40:56 UTC (rev 10302)
+++ trunk/docutils/docutils/transforms/references.py 2026-03-27 08:41:10 UTC (rev 10303)
@@ -14,9 +14,29 @@
from docutils.transforms import Transform
-class PropagateTargets(Transform):
+class SectionIDs(Transform):
+ """
+ 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.
+
+ However, the `parts.Contents` transform and most writers
+ expect sections to have an identifier, so this transform adds them.
"""
+ default_priority = 240
+
+ def apply(self) -> None:
+ if getattr(self.document.settings, "legacy_ids", True):
+ return
+ for node in self.document.findall(nodes.section):
+ self.document.set_id(node)
+
+
+class PropagateTargets(Transform):
+ """
Propagate empty internal targets to the next element.
Given the following nodes::
@@ -222,22 +242,26 @@
self.resolve_indirect_references(target)
def resolve_indirect_target(self, target) -> None:
+ # indirect targets have either a refname or refid attribute
refname = target.get('refname')
- if refname is None:
- reftarget_id = target['refid']
+ refid = target.get('refid')
+ if refid:
+ reftarget = self.document.ids.get(refid)
else:
- reftarget_id = self.document.nameids.get(refname)
- if not reftarget_id:
- # Check the unknown_reference_resolvers
- for resolver_function in \
- self.document.transformer.unknown_reference_resolvers:
- if resolver_function(target):
- break
- else:
- self.nonexistent_indirect_target(target)
- return
- reftarget = self.document.ids[reftarget_id]
- reftarget.note_referenced_by(id=reftarget_id)
+ reftarget = self.document.names.get(refname)
+ refid = self.document.nameids.get(refname)
+ if reftarget and not refid:
+ refid = self.document.set_id(reftarget)
+ if not reftarget:
+ # Check the unknown_reference_resolvers
+ for resolver_function in \
+ self.document.transformer.unknown_reference_resolvers:
+ if resolver_function(target):
+ break
+ else:
+ self.nonexistent_indirect_target(target)
+ return
+ reftarget.note_referenced_by(id=refid)
if (isinstance(reftarget, nodes.target)
and not reftarget.resolved
and reftarget.hasattr('refname')):
@@ -256,7 +280,7 @@
self.document.note_refid(target)
else:
if reftarget['ids']:
- target['refid'] = reftarget_id
+ target['refid'] = refid
self.document.note_refid(target)
else:
self.nonexistent_indirect_target(target)
@@ -266,7 +290,7 @@
target.resolved = True
def nonexistent_indirect_target(self, target) -> None:
- if target['refname'] in self.document.nameids:
+ if self.document.names.get(target['refname'], '') is None:
self.indirect_target_error(target, 'which is a duplicate, and '
'cannot be used as a unique reference')
else:
Modified: trunk/docutils/test/test_transforms/test_contents.py
===================================================================
--- trunk/docutils/test/test_transforms/test_contents.py 2026-03-27 08:40:56 UTC (rev 10302)
+++ trunk/docutils/test/test_transforms/test_contents.py 2026-03-27 08:41:10 UTC (rev 10303)
@@ -20,7 +20,7 @@
from docutils.frontend import get_default_settings
from docutils.parsers.rst import Parser
-from docutils.transforms.references import Substitutions
+from docutils.transforms.references import SectionIDs, Substitutions
from docutils.transforms.universal import TestMessages
from docutils.utils import new_document
@@ -46,7 +46,7 @@
totest = {}
-totest['tables_of_contents'] = ((Substitutions,), [
+totest['tables_of_contents'] = ((SectionIDs, Substitutions,), [
["""\
.. contents::
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-03-27 08:40:56 UTC (rev 10302)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-03-27 08:41:10 UTC (rev 10303)
@@ -21,7 +21,7 @@
from docutils.parsers.rst import Parser
from docutils.transforms.references import PropagateTargets, \
AnonymousHyperlinks, IndirectHyperlinks, ExternalTargets, \
- InternalTargets, DanglingReferences
+ InternalTargets, DanglingReferences, SectionIDs
from docutils.transforms.universal import TestMessages
from docutils.utils import new_document
@@ -31,7 +31,7 @@
transforms = (PropagateTargets, AnonymousHyperlinks, IndirectHyperlinks,
ExternalTargets, InternalTargets, DanglingReferences,
- TestMessages)
+ SectionIDs, TestMessages)
def test_transforms(self):
parser = Parser()
@@ -1100,7 +1100,9 @@
"""],
])
-totest['hyperlinks'] = ({'legacy_ids': False}, [
+totest['hyperlinks'] = ({'legacy_ids': False},
+ # all but the last sample compile as before
+ totest['hyperlinks legacy'][1][:-1] + [
["""\
foo
---
@@ -1114,7 +1116,7 @@
""",
"""\
<document source="test data">
- <section dupnames="foo">
+ <section dupnames="foo" ids="foo-1">
<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-03-27 08:40:56 UTC (rev 10302)
+++ trunk/docutils/test/test_transforms/test_sectnum.py 2026-03-27 08:41:10 UTC (rev 10303)
@@ -20,7 +20,7 @@
from docutils.frontend import get_default_settings
from docutils.parsers.rst import Parser
-from docutils.transforms.references import Substitutions
+from docutils.transforms.references import SectionIDs, Substitutions
from docutils.transforms.universal import TestMessages
from docutils.utils import new_document
@@ -46,7 +46,7 @@
totest = {}
-totest['section_numbers'] = ((Substitutions,), [
+totest['section_numbers'] = ((SectionIDs, Substitutions), [
["""\
.. sectnum::
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-03-27 08:40:59
|
Revision: 10302
http://sourceforge.net/p/docutils/code/10302
Author: milde
Date: 2026-03-27 08:40:56 +0000 (Fri, 27 Mar 2026)
Log Message:
-----------
Improve handling of duplicate reference names.
Separate registration of reference names and ids.
If legacy_ids_ is False, `note_implicit_target()` does not generate
an identifier. This allows an explicit target to use the matching
identifier in case of a name conflict.
Add test case for the new behaviour.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docutils/nodes.py
trunk/docutils/docutils/parsers/rst/directives/misc.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-03-26 13:52:27 UTC (rev 10301)
+++ trunk/docutils/HISTORY.rst 2026-03-27 08:40:56 UTC (rev 10302)
@@ -28,6 +28,16 @@
<target> elements when testing for a <transition> at the begin or end
of a <section> or the <document>.
+ - If legacy_ids_ is False, `note_implicit_target()` does not generate
+ an ID. This allows an explicit target to use the matching ID in case
+ of a name conflict.
+
+ - The new internal attribute `document.names` maps reference names to
+ the referenced elements (or ``None`` if the name is a duplicate).
+ - New method `document.note_names()`.
+ - `document.set_id()` also updates the `document.nameids` map.
+ - `document.set_duplicate_name()` replaces `set_duplicate_name_id()`.
+
* docutils/parsers/rst/__init__.py
- New configuration setting `legacy_ids`_.
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-03-26 13:52:27 UTC (rev 10301)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-03-27 08:40:56 UTC (rev 10302)
@@ -183,6 +183,9 @@
`writers.latex2e.LaTeXTranslator.visit_docinfo_item()`
(ignored since Docutils 0.22) in Docutils 0.24.
+* Remove `nodes.set_name_id_map()` in Docutils 1.0
+ (not used since Docutils 0.23).
+
* Remove `parsers.rst.directives.CSVTable.HeaderDialect`
in Docutils 1.0.
@@ -311,9 +314,21 @@
Configuration changes
- New setting `legacy_ids`_.
+New objects
+ `nodes.document.names`:
+ Internal attribute mapping `reference names`_ to the
+ referenced elements (or ``None`` if the name is a duplicate).
+ `nodes.document.note_names()`:
+ Register an element's names, check for duplicates.
+ `nodes.document.set_duplicate_name()`
+ Called by `nodes.document.note_names()` to handle duplicate names.
+ Provisional.
+
Removed objects
`parsers.rst.directives.tables.CSVTable.check_requirements()`
not required with Python 3.
+ `nodes.document.set_duplicate_name_id()`
+ internal method, replaced by `nodes.document.set_duplicate_name()`.
Release 0.22.4 (2025-12-18)
@@ -1581,6 +1596,7 @@
.. _Docutils XML: docs/ref/doctree.html
.. _"colwidth" attribute: docs/ref/doctree.html#colwidth
.. _<doctest_block>: docs/ref/doctree.html#doctest-block
+.. _reference names: docs/ref/doctree.html#reference-names
.. _<target>: docs/ref/doctree.html#target
.. _"class": docs/ref/rst/directives.html#class
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-03-26 13:52:27 UTC (rev 10301)
+++ trunk/docutils/docutils/nodes.py 2026-03-27 08:40:56 UTC (rev 10302)
@@ -1890,6 +1890,12 @@
self.refids: dict[str, list[Element]] = {}
"""(Incomplete) Mapping of ids to lists of referencing nodes."""
+ self.names: dict[str, Element|None] = {}
+ """Mapping of names to nodes (or ``None`` if name is a duplicate)."""
+
+ self.ids: dict[str, Element] = {}
+ """Mapping of ids to nodes."""
+
self.nameids: dict[str, str] = {}
"""Mapping of names to unique id's."""
@@ -1897,9 +1903,6 @@
"""Mapping of names to hyperlink type. True: explicit, False: implicit.
"""
- self.ids: dict[str, Element] = {}
- """Mapping of ids to nodes."""
-
self.footnote_refs: dict[str, list[footnote_reference]] = {}
"""Mapping of footnote labels to lists of footnote_reference nodes."""
@@ -1973,19 +1976,35 @@
msgnode: Element | None = None,
suggested_prefix: str = '',
) -> str:
- if node['ids']:
- # register and check for duplicates
- for id in node['ids']:
- self.ids.setdefault(id, node)
- if self.ids[id] is not node:
- msg = self.reporter.error(f'Duplicate ID: "{id}" used by '
- f'{self.ids[id].starttag()} '
- f'and {node.starttag()}',
- base_node=node)
- if msgnode is not None:
- msgnode += msg
- return id
- # generate and set id
+ """
+ Check/set identifiers of element `node`. Return last identifier.
+
+ Check `node`s identifiers for duplicates,
+ create a new identifier if there are none.
+ Update `document.ids` and `document.nameids`.
+
+ Provisional.
+ """
+ if not node['ids']:
+ node['ids'].append(self.create_id(node, suggested_prefix))
+ # register and check for duplicates
+ for id in node['ids']:
+ self.ids.setdefault(id, node)
+ if self.ids[id] is not node:
+ msg = self.reporter.error(f'Duplicate ID: "{id}" used by '
+ f'{self.ids[id].starttag()} '
+ f'and {node.starttag()}',
+ base_node=node)
+ if msgnode is not None:
+ msgnode += msg
+ for name in node['names']:
+ self.nameids[name] = id
+ return id
+
+ def create_id(self, node: Element, suggested_prefix: str = '') -> str:
+ # Internal auxiliary method for set_id():
+ # generate and return a suitable identifier for `node`.
+ # See also make_id()
id_prefix = self.settings.id_prefix
auto_id_prefix = self.settings.auto_id_prefix
base_id = ''
@@ -2004,6 +2023,8 @@
# disambiguate name-derived ID
# TODO: remove second condition after announcing change
prefix = id + '-'
+ elif node['dupnames'] and make_id(node['dupnames'][0]):
+ prefix = make_id(node['dupnames'][0]) + '-'
else:
prefix = id_prefix + auto_id_prefix
if prefix.endswith('%'):
@@ -2014,8 +2035,6 @@
id = f'{prefix}{self.id_counter[prefix]}'
if id not in self.ids:
break
- node['ids'].append(id)
- self.ids[id] = node
return id
def set_name_id_map(self,
@@ -2024,36 +2043,54 @@
msgnode: Element | None = None,
explicit: bool = False,
) -> None:
+ """Deprecated. Will be removed in Docutils 1.0."""
+ warnings.warn('nodes.document.set_name_id_map() will be removed'
+ ' in Docutils 1.0.', DeprecationWarning, stacklevel=2)
+ self.note_names(node, msgnode, explicit)
+ for name in node['names']:
+ self.nameids[name] = id
+
+ def set_duplicate_name(self,
+ node: Element,
+ name: str,
+ msgnode: Element,
+ explicit: bool,
+ ) -> None:
"""
- Update the name/id mappings.
+ Handle name conflicts according to the `rST specification`__.
- `self.nameids` maps names to IDs. The value ``None`` indicates
- that the name is a "dupname" (i.e. there are already at least
- two targets with the same name and type).
+ Called by `self.note_names()` when the reference name `name`
+ of the element `node` is already registered in `self.names`.
- `self.nametypes` maps names to booleans representing
- hyperlink target type (True==explicit, False==implicit).
+ `self.names` maps names to elements. The value ``None`` indicates
+ that the name is a "dupname" (i.e. the document contains two or
+ more elements with the same name and target type).
- The following state transition table shows how `self.nameids` items
- ("id") and `self.nametypes` items ("type") change with new input
- (a call to this method), and what actions are performed:
+ `self.nametypes` maps names to booleans representing the target type
+ (True = "explicit", False = "implicit").
- ======== ==== ======== ==== ======== ======== ======= ======
- Input Old State New State Action Notes
- -------- -------------- -------------- ---------------- ------
- type id type id type dupname report
- ======== ==== ======== ==== ======== ======== ======= ======
- explicit new explicit
- implicit new implicit
- explicit old explicit None explicit new,old WARNING [#ex]_
- implicit old explicit old explicit new INFO [#ex]_
- explicit old implicit new explicit old INFO [#ex]_
- implicit old implicit None implicit new,old INFO [#ex]_
- explicit None explicit None explicit new WARNING
- implicit None explicit None explicit new INFO
+ The following state transition table shows how the values
+ of `self.names` ("name") and `self.nametypes` ("type") items
+ with key `name` change and which actions are performed.
+
+ "Old" is the element with conflicting reference name,
+ "new" is the element specified by the argument `node`.
+ The "Input type" is specified by the argument `explicit`.
+
+ ======== ==== ======== ==== ======== =============== =======
+ Input Old State New State Action
+ -------- -------------- -------------- ------------------------
+ type name type name type invalidate [#]_ report
+ ======== ==== ======== ==== ======== =============== =======
+ explicit old explicit None explicit new,old [#ex]_ WARNING
+ implicit old explicit old explicit new INFO
+ explicit old implicit new explicit old INFO
+ implicit old implicit None implicit new,old [#ex]_ INFO
+ explicit None explicit None explicit new WARNING
+ implicit None explicit None explicit new INFO
explicit None implicit new explicit
- implicit None implicit None implicit new INFO
- ======== ==== ======== ==== ======== ======== ======= ======
+ implicit None implicit None implicit new INFO
+ ======== ==== ======== ==== ======== =============== =======
.. [#] When "invalidating" an element, `name` is transferred from
the element's "name" attribute to its "dupnames" attribute.
@@ -2064,32 +2101,15 @@
__ https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html
#implicit-hyperlink-targets
- Provisional. There will be changes to prefer explicit reference names
- as base for an element's ID.
+ Provisional.
"""
- for name in tuple(node['names']):
- if name in self.nameids:
- self.set_duplicate_name_id(node, id, name, msgnode, explicit)
- # attention: modifies node['names']
- else:
- self.nameids[name] = id
- self.nametypes[name] = explicit
-
- def set_duplicate_name_id(self,
- node: Element,
- id: str,
- name: str,
- msgnode: Element,
- explicit: bool,
- ) -> None:
- old_id = self.nameids[name] # None if name is only dupname
+ old_node = self.names[name] # None if name is only dupname
old_explicit = self.nametypes[name]
- old_node = self.ids.get(old_id)
level = 0 # system message level: 1-info, 2-warning
self.nametypes[name] = old_explicit or explicit
- if old_id is not None and (
+ if old_node is not None and (
'refname' in node and node['refname'] == old_node.get('refname')
or 'refuri' in node and node['refuri'] == old_node.get('refuri')
):
@@ -2103,12 +2123,13 @@
level = 2
s = f'Duplicate explicit target name: "{name}".'
dupname(node, name)
- if old_id is not None:
+ if old_node is not None:
dupname(old_node, name)
+ self.names[name] = None
self.nameids[name] = None
else: # new explicit, old implicit -> override
- self.nameids[name] = id
- if old_id is not None:
+ self.names[name] = node
+ if old_node is not None:
level = 1
s = f'Target name overrides implicit target name "{name}".'
dupname(old_node, name)
@@ -2116,15 +2137,17 @@
level = 1
s = f'Duplicate implicit target name: "{name}".'
dupname(node, name)
- if old_id is not None and not old_explicit:
+ if old_node is not None and not old_explicit:
dupname(old_node, name)
+ self.names[name] = None
self.nameids[name] = None
-
+ self.set_id(old_node) # set id to get running numbers right
if level:
- backrefs = [id]
# don't add backref id for empty targets (not shown in output)
if isinstance(node, target) and 'refuri' in node:
backrefs = []
+ else:
+ backrefs = [self.set_id(node)]
msg = self.reporter.system_message(level, s, backrefs=backrefs,
base_node=node)
# try appending near to the problem:
@@ -2131,22 +2154,41 @@
if msgnode is not None and 'Body' in repr(msgnode.content_model):
msgnode += msg
+ def note_names(self,
+ node: Element,
+ msgnode: Element|None = None,
+ explicit: bool = False,
+ ) -> None:
+ """
+ Register the reference names of the element `node`.
+
+ Update `self.names` and `self.nametypes`
+ for each name in the "names" attribute of `node`.
+ In case of name conflicts, call `self.set_duplicate_name()`.
+ """
+ for name in tuple(node['names']):
+ if name in self.names and self.names[name] != node:
+ self.set_duplicate_name(node, name, msgnode, explicit)
+ # attention: modifies node['names']
+ else:
+ self.names[name] = node
+ self.nametypes.setdefault(name, explicit)
+
def has_name(self, name: str) -> bool:
- return name in self.nameids
+ # TODO: deprecate? (use ``name in document.names``)
+ return name in self.names
# "note" here is an imperative verb: "take note of".
- def note_implicit_target(
- self, target: Element, msgnode: Element | None = None) -> None:
- # TODO: Postpone ID creation and register reference name instead of ID?
- id = self.set_id(target, msgnode)
- self.set_name_id_map(target, id, msgnode, explicit=False)
+ def note_implicit_target(self, target: Element,
+ msgnode: Element|None = None) -> None:
+ self.note_names(target, msgnode, explicit=False)
+ if getattr(self.settings, "legacy_ids", True):
+ self.set_id(target, msgnode)
- def note_explicit_target(
- self, target: Element, msgnode: Element | None = None) -> None:
- # TODO: if the id matching the name is applied to an implicid target,
- # transfer it to this target and put a "disambiguated" id on the other.
- id = self.set_id(target, msgnode)
- self.set_name_id_map(target, id, msgnode, explicit=True)
+ def note_explicit_target(self, target: Element,
+ msgnode: Element|None = None) -> None:
+ self.note_names(target, msgnode, explicit=True)
+ self.set_id(target, msgnode)
def note_refname(self, node: Element) -> None:
self.refnames.setdefault(node['refname'], []).append(node)
Modified: trunk/docutils/docutils/parsers/rst/directives/misc.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/directives/misc.py 2026-03-26 13:52:27 UTC (rev 10301)
+++ trunk/docutils/docutils/parsers/rst/directives/misc.py 2026-03-27 08:40:56 UTC (rev 10302)
@@ -233,6 +233,7 @@
settings._source = self.options['source']
document = utils.new_document(settings._source, settings)
document.include_log = self.state.document.include_log
+ document.names = self.state.document.names
document.ids = self.state.document.ids
document.nameids = self.state.document.nameids
document.nametypes = self.state.document.nametypes
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-03-26 13:52:27 UTC (rev 10301)
+++ trunk/docutils/docutils/transforms/references.py 2026-03-27 08:40:56 UTC (rev 10302)
@@ -940,8 +940,8 @@
if node.resolved or not node.hasattr('refname'):
return
refname = node['refname']
- id = self.document.nameids.get(refname)
- if id is not None:
+ id = self.document.nameids.get(refname, '')
+ if id:
# target found, set refid
del node['refname']
node['refid'] = id
@@ -949,11 +949,12 @@
node.resolved = True
return
# Apply component-specific resolving functions (cf. TransformSpec):
+ # (will be removed in Docutils 1.0)
for resolver_function in self.unknown_reference_resolvers:
if resolver_function(node):
return
# Report unresolved references:
- if refname in self.document.nameids:
+ if id is None:
msg = self.document.reporter.error(
'Duplicate target name, cannot be used as a unique '
f'reference: "{refname}".', base_node=node)
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-03-26 13:52:27 UTC (rev 10301)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-03-27 08:40:56 UTC (rev 10302)
@@ -29,19 +29,25 @@
class TransformTestCase(unittest.TestCase):
maxDiff = None
+ transforms = (PropagateTargets, AnonymousHyperlinks, IndirectHyperlinks,
+ ExternalTargets, InternalTargets, DanglingReferences,
+ TestMessages)
+
def test_transforms(self):
parser = Parser()
- settings = get_default_settings(Parser)
- settings.warning_stream = ''
- for name, (transforms, cases) in totest.items():
+ default_settings = get_default_settings(Parser)
+ default_settings.warning_stream = ''
+ for name, (settings_overrides, cases) in totest.items():
+ settings = default_settings.copy()
+ for k, v in settings_overrides.items():
+ setattr(settings, k, v)
for casenum, (case_input, case_expected) in enumerate(cases):
with self.subTest(id=f'totest[{name!r}][{casenum}]'):
- document = new_document('test data', settings.copy())
+ document = new_document('test data', settings)
parser.parse(case_input, document)
# Don't do a ``populate_from_components()`` because that
# would enable the Transformer's default transforms.
- document.transformer.add_transforms(transforms)
- document.transformer.add_transform(TestMessages)
+ document.transformer.add_transforms(self.transforms)
document.transformer.apply_transforms()
output = document.pformat()
self.assertEqual(case_expected, output)
@@ -52,9 +58,7 @@
# Exhaustive listing of hyperlink variations: every combination of
# target/reference, direct/indirect, internal/external, and named/anonymous,
# plus embedded URIs.
-totest['exhaustive_hyperlinks'] = ((PropagateTargets, AnonymousHyperlinks,
- IndirectHyperlinks, ExternalTargets,
- InternalTargets, DanglingReferences), [
+totest['exhaustive_hyperlinks'] = ({}, [
["""\
direct_ external
@@ -575,9 +579,7 @@
"""],
])
-totest['hyperlinks'] = ((PropagateTargets, AnonymousHyperlinks,
- IndirectHyperlinks, ExternalTargets,
- InternalTargets, DanglingReferences), [
+totest['hyperlinks legacy'] = ({'legacy_ids': True}, [
["""\
.. _internal hyperlink:
@@ -1098,6 +1100,42 @@
"""],
])
+totest['hyperlinks'] = ({'legacy_ids': False}, [
+["""\
+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">
+ <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".
+ <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 name="foo" refid="foo">
+ foo
+ points to the explicit target.
+ Referencing from an external document can be done
+ using the matching fragment identifier "#foo".
+"""],
+])
+
+
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-03-26 13:52:28
|
Revision: 10301
http://sourceforge.net/p/docutils/code/10301
Author: milde
Date: 2026-03-26 13:52:27 +0000 (Thu, 26 Mar 2026)
Log Message:
-----------
New configuration setting "legacy_ids".
The next commits will enable matching element (fraction) identifiers
when an explicit target overrides a homonymous implicit target.
The new setting "legacy_ids" section tells the rST parser
to keep IDs compatible to Docutils {U+2264} 0.22.
Add a test that demonstrates the problem.
Update documentation and test samples.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/user/config.rst
trunk/docutils/docutils/parsers/rst/__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/test_transforms/test_hyperlinks.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-02-06 09:09:27 UTC (rev 10300)
+++ trunk/docutils/HISTORY.rst 2026-03-26 13:52:27 UTC (rev 10301)
@@ -28,6 +28,10 @@
<target> elements when testing for a <transition> at the begin or end
of a <section> or the <document>.
+* docutils/parsers/rst/__init__.py
+
+ - New configuration setting `legacy_ids`_.
+
* docutils/parsers/rst/directives/body.py
- Add source and line info to <rubric> elements.
@@ -57,7 +61,7 @@
* docutils/transforms/misc.py:
- - Use `nodes.transition.validate_position() to warn about transitions
+ - Use `nodes.transition.validate_position()` to warn about transitions
at the beginning or end of the document or a section.
* docutils/writers/html5_polyglot/__init__.py
@@ -4846,6 +4850,7 @@
.. _language: docs/user/config.html#language
.. _latex_preamble: docs/user/config.html#latex-preamble
.. _legacy_class_functions: docs/user/config.html#legacy-class-functions
+.. _legacy_ids: docs/user/config.html#legacy-ids
.. _legacy_column_widths: docs/user/config.html#legacy-column-widths
.. _literal_block_env: docs/user/config.html#literal-block-env
.. _math_output: docs/user/config.html#math-output
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-02-06 09:09:27 UTC (rev 10300)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-03-26 13:52:27 UTC (rev 10301)
@@ -89,6 +89,9 @@
* The "rst" parser will warn if a `"figure"`_ directive is missing both
caption and legend in Docutils 1.0.
+* The `legacy_ids`_ configuration setting default will change to False
+ in Docutils 2.0
+
Writers
-------
@@ -305,9 +308,12 @@
- Support the "semantic inline markup roles" from the ``html-roles.txt``
`standard definition file`_.
+Configuration changes
+ - New setting `legacy_ids`_.
+
Removed objects
`parsers.rst.directives.tables.CSVTable.check_requirements()`
- not required with Python 3
+ not required with Python 3.
Release 0.22.4 (2025-12-18)
@@ -1607,6 +1613,7 @@
.. _input_encoding: docs/user/config.html#input-encoding
.. _[latex writers]: docs/user/config.html#latex-writers
.. _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
.. _math_output: docs/user/config.html#math-output
.. _old-format configuration files:
Modified: trunk/docutils/docs/user/config.rst
===================================================================
--- trunk/docutils/docs/user/config.rst 2026-02-06 09:09:27 UTC (rev 10300)
+++ trunk/docutils/docs/user/config.rst 2026-03-26 13:52:27 UTC (rev 10301)
@@ -840,6 +840,19 @@
New in Docutils 0.13.
+legacy_ids
+~~~~~~~~~~
+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`_.
+
+:Default: True; will change to False in Docutils 2.0.
+:Option: ``--legacy-ids``, ``--matching-ids``.
+
+New in Docutils 0.23.
+
pep_references
~~~~~~~~~~~~~~
Recognize and link to standalone PEP references (like "PEP 258").
@@ -1821,7 +1834,7 @@
reference_label
~~~~~~~~~~~~~~~
Per default the LaTeX writer uses ``\hyperref`` for `hyperlink
-references`_ to internal__ or implicit__ targets.
+references`_ to internal__ or `implicit targets`_.
Specify an alternative reference command name, e.g., "ref" or "pageref"
to get the section number or the page number as reference text.
@@ -1839,10 +1852,7 @@
*Default*: "" (use ``\hyperref``). *Option*: ``--reference-label``.
__ ../ref/rst/restructuredtext.html#internal-hyperlink-targets
-__ ../ref/rst/restructuredtext.html#implicit-hyperlink-targets
__ ../dev/todo.html#object-numbering-and-object-references
-.. _hyperlink references: ../ref/rst/restructuredtext.html#hyperlink-references
-.. _interpreted text role: ../ref/rst/restructuredtext.html#interpreted-text
section_enumerator_separator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2638,6 +2648,7 @@
.. _Docutils Generic document type definition:
.. _Document Tree: ../ref/doctree.html
.. _class attribute: ../ref/doctree.html#classes
+.. _identifiers: ../ref/doctree.html#identifiers
.. _title attribute: ../ref/doctree.html#title-attribute
.. _"uri" attribute: ../ref/doctree.html#uri
@@ -2686,14 +2697,20 @@
.. _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
.. _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 target:
+.. _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
.. _literal blocks: ../ref/rst/restructuredtext.html#literal-blocks
.. _option lists: ../ref/rst/restructuredtext.html#option-lists
+.. _reference name: ../ref/rst/restructuredtext.html#reference-names
.. _tables: ../ref/rst/restructuredtext.html#tables
.. _Docutils HTML writers: html.html
Modified: trunk/docutils/docutils/parsers/rst/__init__.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/__init__.py 2026-02-06 09:09:27 UTC (rev 10300)
+++ trunk/docutils/docutils/parsers/rst/__init__.py 2026-03-26 13:52:27 UTC (rev 10301)
@@ -88,7 +88,16 @@
settings_spec = docutils.parsers.Parser.settings_spec + (
'reStructuredText Parser Options',
None,
- (('Recognize and link to standalone PEP references (like "PEP 258").',
+ (('Keep identifiers backwards compatible. Default.',
+ ['--legacy-ids'],
+ {'action': 'store_true',
+ 'validator': frontend.validate_boolean,
+ 'default': True}),
+ ('Explicit targets use identifiers matching the reference name.',
+ ['--matching-ids'],
+ {'action': 'store_false',
+ 'dest': 'legacy_ids'}),
+ ('Recognize and link to standalone PEP references (like "PEP 258").',
['--pep-references'],
{'action': 'store_true', 'validator': frontend.validate_boolean}),
('Base URL for PEP references '
Modified: trunk/docutils/test/data/help/docutils.rst
===================================================================
--- trunk/docutils/test/data/help/docutils.rst 2026-02-06 09:09:27 UTC (rev 10300)
+++ trunk/docutils/test/data/help/docutils.rst 2026-03-26 13:52:27 UTC (rev 10301)
@@ -95,6 +95,9 @@
reStructuredText Parser Options
-------------------------------
+--legacy-ids Keep identifiers backwards compatible. Default.
+--matching-ids Explicit targets use identifiers matching the
+ reference name.
--pep-references Recognize and link to standalone PEP references (like
"PEP 258").
--pep-base-url=<URL> Base URL for PEP references (default
Modified: trunk/docutils/test/data/help/rst2html.rst
===================================================================
--- trunk/docutils/test/data/help/rst2html.rst 2026-02-06 09:09:27 UTC (rev 10300)
+++ trunk/docutils/test/data/help/rst2html.rst 2026-03-26 13:52:27 UTC (rev 10301)
@@ -96,6 +96,9 @@
reStructuredText Parser Options
-------------------------------
+--legacy-ids Keep identifiers backwards compatible. Default.
+--matching-ids Explicit targets use identifiers matching the
+ reference name.
--pep-references Recognize and link to standalone PEP references (like
"PEP 258").
--pep-base-url=<URL> Base URL for PEP references (default
Modified: trunk/docutils/test/data/help/rst2latex.rst
===================================================================
--- trunk/docutils/test/data/help/rst2latex.rst 2026-02-06 09:09:27 UTC (rev 10300)
+++ trunk/docutils/test/data/help/rst2latex.rst 2026-03-26 13:52:27 UTC (rev 10301)
@@ -96,6 +96,9 @@
reStructuredText Parser Options
-------------------------------
+--legacy-ids Keep identifiers backwards compatible. Default.
+--matching-ids Explicit targets use identifiers matching the
+ reference name.
--pep-references Recognize and link to standalone PEP references (like
"PEP 258").
--pep-base-url=<URL> Base URL for PEP references (default
Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-02-06 09:09:27 UTC (rev 10300)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py 2026-03-26 13:52:27 UTC (rev 10301)
@@ -1038,6 +1038,64 @@
<paragraph>
Duplicate target name, cannot be used as a unique reference: "1".
"""],
+["""\
+An explicit target _`foo` overrides a homonymous implicit target.
+
+foo
+---
+
+The reference foo_ points to the explicit target.
+""",
+"""\
+<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">
+ <title>
+ foo
+ <system_message backrefs="foo-1" level="1" line="4" source="test data" type="INFO">
+ <paragraph>
+ Duplicate implicit target name: "foo".
+ <paragraph>
+ The reference \n\
+ <reference name="foo" refid="foo">
+ foo
+ points to the explicit target.
+"""],
+["""\
+foo
+---
+
+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">
+ <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 name="foo" refid="foo-1">
+ foo
+ points to the explicit target. However, referencing from
+ an external document requires the non-obvious fragment identifier "#foo-1".
+"""],
])
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-02-06 09:09:30
|
Revision: 10300
http://sourceforge.net/p/docutils/code/10300
Author: milde
Date: 2026-02-06 09:09:27 +0000 (Fri, 06 Feb 2026)
Log Message:
-----------
Fix `Transition` post-processing transform.
Use `nodes.transition.validate_position() to warn about transitions
at the beginning or end of the document or a section.
Title elements, moving elements and invisible elements (except comments)
are ignored by this test.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/transforms/misc.py
trunk/docutils/test/test_transforms/test_transitions.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-02-06 09:09:19 UTC (rev 10299)
+++ trunk/docutils/HISTORY.rst 2026-02-06 09:09:27 UTC (rev 10300)
@@ -55,6 +55,11 @@
- Add source and line info to <table> elements.
- Fix bug #517: wrong "input_offset" when parsing table cell content.
+* docutils/transforms/misc.py:
+
+ - Use `nodes.transition.validate_position() to warn about transitions
+ at the beginning or end of the document or a section.
+
* docutils/writers/html5_polyglot/__init__.py
- Use a section's last "ids" attribute for the "section-self-link".
@@ -308,9 +313,8 @@
* docutils/transforms/misc.py:
- - Fix for `misc.Transitions`: report an error if a <transition> element
- follows a <meta> or <decoration> element as this is invalid
- according to ``docutils.dtd``.
+ - Warn, if a <transition> element follows a <meta> or <decoration>
+ element as this is invalid according to ``docutils.dtd``.
* docutils/transforms/references.py
Modified: trunk/docutils/docutils/transforms/misc.py
===================================================================
--- trunk/docutils/docutils/transforms/misc.py 2026-02-06 09:09:19 UTC (rev 10299)
+++ trunk/docutils/docutils/transforms/misc.py 2026-02-06 09:09:27 UTC (rev 10300)
@@ -62,12 +62,14 @@
class Transitions(Transform):
-
"""
- Move transitions at the end of sections up the tree. Complain
- on transitions after a title, subtitle, meta, or decoration element,
- at the beginning or end of the document, and after another transition.
+ Post-process <transition> elements.
+ Move transitions at the end of sections up the tree.
+ Warn on transitions at the beginning or end of the document or
+ a section (ignoring title, decoration, or invisible elements),
+ and after another transition.
+
For example, transform this::
<section>
@@ -92,52 +94,38 @@
self.visit_transition(node)
def visit_transition(self, node) -> None:
- index = node.parent.index(node)
- previous_sibling = node.previous_sibling()
msg = ''
if not isinstance(node.parent, (nodes.document, nodes.section)):
- msg = 'Transition must be child of <document> or <section>.'
- elif index == 0 or isinstance(previous_sibling, (nodes.title,
- nodes.subtitle,
- nodes.meta,
- nodes.decoration)):
- msg = 'Document or section may not begin with a transition.'
- elif isinstance(previous_sibling, nodes.transition):
- msg = ('At least one body element must separate transitions; '
- 'adjacent transitions are not allowed.')
- if msg:
- warning = self.document.reporter.warning(msg, base_node=node)
- # Check, if it is valid to insert a body element
- node.parent[index] = nodes.paragraph()
+ self.warn('Transition only valid as child of <document> '
+ 'or <section>.', node)
+ else:
try:
- node.parent.validate(recursive=False)
- except nodes.ValidationError:
- node.parent[index] = node
+ node.validate_position()
+ except nodes.ValidationError as e:
+ msg = str(e)
+ if 'may not end' in msg:
+ # Move transition up the tree.
+ sibling = node.parent # get new predecessor node
+ parent = sibling.parent
+ while parent is not None:
+ index = parent.index(sibling)
+ if index < len(parent) - 1:
+ node.parent.remove(node)
+ parent.insert(index + 1, node)
+ break
+ sibling = sibling.parent
+ parent = sibling.parent
else:
- node.parent[index] = node
- node.parent.insert(index+1, warning)
- index += 1
- if not isinstance(node.parent, (nodes.document, nodes.section)):
- return
- assert index < len(node.parent)
- if index != len(node.parent) - 1:
- # No need to move the node.
- return
- # Node behind which the transition is to be moved.
- sibling = node
- # While sibling is the last node of its parent.
- while index == len(sibling.parent) - 1:
- sibling = sibling.parent
- if sibling.parent is None: # sibling is the top node (document)
- # Transition at the end of document. Do not move the
- # transition up, and place a warning behind.
- warning = self.document.reporter.warning(
- 'Document may not end with a transition.',
- base_node=node)
- node.parent.append(warning)
- return
- index = sibling.parent.index(sibling)
- # Remove the original transition node.
- node.parent.remove(node)
- # Insert the transition after the sibling.
- sibling.parent.insert(index + 1, node)
+ self.warn('Transition at the end of the document.', node)
+ if 'may not begin' in msg:
+ self.warn(f'Transition at the start of the {node.parent.tagname}.',
+ node)
+ elif 'may not directly follow' in msg:
+ self.warn('At least one body element should separate transitions.',
+ node)
+
+ def warn(self, msg, node) -> None:
+ # create a warning message, insert it if valid
+ warning = self.document.reporter.warning(msg, base_node=node)
+ if 'nodes.Body' in repr(node.parent.content_model):
+ node.parent.insert(node.parent.index(node)+1, warning)
Modified: trunk/docutils/test/test_transforms/test_transitions.py
===================================================================
--- trunk/docutils/test/test_transforms/test_transitions.py 2026-02-06 09:09:19 UTC (rev 10299)
+++ trunk/docutils/test/test_transforms/test_transitions.py 2026-02-06 09:09:27 UTC (rev 10300)
@@ -133,33 +133,33 @@
<transition>
<system_message level="2" line="1" source="test data" type="WARNING">
<paragraph>
- Document or section may not begin with a transition.
+ Transition at the start of the document.
<paragraph>
A system message warns about invalid placement of transitions.
"""],
["""\
-The DTD specifies ...
+rST and Doctree specifications say ...
--------
--------
-... that two transitions may not be adjacent:
+... that two transitions should not be adjacent.
""",
"""\
<document source="test data">
<paragraph>
- The DTD specifies ...
+ rST and Doctree specifications say ...
<transition>
<transition>
<system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
- At least one body element must separate transitions; adjacent transitions are not allowed.
+ At least one body element should separate transitions.
<paragraph>
- ... that two transitions may not be adjacent:
+ ... that two transitions should not be adjacent.
"""],
["""\
-The DTD also specifies that a section or document
+The specs also say that a section or document
may not end with a transition.
--------
@@ -167,14 +167,41 @@
"""\
<document source="test data">
<paragraph>
- The DTD also specifies that a section or document
+ The specs also say that a section or document
may not end with a transition.
<transition>
<system_message level="2" line="4" source="test data" type="WARNING">
<paragraph>
- Document may not end with a transition.
+ Transition at the end of the document.
"""],
["""\
+Moving and invisible elements don't count.
+
+----------
+
+.. meta:: :keywords: transition test
+.. footer:: will move away
+.. _anchor:
+.. |substitution reference| replace:: is invisible
+""",
+"""\
+<document source="test data">
+ <meta content="transition test" name="keywords">
+ <decoration>
+ <footer>
+ <paragraph>
+ will move away
+ <paragraph>
+ Moving and invisible elements don't count.
+ <transition>
+ <system_message level="2" line="3" source="test data" type="WARNING">
+ <paragraph>
+ Transition at the end of the document.
+ <target ids="anchor" names="anchor">
+ <substitution_definition names="substitution\\ reference">
+ is invisible
+"""],
+["""\
Sections with transitions at beginning and end.
Section 1
@@ -182,7 +209,7 @@
----------
-Some text after transition.
+.. Comment after transition.
Section 2
=========
@@ -201,9 +228,9 @@
<transition>
<system_message level="2" line="6" source="test data" type="WARNING">
<paragraph>
- Document or section may not begin with a transition.
- <paragraph>
- Some text after transition.
+ Transition at the start of the section.
+ <comment xml:space="preserve">
+ Comment after transition.
<section ids="section-2" names="section\\ 2">
<title>
Section 2
@@ -212,7 +239,7 @@
<transition>
<system_message level="2" line="15" source="test data" type="WARNING">
<paragraph>
- Document may not end with a transition.
+ Transition at the end of the document.
"""],
["""\
A paragraph and two transitions.
@@ -229,10 +256,10 @@
<transition>
<system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
- At least one body element must separate transitions; adjacent transitions are not allowed.
+ At least one body element should separate transitions.
<system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
- Document may not end with a transition.
+ Transition at the end of the document.
"""],
["""\
A paragraph, two transitions, and a blank line.
@@ -250,10 +277,10 @@
<transition>
<system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
- At least one body element must separate transitions; adjacent transitions are not allowed.
+ At least one body element should separate transitions.
<system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
- Document may not end with a transition.
+ Transition at the end of the document.
"""],
["""\
----------
@@ -265,46 +292,39 @@
<transition>
<system_message level="2" line="1" source="test data" type="WARNING">
<paragraph>
- Document or section may not begin with a transition.
+ Transition at the start of the document.
<paragraph>
Document beginning with a transition.
"""],
["""\
+.. class:: classy
.. meta:: :keywords: transition test
+.. footer:: will move away
+.. _anchor:
+.. |substitution reference| replace:: is invisible
----------
-Document beginning with a transition (meta elements don't count).
+Document beginning with a transition (title, moving elements,
+and invisible elements don't count).
""",
"""\
<document source="test data">
<meta content="transition test" name="keywords">
- <transition>
- <system_message level="2" line="3" source="test data" type="WARNING">
- <paragraph>
- Document or section may not begin with a transition.
- <paragraph>
- Document beginning with a transition (meta elements don't count).
-"""],
-["""\
-.. header:: a header
-
-----------
-
-Document beginning with a transition (decoration elements don't count).
-""",
-"""\
-<document source="test data">
<decoration>
- <header>
+ <footer>
<paragraph>
- a header
- <transition>
- <system_message level="2" line="3" source="test data" type="WARNING">
+ will move away
+ <target ids="anchor" names="anchor">
+ <substitution_definition names="substitution\\ reference">
+ is invisible
+ <transition classes="classy">
+ <system_message level="2" line="7" source="test data" type="WARNING">
<paragraph>
- Document or section may not begin with a transition.
+ Transition at the start of the document.
<paragraph>
- Document beginning with a transition (decoration elements don't count).
+ Document beginning with a transition (title, moving elements,
+ and invisible elements don't count).
"""],
["""\
Section 1
@@ -316,14 +336,8 @@
----------
-Implementation Detail
-=====================
-
-If the element containing the transition is invalid after replacing the
-transition with a body element, the system_message is appended at the end
-of the document (by the "universal.Messages" transform).
-This check can lead to overcautious behaviour if there are other
-validity violations (here: several misplaced transitions).
+Section 2
+=========
""",
"""\
<document source="test data">
@@ -331,26 +345,17 @@
<title>
Section 1
<transition>
+ <system_message level="2" line="4" source="test data" type="WARNING">
+ <paragraph>
+ Transition at the start of the section.
<transition>
<transition>
- <section ids="implementation-detail" names="implementation\\ detail">
- <title>
- Implementation Detail
- <paragraph>
- If the element containing the transition is invalid after replacing the
- transition with a body element, the system_message is appended at the end
- of the document (by the "universal.Messages" transform).
- This check can lead to overcautious behaviour if there are other
- validity violations (here: several misplaced transitions).
- <system_message level="2" line="4" source="test data" type="WARNING">
- <paragraph>
- Document or section may not begin with a transition.
- <system_message level="2" line="6" source="test data" type="WARNING">
- <paragraph>
- At least one body element must separate transitions; adjacent transitions are not allowed.
<system_message level="2" line="8" source="test data" type="WARNING">
<paragraph>
- At least one body element must separate transitions; adjacent transitions are not allowed.
+ At least one body element should separate transitions.
+ <section ids="section-2" names="section\\ 2">
+ <title>
+ Section 2
"""],
["""\
----------
@@ -364,36 +369,18 @@
"""\
<document source="test data">
<transition>
+ <system_message level="2" line="1" source="test data" type="WARNING">
+ <paragraph>
+ Transition at the start of the document.
<transition>
<transition>
<system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
- Document may not end with a transition.
- <system_message level="2" line="1" source="test data" type="WARNING">
- <paragraph>
- Document or section may not begin with a transition.
- <system_message level="2" line="3" source="test data" type="WARNING">
- <paragraph>
- At least one body element must separate transitions; adjacent transitions are not allowed.
+ At least one body element should separate transitions.
<system_message level="2" line="5" source="test data" type="WARNING">
<paragraph>
- At least one body element must separate transitions; adjacent transitions are not allowed.
+ Transition at the end of the document.
"""],
-["""\
-A paragraph.
-
-----------
-
-""",
-"""\
-<document source="test data">
- <paragraph>
- A paragraph.
- <transition>
- <system_message level="2" line="3" source="test data" type="WARNING">
- <paragraph>
- Document may not end with a transition.
-"""],
])
@@ -425,7 +412,7 @@
<transition>
<system_message level="2" line="7" source="test data" type="WARNING">
<paragraph>
- Transition must be child of <document> or <section>.
+ Transition only valid as child of <document> or <section>.
<paragraph>
Some text.
<paragraph>
@@ -434,7 +421,7 @@
in a paragraph.
<system_message level="2" line="10" source="test data" type="WARNING">
<paragraph>
- Transition must be child of <document> or <section>.
+ Transition only valid as child of <document> or <section>.
"""],
])
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-02-06 09:09:21
|
Revision: 10299
http://sourceforge.net/p/docutils/code/10299
Author: milde
Date: 2026-02-06 09:09:19 +0000 (Fri, 06 Feb 2026)
Log Message:
-----------
Fix nodes.transition.validate_position()
Ignore title elements as well as moving or invisible elements (except comments)
when validating the restriction:
"Transitions may not begin or end a section or document."
This brings the validation in line with the documentation in
"The Docutils Document Tree" updated in commit [r10268].
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/nodes.py
trunk/docutils/test/test_nodes.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-02-06 09:09:11 UTC (rev 10298)
+++ trunk/docutils/HISTORY.rst 2026-02-06 09:09:19 UTC (rev 10299)
@@ -21,6 +21,13 @@
- Apply patch #216 by Dmitry Shachnev: fix type annotations.
+* docutils/nodes.py
+
+ - `transition.validate_position()` now checks all siblings (not just
+ neighbours and also ignores <pending>, <substitution_definition>, and
+ <target> elements when testing for a <transition> at the begin or end
+ of a <section> or the <document>.
+
* docutils/parsers/rst/directives/body.py
- Add source and line info to <rubric> elements.
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-02-06 09:09:11 UTC (rev 10298)
+++ trunk/docutils/docutils/nodes.py 2026-02-06 09:09:19 UTC (rev 10299)
@@ -1746,31 +1746,35 @@
class transition(SubStructural, Element):
- """Transitions__ are breaks between untitled text parts.
+ """Transitions__ represent "semantic breaks".
__ https://docutils.sourceforge.io/docs/ref/doctree.html#transition
"""
+ # Sibling nodes that are ignored when validating a transition's position
+ # (titles plus moving and invisible elements except comments):
+ ignored_siblings = (decoration, meta, pending, substitution_definition,
+ subtitle, target, title)
def validate_position(self) -> None:
"""Check additional constraints on `transition` placement.
- A transition may not begin or end a section or document,
+ A transition may not begin or end section or document text,
nor may two transitions be immediately adjacent.
"""
messages = [f'Element {self.parent.starttag()} invalid:']
- predecessor = self.previous_sibling()
- if (predecessor is None # index == 0
- or isinstance(predecessor, (title, subtitle, meta, decoration))
- # A transition following these elements still counts as
- # "at the beginning of a document or section".
- ):
+ if isinstance(self.previous_sibling(), transition):
messages.append(
+ '<transition> may not directly follow another transition.')
+ i = self.parent.index(self)
+ prev_siblings = self.parent[:i]
+ if not [sibling for sibling in prev_siblings
+ if not isinstance(sibling, self.ignored_siblings)]:
+ messages.append(
'<transition> may not begin a section or document.')
- if self.parent.index(self) == len(self.parent) - 1:
+ next_siblings = self.parent[i+1:]
+ if not [sibling for sibling in next_siblings
+ if not isinstance(sibling, self.ignored_siblings)]:
messages.append('<transition> may not end a section or document.')
- if isinstance(predecessor, transition):
- messages.append(
- '<transition> may not directly follow another transition.')
if len(messages) > 1:
raise ValidationError('\n '.join(messages),
problematic_element=self)
Modified: trunk/docutils/test/test_nodes.py
===================================================================
--- trunk/docutils/test/test_nodes.py 2026-02-06 09:09:11 UTC (rev 10298)
+++ trunk/docutils/test/test_nodes.py 2026-02-06 09:09:19 UTC (rev 10299)
@@ -818,28 +818,38 @@
def test_validate_content_transition(self):
"""Test additional constraints on <transition> placement:
- Not at begin or end of a section or document,
+ Not at begin or end of section or document text,
not after another transition.
"""
transition = nodes.transition()
+ comment = nodes.comment()
paragraph = nodes.paragraph()
- section = nodes.section('', nodes.title(), transition, paragraph)
+ subdef = nodes.substitution_definition()
+ target = nodes.target()
+ title = nodes.title()
+
+ section = nodes.section('', title, comment, transition, paragraph)
+ self.assertEqual(section.validate_content(), [])
+ section = nodes.section('', title, subdef, transition, target, subdef)
with self.assertRaisesRegex(nodes.ValidationError,
- '<transition> may not begin a section '):
- section.validate_content()
- section = nodes.section('', nodes.title(), paragraph, transition)
+ '<transition> may not begin a section .*\n'
+ ' <transition> may not end a section '):
+ self.assertEqual(section.validate_content(), [])
+ section = nodes.section('', title, paragraph, transition,
+ nodes.transition(), paragraph)
with self.assertRaisesRegex(nodes.ValidationError,
- '<transition> may not end a section '):
- section.validate_content()
- section = nodes.section('', nodes.title(), paragraph,
- nodes.transition(), transition)
- with self.assertRaisesRegex(nodes.ValidationError,
'Element <section> invalid:\n'
- ' <transition> may not end .*\n'
- ' <transition> may not directly '):
- section.validate_content()
+ ' <transition> may not directly follow'):
+ self.assertEqual(section.validate_content(), [])
+ document = utils.new_document('test')
+ document.extend([nodes.decoration(), transition, nodes.meta()])
+ with self.assertRaisesRegex(nodes.ValidationError,
+ '<transition> may not begin a section .*\n'
+ ' <transition> may not end a section '):
+ self.assertEqual(section.validate_content(), [])
+
class MiscTests(unittest.TestCase):
def test_node_class_names(self):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-02-06 09:09:14
|
Revision: 10298
http://sourceforge.net/p/docutils/code/10298
Author: milde
Date: 2026-02-06 09:09:11 +0000 (Fri, 06 Feb 2026)
Log Message:
-----------
Re-sort class definitions in nodes.py.
Move the definition of "special purpose elements" before all other
concrete DocTree elements.
Required for the fix to `transition.validate_position()` in the next commit
(most "special purpose elements" must be ignored when validating that
the transition is not first or last element of its parent).
Modified Paths:
--------------
trunk/docutils/docutils/nodes.py
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-02-06 09:09:04 UTC (rev 10297)
+++ trunk/docutils/docutils/nodes.py 2026-02-06 09:09:11 UTC (rev 10298)
@@ -1550,6 +1550,144 @@
#
# See https://docutils.sourceforge.io/docs/ref/doctree.html#element-reference
+# Special purpose elements
+# ========================
+#
+# Body elements for internal use or special requests.
+
+class comment(Invisible, FixedTextElement, PureTextElement):
+ """Author notes, hidden from the output."""
+
+
+class substitution_definition(Invisible, TextElement):
+ valid_attributes: Final = Element.valid_attributes + ('ltrim', 'rtrim')
+
+
+class target(Invisible, Inline, TextElement, Targetable):
+ valid_attributes: Final = Element.valid_attributes + (
+ 'anonymous', 'refid', 'refname', 'refuri')
+
+
+class system_message(Special, BackLinkable, PreBibliographic, Element):
+ """
+ System message element.
+
+ Do not instantiate this class directly; use
+ ``document.reporter.info/warning/error/severe()`` instead.
+ """
+ valid_attributes: Final = BackLinkable.valid_attributes + (
+ 'level', 'line', 'type')
+ content_model: Final = ((Body, '+'),) # (%body.elements;)+
+
+ def __init__(self,
+ message: str | None = None,
+ *children,
+ **attributes: Any,
+ ) -> None:
+ rawsource = attributes.pop('rawsource', '')
+ if message:
+ p = paragraph('', message)
+ children = (p,) + children
+ try:
+ Element.__init__(self, rawsource, *children, **attributes)
+ except: # NoQA: E722 (catchall)
+ print('system_message: children=%r' % (children,))
+ raise
+
+ def astext(self) -> str:
+ line = self.get('line', '')
+ return '%s:%s: (%s/%s) %s' % (self['source'], line, self['type'],
+ self['level'], Element.astext(self))
+
+
+class pending(Invisible, Element):
+ """
+ Placeholder for pending operations.
+
+ The "pending" element is used to encapsulate a pending operation: the
+ operation (transform), the point at which to apply it, and any data it
+ requires. Only the pending operation's location within the document is
+ stored in the public document tree (by the "pending" object itself); the
+ operation and its data are stored in the "pending" object's internal
+ instance attributes.
+
+ For example, say you want a table of contents in your reStructuredText
+ document. The easiest way to specify where to put it is from within the
+ document, with a directive::
+
+ .. contents::
+
+ But the "contents" directive can't do its work until the entire document
+ has been parsed and possibly transformed to some extent. So the directive
+ code leaves a placeholder behind that will trigger the second phase of its
+ processing, something like this::
+
+ <pending ...public attributes...> + internal attributes
+
+ Use `document.note_pending()` so that the
+ `docutils.transforms.Transformer` stage of processing can run all pending
+ transforms.
+ """
+
+ def __init__(self,
+ transform: Transform,
+ details: Mapping[str, Any] | None = None,
+ rawsource: str = '',
+ *children,
+ **attributes: Any,
+ ) -> None:
+ Element.__init__(self, rawsource, *children, **attributes)
+
+ self.transform: Transform = transform
+ """The `docutils.transforms.Transform` class implementing the pending
+ operation."""
+
+ self.details: Mapping[str, Any] = details or {}
+ """Detail data (dictionary) required by the pending operation."""
+
+ def pformat(self, indent: str = ' ', level: int = 0) -> str:
+ internals = ['.. internal attributes:',
+ ' .transform: %s.%s' % (self.transform.__module__,
+ self.transform.__name__),
+ ' .details:']
+ details = sorted(self.details.items())
+ for key, value in details:
+ if isinstance(value, Node):
+ internals.append('%7s%s:' % ('', key))
+ internals.extend(['%9s%s' % ('', line)
+ for line in value.pformat().splitlines()])
+ elif (value
+ and isinstance(value, list)
+ and isinstance(value[0], Node)):
+ internals.append('%7s%s:' % ('', key))
+ for v in value:
+ internals.extend(['%9s%s' % ('', line)
+ for line in v.pformat().splitlines()])
+ else:
+ internals.append('%7s%s: %r' % ('', key, value))
+ return (Element.pformat(self, indent, level)
+ + ''.join((' %s%s\n' % (indent * level, line))
+ for line in internals))
+
+ def copy(self) -> Self:
+ obj = self.__class__(self.transform, self.details, self.rawsource,
+ **self.attributes)
+ obj._document = self._document
+ obj.source = self.source
+ obj.line = self.line
+ return obj
+
+
+class raw(Special, Inline, PreBibliographic,
+ FixedTextElement, PureTextElement):
+ """Raw data that is to be passed untouched to the Writer.
+
+ Can be used as Body element or Inline element.
+ """
+ valid_attributes: Final = Element.valid_attributes + (
+ 'format', 'xml:space')
+
+
# Decorative Elements
# ===================
@@ -2470,143 +2608,6 @@
# (title?, tgroup+)
-# Special purpose elements
-# ------------------------
-# Body elements for internal use or special requests.
-
-class comment(Invisible, FixedTextElement, PureTextElement):
- """Author notes, hidden from the output."""
-
-
-class substitution_definition(Invisible, TextElement):
- valid_attributes: Final = Element.valid_attributes + ('ltrim', 'rtrim')
-
-
-class target(Invisible, Inline, TextElement, Targetable):
- valid_attributes: Final = Element.valid_attributes + (
- 'anonymous', 'refid', 'refname', 'refuri')
-
-
-class system_message(Special, BackLinkable, PreBibliographic, Element):
- """
- System message element.
-
- Do not instantiate this class directly; use
- ``document.reporter.info/warning/error/severe()`` instead.
- """
- valid_attributes: Final = BackLinkable.valid_attributes + (
- 'level', 'line', 'type')
- content_model: Final = ((Body, '+'),) # (%body.elements;)+
-
- def __init__(self,
- message: str | None = None,
- *children,
- **attributes: Any,
- ) -> None:
- rawsource = attributes.pop('rawsource', '')
- if message:
- p = paragraph('', message)
- children = (p,) + children
- try:
- Element.__init__(self, rawsource, *children, **attributes)
- except: # NoQA: E722 (catchall)
- print('system_message: children=%r' % (children,))
- raise
-
- def astext(self) -> str:
- line = self.get('line', '')
- return '%s:%s: (%s/%s) %s' % (self['source'], line, self['type'],
- self['level'], Element.astext(self))
-
-
-class pending(Invisible, Element):
- """
- Placeholder for pending operations.
-
- The "pending" element is used to encapsulate a pending operation: the
- operation (transform), the point at which to apply it, and any data it
- requires. Only the pending operation's location within the document is
- stored in the public document tree (by the "pending" object itself); the
- operation and its data are stored in the "pending" object's internal
- instance attributes.
-
- For example, say you want a table of contents in your reStructuredText
- document. The easiest way to specify where to put it is from within the
- document, with a directive::
-
- .. contents::
-
- But the "contents" directive can't do its work until the entire document
- has been parsed and possibly transformed to some extent. So the directive
- code leaves a placeholder behind that will trigger the second phase of its
- processing, something like this::
-
- <pending ...public attributes...> + internal attributes
-
- Use `document.note_pending()` so that the
- `docutils.transforms.Transformer` stage of processing can run all pending
- transforms.
- """
-
- def __init__(self,
- transform: Transform,
- details: Mapping[str, Any] | None = None,
- rawsource: str = '',
- *children,
- **attributes: Any,
- ) -> None:
- Element.__init__(self, rawsource, *children, **attributes)
-
- self.transform: Transform = transform
- """The `docutils.transforms.Transform` class implementing the pending
- operation."""
-
- self.details: Mapping[str, Any] = details or {}
- """Detail data (dictionary) required by the pending operation."""
-
- def pformat(self, indent: str = ' ', level: int = 0) -> str:
- internals = ['.. internal attributes:',
- ' .transform: %s.%s' % (self.transform.__module__,
- self.transform.__name__),
- ' .details:']
- details = sorted(self.details.items())
- for key, value in details:
- if isinstance(value, Node):
- internals.append('%7s%s:' % ('', key))
- internals.extend(['%9s%s' % ('', line)
- for line in value.pformat().splitlines()])
- elif (value
- and isinstance(value, list)
- and isinstance(value[0], Node)):
- internals.append('%7s%s:' % ('', key))
- for v in value:
- internals.extend(['%9s%s' % ('', line)
- for line in v.pformat().splitlines()])
- else:
- internals.append('%7s%s: %r' % ('', key, value))
- return (Element.pformat(self, indent, level)
- + ''.join((' %s%s\n' % (indent * level, line))
- for line in internals))
-
- def copy(self) -> Self:
- obj = self.__class__(self.transform, self.details, self.rawsource,
- **self.attributes)
- obj._document = self._document
- obj.source = self.source
- obj.line = self.line
- return obj
-
-
-class raw(Special, Inline, PreBibliographic,
- FixedTextElement, PureTextElement):
- """Raw data that is to be passed untouched to the Writer.
-
- Can be used as Body element or Inline element.
- """
- valid_attributes: Final = Element.valid_attributes + (
- 'format', 'xml:space')
-
-
# Inline Elements
# ===============
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-02-06 09:09:06
|
Revision: 10297
http://sourceforge.net/p/docutils/code/10297
Author: milde
Date: 2026-02-06 09:09:04 +0000 (Fri, 06 Feb 2026)
Log Message:
-----------
Update various comments and docstrings.
Modified Paths:
--------------
trunk/docutils/docutils/nodes.py
trunk/docutils/docutils/parsers/rst/directives/parts.py
trunk/docutils/docutils/transforms/parts.py
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-02-06 09:08:56 UTC (rev 10296)
+++ trunk/docutils/docutils/nodes.py 2026-02-06 09:09:04 UTC (rev 10297)
@@ -1913,10 +1913,15 @@
implicit None implicit None implicit new INFO
======== ==== ======== ==== ======== ======== ======= ======
- .. [#] Do not clear the name-to-id map or invalidate the old target if
- both old and new targets refer to identical URIs or reference names.
- The new target is invalidated regardless.
+ .. [#] When "invalidating" an element, `name` is transferred from
+ the element's "name" attribute to its "dupnames" attribute.
+ .. [#ex] If both "old" and "new" refer to identical URIs or
+ reference names, keep the old state and only invalidate "new".
+
+ __ https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html
+ #implicit-hyperlink-targets
+
Provisional. There will be changes to prefer explicit reference names
as base for an element's ID.
"""
Modified: trunk/docutils/docutils/parsers/rst/directives/parts.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/directives/parts.py 2026-02-06 09:08:56 UTC (rev 10296)
+++ trunk/docutils/docutils/parsers/rst/directives/parts.py 2026-02-06 09:09:04 UTC (rev 10297)
@@ -66,7 +66,6 @@
title = nodes.title('', language.labels['contents'])
topic = nodes.topic(classes=['contents'])
topic['classes'] += self.options.get('class', [])
- # the latex2e writer needs source and line for a warning:
topic.source, topic.line = self.state_machine.get_source_and_line()
topic.line -= 1
if 'local' in self.options:
Modified: trunk/docutils/docutils/transforms/parts.py
===================================================================
--- trunk/docutils/docutils/transforms/parts.py 2026-02-06 09:08:56 UTC (rev 10296)
+++ trunk/docutils/docutils/transforms/parts.py 2026-02-06 09:09:04 UTC (rev 10297)
@@ -78,9 +78,9 @@
The depth may be specified. Two-way references between the table of
contents and section titles are generated (requires Writer support).
- This transform requires a startnode, which contains generation
- options and provides the location for the generated table of contents (the
- startnode is replaced by the table of contents "topic").
+ This transform requires a startnode, a "pending" element which contains
+ generation options and provides the location for the generated ToC (the
+ startnode is replaced by the table of contents "bullet-list").
"""
default_priority = 720
@@ -91,11 +91,11 @@
# TODO: handle "generate_oowriter_toc" setting of the "ODT" writer.
if toc_by_writer:
return
+
details = self.startnode.details
if 'local' in details:
startnode = self.startnode.parent.parent
- while not (isinstance(startnode, nodes.section)
- or isinstance(startnode, nodes.document)):
+ while not isinstance(startnode, (nodes.section, nodes.document)):
# find the ToC root: a direct ancestor of startnode
startnode = startnode.parent
else:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-02-06 09:08:58
|
Revision: 10296
http://sourceforge.net/p/docutils/code/10296
Author: milde
Date: 2026-02-06 09:08:56 +0000 (Fri, 06 Feb 2026)
Log Message:
-----------
Simplify check if its valid to insert a system_message.
Modified Paths:
--------------
trunk/docutils/docutils/nodes.py
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-02-05 21:27:00 UTC (rev 10295)
+++ trunk/docutils/docutils/nodes.py 2026-02-06 09:08:56 UTC (rev 10296)
@@ -1978,18 +1978,11 @@
# don't add backref id for empty targets (not shown in output)
if isinstance(node, target) and 'refuri' in node:
backrefs = []
- msg = self.reporter.system_message(level, s,
- backrefs=backrefs,
+ msg = self.reporter.system_message(level, s, backrefs=backrefs,
base_node=node)
# try appending near to the problem:
- if msgnode is not None:
+ if msgnode is not None and 'Body' in repr(msgnode.content_model):
msgnode += msg
- try:
- msgnode.validate(recursive=False)
- except ValidationError:
- # detach -> will be handled by `Messages` transform
- msgnode.pop()
- msg.parent = None
def has_name(self, name: str) -> bool:
return name in self.nameids
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-02-05 21:27:02
|
Revision: 10295
http://sourceforge.net/p/docutils/code/10295
Author: milde
Date: 2026-02-05 21:27:00 +0000 (Thu, 05 Feb 2026)
Log Message:
-----------
"Directives" documentation: Correct the matrix of supported image formats.
The ODT writer does not support vector images.
The ODT format supports vector images in the ODG format,
but this is currently not supported by the Docutils ODT writer.
Modified Paths:
--------------
trunk/docutils/docs/ref/rst/directives.rst
Modified: trunk/docutils/docs/ref/rst/directives.rst
===================================================================
--- trunk/docutils/docs/ref/rst/directives.rst 2026-01-25 14:12:56 UTC (rev 10294)
+++ trunk/docutils/docs/ref/rst/directives.rst 2026-02-05 21:27:00 UTC (rev 10295)
@@ -174,7 +174,7 @@
manpage_
-ODT_ ✓ ✓ ✓ ✓ ✓
+ODT_ ✓ ✓ ✓
=========== ====== ====== ===== ===== ===== ===== ===== ===== ===== =====
.. [#video]
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-01-25 14:12:59
|
Revision: 10294
http://sourceforge.net/p/docutils/code/10294
Author: milde
Date: 2026-01-25 14:12:56 +0000 (Sun, 25 Jan 2026)
Log Message:
-----------
Fix type annotation for get_default_settings()
Apply patch #216 by Dmitry Shachnev to fix type annotation
of `get_default_settings():
It accepts classes themselves, not instances of those classes.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/frontend.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-01-21 15:18:32 UTC (rev 10293)
+++ trunk/docutils/HISTORY.rst 2026-01-25 14:12:56 UTC (rev 10294)
@@ -17,6 +17,10 @@
Release 0.23b.dev (unpublished)
===============================
+* docutils/frontend.py
+
+ - Apply patch #216 by Dmitry Shachnev: fix type annotations.
+
* docutils/parsers/rst/directives/body.py
- Add source and line info to <rubric> elements.
Modified: trunk/docutils/docutils/frontend.py
===================================================================
--- trunk/docutils/docutils/frontend.py 2026-01-21 15:18:32 UTC (rev 10293)
+++ trunk/docutils/docutils/frontend.py 2026-01-25 14:12:56 UTC (rev 10294)
@@ -1162,7 +1162,7 @@
"""Warning for deprecated configuration file features."""
-def get_default_settings(*components: SettingsSpec) -> Values:
+def get_default_settings(*components: type[SettingsSpec]) -> Values:
"""Return default runtime settings for `components`.
Return a `frontend.Values` instance with defaults for generic Docutils
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-01-21 15:18:34
|
Revision: 10293
http://sourceforge.net/p/docutils/code/10293
Author: milde
Date: 2026-01-21 15:18:32 +0000 (Wed, 21 Jan 2026)
Log Message:
-----------
Fix :number-lines: option of the "include" directive.
Fix Sphinx issue #14261: ":number-lines: 0 for includes does not work correctly".
Commit [r9909] changed the conversion function to return "None" or an integer.
The former simple test for an optional start value failed for value 0,
because bool("0") == True but bool(0) == False.
Use the conversion function `value_or((None,), int)` also in the Code directive.
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/docutils/parsers/rst/directives/body.py
trunk/docutils/docutils/parsers/rst/directives/misc.py
trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-01-15 22:33:54 UTC (rev 10292)
+++ trunk/docutils/HISTORY.rst 2026-01-21 15:18:32 UTC (rev 10293)
@@ -25,6 +25,8 @@
- "Include" options :start-after: and :end-before: may now also
be used without value (standing for an empty line).
+ - Fix Sphinx issue #14261:
+ The "Include" option :number-lines: changed a start value 0 to 1.
- The severity of "include" problems is lowered to 3: ERROR.
* docutils/parsers/rst/directives/tables.py,
Modified: trunk/docutils/docutils/parsers/rst/directives/body.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/directives/body.py 2026-01-15 22:33:54 UTC (rev 10292)
+++ trunk/docutils/docutils/parsers/rst/directives/body.py 2026-01-21 15:18:32 UTC (rev 10293)
@@ -157,7 +157,7 @@
optional_arguments = 1
option_spec = {'class': directives.class_option,
'name': directives.unchanged,
- 'number-lines': directives.unchanged # integer or None
+ 'number-lines': directives.value_or((None,), int),
}
has_content = True
@@ -186,11 +186,9 @@
raise self.warning(error)
if 'number-lines' in options:
- # optional argument `startline`, defaults to 1
- try:
- startline = int(options['number-lines'] or 1)
- except ValueError:
- raise self.error(':number-lines: with non-integer start value')
+ startline = self.options['number-lines']
+ if startline is None:
+ startline = 1
endline = startline + len(self.content)
# add linenumber filter:
tokens = NumberLines(tokens, startline, endline)
Modified: trunk/docutils/docutils/parsers/rst/directives/misc.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/directives/misc.py 2026-01-15 22:33:54 UTC (rev 10292)
+++ trunk/docutils/docutils/parsers/rst/directives/misc.py 2026-01-21 15:18:32 UTC (rev 10293)
@@ -181,7 +181,9 @@
literal_block.line = self.options.get('start-line', 0) + 1
self.add_name(literal_block)
if 'number-lines' in self.options:
- firstline = self.options['number-lines'] or 1
+ firstline = self.options['number-lines']
+ if firstline is None:
+ firstline = 1
text = text.removesuffix('\n')
lastline = firstline + len(text.splitlines())
tokens = NumberLines([([], text)], firstline, lastline)
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-01-15 22:33:54 UTC (rev 10292)
+++ trunk/docutils/test/test_parsers/test_rst/test_directives/test_include.py 2026-01-21 15:18:32 UTC (rev 10293)
@@ -210,6 +210,26 @@
This file is used by ``test_include.py``.
"""],
[f"""\
+Literal include, add line numbers
+
+.. include:: {include1}
+ :literal:
+ :start-line: 2
+ :number-lines: 0
+""",
+f"""\
+<document source="test data">
+ <paragraph>
+ Literal include, add line numbers
+ <literal_block source="{include1}" xml:space="preserve">
+ <inline classes="ln">
+ 0 \n\
+ \n\
+ <inline classes="ln">
+ 1 \n\
+ This file is used by ``test_include.py``.
+"""],
+[f"""\
Include code
.. include:: {include1}
@@ -1157,7 +1177,7 @@
.. include:: {include1}
:code: rst
- :number-lines:
+ :number-lines: 0
""",
f"""\
<document source="test data">
@@ -1165,21 +1185,21 @@
Included code
<literal_block classes="code rst" source="{include1}" xml:space="preserve">
<inline classes="ln">
- 1 \n\
+ 0 \n\
<inline classes="generic heading">
Inclusion 1
\n\
<inline classes="ln">
- 2 \n\
+ 1 \n\
<inline classes="generic heading">
-----------
\n\
<inline classes="ln">
- 3 \n\
+ 2 \n\
<inline classes="whitespace">
\n\
<inline classes="ln">
- 4 \n\
+ 3 \n\
<inline classes="whitespace">
This file is used by \n\
<inline classes="literal string">
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-01-15 22:33:55
|
Revision: 10292
http://sourceforge.net/p/docutils/code/10292
Author: milde
Date: 2026-01-15 22:33:54 +0000 (Thu, 15 Jan 2026)
Log Message:
-----------
Update .htaccess web configuration file
Use the unregistered MIME type "text/x-rst" for reStructuredText source files.
cf. bug #516.
Update redirects to point to *.rst files instead of nonexisting *.txt files.
Add a rewrite rule to re-direct URIs ending in .txt to *.rst files.
Modified Paths:
--------------
trunk/web/.htaccess
Modified: trunk/web/.htaccess
===================================================================
--- trunk/web/.htaccess 2026-01-14 20:46:05 UTC (rev 10291)
+++ trunk/web/.htaccess 2026-01-15 22:33:54 UTC (rev 10292)
@@ -1,14 +1,21 @@
-Options Indexes
+# Do not edit arbitrarily. Check with doc...@li... first.
+# Enable directory index listings
+# ===============================
+Options +Indexes
+
+# MIME types
+# ==========
+# use "text/x-rst" instead of the personal/vanity entry "text.prs.fallenstein.r
+AddType text/x-rst .rst
+
# Redirects
# =========
-# Do not edit arbitrarily. Check with doc...@li... first.
-
# Moved files and directories.
Redirect permanent docs/ref/rst/substitutions.html http://docutils.sourceforge.net/docs/ref/rst/definitions.html
-Redirect permanent docs/ref/rst/substitutions.txt http://docutils.sourceforge.net/docs/ref/rst/definitions.txt
+Redirect permanent docs/ref/rst/substitutions.txt http://docutils.sourceforge.net/docs/ref/rst/definitions.rst
Redirect permanent /sandbox/leawiemann http://docutils.sourceforge.net/sandbox/wiemann
Redirect permanent /sandbox/wiemann/xhtml2rest http://docutils.sourceforge.net/sandbox/xhtml2rest
Redirect permanent /sandbox/ax- http://docutils.sourceforge.net/sandbox/axk
@@ -17,11 +24,11 @@
# Redirection from old URLs to new URLs after a site reorganization.
Redirect permanent /docs/config.html http://docutils.sourceforge.net/docs/user/config.html
-Redirect permanent /docs/config.txt http://docutils.sourceforge.net/docs/user/config.txt
+Redirect permanent /docs/config.txt http://docutils.sourceforge.net/docs/user/config.rst
Redirect permanent /docs/latex.html http://docutils.sourceforge.net/docs/user/latex.html
-Redirect permanent /docs/latex.txt http://docutils.sourceforge.net/docs/user/latex.txt
+Redirect permanent /docs/latex.txt http://docutils.sourceforge.net/docs/user/latex.rst
Redirect permanent /docs/tools.html http://docutils.sourceforge.net/docs/user/tools.html
-Redirect permanent /docs/tools.txt http://docutils.sourceforge.net/docs/user/tools.txt
+Redirect permanent /docs/tools.txt http://docutils.sourceforge.net/docs/user/tools.rst
Redirect permanent /docs/rst/ http://docutils.sourceforge.net/docs/user/rst/
@@ -28,38 +35,41 @@
Redirect permanent /spec/howto/ http://docutils.sourceforge.net/docs/howto/
Redirect permanent /spec/pysource.dtd http://docutils.sourceforge.net/docs/dev/pysource.dtd
-Redirect permanent /spec/pysource.txt http://docutils.sourceforge.net/docs/dev/pysource.txt
+Redirect permanent /spec/pysource.txt http://docutils.sourceforge.net/docs/dev/pysource.rst
Redirect permanent /spec/pysource.html http://docutils.sourceforge.net/docs/dev/pysource.html
-Redirect permanent /spec/semantics.txt http://docutils.sourceforge.net/docs/dev/semantics.txt
+Redirect permanent /spec/semantics.txt http://docutils.sourceforge.net/docs/dev/semantics.rst
Redirect permanent /spec/semantics.html http://docutils.sourceforge.net/docs/dev/semantics.html
-Redirect permanent /spec/notes.txt http://docutils.sourceforge.net/docs/dev/todo.txt
+Redirect permanent /spec/notes.txt http://docutils.sourceforge.net/docs/dev/todo.rst
Redirect permanent /spec/notes.html http://docutils.sourceforge.net/docs/dev/todo.html
-Redirect permanent /spec/doctree.txt http://docutils.sourceforge.net/docs/ref/doctree.txt
+Redirect permanent /spec/doctree.txt http://docutils.sourceforge.net/docs/ref/doctree.rst
Redirect permanent /spec/doctree.html http://docutils.sourceforge.net/docs/ref/doctree.html
Redirect permanent /spec/docutils.dtd http://docutils.sourceforge.net/docs/ref/docutils.dtd
Redirect permanent /spec/soextblx.dtd http://docutils.sourceforge.net/docs/ref/soextblx.dtd
-Redirect permanent /spec/transforms.txt http://docutils.sourceforge.net/docs/ref/transforms.txt
+Redirect permanent /spec/transforms.txt http://docutils.sourceforge.net/docs/ref/transforms.rst
Redirect permanent /spec/transforms.html http://docutils.sourceforge.net/docs/ref/transforms.html
-Redirect permanent /spec/rst/alternatives.txt http://docutils.sourceforge.net/docs/dev/rst/alternatives.txt
+Redirect permanent /spec/rst/alternatives.txt http://docutils.sourceforge.net/docs/dev/rst/alternatives.rst
Redirect permanent /spec/rst/alternatives.html http://docutils.sourceforge.net/docs/dev/rst/alternatives.html
-Redirect permanent /spec/rst/problems.txt http://docutils.sourceforge.net/docs/dev/rst/problems.txt
+Redirect permanent /spec/rst/problems.txt http://docutils.sourceforge.net/docs/dev/rst/problems.rst
Redirect permanent /spec/rst/problems.html http://docutils.sourceforge.net/docs/dev/rst/problems.html
-Redirect permanent /spec/rst/reStructuredText.txt http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.txt
+Redirect permanent /spec/rst/reStructuredText.txt http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.rst
Redirect permanent /spec/rst/reStructuredText.html http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html
-Redirect permanent /spec/rst/restructuredtext.txt http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.txt
+Redirect permanent /spec/rst/restructuredtext.txt http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.rst
Redirect permanent /spec/rst/restructuredtext.html http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html
-Redirect permanent /spec/rst/directives.txt http://docutils.sourceforge.net/docs/ref/rst/directives.txt
+Redirect permanent /spec/rst/directives.txt http://docutils.sourceforge.net/docs/ref/rst/directives.rst
Redirect permanent /spec/rst/directives.html http://docutils.sourceforge.net/docs/ref/rst/directives.html
-Redirect permanent /spec/rst/interpreted.txt http://docutils.sourceforge.net/docs/ref/rst/roles.txt
+Redirect permanent /spec/rst/interpreted.txt http://docutils.sourceforge.net/docs/ref/rst/roles.rst
Redirect permanent /spec/rst/interpreted.html http://docutils.sourceforge.net/docs/ref/rst/roles.html
-Redirect permanent /spec/rst/introduction.txt http://docutils.sourceforge.net/docs/ref/rst/introduction.txt
+Redirect permanent /spec/rst/introduction.txt http://docutils.sourceforge.net/docs/ref/rst/introduction.rst
Redirect permanent /spec/rst/introduction.html http://docutils.sourceforge.net/docs/ref/rst/introduction.html
RedirectMatch permanent /spec/pep-(.*) http://docutils.sourceforge.net/docs/peps/pep-$1
-Redirect permanent /tools/test.txt http://docutils.sourceforge.net/docs/user/rst/demo.txt
+Redirect permanent /tools/test.txt http://docutils.sourceforge.net/docs/user/rst/demo.rst
Redirect permanent /tools/test.html http://docutils.sourceforge.net/docs/user/rst/demo.html
+
+# extension for rST source files changed from .txt to .rst
+RewriteRule ^(.*)\.txt$ $1.rst
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-01-14 20:46:07
|
Revision: 10291
http://sourceforge.net/p/docutils/code/10291
Author: milde
Date: 2026-01-14 20:46:05 +0000 (Wed, 14 Jan 2026)
Log Message:
-----------
HTML5 writer: Use the last "ids" value for the section-self-link.
If a section has several IDs, use the last one
(from the first explicit target) in the "self-link".
All hyperlinks to the section stay valid (we only change which ID is
shown to users when hovering over the link symbol).
Modified Paths:
--------------
trunk/docutils/HISTORY.rst
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docutils/writers/html5_polyglot/__init__.py
trunk/docutils/test/functional/expected/misc_rst_html5.html
Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst 2026-01-11 19:35:49 UTC (rev 10290)
+++ trunk/docutils/HISTORY.rst 2026-01-14 20:46:05 UTC (rev 10291)
@@ -42,6 +42,10 @@
- Add source and line info to <table> elements.
- Fix bug #517: wrong "input_offset" when parsing table cell content.
+* docutils/writers/html5_polyglot/__init__.py
+
+ - Use a section's last "ids" attribute for the "section-self-link".
+
* docutils/writers/latex2e/*
- Default styling for "semantic inline markup roles" from the
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-01-11 19:35:49 UTC (rev 10290)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-01-14 20:46:05 UTC (rev 10291)
@@ -108,11 +108,6 @@
* "html5" writer:
- - If a section title has several IDs, use the last one (from the first
- `explicit target`__) as self-link_ in Docutils 0.23.
-
- __ docs/ref/rst/restructuredtext.html#explicit-hyperlink-targets
-
- The default of the self-link_ configuration setting will change to
"True" in Docutils 1.0.
@@ -297,6 +292,12 @@
defaults to the role's name (if supported by Pygments_).
Specifying ``:language: none`` turns off syntax highlight.
+HTML5 writer:
+ - If a section has several IDs, use the last one (from the first
+ `explicit target`__) as self-link_.
+
+ __ docs/ref/rst/restructuredtext.html#explicit-hyperlink-targets
+
LaTeX writer:
- Only write ``\label`` commands for explicit IDs and IDs that are
referenced in the current document (i.e. not for un-referenced
Modified: trunk/docutils/docutils/writers/html5_polyglot/__init__.py
===================================================================
--- trunk/docutils/docutils/writers/html5_polyglot/__init__.py 2026-01-11 19:35:49 UTC (rev 10290)
+++ trunk/docutils/docutils/writers/html5_polyglot/__init__.py 2026-01-14 20:46:05 UTC (rev 10291)
@@ -388,11 +388,9 @@
def section_title_tags(self, node):
start_tag, close_tag = super().section_title_tags(node)
ids = node.parent['ids']
- # TODO: use ``ids[-1]``
- # (IDs from explicit targets are appended to the implicit ID)
if (ids and getattr(self.settings, 'section_self_link', None)
and not isinstance(node.parent, nodes.document)):
self_link = ('<a class="self-link" title="link to this section"'
- f' href="#{ids[0]}"></a>')
+ f' href="#{ids[-1]}"></a>')
close_tag = close_tag.replace('</h', self_link + '</h')
return start_tag, close_tag
Modified: trunk/docutils/test/functional/expected/misc_rst_html5.html
===================================================================
--- trunk/docutils/test/functional/expected/misc_rst_html5.html 2026-01-11 19:35:49 UTC (rev 10290)
+++ trunk/docutils/test/functional/expected/misc_rst_html5.html 2026-01-14 20:46:05 UTC (rev 10291)
@@ -97,7 +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="#section-titles-with-inline-markup"></a></h2>
+<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>
<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>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-01-11 19:35:51
|
Revision: 10290
http://sourceforge.net/p/docutils/code/10290
Author: milde
Date: 2026-01-11 19:35:49 +0000 (Sun, 11 Jan 2026)
Log Message:
-----------
Update FAQ answer about MIME type.
Document the 3rd party entry "text/prs.fallenstein.rst" in the
"personal or vanity" IANA Media Type Registration Tree.
Cf. bug #516.
Modified Paths:
--------------
trunk/docutils/FAQ.rst
Modified: trunk/docutils/FAQ.rst
===================================================================
--- trunk/docutils/FAQ.rst 2026-01-07 13:43:01 UTC (rev 10289)
+++ trunk/docutils/FAQ.rst 2026-01-11 19:35:49 UTC (rev 10290)
@@ -800,10 +800,12 @@
What's the official MIME type for reStructuredText data?
--------------------------------------------------------
-While there is no registered MIME type for reStructuredText, the
-"official unofficial" standard MIME type is "text/x-rst". [#]_ This was
-invented for the build system for PEPs (Python Enhancement Proposals),
-and it's used by the python.org web site build system.
+There is no official MIME type.
+The IANA lists `text/prs.fallenstein.rst`_ as MIME type
+for `reStructuredText` in the `"personal or vanity"`__
+`Media Type Registration Tree`__.
+Docutils recommends "text/x-rst" [#]_
+(unless you require a registered type).
Also see `What's the standard filename extension for a
reStructuredText file?`_
@@ -810,7 +812,12 @@
.. [#] The "x-" prefix means it's an unregistered MIME type.
+.. _text/prs.fallenstein.rst:
+ https://www.iana.org/assignments/media-types/text/prs.fallenstein.rst
+__ https://datatracker.ietf.org/doc/html/rfc2048#section-2.1.3
+__ https://datatracker.ietf.org/doc/html/rfc2048#section-2.1
+
How can I specify an image grid?
--------------------------------
@@ -847,17 +854,17 @@
What is the status of the HTML Writer?
--------------------------------------
-The default HTML Writer module, `html4css1`_, is
-a proof-of-concept reference implementation. While it is a complete
-implementation, some aspects of the HTML it produces may be outdated or
-incompatible with older browsers or specialized applications (such as
-web templating).
+The default HTML Writer module, `html4css1`_ is a complete
+implementation but the HTML variant it produces is outdated.
-The `html5 writer`_ generates semantic HTML output compatible with HTML5.
+The `html5 writer`_ generates valid XML that conforms to HTML5
+(`HTML Living standard`_).
+
For the full selection see `Docutils HTML writers`_
.. _html4css1: docs/user/html.html#html4css1
.. _HTML5 writer: docs/user/html.html#html5
+.. _HTML Living standard: https://html.spec.whatwg.org/multipage/
.. _Docutils HTML writers: docs/user/html.html
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <mi...@us...> - 2026-01-07 13:43:04
|
Revision: 10289
http://sourceforge.net/p/docutils/code/10289
Author: milde
Date: 2026-01-07 13:43:01 +0000 (Wed, 07 Jan 2026)
Log Message:
-----------
Small documentation updates.
Announce change to "rubric" styling in HTML5.
Clarify the relationship between the `<address>` Doctree element
and `<address>` HTML element.
Update some comments and docstrings.
Modified Paths:
--------------
trunk/docutils/RELEASE-NOTES.rst
trunk/docutils/docs/ref/doctree.rst
trunk/docutils/docutils/nodes.py
trunk/docutils/docutils/transforms/references.py
Modified: trunk/docutils/RELEASE-NOTES.rst
===================================================================
--- trunk/docutils/RELEASE-NOTES.rst 2026-01-07 13:42:50 UTC (rev 10288)
+++ trunk/docutils/RELEASE-NOTES.rst 2026-01-07 13:43:01 UTC (rev 10289)
@@ -117,7 +117,7 @@
"True" in Docutils 1.0.
- Prefer explicit reference names as base for an HTML element's ID
- in Docutils 1.0. No change for internal cross-references.
+ in Docutils 1.0. No change for internal cross-references.
Cf. `Sphinx issue #1961`__
__ https://github.com/sphinx-doc/sphinx/issues/1961
@@ -131,6 +131,9 @@
- Change the default value of the initial_header_level_ setting to "auto"
(<h2> if there is a document title, else <h1>) in Docutils 1.0.
+ - Use normal font size and colour for informal titles of type "rubric"
+ in Docutils 1.0.
+
- Remove option ``--embed-images`` (obsoleted by "image_loading_")
in Docutils 2.0.
Modified: trunk/docutils/docs/ref/doctree.rst
===================================================================
--- trunk/docutils/docs/ref/doctree.rst 2026-01-07 13:42:50 UTC (rev 10288)
+++ trunk/docutils/docs/ref/doctree.rst 2026-01-07 13:43:01 UTC (rev 10289)
@@ -438,6 +438,8 @@
:Category: `Bibliographic Elements`_
:Analogues: <address> is analogous to the DocBook_ <address> element.
+ The HTML_ <address> element, in contrast, is analogous
+ to the `<contact>`_ element.
:Processing: As with the `\<literal_block>`_ element, newlines are
significant and must be preserved.
However, a monospaced typeface should not be used.
@@ -1083,8 +1085,8 @@
It is typically used for an email or web address.
:Category: `Bibliographic Elements`_
-:Analogues: <contact> is analogous to the DocBook_ <email> element.
- The HTML_ <address> element serves a similar purpose.
+:Analogues: <contact> is analogous to the DocBook_ <email> element
+ and the HTML_ <address> element.
:Processing: See `\<docinfo>`_.
:Parents: `\<docinfo>`_, `\<authors>`_
:Children: text data plus `inline elements`_ (`%text.model`_)
Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py 2026-01-07 13:42:50 UTC (rev 10288)
+++ trunk/docutils/docutils/nodes.py 2026-01-07 13:43:01 UTC (rev 10289)
@@ -1746,7 +1746,7 @@
"""Mapping of names to lists of referencing nodes."""
self.refids: dict[str, list[Element]] = {}
- """Mapping of ids to lists of referencing nodes."""
+ """(Incomplete) Mapping of ids to lists of referencing nodes."""
self.nameids: dict[str, str] = {}
"""Mapping of names to unique id's."""
Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py 2026-01-07 13:42:50 UTC (rev 10288)
+++ trunk/docutils/docutils/transforms/references.py 2026-01-07 13:43:01 UTC (rev 10289)
@@ -81,6 +81,7 @@
# Remove target node from places where it is invalid.
# TODO: always remove target?
# +1 It did complete its mission and is currently ignored.
+ # (except for the Sphinx LaTeX writer)
# -1 It may help a future rST writer.
if isinstance(target.parent, nodes.figure) and isinstance(
next_node, nodes.caption):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|