Repository: jackdewinter/pymarkdown

Issue:
Rule Md005 : Fires correctly, but reports wrong expected and actual
During https://github.com/jackdewinter/pymarkdown/issues/93

Verified that the rule is firing properly, but the expected and actual values are not always correct.  To properly figure out these values, will need to understand what the alignment of the list is to properly calculate where the incorrect item should be.

Discussion:

Patch:
diff --git a/changelog.md b/changelog.md
index 4b2c68c6..82883a81 100644
--- a/changelog.md
+++ b/changelog.md
@@ -15,6 +15,8 @@
 
 - [Fixed - Issue 95](https://github.com/jackdewinter/pymarkdown/issues/95)
   - parser: with certain cases involving a new list item, can start a container in the middle of line
+- [Fixed - Issue 161](https://github.com/jackdewinter/pymarkdown/issues/161)
+  - rule md005: was not returning proper values for actual and expected
 - [Fixed - Issue 189](https://github.com/jackdewinter/pymarkdown/issues/189)
   - rule md027: addressed index out of bounds error keeping track of blank lines after a block quote was started in a previous section
 
diff --git a/publish/coverage.json b/publish/coverage.json
index 2576234f..7fa63c49 100644
--- a/publish/coverage.json
+++ b/publish/coverage.json
@@ -2,12 +2,12 @@
     "projectName": "pymarkdown",
     "reportSource": "pytest",
     "branchLevel": {
-        "totalMeasured": 3034,
-        "totalCovered": 3034
+        "totalMeasured": 3030,
+        "totalCovered": 3030
     },
     "lineLevel": {
-        "totalMeasured": 10593,
-        "totalCovered": 10593
+        "totalMeasured": 10584,
+        "totalCovered": 10584
     }
 }
 
diff --git a/pymarkdown/plugins/rule_md_005.py b/pymarkdown/plugins/rule_md_005.py
index 4a638143..47d1c610 100644
--- a/pymarkdown/plugins/rule_md_005.py
+++ b/pymarkdown/plugins/rule_md_005.py
@@ -4,6 +4,7 @@ are equivalent with each other.
 """
 from enum import Enum
 
+# from pymarkdown.parser_helper import ParserHelper
 from pymarkdown.plugin_details import PluginDetails
 from pymarkdown.rule_plugin import RulePlugin
 
@@ -31,6 +32,7 @@ class RuleMd005(RulePlugin):
         self.__ordered_list_starts = {}
         self.__ordered_tokens = {}
         self.__ordered_list_alignment = {}
+        # self.__debug = False
 
     def get_details(self):
         """
@@ -56,42 +58,18 @@ class RuleMd005(RulePlugin):
         self.__ordered_tokens = {}
         self.__ordered_list_alignment = {}
 
-    def __report_issue(self, context, token):
-        # print(f"token>>{ParserHelper.make_value_visible(token)}")
-        # print(f"self.__list_stack[]>>{ParserHelper.make_value_visible(self.__list_stack)}")
-        # show_item = str(self.__list_stack[-1]).replace(ParserHelper.newline_character, "\\n")
-        # print(f"self.__list_stack[-1]>>{show_item}")
-        if self.__list_stack[-1].is_unordered_list_start:
-            delta = self.__list_stack[-1].indent_level - 2
-        else:
-            delta = (
-                self.__list_stack[-1].indent_level
-                - 2
-                - len(self.__list_stack[-1].list_start_content)
-            )
-        current_list_indent = len(self.__list_stack[-1].extracted_whitespace) + delta
-        if self.__list_stack[0].is_unordered_list_start:
-            indent_adjust = self.__list_stack[0].column_number - 1
-        else:
-            indent_adjust = -1
-        token_indent = len(token.extracted_whitespace)
-        # print(f"token_indent>>{token_indent}")
-        token_indent -= indent_adjust
-        # print(f"token_indent>>{token_indent}")
-        if (
-            token_indent <= current_list_indent
-            and len(self.__list_stack) > 1
-            and self.__list_stack[-2].is_list_start
-        ):
-            # show_item = str(self.__list_stack[-2]).replace(ParserHelper.newline_character, "\\n")
-            # print(f"self.__list_stack[-2]>>{show_item}")
+    def __report_issue(self, context, token, expected_indent):
+        if expected_indent < 0:
+            list_level = len(self.__list_stack)
             expected_indent = (
-                len(self.__list_stack[-2].extracted_whitespace)
-                + self.__list_stack[-2].indent_level
+                self.__ordered_list_starts[list_level].indent_level
+                - 2
+                - len(token.list_start_content)
             )
-        else:
-            expected_indent = current_list_indent
-        extra_data = f"Expected: {expected_indent}; Actual: {token_indent}"
+
+        extra_data = f"Expected: {expected_indent}; Actual: {token.column_number - 1}"
+        # if self.__debug:
+        #     print(f"ERROR>>{extra_data}")
         self.report_next_token_error(context, token, extra_data)
 
     def __handle_ordered_list_item(self, context, token):
@@ -114,11 +92,17 @@ class RuleMd005(RulePlugin):
                     == self.__ordered_list_starts[list_level].indent_level
                 )
             else:
-                self.__report_issue(context, token)
+                # if self.__debug:
+                #     print("ri1")
+                self.__report_issue(context, token, -1)
         elif (
             self.__ordered_list_starts[list_level].column_number != token.column_number
         ):
-            self.__report_issue(context, token)
+            # if self.__debug:
+            #     print("ri2")
+            self.__report_issue(
+                context, token, self.__ordered_list_starts[list_level].column_number - 1
+            )
 
     def __compute_ordered_list_alignment(self):
 
@@ -156,7 +140,11 @@ class RuleMd005(RulePlugin):
         if list_level not in self.__unordered_list_indents:
             self.__unordered_list_indents[list_level] = token.indent_level
         if self.__unordered_list_indents[list_level] != token.indent_level:
-            self.__report_issue(context, token)
+            # if self.__debug:
+            #     print("ri3")
+            self.__report_issue(
+                context, token, self.__unordered_list_indents[list_level] - 2
+            )
 
     def __handle_ordered_list_start(self, token):
         self.__list_stack.append(token)
@@ -173,7 +161,15 @@ class RuleMd005(RulePlugin):
                 self.__unordered_list_indents[len(self.__list_stack)]
                 != token.indent_level
             ):
