Repository: jackdewinter/pymarkdown

Issue:
Md031 Fix - Multiple drop with only lists causes bad fix.
## Prerequisites

* [X] Are you running the latest version of this application?
* [X] Have you checked the [Frequently Asked Questions](https://pymarkdown.readthedocs.io/en/latest/faq) document?
* [X] Have you simplified the bug report to the essential details?
  * [X] Do you have a distinct command line to report?
  * [X] Can you clearly state the configuration for this bug report?
  * [X] Do you have a minimal document that highlights this bug?
  * [X] Are any required files (configuration or Markdown document) attached to the issue?
* [X] Did you perform a cursory search of other issues to look for related issues?

## Bug Report

### Bug Type

* [X] Fix/Rule not working as expected

### Description

When fixing a triple or quadruple drop where the containers are all lists, the indent is not calculated.

### Specifics

What operating system and version are you running into this behavior on?

Win11

What version are you seeing this behavior in? (Run `pip list` or `pipenv run pip list` and look for the entry beside `pymarkdownlnt`.)

latest, main

Are there any extra steps that need to be taken before executing the application?

No

What is the command line you invoke to get this behavior?

bad_fenced_block_in_list_in_list_in_list_with_previous_block_triple_drop_with_thematics

Are you using a configuration file? Either on the command line or one of the implicit configuration files? If so, attach that file to this issue.

N/A

What Markdown document causes this behavior to manifest?  Attach that file to this issue.

```
+ + + -----
      > block 1
      > block 2
  -----
  ```block
  A code block
  ```
  -----
  another list
```

### Actual Behavior

When reconstructed, the second last line did not have the right indentation.  When that was fixed, the 4th line did not have the right indentation.  These are both specific to 3+ drop cases with only lists.

### Expected Behavior

The markdown parse and back to markdown loop should not have any issues.

Discussion:
sourcery-ai[bot]: <!-- Generated by sourcery-ai[bot]: start review_guide -->

🧙 Sourcery is reviewing your pull request!

---

<details>
<summary>Tips and commands</summary>

#### Interacting with Sourcery

- **Trigger a new review:** Comment `@sourcery-ai review` on the pull request.
- **Continue discussions:** Reply directly to Sourcery's review comments.
- **Generate a GitHub issue from a review comment:** Ask Sourcery to create an
  issue from a review comment by replying to it.
- **Generate a pull request title:** Write `@sourcery-ai` anywhere in the pull
  request title to generate a title at any time.
- **Generate a pull request summary:** Write `@sourcery-ai summary` anywhere in
  the pull request body to generate a PR summary at any time. You can also use
  this command to specify where the summary should be inserted.

#### Customizing Your Experience

Access your [dashboard](https://app.sourcery.ai) to:
- Enable or disable review features such as the Sourcery-generated pull request
  summary, the reviewer's guide, and others.
- Change the review language.
- Add, remove or edit custom review instructions.
- Adjust other review settings.

#### Getting Help

- [Contact our support team](mailto:support@sourcery.ai) for questions or feedback.
- Visit our [documentation](https://docs.sourcery.ai) for detailed guides and information.
- Keep in touch with the Sourcery team by following us on [X/Twitter](https://x.com/SourceryAI), [LinkedIn](https://www.linkedin.com/company/sourcery-ai/) or [GitHub](https://github.com/sourcery-ai).

</details>

<!-- Generated by sourcery-ai[bot]: end review_guide -->
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/jackdewinter/pymarkdown/pull/1248?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 99.98%. Comparing base [(`cee1f3f`)](https://app.codecov.io/gh/jackdewinter/pymarkdown/commit/cee1f3f5575f73b671deb4374c6e7a263fa40df9?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) to head [(`6721ca2`)](https://app.codecov.io/gh/jackdewinter/pymarkdown/commit/6721ca2b74c51c20f47c267516a86cea3cc62bc8?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #1248      +/-   ##
==========================================
- Coverage   99.99%   99.98%   -0.01%     
==========================================
  Files         191      191              
  Lines       21094    21123      +29     
  Branches     2696     2701       +5     
==========================================
+ Hits        21092    21120      +28     
  Misses          1        1              
- Partials        1        2       +1     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/jackdewinter/pymarkdown/pull/1248?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).


Patch:
diff --git a/newdocs/src/changelog.md b/newdocs/src/changelog.md
index be928638..9acc115f 100644
--- a/newdocs/src/changelog.md
+++ b/newdocs/src/changelog.md
@@ -23,6 +23,10 @@
 - [Issue 1245](https://github.com/jackdewinter/pymarkdown/issues/1245)
     - Handling leading spaces in `__fix_spacing` function now that data
       is present.
+- [Issue 1247](https://github.com/jackdewinter/pymarkdown/issues/1247)
+    - In 3+ drop cases with only lists and no block quotes, indent is
+      not calculated properly on rehydrate.  This in turn causes the
+      fixed text to be wrong.
 
 <!--- pyml disable-next-line no-duplicate-heading-->
 ### Changed
diff --git a/publish/coverage.json b/publish/coverage.json
index 398dc062..11801c21 100644
--- a/publish/coverage.json
+++ b/publish/coverage.json
@@ -2,12 +2,12 @@
     "projectName": "pymarkdown",
     "reportSource": "pytest",
     "branchLevel": {
-        "totalMeasured": 5393,
-        "totalCovered": 5392
+        "totalMeasured": 5403,
+        "totalCovered": 5401
     },
     "lineLevel": {
-        "totalMeasured": 21094,
-        "totalCovered": 21093
+        "totalMeasured": 21123,
+        "totalCovered": 21122
     }
 }
 
diff --git a/pymarkdown/plugins/rule_md_031.py b/pymarkdown/plugins/rule_md_031.py
index 07d958bc..c6ebf6fc 100644
--- a/pymarkdown/plugins/rule_md_031.py
+++ b/pymarkdown/plugins/rule_md_031.py
@@ -56,6 +56,7 @@ class RuleMd031(RulePlugin):
         self.__removed_container_adjustments: Optional[
             List[PendingContainerAdjustment]
         ] = None
+        self.__last_end_container_tokens: List[MarkdownToken] = []
 
         self.__leading_space_index_tracker = LeadingSpaceIndexTracker()
 
@@ -513,17 +514,26 @@ class RuleMd031(RulePlugin):
         new_token.adjust_line_number(context, self.__fix_count)
         assert self.__last_token is not None
         if token.is_fenced_code_block and self.__last_token.is_list_end:
+            end_container_index = len(self.__last_end_container_tokens) - 1
+            while (
+                end_container_index >= 0
+                and self.__last_end_container_tokens[end_container_index].is_list_end
+            ):
+                end_container_index -= 1
+            first_token = self.__last_end_container_tokens[end_container_index + 1]
             replacement_tokens: List[MarkdownToken] = [
                 BlankLineMarkdownToken(
                     extracted_whitespace="",
                     position_marker=PositionMarker(new_token.line_number - 1, 0, ""),
                     column_delta=1,
-                ),
-                self.__last_token,
-                new_token,
+                )
             ]
+            replacement_tokens.extend(
+                self.__last_end_container_tokens[end_container_index + 1 :]
+            )
+            replacement_tokens.append(new_token)
             self.register_replace_tokens_request(
-                context, self.__last_token, token, replacement_tokens
+                context, first_token, token, replacement_tokens
             )
         elif did_special_list_fix:
             assert self.__last_token and self.__last_token.is_block_quote_end
@@ -755,6 +765,11 @@ class RuleMd031(RulePlugin):
         ):
             self.__last_non_end_token = token
 
+        if token.is_block_quote_end or token.is_list_end:
+            self.__last_end_container_tokens.append(token)
+        else:
+            self.__last_end_container_tokens.clear()
+
         self.__second_last_token = self.__last_token
         self.__last_token = token
         self.__removed_container_stack_token = None
diff --git a/pymarkdown/transform_markdown/transform_containers.py b/pymarkdown/transform_markdown/transform_containers.py
index 18b20bc9..f3d5eb56 100644
--- a/pymarkdown/transform_markdown/transform_containers.py
+++ b/pymarkdown/transform_markdown/transform_containers.py
@@ -426,9 +426,55 @@ class TransformContainers:
 
     # pylint: enable=too-many-arguments, too-many-boolean-expressions
 
+    @staticmethod
+    def __abcd_final_list_second_half(
+        removed_tokens: List[MarkdownToken],
+        removed_token_indices: List[int],
+        container_stack: List[MarkdownToken],
+        possible_prefix: Optional[str],
+    ) -> Optional[str]:
+        container_stack_copy: List[MarkdownToken] = container_stack[:]
+        container_stack_copy.extend(removed_tokens[::-1])
+        is_only_list_starts_on_stack = not any(
+            i.is_block_quote_start for i in container_stack_copy
+        )
+
+        prefix = None
+        if is_only_list_starts_on_stack and possible_prefix is not None:
+            prefix = possible_prefix
+            token_index = len(removed_tokens) - 1
+            while token_index >= 0:
+                list_token = cast(ListStartMarkdownToken, removed_tokens[token_index])
+                assert list_token.leading_spaces is None
+                assert removed_token_indices[token_index] == 0
+                token_index -= 1
+                del removed_tokens[0]
+                del removed_token_indices[0]
+
+            list_token = cast(ListStartMarkdownToken, container_stack[-1])
+            current_indent_level = list_token.indent_level if container_stack else 0
+            prefix = " " * current_indent_level
+        else:
+            if removed_tokens[0].is_block_quote_start:
+                removed_block_quote_token = cast(
+                    BlockQuoteMarkdownToken, removed_tokens[0]
+                )
+                assert removed_block_quote_token.bleading_spaces is not None
+                split_bleading_spaces = removed_block_quote_token.bleading_spaces.split(
+                    "\n"
+                )
+                assert removed_token_indices[0] < len(split_bleading_spaces)
+                prefix = "" if possible_prefix is None else possible_prefix
+                prefix = f"{split_bleading_spaces[removed_token_indices[0]]}{prefix}"
+            del removed_tokens[0]
+            del removed_token_indices[0]
+        return prefix
+
     @staticmethod
     def __abcd_final_list(
-        removed_tokens: List[MarkdownToken], removed_token_indices: List[int]
+        removed_tokens: List[MarkdownToken],
+        removed_token_indices: List[int],
+        container_stack: List[MarkdownToken],
     ) -> Optional[str]:
         removed_list_token = cast(ListStartMarkdownToken, removed_tokens[0])
         assert removed_list_token.leading_spaces is not None
@@ -437,26 +483,17 @@ class TransformContainers:
         # prefix is None for most cases
         possible_prefix = None
         if (
-            removed_token_indices[0] < len(split_leading_spaces)
-            and split_leading_spaces[removed_token_indices[0]]
+            removed_token_indices[0]
+            < len(split_leading_spaces)
+            # and split_leading_spaces[removed_token_indices[0]]
         ):
             possible_prefix = split_leading_spaces[removed_token_indices[0]]
         del removed_tokens[0]
         del removed_token_indices[0]
 
-        prefix = None
-        if removed_tokens[0].is_block_quote_start:
-            removed_block_quote_token = cast(BlockQuoteMarkdownToken, removed_tokens[0])
-            assert removed_block_quote_token.bleading_spaces is not None
-            split_bleading_spaces = removed_block_quote_token.bleading_spaces.split(
-                "\n"
-            )
-            assert removed_token_indices[0] < len(split_bleading_spaces)
-            prefix = "" if possible_prefix is None else possible_prefix
-            prefix = f"{split_bleading_spaces[removed_token_indices[0]]}{prefix}"
-        del removed_tokens[0]
-        del removed_token_indices[0]
-        return prefix
+        return TransformContainers.__abcd_final_list_second_half(
+            removed_tokens, removed_token_indices, container_stack, possible_prefix
+        )
 
     @staticmethod
     def __abcd_final(
@@ -506,7 +543,7 @@ class TransformContainers:
                 del removed_token_indices[0]
         else:
             prefix = TransformContainers.__abcd_final_list(
-                removed_tokens, removed_token_indices
+                removed_tokens, removed_token_indices, container_stack
             )
         return prefix
 


Test patch:
diff --git a/publish/test-results.json b/publish/test-results.json
index 7e2b78aa..0fe7cc94 100644
--- a/publish/test-results.json
+++ b/publish/test-results.json
@@ -1367,7 +1367,7 @@
             "totalTests": 653,
             "failedTests": 0,
             "errorTests": 0,
-            "skippedTests": 62,
+            "skippedTests": 61,
             "elapsedTimeInMilliseconds": 0
         },
         {
@@ -1620,7 +1620,7 @@
         },
         {
             "name": "test.test_markdown_extra",
-            "totalTests": 206,
+            "totalTests": 210,
             "failedTests": 0,
             "errorTests": 0,
             "skippedTests": 3,
diff --git a/test/rules/test_md031.py b/test/rules/test_md031.py
index 435a4958..d1538cae 100644
--- a/test/rules/test_md031.py
+++ b/test/rules/test_md031.py
@@ -30,6 +30,7 @@ The value for property 'plugins.md031.list_items' must be of type 'bool'.""",
     ),
 ]
 
+skip_fix_bad_markdown = True
 skip_fix_asserts = True
 
 scanTests = [
@@ -810,7 +811,7 @@ A code block
 This is a blank line and some text.
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         scan_expected_return_code=1,
         scan_expected_output="""{temp_source_path}:3:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 {temp_source_path}:5:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
@@ -2188,7 +2189,7 @@ A code block
 {temp_source_path}:6:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> > > block 3
 > > > block 3
 > > > block 3
@@ -2469,7 +2470,7 @@ A code block
 {temp_source_path}:6:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> > + block 3
 > >   block 3
 > > + block 3
@@ -2652,7 +2653,7 @@ A code block
 {temp_source_path}:6:5: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> > >
 > > > > fourth block 1
 > > > > fourth block 2
@@ -2910,7 +2911,7 @@ A code block
 {temp_source_path}:7:5: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> > >
 > > > + inner list 1
 > > >   inner list 2
@@ -2939,7 +2940,7 @@ A code block
 {temp_source_path}:7:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> > >
 > > > + inner list 1
 > > >   inner list 2
@@ -3130,7 +3131,7 @@ A code block
 {temp_source_path}:6:5: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         use_debug=True,
         fix_expected_file_contents="""> > + --------
 > >   > block 1
@@ -3270,7 +3271,7 @@ A code block
 """,
         disable_rules="md032",
         use_debug=True,
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> > + --------
 > >   > block 1
 > >   > block 2
@@ -3300,7 +3301,7 @@ A code block
 """,
         disable_rules="md032",
         use_debug=True,
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> > + --------
 > >   > block 1
 > >   > block 2
@@ -3419,7 +3420,7 @@ A code block
 {temp_source_path}:7:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md035",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> > + ______
 > >   + list 1
 > >     list 2
@@ -3537,7 +3538,7 @@ ______
 {temp_source_path}:8:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md035",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> > + ______
 > >   + list 1
 > >     list 2
@@ -4245,7 +4246,7 @@ A code block
 {temp_source_path}:6:6: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > > ----
    > > > block 1
    > > > block 2
@@ -4350,7 +4351,7 @@ A code block
 {temp_source_path}:6:6: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > > ----
    > > + block 1
    > >   block 2
@@ -4377,7 +4378,7 @@ A code block
 {temp_source_path}:6:4: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > > ----
    > > + block 1
    > >   block 2
@@ -4480,7 +4481,7 @@ A code block
 """,
         disable_rules="md032,md027",
         use_debug=True,
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > + ----
    >   > block 1
    >   > block 2
@@ -4822,7 +4823,7 @@ A code block
 {temp_source_path}:8:4: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > + ----
    >   + list 1
    >     list 2
@@ -4853,7 +4854,7 @@ A code block
 {temp_source_path}:8:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > + ----
    >   + list 1
    >     list 2
@@ -4944,7 +4945,7 @@ A code block
 {temp_source_path}:6:6: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > > ----
    > > > inner block 1
    > > > inner block 2
@@ -5080,7 +5081,7 @@ A code block
 {temp_source_path}:7:4: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > > ----
    > > > inner block 1
    > > > inner block 2
@@ -5109,7 +5110,7 @@ A code block
 {temp_source_path}:7:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > > ----
    > > > inner block 1
    > > > inner block 2
@@ -5200,7 +5201,7 @@ A code block
 {temp_source_path}:7:6: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > > ----
    > > + list 1
    > >   list 2
@@ -5229,7 +5230,7 @@ A code block
 {temp_source_path}:7:4: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > > ----
    > > + list 1
    > >   list 2
@@ -5317,7 +5318,7 @@ A code block
 {temp_source_path}:8:6: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > > ----
    > > + list 1
    > >   list 2
@@ -5348,7 +5349,7 @@ A code block
 {temp_source_path}:8:4: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""1. > > ----
    > > + list 1
    > >   list 2
@@ -5647,7 +5648,7 @@ another list
 {temp_source_path}:6:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> + list 1
 >   > block 2
 >   > block 3
@@ -6312,7 +6313,7 @@ another list
 """,
         disable_rules="md032,md027,md007,md023",
         use_debug=True,
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> + > -----
 >   > > block 1
 >   > > block 2
@@ -6643,7 +6644,7 @@ another list
 {temp_source_path}:7:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> + > -----
 >   > + list 1
 >   >   list 2
@@ -6947,7 +6948,7 @@ another list
 {temp_source_path}:6:5: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> + + -----
 >     > block 1
 >     > block 2
@@ -6976,7 +6977,7 @@ another list
 {temp_source_path}:6:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> + + -----
 >     > block 1
 >     > block 2
@@ -7064,7 +7065,7 @@ another list
 {temp_source_path}:7:5: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> + + -----
 >     > block 1
 >     > block 2
@@ -7095,7 +7096,7 @@ another list
 {temp_source_path}:7:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> + + -----
 >     > block 1
 >     > block 2
@@ -7347,7 +7348,7 @@ another list
 {temp_source_path}:8:5: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""> + + -----
 >     + list 1
 >       list 2
@@ -7657,7 +7658,7 @@ another list
 {temp_source_path}:7:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""+ + list 1
     > block 2.1
     > block 2.2
@@ -7688,7 +7689,7 @@ A code block
 {temp_source_path}:7:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""+ + list 1
     > block 2.1
     > block 2.2
@@ -8293,7 +8294,7 @@ another list
 {temp_source_path}:7:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""+ + > -----
     > > block 1
     > > block 2
@@ -8420,7 +8421,7 @@ another list
 {temp_source_path}:7:5: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""+ + > -----
     > + list 1
     >   list 2
@@ -8546,7 +8547,7 @@ another list
 {temp_source_path}:8:5: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""+ + > -----
     > + list 1
     >   list 2
@@ -8579,7 +8580,7 @@ another list
 {temp_source_path}:8:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_bad_markdown,
         fix_expected_file_contents="""+ + > -----
     > + list 1
     >   list 2
@@ -8776,7 +8777,7 @@ another list
   another list
 """,
     ),
-    pluginRuleTest(
+    pluginRuleTest(  # test_extra_050c2 test_extra_050c3
         "bad_fenced_block_in_list_in_list_in_list_with_previous_block_quad_drop",
         source_file_contents="""+ + + -----
       > block 1
@@ -8866,7 +8867,7 @@ another list
   + another list
 """,
     ),
-    pluginRuleTest(
+    pluginRuleTest(  # test_extra_050c0 test_extra_050c1
         "bad_fenced_block_in_list_in_list_in_list_with_previous_block_triple_drop_with_thematics",
         source_file_contents="""+ + + -----
       > block 1
@@ -8883,7 +8884,6 @@ another list
 {temp_source_path}:7:3: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        mark_fix_as_skipped=True,
         fix_expected_file_contents="""+ + + -----
       > block 1
       > block 2
diff --git a/test/test_markdown_extra.py b/test/test_markdown_extra.py
index 272eec4c..191c52c5 100644
--- a/test/test_markdown_extra.py
+++ b/test/test_markdown_extra.py
@@ -9243,6 +9243,279 @@ list 2</li>
     act_and_assert(source_markdown, expected_gfm, expected_tokens, show_debug=False)
 
 
+@pytest.mark.gfm
+def test_extra_050c0():
+    """
+    TBD
+    bad_fenced_block_in_list_in_list_in_list_with_previous_block_triple_drop_with_thematics
+    """
+
+    # Arrange
+    source_markdown = """+ + + -----
+      > block 1
+      > block 2
+  -----
+  ```block
+  A code block
+  ```
+  -----
+  another list
+"""
+    expected_tokens = [
+        "[ulist(1,1):+::2::  \n  \n  \n  \n  \n]",
+        "[ulist(1,3):+::4:  ]",
+        "[ulist(1,5):+::6:    :\n\n]",
+        "[tbreak(1,7):-::-----]",
+        "[block-quote(2,7):      :      > \n      > ]",
+        "[para(2,9):\n]",
+        "[text(2,9):block 1\nblock 2::\n]",
+        "[end-para:::True]",
+        "[end-block-quote:::True]",
+        "[end-ulist:::True]",
+        "[end-ulist:::True]",
+        "[tbreak(4,3):-::-----]",
+        "[fcode-block(5,3):`:3:block:::::]",
+        "[text(6,3):A code block:]",
+        "[end-fcode-block:::3:False]",
+        "[tbreak(8,3):-::-----]",
+        "[para(9,3):]",
+        "[text(9,3):another list:]",
+        "[end-para:::True]",
+        "[BLANK(10,1):]",
+        "[end-ulist:::True]",
+    ]
+    expected_gfm = """<ul>
+<li>
+<ul>
+<li>
+<ul>
+<li>
+<hr />
+<blockquote>
+<p>block 1
+block 2</p>
+</blockquote>
+</li>
+</ul>
+</li>
+</ul>
+<hr />
+<pre><code class="language-block">A code block
+</code></pre>
+<hr />
+another list</li>
+</ul>"""
+
+    # Act & Assert
+    act_and_assert(source_markdown, expected_gfm, expected_tokens, show_debug=False)
+
+
+@pytest.mark.gfm
+def test_extra_050c1():
+    """
+    TBD
+    bad_fenced_block_in_list_in_list_in_list_with_previous_block_triple_drop_with_thematics
+    """
+
+    # Arrange
+    source_markdown = """+ + + -----
+      > block 1
+      > block 2
+  -----
+
+  ```block
+  A code block
+  ```
+
+  -----
+  another list
+"""
+    expected_tokens = [
+        "[ulist(1,1):+::2::\n  \n  \n  \n\n  \n  \n]",
+        "[ulist(1,3):+::4:  ]",
+        "[ulist(1,5):+::6:    :\n\n]",
+        "[tbreak(1,7):-::-----]",
+        "[block-quote(2,7):      :      > \n      > ]",
+        "[para(2,9):\n]",
+        "[text(2,9):block 1\nblock 2::\n]",
+        "[end-para:::True]",
+        "[end-block-quote:::True]",
+        "[end-ulist:::True]",
+        "[end-ulist:::True]",
+        "[tbreak(4,3):-::-----]",
+        "[BLANK(5,1):]",
+        "[fcode-block(6,3):`:3:block:::::]",
+        "[text(7,3):A code block:]",
+        "[end-fcode-block:::3:False]",
+        "[BLANK(9,1):]",
+        "[tbreak(10,3):-::-----]",
+        "[para(11,3):]",
+        "[text(11,3):another list:]",
+        "[end-para:::True]",
+        "[BLANK(12,1):]",
+        "[end-ulist:::True]",
+    ]
+    expected_gfm = """<ul>
+<li>
+<ul>
+<li>
+<ul>
+<li>
+<hr />
+<blockquote>
+<p>block 1
+block 2</p>
+</blockquote>
+</li>
+</ul>
+</li>
+</ul>
+<hr />
+<pre><code class="language-block">A code block
+</code></pre>
+<hr />
+<p>another list</p>
+</li>
+</ul>"""
+
+    # Act & Assert
+    act_and_assert(source_markdown, expected_gfm, expected_tokens, show_debug=False)
+
+
+@pytest.mark.gfm
+def test_extra_050c2():
+    """
+    TBD
+    bad_fenced_block_in_list_in_list_in_list_with_previous_block_quad_drop
+    """
+
+    # Arrange
+    source_markdown = """+ + + -----
+      > block 1
+      > block 2
+```block
+A code block
+```
+-----
+another list
+"""
+    expected_tokens = [
+        "[ulist(1,1):+::2:]",
+        "[ulist(1,3):+::4:  ]",
+        "[ulist(1,5):+::6:    :\n\n]",
+        "[tbreak(1,7):-::-----]",
+        "[block-quote(2,7):      :      > \n      > ]",
+        "[para(2,9):\n]",
+        "[text(2,9):block 1\nblock 2::\n]",
+        "[end-para:::True]",
+        "[end-block-quote:::True]",
+        "[end-ulist:::True]",
+        "[end-ulist:::True]",
+        "[end-ulist:::True]",
+        "[fcode-block(4,1):`:3:block:::::]",
+        "[text(5,1):A code block:]",
+        "[end-fcode-block:::3:False]",
+        "[tbreak(7,1):-::-----]",
+        "[para(8,1):]",
+        "[text(8,1):another list:]",
+        "[end-para:::True]",
+        "[BLANK(9,1):]",
+    ]
+    expected_gfm = """<ul>
+<li>
+<ul>
+<li>
+<ul>
+<li>
+<hr />
+<blockquote>
+<p>block 1
+block 2</p>
+</blockquote>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<pre><code class="language-block">A code block
+</code></pre>
+<hr />
+<p>another list</p>"""
+
+    # Act & Assert
+    act_and_assert(source_markdown, expected_gfm, expected_tokens, show_debug=False)
+
+
+@pytest.mark.gfm
+def test_extra_050c3():
+    """
+    TBD
+    bad_fenced_block_in_list_in_list_in_list_with_previous_block_quad_drop
+    """
+
+    # Arrange
+    source_markdown = """+ + + -----
+      > block 1
+      > block 2
+
+```block
+A code block
+```
+
+-----
+another list
+"""
+    expected_tokens = [
+        "[ulist(1,1):+::2:]",
+        "[ulist(1,3):+::4:  ]",
+        "[ulist(1,5):+::6:    :\n\n]",
+        "[tbreak(1,7):-::-----]",
+        "[block-quote(2,7):      :      > \n      > \n]",
+        "[para(2,9):\n]",
+        "[text(2,9):block 1\nblock 2::\n]",
+        "[end-para:::True]",
+        "[end-block-quote:::True]",
+        "[BLANK(4,1):]",
+        "[end-ulist:::True]",
+        "[end-ulist:::True]",
+        "[end-ulist:::True]",
+        "[fcode-block(5,1):`:3:block:::::]",
+        "[text(6,1):A code block:]",
+        "[end-fcode-block:::3:False]",
+        "[BLANK(8,1):]",
+        "[tbreak(9,1):-::-----]",
+        "[para(10,1):]",
+        "[text(10,1):another list:]",
+        "[end-para:::True]",
+        "[BLANK(11,1):]",
+    ]
+    expected_gfm = """<ul>
+<li>
+<ul>
+<li>
+<ul>
+<li>
+<hr />
+<blockquote>
+<p>block 1
+block 2</p>
+</blockquote>
+</li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+<pre><code class="language-block">A code block
+</code></pre>
+<hr />
+<p>another list</p>"""
+
+    # Act & Assert
+    act_and_assert(source_markdown, expected_gfm, expected_tokens, show_debug=False)
+
+
 @pytest.mark.gfm
 def test_extra_999():
     """
@@ -9270,9 +9543,9 @@ def test_extra_999():
 
 
 # Fix
+# bad_fenced_block_in_list_in_list_in_list_with_previous_block_triple_drop_with_thematics
 
 # Bad fix
-# bad_fenced_block_in_list_in_list_in_list_with_previous_block_triple_drop_with_thematics
 # bad_fenced_block_in_list_in_list_in_block_quote_with_previous_list_double_drop_and_thematics
 # bad_fenced_block_in_list_in_list_in_block_quote_with_previous_block_double_drop
 # bad_fenced_block_in_list_in_list_in_block_quote_with_previous_block_double_drop_with_thematics