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

milde--- via Docutils-checkins <[email protected]>
Newsgroups gmane.text.docutils.cvs
Message-ID <[email protected]>
Revision: 9744
          http://sourceforge.net/p/docutils/code/9744
Author:   milde
Date:     2024-06-06 14:03:33 +0000 (Thu, 06 Jun 2024)
Log Message:
-----------
xml-parser: Register IDs, report duplicate IDs.

Add element IDs to `document.ids`.

Report an ERROR system message for duplicate IDs.

Improves co-operation with "rST" parser when including XML
files in an rST file.

Modified Paths:
--------------
    trunk/docutils/docutils/parsers/docutils_xml.py
    trunk/docutils/test/test_parsers/test_docutils_xml/test_parse.py
    trunk/docutils/test/test_parsers/test_docutils_xml/test_parse_element.py

Added Paths:
-----------
    trunk/docutils/test/test_parsers/test_docutils_xml/test_misc.py

Modified: trunk/docutils/docutils/parsers/docutils_xml.py
===================================================================
--- trunk/docutils/docutils/parsers/docutils_xml.py	2024-06-06 14:03:21 UTC (rev 9743)
+++ trunk/docutils/docutils/parsers/docutils_xml.py	2024-06-06 14:03:33 UTC (rev 9744)
@@ -147,6 +147,14 @@
             if key in node.list_attributes:
                 value = value.split()
             node.attributes[key] = value  # node becomes invalid!
+    # register ids, check for duplicates
+    for id in node['ids']:
+        document.ids.setdefault(id, node)
+        if document.ids[id] is not node:
+            document.reporter.error(f'Duplicate ID: "{id}" used by '
+                                    f'{document.ids[id].starttag()} '
+                                    f'and {node.starttag()}',
+                                    base_node=node)
 
     # Append content:
     # update "unindent" flag: change line indentation?

Added: trunk/docutils/test/test_parsers/test_docutils_xml/test_misc.py
===================================================================
--- trunk/docutils/test/test_parsers/test_docutils_xml/test_misc.py	                        (rev 0)
+++ trunk/docutils/test/test_parsers/test_docutils_xml/test_misc.py	2024-06-06 14:03:33 UTC (rev 9744)
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+# :Copyright: © 2024 Günter Milde.
+# :License: Released under the terms of the `2-Clause BSD license`_, in short:
+#
+#    Copying and distribution of this file, with or without modification,
+#    are permitted in any medium without royalty provided the copyright
+#    notice and this notice are preserved.
+#    This file is offered as-is, without any warranty.
+#
+# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause
+
+"""Various tests for the XML parser.
+
+Test parsing + transformations with `publish_string()`.
+"""
+
+from pathlib import Path
+import sys
+import unittest
+
+if __name__ == '__main__':
+    # prepend the "docutils root" to the Python library path
+    # so we import the local `docutils` package.
+    sys.path.insert(0, str(Path(__file__).resolve().parents[3]))
+
+from docutils.core import publish_string
+from docutils.parsers import docutils_xml
+
+parser = docutils_xml.Parser()
+
+
+class XMLParserTests(unittest.TestCase):
+    maxDiff = None
+
+    mysettings = {'_disable_config': True,
+                  'output_encoding': 'unicode',
+                  'warning_stream': '',
+                  }
+
+    def test_publish(self):
+        for name, (settings, cases) in totest.items():
+            settings = self.mysettings | settings
+            for casenum, (case_input, case_expected) in enumerate(cases):
+                with self.subTest(id=f'totest[{name!r}][{casenum}]'):
+                    output = publish_string(case_input, parser=parser,
+                                            settings_overrides=settings)
+                    self.assertEqual(case_expected, output)
+
+
+totest = {}
+
+totest['hyperlinks'] = ({},
+[
+# resolve anonymous hyperlinks
+["""\
+<document source="test data">
+    <paragraph>A <reference anonymous="1" name="link">link</reference> to Docutils.</paragraph>
+    <target anonymous="1" ids="target-1" refuri="http://docutils.sourceforge.io"/>
+</document>
+""",
+"""\
+<document source="test data">
+    <paragraph>
+        A \n\
+        <reference anonymous="1" name="link" refuri="http://docutils.sourceforge.io">
+            link
+         to Docutils.
+    <target anonymous="1" ids="target-1" refuri="http://docutils.sourceforge.io">
+"""],
+# duplicate ids are an error
+["""\
+<tip ids="i1 i2">
+    <paragraph><strong ids="i2 i3"></strong></paragraph>
+</tip>
+""",
+"""\
+<document source="<string>">
+    <tip ids="i1 i2">
+        <paragraph>
+            <strong ids="i2 i3">
+    <section classes="system-messages">
+        <title>
+            Docutils System Messages
+        <system_message level="3" line="2" source="<string>" type="ERROR">
+            <paragraph>
+                Duplicate ID: "i2" used by <tip ids="i1 i2"> and <strong ids="i2 i3">
+"""],
+])
+
+if __name__ == '__main__':
+    unittest.main()


Property changes on: trunk/docutils/test/test_parsers/test_docutils_xml/test_misc.py
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Modified: trunk/docutils/test/test_parsers/test_docutils_xml/test_parse.py
===================================================================
--- trunk/docutils/test/test_parsers/test_docutils_xml/test_parse.py	2024-06-06 14:03:21 UTC (rev 9743)
+++ trunk/docutils/test/test_parsers/test_docutils_xml/test_parse.py	2024-06-06 14:03:33 UTC (rev 9744)
@@ -28,13 +28,13 @@
 
 
 class XmlParserTestCase(unittest.TestCase):
-    def test_parser(self):
-        settings = get_default_settings(docutils_xml.Parser)
-        # settings.warning_stream = ''
+    def test_parse(self):
+        settings = get_default_settings(parser)
+        settings.warning_stream = ''
         for name, cases in totest.items():
             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)

Modified: trunk/docutils/test/test_parsers/test_docutils_xml/test_parse_element.py
===================================================================
--- trunk/docutils/test/test_parsers/test_docutils_xml/test_parse_element.py	2024-06-06 14:03:21 UTC (rev 9743)
+++ trunk/docutils/test/test_parsers/test_docutils_xml/test_parse_element.py	2024-06-06 14:03:33 UTC (rev 9744)
@@ -27,6 +27,7 @@
 
 class ParseElementTestCase(unittest.TestCase):
     """Test the `docutils.xml.parse_element()` function."""
+    maxDiff = None
 
     # supress warnings when passing `document` to `parse_element()`
     settings = frontend.get_default_settings(docutils_xml.Parser)

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



_______________________________________________
Docutils-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/docutils-checkins
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.