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

milde--- via Docutils-checkins <[email protected]> Tue, 19 Aug 2025 18:37:49 +0000
Newsgroups gmane.text.docutils.cvs
Message-ID <[email protected]>
Revision: 10208
          http://sourceforge.net/p/docutils/code/10208
Author:   milde
Date:     2025-08-19 18:37:49 +0000 (Tue, 19 Aug 2025)
Log Message:
-----------
Better error reporting for table markup.

Based on [patches:#214] by Jynn Nelson.
Solves [bugs:#504].

Modified Paths:
--------------
    trunk/docutils/HISTORY.rst
    trunk/docutils/docutils/parsers/rst/states.py
    trunk/docutils/test/test_parsers/test_rst/test_tables.py

Modified: trunk/docutils/HISTORY.rst
===================================================================
--- trunk/docutils/HISTORY.rst	2025-08-19 17:03:49 UTC (rev 10207)
+++ trunk/docutils/HISTORY.rst	2025-08-19 18:37:49 UTC (rev 10208)
@@ -32,6 +32,8 @@
   - Ensure new "current node" is valid when switching section level
     (cf. bugs #508 and #509).
   - Use a `separate title style hierarchy for nested parsing`__.
+  - Better error messages for grid table markup errors (bug #504),
+    based on patch #214 by Jynn Nelson.
 
 __ RELEASE-NOTES.html#nested-parsing
 

Modified: trunk/docutils/docutils/parsers/rst/states.py
===================================================================
--- trunk/docutils/docutils/parsers/rst/states.py	2025-08-19 17:03:49 UTC (rev 10207)
+++ trunk/docutils/docutils/parsers/rst/states.py	2025-08-19 18:37:49 UTC (rev 10208)
@@ -1763,19 +1763,21 @@
                 del block[i:]
                 break
         if not self.grid_table_top_pat.match(block[-1]):  # find bottom
-            blank_finish = 0
             # from second-last to third line of table:
             for i in range(len(block) - 2, 1, -1):
                 if self.grid_table_top_pat.match(block[i]):
                     self.state_machine.previous_line(len(block) - i + 1)
                     del block[i+1:]
+                    blank_finish = 0
                     break
             else:
-                messages.extend(self.malformed_table(block))
+                detail = 'Bottom border missing or corrupt.'
+                messages.extend(self.malformed_table(block, detail, i))
                 return [], messages, blank_finish
         for i in range(len(block)):     # check right edge
             if len(block[i]) != width or block[i][-1] not in '+|':
-                messages.extend(self.malformed_table(block))
+                detail = 'Right border not aligned or missing.'
+                messages.extend(self.malformed_table(block, detail, i))
                 return [], messages, blank_finish
         return block, messages, blank_finish
 
@@ -1795,8 +1797,8 @@
                 if len(line.strip()) != toplen:
                     self.state_machine.next_line(i - start)
                     messages = self.malformed_table(
-                        lines[start:i+1], 'Bottom/header table border does '
-                        'not match top border.')
+                        lines[start:i+1], 'Bottom border or header rule does '
+                        'not match top border.', i-start)
                     return [], messages, i == limit or not lines[i+1].strip()
                 found += 1
                 found_at = i
@@ -1805,17 +1807,16 @@
                     break
             i += 1
         else:                           # reached end of input_lines
+            details = 'No bottom table border found'
             if found:
-                extra = ' or no blank line after table bottom'
+                details += ' or no blank line after table bottom'
                 self.state_machine.next_line(found_at - start)
                 block = lines[start:found_at+1]
             else:
-                extra = ''
                 self.state_machine.next_line(i - start - 1)
                 block = lines[start:]
-            messages = self.malformed_table(
-                block, 'No bottom table border found%s.' % extra)
-            return [], messages, not extra
+            messages = self.malformed_table(block, details + '.')
+            return [], messages, not found
         self.state_machine.next_line(end - start)
         block = lines[start:end+1]
         # for East Asian chars:

Modified: trunk/docutils/test/test_parsers/test_rst/test_tables.py
===================================================================
--- trunk/docutils/test/test_parsers/test_rst/test_tables.py	2025-08-19 17:03:49 UTC (rev 10207)
+++ trunk/docutils/test/test_parsers/test_rst/test_tables.py	2025-08-19 18:37:49 UTC (rev 10208)
@@ -86,20 +86,89 @@
 """],
 ["""\
 +-----------------------+
-| A malformed table. |
+| A misaligned table. |
 +-----------------------+
+
++-----------------------+
+| Right border missing.
++-----------------------+
 """,
 """\
 <document source="test data">
-    <system_message level="3" line="1" source="test data" type="ERROR">
+    <system_message level="3" line="2" source="test data" type="ERROR">
         <paragraph>
             Malformed table.
+            Right border not aligned or missing.
         <literal_block xml:space="preserve">
             +-----------------------+
-            | A malformed table. |
+            | A misaligned table. |
             +-----------------------+
+    <system_message level="3" line="6" source="test data" type="ERROR">
+        <paragraph>
+            Malformed table.
+            Right border not aligned or missing.
+        <literal_block xml:space="preserve">
+            +-----------------------+
+            | Right border missing.
+            +-----------------------+
 """],
 ["""\
++-------------------------+
+| A table with one cell   |
+| and missing bottom.     |
+""",
+"""\
+<document source="test data">
+    <system_message level="3" line="3" source="test data" type="ERROR">
+        <paragraph>
+            Malformed table.
+            Bottom border missing or corrupt.
+        <literal_block xml:space="preserve">
+            +-------------------------+
+            | A table with one cell   |
+            | and missing bottom.     |
+"""],
+["""\
++-------------------------+
+| A table with one cell   |
+| and corrupt bottom.     |
++------------------------ +
+""",
+"""\
+<document source="test data">
+    <system_message level="3" line="3" source="test data" type="ERROR">
+        <paragraph>
+            Malformed table.
+            Bottom border missing or corrupt.
+        <literal_block xml:space="preserve">
+            +-------------------------+
+            | A table with one cell   |
+            | and corrupt bottom.     |
+            +------------------------ +
+"""],
+["""\
++-------------------------+
+| A table with one cell   |
+| and corrupt bottom.     |
+--------------------------+
+""",
+"""\
+<document source="test data">
+    <system_message level="3" line="4" source="test data" type="ERROR">
+        <paragraph>
+            Malformed table.
+            Bottom border missing or corrupt.
+        <literal_block xml:space="preserve">
+            +-------------------------+
+            | A table with one cell   |
+            | and corrupt bottom.     |
+    <system_message level="2" line="4" source="test data" type="WARNING">
+        <paragraph>
+            Blank line required after table.
+    <paragraph>
+        --------------------------+
+"""],
+["""\
 +------------------------+
 | A well-formed | table. |
 +------------------------+
@@ -884,9 +953,9 @@
 ["""\
 ==============  ======
 A simple table  cell 2
-cell 3          cell 4
 ==============  ======
-No blank line after table.
+this could be   cell content
+or text after   the table
 """,
 """\
 <document source="test data">
@@ -897,13 +966,13 @@
         <literal_block xml:space="preserve">
             ==============  ======
             A simple table  cell 2
-            cell 3          cell 4
             ==============  ======
-    <system_message level="2" line="5" source="test data" type="WARNING">
+    <system_message level="2" line="4" source="test data" type="WARNING">
         <paragraph>
             Blank line required after table.
     <paragraph>
-        No blank line after table.
+        this could be   cell content
+        or text after   the table
 """],
 ["""\
 ==============  ======
@@ -1117,10 +1186,10 @@
 """,
 """\
 <document source="test data">
-    <system_message level="3" line="1" source="test data" type="ERROR">
+    <system_message level="3" line="4" source="test data" type="ERROR">
         <paragraph>
             Malformed table.
-            Bottom/header table border does not match top border.
+            Bottom border or header rule does not match top border.
         <literal_block xml:space="preserve">
             ==============  ======
             A simple table  this text extends to the right

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