-                self.__report_issue(context, token)
+                # if self.__debug:
+                #     print("ri4")
+                #     print("token.indent_level=" + str(token.indent_level))
+                #     print("un_li=" + ParserHelper.make_value_visible(self.__unordered_list_indents))
+                self.__report_issue(
+                    context,
+                    token,
+                    self.__unordered_list_indents[len(self.__list_stack)] - 2,
+                )
         else:
             self.__ordered_tokens[len(self.__list_stack)].append(token)
 


Test patch:
diff --git a/test/test_md005.py b/test/test_md005.py
index c9991f11..15af944f 100644
--- a/test/test_md005.py
+++ b/test/test_md005.py
@@ -278,7 +278,7 @@ def test_md005_bad_ordered_list_single_level_x():
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_single_level.md:2:2: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 0; Actual: 2] (list-indent)"
+        + "[Expected: 0; Actual: 1] (list-indent)"
     )
     expected_error = ""
 
@@ -342,7 +342,7 @@ def test_md005_bad_ordered_list_single_level_widths():
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_single_level_widths.md:2:2: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 0; Actual: 2] (list-indent)"
+        + "[Expected: 0; Actual: 1] (list-indent)"
     )
     expected_error = ""
 
@@ -405,7 +405,7 @@ def test_md005_bad_ordered_list_single_level_widths_right():
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_single_level_widths_right.md:2:1: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 6; Actual: 1] (list-indent)"
+        + "[Expected: 3; Actual: 0] (list-indent)"
     )
     expected_error = ""
 
@@ -583,7 +583,7 @@ def test_md005_bad_ordered_list_double_level_weirdx():
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_double_level_weird.md:3:5: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 3; Actual: 5] (list-indent)"
+        + "[Expected: 3; Actual: 4] (list-indent)"
     )
     expected_error = ""
 
@@ -616,7 +616,8 @@ def test_md005_bad_ordered_list_double_level_weirder():
     expected_return_code = 1
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_double_level_weirder.md:3:3: "
-        + "MD005: Inconsistent indentation for list items at the same level [Expected: 0; Actual: 3] (list-indent)"
+        + "MD005: Inconsistent indentation for list items at the same level "
+        + "[Expected: 0; Actual: 2] (list-indent)"
     )
     expected_error = ""
 
