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

milde--- via Docutils-checkins <[email protected]> Fri, 06 Feb 2026 09:09:28 +0000
Newsgroups gmane.text.docutils.cvs
Message-ID <[email protected]>
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.