diff --git a/src/Markdig.Tests/RoundtripSpecs/TestLinkReferenceDefinition.cs b/src/Markdig.Tests/RoundtripSpecs/TestLinkReferenceDefinition.cs
index a272df0d..ccc2834a 100644
--- a/src/Markdig.Tests/RoundtripSpecs/TestLinkReferenceDefinition.cs
+++ b/src/Markdig.Tests/RoundtripSpecs/TestLinkReferenceDefinition.cs
@@ -209,4 +209,16 @@ public void TestSetextHeader(string value)
{
RoundTrip(value);
}
+
+ [TestCase("> [foo]: /url 'the title'\n")]
+ [TestCase("> [foo]: /url\n> 'the title'\n")]
+ [TestCase("> [foo]:\n> /url 'the title'\n")]
+ [TestCase("> [foo]:\n> /url\n> 'the title'\n")]
+ [TestCase("> [foo]:\n> /url\n>\n> [foo]\n")]
+ [TestCase("> [foo]:\n> /url 'the title'\n>\n> [foo]\n")]
+ [TestCase("> [foo]:\n> /url\n> 'the title'\n>\n> [foo]\n")]
+ public void TestMultilineInBlockquote(string value)
+ {
+ RoundTrip(value);
+ }
}
diff --git a/src/Markdig/Helpers/StringLineGroup.cs b/src/Markdig/Helpers/StringLineGroup.cs
index 14b6680a..22072f45 100644
--- a/src/Markdig/Helpers/StringLineGroup.cs
+++ b/src/Markdig/Helpers/StringLineGroup.cs
@@ -2,6 +2,7 @@
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.
+using Markdig.Syntax;
using System.Collections;
using System.Diagnostics;
using System.Runtime.CompilerServices;
@@ -190,6 +191,33 @@ public void Trim()
}
}
+ internal SourceSpan ConvertToAbsoluteSpan(SourceSpan span)
+ {
+ if (span.IsEmpty || Count == 0) return span;
+
+ var startPosition = GetAbsolutePosition(span.Start);
+ var endPosition = GetAbsolutePosition(span.End);
+
+ return new SourceSpan(startPosition, endPosition);
+ }
+
+ private int GetAbsolutePosition(int position)
+ {
+ int offset = 0;
+ for (int i = 0; i < Count; i++)
+ {
+ ref StringSlice slice = ref Lines[i].Slice;
+ var lineLength = slice.Length + slice.NewLine.Length();
+
+ if (i == Count - 1 || position < offset + lineLength)
+ {
+ return slice.Start + (position - offset);
+ }
+ offset += lineLength;
+ }
+ return Lines[Count - 1].Slice.End + 1;
+ }
+
///
/// Gets or sets the enumerator.
///
diff --git a/src/Markdig/Parsers/ParagraphBlockParser.cs b/src/Markdig/Parsers/ParagraphBlockParser.cs
index 3773b3c1..71412ee0 100644
--- a/src/Markdig/Parsers/ParagraphBlockParser.cs
+++ b/src/Markdig/Parsers/ParagraphBlockParser.cs
@@ -212,13 +212,11 @@ private static bool TryMatchLinkReferenceDefinition(ref StringLineGroup lines, B
// Correct the locations of each field
linkReferenceDefinition.Line = lines.Lines[0].Line;
- int startPosition = lines.Lines[0].Slice.Start;
-
- linkReferenceDefinition.Span = linkReferenceDefinition.Span .MoveForward(startPosition);
- linkReferenceDefinition.LabelSpan = linkReferenceDefinition.LabelSpan .MoveForward(startPosition);
- linkReferenceDefinition.UrlSpan = linkReferenceDefinition.UrlSpan .MoveForward(startPosition);
- linkReferenceDefinition.TitleSpan = linkReferenceDefinition.TitleSpan .MoveForward(startPosition);
+ linkReferenceDefinition.Span = lines.ConvertToAbsoluteSpan(linkReferenceDefinition.Span);
+ linkReferenceDefinition.LabelSpan = lines.ConvertToAbsoluteSpan(linkReferenceDefinition.LabelSpan);
+ linkReferenceDefinition.UrlSpan = lines.ConvertToAbsoluteSpan(linkReferenceDefinition.UrlSpan);
+ linkReferenceDefinition.TitleSpan = lines.ConvertToAbsoluteSpan(linkReferenceDefinition.TitleSpan);
lines = iterator.Remaining();
}
else
@@ -256,24 +254,23 @@ private static bool TryMatchLinkReferenceDefinitionTrivia(ref StringLineGroup li
// Correct the locations of each field
lrd.Line = lines.Lines[0].Line;
var text = lines.Lines[0].Slice.Text;
- int startPosition = lines.Lines[0].Slice.Start;
-
- triviaBeforeLabel = triviaBeforeLabel.MoveForward(startPosition);
- labelWithTrivia = labelWithTrivia.MoveForward(startPosition);
- triviaBeforeUrl = triviaBeforeUrl.MoveForward(startPosition);
- unescapedUrl = unescapedUrl.MoveForward(startPosition);
- triviaBeforeTitle = triviaBeforeTitle.MoveForward(startPosition);
- unescapedTitle = unescapedTitle.MoveForward(startPosition);
- triviaAfterTitle = triviaAfterTitle.MoveForward(startPosition);
- lrd.Span = lrd.Span.MoveForward(startPosition);
+
+ triviaBeforeLabel = lines.ConvertToAbsoluteSpan(triviaBeforeLabel);
+ labelWithTrivia = lines.ConvertToAbsoluteSpan(labelWithTrivia);
+ triviaBeforeUrl = lines.ConvertToAbsoluteSpan(triviaBeforeUrl);
+ unescapedUrl = lines.ConvertToAbsoluteSpan(unescapedUrl);
+ triviaBeforeTitle = lines.ConvertToAbsoluteSpan(triviaBeforeTitle);
+ unescapedTitle = lines.ConvertToAbsoluteSpan(unescapedTitle);
+ triviaAfterTitle = lines.ConvertToAbsoluteSpan(triviaAfterTitle);
+ lrd.Span = lines.ConvertToAbsoluteSpan(lrd.Span);
lrd.TriviaBefore = new StringSlice(text, triviaBeforeLabel.Start, triviaBeforeLabel.End);
- lrd.LabelSpan = lrd.LabelSpan.MoveForward(startPosition);
+ lrd.LabelSpan = lines.ConvertToAbsoluteSpan(lrd.LabelSpan);
lrd.LabelWithTrivia = new StringSlice(text, labelWithTrivia.Start, labelWithTrivia.End);
lrd.TriviaBeforeUrl = new StringSlice(text, triviaBeforeUrl.Start, triviaBeforeUrl.End);
- lrd.UrlSpan = lrd.UrlSpan.MoveForward(startPosition);
+ lrd.UrlSpan = lines.ConvertToAbsoluteSpan(lrd.UrlSpan);
lrd.UnescapedUrl = new StringSlice(text, unescapedUrl.Start, unescapedUrl.End);
lrd.TriviaBeforeTitle = new StringSlice(text, triviaBeforeTitle.Start, triviaBeforeTitle.End);
- lrd.TitleSpan = lrd.TitleSpan.MoveForward(startPosition);
+ lrd.TitleSpan = lines.ConvertToAbsoluteSpan(lrd.TitleSpan);
lrd.UnescapedTitle = new StringSlice(text, unescapedTitle.Start, unescapedTitle.End);
lrd.TriviaAfter = new StringSlice(text, triviaAfterTitle.Start, triviaAfterTitle.End);
lrd.LinesBefore = paragraph.LinesBefore;
@@ -292,4 +289,5 @@ private static bool TryMatchLinkReferenceDefinitionTrivia(ref StringLineGroup li
return atLeastOneFound;
}
+
}
diff --git a/src/Markdig/Renderers/TextRendererBase.cs b/src/Markdig/Renderers/TextRendererBase.cs
index 199ecb19..983f9c95 100644
--- a/src/Markdig/Renderers/TextRendererBase.cs
+++ b/src/Markdig/Renderers/TextRendererBase.cs
@@ -320,6 +320,10 @@ public void Write(ReadOnlySpan content)
{
WriteIndent();
WriteRaw(content);
+ if (content[content.Length - 1] == '\n')
+ {
+ previousWasLine = true;
+ }
}
}