From bc4e399087e19ddbbdf95dc698bec7f752b3c8e5 Mon Sep 17 00:00:00 2001 From: Alexandre Mutel Date: Sat, 13 Jun 2026 14:38:30 +0200 Subject: [PATCH] Fix blockquote ordered list parsing (#887) --- src/Markdig.Tests/MiscTests.cs | 55 ++++++++++++++++++++++++++ src/Markdig/Parsers/BlockProcessor.cs | 8 ++++ src/Markdig/Parsers/ListBlockParser.cs | 7 +++- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/Markdig.Tests/MiscTests.cs b/src/Markdig.Tests/MiscTests.cs index 3fa4d502..66460068 100644 --- a/src/Markdig.Tests/MiscTests.cs +++ b/src/Markdig.Tests/MiscTests.cs @@ -481,6 +481,61 @@ A tip inside a note

TestParser.TestSpec(input, expected, new MarkdownPipelineBuilder().UseAlertBlocks(allowNestedAlerts: true).Build()); } + [Test] + public void TestIssue887ListAfterNestedBlockQuote() + { + var input = @"> >* _Unordered 1_ QL2 level 1 no space sep +> > Continued 1 +> > * Unordered 2 level 1 +> > 1. **Ordered 1** QL2 level 1 +> > Continued 1 +> > > Not continued QL3 +> > 2. Ordered 2 QL2 level 1 +> > Continued 2a +> > +> > Continued 2b +> > +> > Continued 2c +> > +> > 3. Ordered 3 QL2 level 2 +> > Continued 3a +> > +> > Continued 3b +"; + + var expected = @"
+
+
    +
  • Unordered 1 QL2 level 1 no space sep +Continued 1
  • +
  • Unordered 2 level 1
  • +
+
    +
  1. Ordered 1 QL2 level 1 +Continued 1
  2. +
+
+

Not continued QL3

+
+
    +
  1. Ordered 2 QL2 level 1 +Continued 2a

    +

    Continued 2b

    +

    Continued 2c

    +
      +
    1. Ordered 3 QL2 level 2 +Continued 3a

      +

      Continued 3b

      +
    2. +
    +
  2. +
+
+
"; + + TestParser.TestSpec(input, expected); + } + [Test] public void TestIssue845ListItemBlankLine() { diff --git a/src/Markdig/Parsers/BlockProcessor.cs b/src/Markdig/Parsers/BlockProcessor.cs index bb8ff251..c2b96ac3 100644 --- a/src/Markdig/Parsers/BlockProcessor.cs +++ b/src/Markdig/Parsers/BlockProcessor.cs @@ -152,6 +152,11 @@ public class BlockProcessor /// public bool IsLazy { get; private set; } + /// + /// Gets a value indicating whether the current line failed to continue one of the open containers. + /// + internal bool HasUnmatchedBlocks { get; private set; } + /// /// Gets the current stack of being processed. /// @@ -689,6 +694,7 @@ public class BlockProcessor private void TryContinueBlocks() { IsLazy = false; + HasUnmatchedBlocks = false; // Set all blocks non opened. // They will be marked as open in the following loop @@ -723,6 +729,7 @@ public class BlockProcessor if (result == BlockState.None) { + HasUnmatchedBlocks = true; break; } @@ -1049,6 +1056,7 @@ public class BlockProcessor SkipFirstUnwindSpace = false; ContinueProcessingLine = false; IsLazy = false; + HasUnmatchedBlocks = false; currentStackIndex = 0; originalLineStart = 0; diff --git a/src/Markdig/Parsers/ListBlockParser.cs b/src/Markdig/Parsers/ListBlockParser.cs index 23a5b05d..f83a42cb 100644 --- a/src/Markdig/Parsers/ListBlockParser.cs +++ b/src/Markdig/Parsers/ListBlockParser.cs @@ -275,8 +275,13 @@ public class ListBlockParser : BlockParser block ??= state.LastBlock; if (block is not null && block.IsParagraphBlock) { + bool isOrderedListInterruptingParagraph = !state.HasUnmatchedBlocks && + state.IsOpen(block) && + listInfo.BulletType == '1' && + listInfo.OrderedStart is not "1"; + if (state.IsBlankLine || - state.IsOpen(block) && listInfo.BulletType == '1' && listInfo.OrderedStart is not "1") + isOrderedListInterruptingParagraph) { state.GoToColumn(initColumn); state.TriviaStart = savedTriviaStart; // restore changed TriviaStart state