Repository: jackdewinter/pymarkdown

Issue:
MD031 Fix mode: Handle leading spaces assertion
## 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

In a couple of small areas during md031 fix mode, "leading spaces" asserts were triggered.

### 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_block_quote_in_block_quote_with_previous_list_double_drop
bad_fenced_block_in_list_in_block_quote_in_list_with_previous_list_double_drop
bad_fenced_block_in_list_in_block_quote_with_previous_inner_list_double_drop
bad_fenced_block_in_list_in_list_in_block_quote_with_previous_list_triple_drop
bad_fenced_block_in_list_in_list_with_previous_inner_list_double_drop

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.

See command line above.

### Actual Behavior

In all the above cases, an assert was added for MyPy to protect against usage of an optional str with a value of None. These triggered the asserts, noting that we have a new use case that demonstrates the need for handling of that case.

### Expected Behavior

These cases should be handled properly.

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/1246?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
Attention: Patch coverage is `93.10345%` with `2 lines` in your changes missing coverage. Please review.
> Project coverage is 99.99%. Comparing base [(`911e871`)](https://app.codecov.io/gh/jackdewinter/pymarkdown/commit/911e871a488de37a5b90ebaf9e2f489e278848a3?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) to head [(`309a3b8`)](https://app.codecov.io/gh/jackdewinter/pymarkdown/commit/309a3b8e12c1dd764c0ca7bd9c365aee56dd0fee?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).

| [Files with missing lines](https://app.codecov.io/gh/jackdewinter/pymarkdown/pull/1246?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Patch % | Lines |
|---|---|---|
| [...arkdown/transform\_markdown/transform\_containers.py](https://app.codecov.io/gh/jackdewinter/pymarkdown/pull/1246?src=pr&el=tree&filepath=pymarkdown%2Ftransform_markdown%2Ftransform_containers.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-cHltYXJrZG93bi90cmFuc2Zvcm1fbWFya2Rvd24vdHJhbnNmb3JtX2NvbnRhaW5lcnMucHk=) | 77.77% | [1 Missing and 1 partial :warning: ](https://app.codecov.io/gh/jackdewinter/pymarkdown/pull/1246?src=pr&el=tree&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    #1246      +/-   ##
===========================================
- Coverage   100.00%   99.99%   -0.01%     
===========================================
  Files          191      191              
  Lines        21081    21094      +13     
  Branches      2692     2696       +4     
===========================================
+ Hits         21081    21092      +11     
- Misses           0        1       +1     
- Partials         0        1       +1     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/jackdewinter/pymarkdown/pull/1246?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 39b9359f..be928638 100644
--- a/newdocs/src/changelog.md
+++ b/newdocs/src/changelog.md
@@ -5,12 +5,24 @@
 <!--- pyml disable-next-line no-duplicate-heading-->
 ### Added
 
-- None
+- [Issue 1233](https://github.com/jackdewinter/pymarkdown/issues/1233)
+- [Issue 1234](https://github.com/jackdewinter/pymarkdown/issues/1234)
+- [Issue 1235](https://github.com/jackdewinter/pymarkdown/issues/1235)
+    - Adding more comprehensive "drop X" tests where multiple levels of
+      containers are involved, and then dropping one or more of those
+      containers in a single line.
 
 <!--- pyml disable-next-line no-duplicate-heading-->
 ### Fixed
 
-- None
+- [Issue 1233](https://github.com/jackdewinter/pymarkdown/issues/1233)
+- [Issue 1234](https://github.com/jackdewinter/pymarkdown/issues/1234)
+- [Issue 1235](https://github.com/jackdewinter/pymarkdown/issues/1235)
+    - Adding new "drop_x" tests and resolve any scan issues with them.
+- [Issue 1243](https://github.com/jackdewinter/pymarkdown/issues/1243)
+- [Issue 1245](https://github.com/jackdewinter/pymarkdown/issues/1245)
+    - Handling leading spaces in `__fix_spacing` function now that data
+      is present.
 
 <!--- pyml disable-next-line no-duplicate-heading-->
 ### Changed
diff --git a/publish/coverage.json b/publish/coverage.json
index 7133420f..398dc062 100644
--- a/publish/coverage.json
+++ b/publish/coverage.json
@@ -2,12 +2,12 @@
     "projectName": "pymarkdown",
     "reportSource": "pytest",
     "branchLevel": {
-        "totalMeasured": 5385,
-        "totalCovered": 5385
+        "totalMeasured": 5393,
+        "totalCovered": 5392
     },
     "lineLevel": {
-        "totalMeasured": 21081,
-        "totalCovered": 21081
+        "totalMeasured": 21094,
+        "totalCovered": 21093
     }
 }
 
diff --git a/pymarkdown/block_quotes/block_quote_count_helper.py b/pymarkdown/block_quotes/block_quote_count_helper.py
index f4e30a01..77568df7 100644
--- a/pymarkdown/block_quotes/block_quote_count_helper.py
+++ b/pymarkdown/block_quotes/block_quote_count_helper.py
@@ -328,7 +328,9 @@ class BlockQuoteCountHelper:
         )
         assert parser_state.original_line_to_parse is not None
         if (
-            parser_state.original_line_to_parse[
+            embedded_list_stack_token.indent_level
+            >= len(parser_state.original_line_to_parse)
+            or parser_state.original_line_to_parse[
                 start_index : embedded_list_stack_token.indent_level
             ].strip()
             or parser_state.original_line_to_parse[
diff --git a/pymarkdown/plugins/rule_md_031.py b/pymarkdown/plugins/rule_md_031.py
index ceb970a7..07d958bc 100644
--- a/pymarkdown/plugins/rule_md_031.py
+++ b/pymarkdown/plugins/rule_md_031.py
@@ -359,7 +359,8 @@ class RuleMd031(RulePlugin):
         removed_list_token = cast(
             ListStartMarkdownToken, self.__removed_container_stack_token
         )
-        assert removed_list_token.leading_spaces is not None
+        if removed_list_token.leading_spaces is None:
+            return
         split_spaces = removed_list_token.leading_spaces.split("\n")
         split_spaces_length = len(split_spaces)
         if split_spaces_length > 1:
@@ -461,6 +462,40 @@ class RuleMd031(RulePlugin):
             else 1
         )
 
+    def __fix_spacing_one_container(
+        self, context: PluginScanContext, token: MarkdownToken
+    ) -> bool:
+        did_special_list_fix = False
+        if self.__leading_space_index_tracker.get_container_stack_item(
+            -1
+        ).is_block_quote_start:
+            self.__fix_spacing_block_quote(token)
+        else:
+            did_special_list_fix = self.__fix_spacing_list(context, token)
+        return did_special_list_fix
+
+    def __fix_spacing_removed_container(
+        self, context: PluginScanContext, token: MarkdownToken
+    ) -> None:
+        _ = token
+        assert self.__removed_container_stack_token is not None
+        if self.__removed_container_stack_token.is_list_start:
+            removed_list_token = cast(
+                ListStartMarkdownToken, self.__removed_container_stack_token
+            )
+            if removed_list_token.leading_spaces is not None:
+                split_spaces = removed_list_token.leading_spaces.split("\n")
+                split_spaces.append("")
+            else:
+                split_spaces = [""]
+            self.register_fix_token_request(
+                context,
+                self.__removed_container_stack_token,
+                "next_token",
+                "leading_spaces",
+                "\n".join(split_spaces),
+            )
+
     def __fix_spacing(
         self, context: PluginScanContext, token: MarkdownToken, special_case: bool
     ) -> None:
@@ -469,30 +504,9 @@ class RuleMd031(RulePlugin):
             self.__fix_spacing_special_case(context, token)
             return
         if self.__leading_space_index_tracker.in_at_least_one_container():
-            if self.__leading_space_index_tracker.get_container_stack_item(
-                -1
-            ).is_block_quote_start:
-                self.__fix_spacing_block_quote(token)
-            else:
-                did_special_list_fix = self.__fix_spacing_list(context, token)
+            did_special_list_fix = self.__fix_spacing_one_container(context, token)
         elif self.__removed_container_stack_token:
-            if self.__removed_container_stack_token.is_list_start:
-                removed_list_token = cast(
-                    ListStartMarkdownToken, self.__removed_container_stack_token
-                )
-                assert removed_list_token.leading_spaces is None
-                # if removed_list_token.leading_spaces is not None:
-                #     split_spaces = removed_list_token.leading_spaces.split("\n")
-                #     split_spaces.append("")
-                # else:
-                split_spaces = [""]
-                self.register_fix_token_request(
-                    context,
-                    self.__removed_container_stack_token,
-                    "next_token",
-                    "leading_spaces",
-                    "\n".join(split_spaces),
-                )
+            self.__fix_spacing_removed_container(context, token)
 
         new_token = copy.deepcopy(token)
         self.__fix_count += 1
diff --git a/pymarkdown/transform_markdown/transform_containers.py b/pymarkdown/transform_markdown/transform_containers.py
index 9c95cadb..18b20bc9 100644
--- a/pymarkdown/transform_markdown/transform_containers.py
+++ b/pymarkdown/transform_markdown/transform_containers.py
@@ -1435,11 +1435,15 @@ class TransformContainers:
         do_it = True
         if token_stack[-1].is_list_start and removed_tokens[-1].is_list_start:
             removed_list_token = cast(ListStartMarkdownToken, removed_tokens[-1])
-            assert removed_list_token.leading_spaces is not None
-            removed_token_split_spaces = removed_list_token.leading_spaces.split("\n")
             removed_token_index = removed_token_indices[-1]
-            assert removed_token_index < len(removed_token_split_spaces)
-            removed_token_indices[-1] += 1
+            if removed_list_token.leading_spaces is None:
+                assert removed_token_index == 0
+            else:
+                removed_token_split_spaces = removed_list_token.leading_spaces.split(
+                    "\n"
+                )
+                assert removed_token_index < len(removed_token_split_spaces)
+                removed_token_indices[-1] += 1
             do_it = False
             block_me = True
         if do_it:
@@ -1858,13 +1862,14 @@ class TransformContainers:
                 if token_stack[-1].is_new_list_item
                 else cast(ListStartMarkdownToken, token_stack[-1])
             )
-            assert (
-                prev_list_token.leading_spaces is not None
-            ), "Leading spaces must be defined by this point."
-            split_leading_spaces = prev_list_token.leading_spaces.split(
-                ParserHelper.newline_character
-            )
-        if last_container_token_index < len(split_leading_spaces):
+            split_leading_spaces = None
+            if prev_list_token.leading_spaces is not None:
+                split_leading_spaces = prev_list_token.leading_spaces.split(
+                    ParserHelper.newline_character
+                )
+        if split_leading_spaces is not None and last_container_token_index < len(
+            split_leading_spaces
+        ):
             POGGER.debug(f" -->{ParserHelper.make_value_visible(split_leading_spaces)}")
             POGGER.debug(
                 f" primary-->container_line>:{ParserHelper.make_value_visible(container_line)}:<"


Test patch:
diff --git a/publish/test-results.json b/publish/test-results.json
index cffe29c8..7e2b78aa 100644
--- a/publish/test-results.json
+++ b/publish/test-results.json
@@ -1367,7 +1367,7 @@
             "totalTests": 653,
             "failedTests": 0,
             "errorTests": 0,
-            "skippedTests": 84,
+            "skippedTests": 62,
             "elapsedTimeInMilliseconds": 0
         },
         {
@@ -1620,10 +1620,10 @@
         },
         {
             "name": "test.test_markdown_extra",
-            "totalTests": 203,
+            "totalTests": 206,
             "failedTests": 0,
             "errorTests": 0,
-            "skippedTests": 2,
+            "skippedTests": 3,
             "elapsedTimeInMilliseconds": 0
         },
         {
diff --git a/test/rules/test_md031.py b/test/rules/test_md031.py
index b99e3eef..435a4958 100644
--- a/test/rules/test_md031.py
+++ b/test/rules/test_md031.py
@@ -30,6 +30,8 @@ The value for property 'plugins.md031.list_items' must be of type 'bool'.""",
     ),
 ]
 
+skip_fix_asserts = True
+
 scanTests = [
     pluginRuleTest(
         "good_both_fenced_with_consistent",
@@ -1600,7 +1602,6 @@ another list
 {temp_source_path}:6:1: 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="""+ list
   > inner list
   > couple of lines
@@ -2678,7 +2679,8 @@ A code block
 {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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""> > >
 > > > > fourth block 1
 > > > > fourth block 2
@@ -2788,7 +2790,8 @@ A code block
 {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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""> > >
 > > > > fourth block 1
 > > > > fourth block 2
@@ -3156,7 +3159,7 @@ A code block
 """,
         disable_rules="md032",
         use_debug=True,
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_asserts,
         fix_expected_file_contents="""> > + --------
 > >   > block 1
 > >   > block 2
@@ -3183,8 +3186,6 @@ A code block
 {temp_source_path}:6:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032",
-        use_debug=True,
-        mark_fix_as_skipped=True,
         fix_expected_file_contents="""> > + --------
 > >   > block 1
 > >   > block 2
@@ -3390,7 +3391,6 @@ A code block
 {temp_source_path}:7:5: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md035",
-        mark_fix_as_skipped=True,
         fix_expected_file_contents="""> > + ______
 > >   + list 1
 > >     list 2
@@ -3748,7 +3748,8 @@ A code block
 {temp_source_path}:6: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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""1. > >
    > > block 3
    > > block 3
@@ -4032,7 +4033,6 @@ A code block
 {temp_source_path}:6:1: 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="""1. > +
    >   list 3
    > + list 3
@@ -4298,7 +4298,6 @@ A code block
 {temp_source_path}:6:1: 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="""1. > > ----
    > > > block 1
    > > > block 2
@@ -4405,7 +4404,6 @@ A code block
 {temp_source_path}:6:1: 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="""1. > > ----
    > > + block 1
    > >   block 2
@@ -4510,7 +4508,7 @@ A code block
 """,
         disable_rules="md032,md027",
         use_debug=True,
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_asserts,
         fix_expected_file_contents="""1. > + ----
    >   > block 1
    >   > block 2
@@ -4538,7 +4536,7 @@ A code block
 """,
         disable_rules="md032,md027",
         use_debug=True,
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_asserts,
         fix_expected_file_contents="""1. > + ----
    >   > block 1
    >   > block 2
@@ -4678,7 +4676,6 @@ 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,
         fix_expected_file_contents="""1. > + ----
    >   + list 1
    >     list 2
@@ -4735,7 +4732,6 @@ 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,
         fix_expected_file_contents="""1. > + ----
    >   + list 1
    >     list 2
@@ -4796,7 +4792,6 @@ A code block
 """,
         disable_rules="md032",
         use_debug=True,
-        mark_fix_as_skipped=True,
         fix_expected_file_contents="""1. > + ----
    >   + list 1
    >     list 2
@@ -5002,7 +4997,6 @@ A code block
 {temp_source_path}:6:1: 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="""1. > > ----
    > > > inner block 1
    > > > inner block 2
@@ -5264,7 +5258,6 @@ 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,
         fix_expected_file_contents="""1. > > ----
    > > + list 1
    > >   list 2
@@ -5600,8 +5593,6 @@ another list
 {temp_source_path}:7:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
-        use_debug=True,
         fix_expected_file_contents="""> + list 1
 >   > block 2
 >   > block 3
@@ -5683,7 +5674,6 @@ another list
 {temp_source_path}:6:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
         fix_expected_file_contents="""> + list 1
 >   > block 2
 >   > block 3
@@ -5860,7 +5850,6 @@ another list
 {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,
         fix_expected_file_contents="""> + list 1
 >   + list 2
 >     list 3
@@ -6264,7 +6253,6 @@ another list
 {temp_source_path}:6:7: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        use_debug=True,
         fix_expected_file_contents="""> + > -----
 >   > > block 1
 >   > > block 2
@@ -6294,7 +6282,7 @@ another list
 """,
         disable_rules="md032,md027",
         use_debug=True,
-        mark_fix_as_skipped=True,
+        mark_fix_as_skipped=skip_fix_asserts,
         fix_expected_file_contents="""> + > -----
 >   > > block 1
 >   > > block 2
@@ -6353,8 +6341,6 @@ another list
 {temp_source_path}:6:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        use_debug=True,
-        mark_fix_as_skipped=True,
         fix_expected_file_contents="""> + > -----
 >   > > block 1
 >   > > block 2
@@ -6448,7 +6434,8 @@ 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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""> + > -----
 >   > > block 1
 >   > > block 2
@@ -6479,7 +6466,8 @@ 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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""> + > -----
 >   > > block 1
 >   > > block 2
@@ -6510,8 +6498,6 @@ another list
 {temp_source_path}:7:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
-        use_debug=True,
         fix_expected_file_contents="""> + > -----
 >   > > block 1
 >   > > block 2
@@ -6688,8 +6674,6 @@ another list
 {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,
-        use_debug=True,
         fix_expected_file_contents="""> + > -----
 >   > + list 1
 >   >   list 2
@@ -6753,7 +6737,8 @@ another list
 {temp_source_path}:8: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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""> + > -----
 >   > + list 1
 >   >   list 2
@@ -6786,7 +6771,8 @@ 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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""> + > -----
 >   > + list 1
 >   >   list 2
@@ -6819,8 +6805,6 @@ another list
 {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,
-        use_debug=True,
         fix_expected_file_contents="""> + > -----
 >   > + list 1
 >   >   list 2
@@ -7021,8 +7005,6 @@ another list
 {temp_source_path}:6:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
-        use_debug=True,
         fix_expected_file_contents="""> + + -----
 >     > block 1
 >     > block 2
@@ -7144,8 +7126,6 @@ another list
 {temp_source_path}:7:1: MD031: Fenced code blocks should be surrounded by blank lines (blanks-around-fences)
 """,
         disable_rules="md032,md027",
-        mark_fix_as_skipped=True,
-        use_debug=True,
         fix_expected_file_contents="""> + + -----
 >     > block 1
 >     > block 2
@@ -7242,7 +7222,8 @@ 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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""> + + -----
 >     + list 1
 >       list 2
@@ -7273,7 +7254,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="""> + + -----
 >     + list 1
 >       list 2
@@ -7578,7 +7558,7 @@ another list
   + another list
 """,
     ),
-    pluginRuleTest(
+    pluginRuleTest(  # test_extra_050a0
         "bad_fenced_block_in_list_in_list_with_previous_inner_block_double_drop",
         source_file_contents="""+ + list 1
     > block 2.1
@@ -7593,7 +7573,8 @@ another list
 {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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""+ + list 1
     > block 2.1
     > block 2.2
@@ -7798,7 +7779,6 @@ another list
 {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,
         fix_expected_file_contents="""+ + list 1
 + + + list 2.1
       list 2.2
@@ -8194,7 +8174,8 @@ another list
 {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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""+ + > -----
     > > block 1
     > > block 2
@@ -8470,7 +8451,8 @@ 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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""+ + > -----
     > + list 1
     >   list 2
@@ -8780,7 +8762,8 @@ another list
 {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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""+ + + -----
       > block 1
       > block 2
@@ -8868,7 +8851,8 @@ 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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""+ + + -----
       > block 1
       > block 2
@@ -9131,7 +9115,7 @@ another list
   + another list
 """,
     ),
-    pluginRuleTest(
+    pluginRuleTest(  # test_extra_050b0 test_extra_050b1
         "bad_fenced_block_in_list_in_list_in_list_with_previous_list_double_drop",
         source_file_contents="""+ + + -----
       + list 1
@@ -9147,7 +9131,9 @@ 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_asserts,
+        use_fix_debug=True,
+        use_debug=True,
         fix_expected_file_contents="""+ + + -----
       + list 1
         list 2
@@ -9176,7 +9162,8 @@ 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_asserts,
+        use_debug=True,
         fix_expected_file_contents="""+ + + -----
       + list 1
         list 2
diff --git a/test/test_markdown_extra.py b/test/test_markdown_extra.py
index eec32ac3..272eec4c 100644
--- a/test/test_markdown_extra.py
+++ b/test/test_markdown_extra.py
@@ -9042,6 +9042,207 @@ def test_extra_049l4a():
     act_and_assert(source_markdown, expected_gfm, expected_tokens, show_debug=True)
 
 
+@pytest.mark.gfm
+@pytest.mark.skip
+def test_extra_050a0():
+    """
+    TBD
+    bad_fenced_block_in_list_in_list_with_previous_inner_block_double_drop
+    """
+
+    # Arrange
+    source_markdown = """+ + list 1
+    > block 2.1
+    > block 2.2
+  ```block
+  A code block
+  ```
+  another list
+"""
+    expected_tokens = [
+        "[ulist(1,1):+::2::  \n  \n  \n]",
+        "[ulist(1,3):+::4:  :\n\n]",
+        "[para(1,5):]",
+        "[text(1,5):list 1:]",
+        "[end-para:::True]",
+        "[block-quote(2,5):    :    > \n    > ]",
+        "[para(2,7):\n]",
+        "[text(2,7):block 2.1\nblock 2.2::\n]",
+        "[end-para:::True]",
+        "[end-block-quote:::True]",
+        "[end-ulist:::True]",
+        "[fcode-block(4,3):`:3:block:::::]",
+        "[text(5,3):A code block:]",
+        "[end-fcode-block:::3:False]",
+        "[para(7,3):]",
+        "[text(7,3):another list:]",
+        "[end-para:::True]",
+        "[BLANK(8,1):]",
+        "[end-ulist:::True]",
+    ]
+    expected_gfm = """<ul>
+<li>
+<ul>
+<li>list 1
+<blockquote>
+<p>block 2.1
+block 2.2</p>
+</blockquote>
+</li>
+</ul>
+<pre><code class="language-block">A code block
+</code></pre>
+another list</li>
+</ul>"""
+
+    # Act & Assert
+    act_and_assert(source_markdown, expected_gfm, expected_tokens, show_debug=False)
+
+
+@pytest.mark.gfm
+def test_extra_050b0():
+    """
+    TBD
+    bad_fenced_block_in_list_in_list_in_list_with_previous_list_double_drop
+    """
+
+    # Arrange
+    source_markdown = """+ + + -----
+      + list 1
+        list 2
+      + list 3
+    ```block
+    A code block
+    ```
+  + another list
+"""
+    expected_tokens = [
+        "[ulist(1,1):+::2:]",
+        "[ulist(1,3):+::4:  :    \n    \n    \n]",
+        "[ulist(1,5):+::6:    ]",
+        "[tbreak(1,7):-::-----]",
+        "[ulist(2,7):+::8:      :        ]",
+        "[para(2,9):\n]",
+        "[text(2,9):list 1\nlist 2::\n]",
+        "[end-para:::True]",
+        "[li(4,7):8:      :]",
+        "[para(4,9):]",
+        "[text(4,9):list 3:]",
+        "[end-para:::True]",
+        "[end-ulist:::True]",
+        "[end-ulist:::True]",
+        "[fcode-block(5,5):`:3:block:::::]",
+        "[text(6,5):A code block:]",
+        "[end-fcode-block:::3:False]",
+        "[li(8,3):4:  :]",
+        "[para(8,5):]",
+        "[text(8,5):another list:]",
+        "[end-para:::True]",
+        "[BLANK(9,1):]",
+        "[end-ulist:::True]",
+        "[end-ulist:::True]",
+    ]
+    expected_gfm = """<ul>
+<li>
+<ul>
+<li>
+<ul>
+<li>
+<hr />
+<ul>
+<li>list 1
+list 2</li>
+<li>list 3</li>
+</ul>
+</li>
+</ul>
+<pre><code class="language-block">A code block
+</code></pre>
+</li>
+<li>another list</li>
+</ul>
+</li>
+</ul>"""
+
+    # Act & Assert
+    act_and_assert(source_markdown, expected_gfm, expected_tokens, show_debug=False)
+
+
+@pytest.mark.gfm
+def test_extra_050b1():
+    """
+    TBD
+    bad_fenced_block_in_list_in_list_in_list_with_previous_list_double_drop
+    """
+
+    # Arrange
+    source_markdown = """+ + + -----
+      + list 1
+        list 2
+      + list 3
+
+    ```block
+    A code block
+    ```
+
+  + another list
+"""
+    expected_tokens = [
+        "[ulist(1,1):+::2:]",
+        "[ulist(1,3):+::4:  :    \n    \n    \n\n]",
+        "[ulist(1,5):+::6:    ]",
+        "[tbreak(1,7):-::-----]",
+        "[ulist(2,7):+::8:      :        \n]",
+        "[para(2,9):\n]",
+        "[text(2,9):list 1\nlist 2::\n]",
+        "[end-para:::True]",
+        "[li(4,7):8:      :]",
+        "[para(4,9):]",
+        "[text(4,9):list 3:]",
+        "[end-para:::True]",
+        "[BLANK(5,1):]",
+        "[end-ulist:::True]",
+        "[end-ulist:::True]",
+        "[fcode-block(6,5):`:3:block:::::]",
+        "[text(7,5):A code block:]",
+        "[end-fcode-block:::3:False]",
+        "[BLANK(9,1):]",
+        "[li(10,3):4:  :]",
+        "[para(10,5):]",
+        "[text(10,5):another list:]",
+        "[end-para:::True]",
+        "[BLANK(11,1):]",
+        "[end-ulist:::True]",
+        "[end-ulist:::True]",
+    ]
+    expected_gfm = """<ul>
+<li>
+<ul>
+<li>
+<ul>
+<li>
+<hr />
+<ul>
+<li>list 1
+list 2</li>
+<li>list 3</li>
+</ul>
+</li>
+</ul>
+<pre><code class="language-block">A code block
+</code></pre>
+</li>
+<li>
+<p>another list</p>
+</li>
+</ul>
+</li>
+</ul>"""
+
+    # Act & Assert
+    act_and_assert(source_markdown, expected_gfm, expected_tokens, show_debug=False)
+
+
 @pytest.mark.gfm
 def test_extra_999():
     """
@@ -9100,33 +9301,52 @@ def test_extra_999():
 # bad_fenced_block_in_block_quote_in_block_quote_in_block_quote_with_previous_block_double_drop
 # bad_fenced_block_in_block_quote_in_block_quote_double_drop_with_previous_inner_block
 # bad_fenced_block_in_block_quote_with_previous_inner_list_double_drop
+# bad_fenced_block_in_list_in_block_quote_in_block_quote_with_previous_block_triple_drop_with_thematics
+# bad_fenced_block_in_list_in_block_quote_in_block_quote_with_previous_block_quad_drop_with_thematics
+# bad_fenced_block_in_block_quote_in_block_quote_in_block_quote_with_previous_list_double_drop
+# bad_fenced_block_in_block_quote_in_block_quote_in_block_quote_with_previous_list_triple_drop
+# bad_fenced_block_in_list_in_block_quote_in_block_quote_with_previous_list_triple_drop
+# bad_fenced_block_in_block_quote_in_block_quote_in_list_with_previous_inner_list_double_drop
+# bad_fenced_block_in_block_quote_in_list_in_block_quote_with_previous_block_double_drop_with_thematics
 
 # Assert
-# bad_fenced_block_in_list_in_list_in_list_with_previous_list_double_drop
-# bad_fenced_block_in_list_in_list_in_list_with_previous_list_triple_drop
-# bad_fenced_block_in_list_in_list_in_list_with_previous_block_double_drop_with_thematics
-# bad_fenced_block_in_list_in_list_in_block_quote_with_previous_list_double_drop
-# bad_fenced_block_in_list_in_list_in_list_with_previous_block_triple_drop
-# bad_fenced_block_in_list_in_list_in_block_quote_with_previous_list_triple_drop
+
+# bad_fenced_block_in_block_quote_in_list_in_block_quote_with_previous_block_triple_drop_with_thematics
+# bad_fenced_block_in_block_quote_in_block_quote_in_block_quote_with_previous_block_triple_drop
+# bad_fenced_block_in_block_quote_in_block_quote_in_block_quote_with_previous_block_triple_drop_with_thematics
+#   File "c:\enlistments\pymarkdown\pymarkdown\transform_markdown\transform_containers.py", line 424, in __abcd
+#     assert keep_going
+# AssertionError
+
+# bad_fenced_block_in_list_in_block_quote_in_list_with_previous_block_triple_drop
+# bad_fenced_block_in_list_in_block_quote_in_list_with_previous_block_quad_drop
+#   File "c:\enlistments\pymarkdown\pymarkdown\transform_markdown\transform_containers.py", line 454, in __abcd_final_list
+#     assert removed_token_indices[0] < len(split_bleading_spaces)
+# AssertionError
+
+
+# bad_fenced_block_in_block_quote_in_list_in_block_quote_with_previous_list_double_drop_and_thematics
+#   File "c:\enlistments\pymarkdown\pymarkdown\transform_markdown\transform_containers.py", line 503, in __abcd_final
+#     assert container_indices_copy[-1] == len(list_split_spaces) - 1
+# AssertionError
+
+# (probably bad regen after fix)
 # bad_fenced_block_in_list_in_list_with_previous_inner_block_double_drop
 # bad_fenced_block_in_block_quote_in_list_in_list_with_previous_list_triple_drop
-# bad_fenced_block_in_list_in_block_quote_in_list_with_previous_list_double_drop
-# bad_fenced_block_in_block_quote_in_block_quote_in_list_with_previous_block_quad_drop
 # bad_fenced_block_in_block_quote_in_list_in_list_with_previous_block_triple_drop
-# bad_fenced_block_in_list_in_list_with_previous_inner_list_double_drop
+# bad_fenced_block_in_list_in_list_in_list_with_previous_block_double_drop_with_thematics
+# bad_fenced_block_in_list_in_block_quote_in_block_quote_with_previous_block_triple_drop
+# bad_fenced_block_in_list_in_list_in_list_with_previous_list_double_drop
+# bad_fenced_block_in_list_in_list_in_list_with_previous_list_triple_drop
+# bad_fenced_block_in_list_in_list_in_list_with_previous_block_triple_drop
+# bad_fenced_block_in_list_in_list_in_block_quote_with_previous_list_double_drop
+#   File "c:\enlistments\pymarkdown\pymarkdown\tokens\markdown_token.py", line 599, in adjust_line_number
+#     raise BadPluginFixError(
+# pymarkdown.plugin_manager.bad_plugin_fix_error.BadPluginFixError: Token 'fcode-block' can only be modified during the token pass in fix mode.
+
+# (probably bad regen after fix)
 # bad_fenced_block_in_block_quote_in_list_in_block_quote_with_previous_blockx_double_drop
 # bad_fenced_block_in_block_quote_in_list_in_block_quote_with_previous_list_triple_drop_and_thematics
-# bad_fenced_block_in_block_quote_in_list_in_block_quote_with_previous_list_double_drop_and_thematics
-# bad_fenced_block_in_block_quote_in_list_in_block_quote_with_previous_block_triple_drop_with_thematics
-# bad_fenced_block_in_block_quote_in_list_in_block_quote_with_previous_block_double_drop_with_thematics
-# bad_fenced_block_in_list_in_block_quote_with_previous_inner_list_double_drop
-# bad_fenced_block_in_block_quote_in_block_quote_in_list_with_previous_list_quad_drop]
-# bad_fenced_block_in_list_in_block_quote_in_list_with_previous_list_quad_drop
-# bad_fenced_block_in_block_quote_in_block_quote_in_list_with_previous_inner_list_quad_drop
-# bad_fenced_block_in_block_quote_in_block_quote_in_list_with_previous_inner_block_quad_drop
-# bad_fenced_block_in_block_quote_in_list_with_previous_inner_list_triple_drop
-# bad_fenced_block_in_block_quote_in_list_with_previous_inner_block_triple_drop
-# bad_fenced_block_in_list_in_block_quote_in_block_quote_with_previous_list_double_drop
-# bad_fenced_block_in_block_quote_in_block_quote_in_block_quote_with_previous_block_triple_drop_with_thematics
-# bad_fenced_block_in_block_quote_in_block_quote_in_block_quote_with_previous_block_triple_drop
-# bad_fenced_block_in_list_with_previous_inner_block_double_drop
+#   File "c:\enlistments\pymarkdown\pymarkdown\block_quotes\block_quote_processor.py", line 698, in __handle_existing_block_quote_fenced_special_part_two
+#     assert sd == ">"
+# AssertionError