SF.net SVN: docutils:[10384 ] trunk/docutils

milde--- via Docutils-checkins <[email protected]> Thu, 16 Jul 2026 10:43:15 +0000
Newsgroups gmane.text.docutils.cvs
Message-ID <[email protected]>
Revision: 10384
          http://sourceforge.net/p/docutils/code/10384
Author:   milde
Date:     2026-07-16 10:43:14 +0000 (Thu, 16 Jul 2026)
Log Message:
-----------
"lazy IDs": postpone generation of IDs for anonymous targets.

Generate IDs for explicit targets after parsing is complete:

`nodes.document.note_explicit_target()` only generates an ID for the target,
if the "legacy_ids" setting is True.

The `transforms.references.PropagateTargets` transform now can also
propagate targets without reference name or ID and sets an ID on the
destination of the propagation if required.

This is a precondition for a future check whether the destination of
to-be-propagated anonymous targets is an external or indirect target
that does not require an ID.

Anonymous internal targets now re-use an existing ID or get an auto-ID
based on the tagname of the target element

Modified Paths:
--------------
    trunk/docutils/HISTORY.rst
    trunk/docutils/docutils/nodes.py
    trunk/docutils/docutils/transforms/references.py
    trunk/docutils/test/test_transforms/test_hyperlinks.py

Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst	2026-07-15 18:57:56 UTC (rev 10383)
+++ trunk/docutils/HISTORY.rst	2026-07-16 10:43:14 UTC (rev 10384)
@@ -47,9 +47,9 @@
 
   - Remove "name" from `reference.valid_attributes`.
   - Remove the internal attribute `Targetable.indirect_reference_name`.
-  - "lazy IDs": `document.note_explicit_target()` and
-    `document.note_anonymous_target()` generate identifiers for indirect
-    or external targets only if the `legacy_ids`_ setting is True.
+  - "lazy IDs":
+    `document.note_explicit_target()` and `document.note_anonymous_target()`
+    generate identifiers only if the `legacy_ids`_ setting is True.
 
 * docutils/parsers/__init__.py
 

Modified: trunk/docutils/docutils/nodes.py
===================================================================
--- trunk/docutils/docutils/nodes.py	2026-07-15 18:57:56 UTC (rev 10383)
+++ trunk/docutils/docutils/nodes.py	2026-07-16 10:43:14 UTC (rev 10384)
@@ -2192,8 +2192,7 @@
             self.note_refname(target)
 
     def note_anonymous_target(self, target: target) -> None:
-        if (getattr(self.settings, "legacy_ids", True)
-                or 'refuri' not in target and 'refname' not in target):
+        if getattr(self.settings, "legacy_ids", True):
             self.set_id(target)
 
     def note_autofootnote(self, footnote: footnote) -> None:

Modified: trunk/docutils/docutils/transforms/references.py
===================================================================
--- trunk/docutils/docutils/transforms/references.py	2026-07-15 18:57:56 UTC (rev 10383)
+++ trunk/docutils/docutils/transforms/references.py	2026-07-16 10:43:14 UTC (rev 10384)
@@ -43,7 +43,7 @@
     Given the following nodes::
 
         <target names="internal1">
-        <target anonymous="1" ids="id1">
+        <target anonymous="1">
         <target names="internal2">
         <paragraph>
             This is a test.
@@ -53,9 +53,9 @@
     to the paragraph itself::
 
         <target refid="internal1">
-        <target anonymous="1" refid="id1">
+        <target anonymous="1" refid="internal1">
         <target refid="internal2">