@@ -676,7 +677,7 @@ def test_md005_good_unordered_list_double_level_in_block_quote_first():
     expected_output = (
         "test/resources/rules/md005/bad_unordered_list_double_level_in_block_quote_first.md:4:4: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 2; Actual: -1] (list-indent)"
+        + "[Expected: 2; Actual: 3] (list-indent)"
     )
     expected_error = ""
 
@@ -709,10 +710,10 @@ def test_md005_good_unordered_list_double_level_in_block_quote_second():
     expected_output = (
         "test/resources/rules/md005/bad_unordered_list_double_level_in_block_quote_second.md:5:6: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 4; Actual: 1] (list-indent)\n"
+        + "[Expected: 4; Actual: 5] (list-indent)\n"
         + "test/resources/rules/md005/bad_unordered_list_double_level_in_block_quote_second.md:6:6: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 4; Actual: 1] (list-indent)"
+        + "[Expected: 4; Actual: 5] (list-indent)"
     )
     expected_error = ""
 
@@ -746,10 +747,10 @@ def test_md005_bad_ordered_list_double_level_left():
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_double_level_left.md:5:5: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 3; Actual: 5] (list-indent)\n"
+        + "[Expected: 3; Actual: 4] (list-indent)\n"
         + "test/resources/rules/md005/bad_ordered_list_double_level_left.md:6:5: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 3; Actual: 5] (list-indent)"
+        + "[Expected: 3; Actual: 4] (list-indent)"
     )
     expected_error = ""
 
@@ -763,7 +764,7 @@ def test_md005_bad_ordered_list_double_level_left():
 
 
 @pytest.mark.rules
-def test_md005_bad_ordered_list_double_level_right():
+def test_md005_bad_ordered_list_double_level_right_x():
     """
     Test to make sure this rule does trigger with a document that
     has two level 1 ordered lists with right alignment and bad indentation
@@ -783,10 +784,10 @@ def test_md005_bad_ordered_list_double_level_right():
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_double_level_right.md:5:6: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 3; Actual: 6] (list-indent)\n"
+        + "[Expected: 4; Actual: 5] (list-indent)\n"
         + "test/resources/rules/md005/bad_ordered_list_double_level_right.md:6:5: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 3; Actual: 5] (list-indent)"
+        + "[Expected: 3; Actual: 4] (list-indent)"
     )
     expected_error = ""
 
@@ -820,7 +821,7 @@ def test_md005_bad_ordered_list_double_level_left_then_right():
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_double_level_left_then_right.md:5:5: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 3; Actual: 5] (list-indent)"
+        + "[Expected: 3; Actual: 4] (list-indent)"
     )
     expected_error = ""
 
@@ -854,7 +855,7 @@ def test_md005_bad_ordered_list_double_level_right_then_left():
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_double_level_right_then_left.md:5:4: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 3; Actual: 4] (list-indent)"
+        + "[Expected: 4; Actual: 3] (list-indent)"
     )
     expected_error = ""
 
@@ -888,7 +889,7 @@ def test_md005_bad_ordered_list_single_level_left_then_right():
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_single_level_left_then_right.md:3:2: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 0; Actual: 2] (list-indent)"
+        + "[Expected: 0; Actual: 1] (list-indent)"
     )
     expected_error = ""
 
@@ -914,6 +915,7 @@ def test_md005_bad_ordered_list_single_level_right_then_left():
     supplied_arguments = [
         "--disable-rules",
         "md029",
+        "--stack-trace",
         "scan",
         "test/resources/rules/md005/bad_ordered_list_single_level_right_then_left.md",
     ]
@@ -922,7 +924,7 @@ def test_md005_bad_ordered_list_single_level_right_then_left():
     expected_output = (
         "test/resources/rules/md005/bad_ordered_list_single_level_right_then_left.md:3:1: "
         + "MD005: Inconsistent indentation for list items at the same level "
-        + "[Expected: 2; Actual: 1] (list-indent)"
+        + "[Expected: 1; Actual: 0] (list-indent)"
     )
     expected_error = ""