-        <paragraph ids="internal2 id1 internal1" names="internal2 internal1">
+        <paragraph ids="internal2 internal1" names="internal2 internal1">
             This is a test.
     """
 
@@ -124,13 +124,20 @@
                     next_node, nodes.caption):
                 target.parent.remove(target)
                 continue
-            # Set refid to point to the first former ID of target
-            # which is now an ID of next_node.
-            target['refid'] = target['ids'][0]
+            # Set refid or refname to point to the next_node.
             # Clear ids and names; they have been moved to next_node.
-            target['ids'] = []
+            if target['ids']:
+                target['refid'] = target['ids'][0]
+                self.document.note_refid(target)
+                target['ids'] = []
+            elif target['names']:
+                target['refname'] = target['names'][0]
+                self.document.note_refname(target)
+            elif next_node['names']:
+                target['refname'] = next_node['names'][0]
+            else:
+                target['refid'] = self.document.set_id(next_node)
             target['names'] = []
-            self.document.note_refid(target)
 
 
 class AnonymousHyperlinks(Transform):

Modified: trunk/docutils/test/test_transforms/test_hyperlinks.py
===================================================================
--- trunk/docutils/test/test_transforms/test_hyperlinks.py	2026-07-15 18:57:56 UTC (rev 10383)
+++ trunk/docutils/test/test_transforms/test_hyperlinks.py	2026-07-16 10:43:14 UTC (rev 10384)
@@ -1506,10 +1506,10 @@
     <target refid="img1">
     <reference ids="img1" names="img1" refuri="uri1.html">
         <image uri="pic1.png">
-    <target anonymous="1" refid="target-1">
-    <image ids="target-1" uri="pic2.png">
-    <target anonymous="1" refid="target-2">
-    <reference ids="target-2" refuri="uri3.html">
+    <target anonymous="1" refid="image-1">
+    <image ids="image-1" uri="pic2.png">
+    <target anonymous="1" refid="reference-1">
+    <reference ids="reference-1" refuri="uri3.html">
         <image uri="pic3.png">
     <paragraph>
         Named link to \n\
@@ -1517,7 +1517,7 @@
             img1
          with target and anonymous links to
         the targetless \n\
-        <reference anonymous="1" refid="target-1">
+        <reference anonymous="1" refid="image-1">
             img2
          and
         <reference anonymous="1" refuri="uri3.html">
@@ -1549,8 +1549,8 @@
 """\
 <document source="test data">
     <target anonymous="1" refid="target-1">
-    <target anonymous="1" refid="target-2">
-    <reference ids="target-2 target-1" refuri="uri1.html">
+    <target anonymous="1" refid="target-1">
+    <reference ids="target-1" refuri="uri1.html">
         <image uri="pic1.png">
     <paragraph>
         Two \n\
@@ -1561,8 +1561,8 @@
             image with target
          (sic!).
     <target refid="named">
-    <target anonymous="1" refid="target-3">
-    <reference ids="target-3 named" names="named" refuri="uri2.html">
+    <target anonymous="1" refid="named">
+    <reference ids="named" names="named" refuri="uri2.html">
         <image uri="pic2.png">
     <paragraph>
         <reference refid="named">
@@ -1571,9 +1571,9 @@
         <reference anonymous="1" refuri="uri2.html">
             anonymous
          link to an image with target (sic!).
-    <target anonymous="1" refid="target-4">
+    <target anonymous="1" refname="named link">
     <target refid="named-link">
-    <reference ids="named-link target-4" names="named\\ link" refuri="uri3.html">
+    <reference ids="named-link" names="named\\ link" refuri="uri3.html">
         <image uri="pic3.png">
     <paragraph>
         <reference anonymous="1" refuri="uri3.html">
@@ -1604,8 +1604,8 @@
     <target anonymous="1" ids="target-1" refuri="http://simplified">
     <target names="external" refuri="http://indirect.external">
     <target anonymous="1" refuri="http://indirect.external">
-    <target anonymous="1" refid="target-2">
-    <paragraph ids="target-2">
+    <target anonymous="1" refid="paragraph-1">
+    <paragraph ids="paragraph-1">
         <reference anonymous="1" refuri="http://full">
             Full syntax anonymous external hyperlink reference
         ,
@@ -1618,7 +1618,7 @@
         <reference anonymous="1" refuri="http://indirect.external">
             indirect anonymous hyperlink reference
         ,
-        <reference anonymous="1" refid="target-2">
+        <reference anonymous="1" refid="paragraph-1">
             internal anonymous hyperlink reference
         .
 """],

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.