diff --git a/src/Markdig.Tests/MiscTests.cs b/src/Markdig.Tests/MiscTests.cs index f3793ebfd..858479886 100644 --- a/src/Markdig.Tests/MiscTests.cs +++ b/src/Markdig.Tests/MiscTests.cs @@ -1,7 +1,8 @@ using System.Text.RegularExpressions; using Markdig.Extensions.AutoLinks; - +using Markdig.Extensions.Tables; +using Markdig.Syntax; using NUnit.Framework; namespace Markdig.Tests; @@ -198,9 +199,9 @@ public void VisualizeMathExpressions()
\begin{align} \sqrt{37} & = \sqrt{\frac{73^2-1}{12^2}} \\ - & = \sqrt{\frac{73^2}{12^2}\cdot\frac{73^2-1}{73^2}} \\ + & = \sqrt{\frac{73^2}{12^2}\cdot\frac{73^2-1}{73^2}} \\ & = \sqrt{\frac{73^2}{12^2}}\sqrt{\frac{73^2-1}{73^2}} \\ - & = \frac{73}{12}\sqrt{1 - \frac{1}{73^2}} \\ + & = \frac{73}{12}\sqrt{1 - \frac{1}{73^2}} \\ & \approx \frac{73}{12}\left(1 - \frac{1}{2\cdot73^2}\right) \end{align}
@@ -291,4 +292,29 @@ public void CanUseHttpsPrefixForWWWAutoLinks() TestParser.TestSpec("www.foo.bar", "

www.foo.bar

", pipeline); TestParser.TestSpec("www.foo.bar", "

www.foo.bar

", httpsPipeline); } + + [Test] + public void RootInlineHasCorrectSourceSpan() + { + var pipeline = new MarkdownPipelineBuilder().UsePreciseSourceLocation().Build(); + pipeline.TrackTrivia = true; + + var document = Markdown.Parse("0123456789\n", pipeline); + + var expectedSourceSpan = new SourceSpan(0, 10); + Assert.That(((LeafBlock)document.LastChild).Inline.Span == expectedSourceSpan); + } + + [Test] + public void RootInlineInTableCellHasCorrectSourceSpan() + { + var pipeline = new MarkdownPipelineBuilder().UsePreciseSourceLocation().UseAdvancedExtensions().Build(); + pipeline.TrackTrivia = true; + + var document = Markdown.Parse("| a | b |\n| --- | --- |\n| *dest*
| \\[in\\] The address of the result of the operation.
|", pipeline); + + var paragraph = (ParagraphBlock)((TableCell)((TableRow)((Table)document.LastChild).LastChild).First()).LastChild; + Assert.That(paragraph.Inline.Span.Start == paragraph.Inline.FirstChild.Span.Start); + Assert.That(paragraph.Inline.Span.End == paragraph.Inline.LastChild.Span.End); + } } diff --git a/src/Markdig.Tests/TestSourcePosition.cs b/src/Markdig.Tests/TestSourcePosition.cs index e36372431..62a5eafbe 100644 --- a/src/Markdig.Tests/TestSourcePosition.cs +++ b/src/Markdig.Tests/TestSourcePosition.cs @@ -67,6 +67,28 @@ public void TestParagraph2() "); } + [Test] + public void TestParagraphWithEndNewLine() + { + Check("0123456789\n", @" +paragraph ( 0, 0) 0-10 +literal ( 0, 0) 0-9 +linebreak ( 0,10) 10-10 +", trackTrivia: true); + + Check("0123456789\r", @" +paragraph ( 0, 0) 0-10 +literal ( 0, 0) 0-9 +linebreak ( 0,10) 10-10 +", trackTrivia: true); + + Check("0123456789\r\n", @" +paragraph ( 0, 0) 0-11 +literal ( 0, 0) 0-9 +linebreak ( 0,10) 10-11 +", trackTrivia: true); + } + [Test] public void TestEmphasis() { @@ -825,9 +847,10 @@ public void TestDocument() "); } - private static void Check(string text, string expectedResult, string extensions = null) + private static void Check(string text, string expectedResult, string extensions = null, bool trackTrivia = false) { var pipelineBuilder = new MarkdownPipelineBuilder().UsePreciseSourceLocation(); + pipelineBuilder.TrackTrivia = trackTrivia; if (extensions != null) { pipelineBuilder.Configure(extensions); diff --git a/src/Markdig/Extensions/Tables/PipeTableParser.cs b/src/Markdig/Extensions/Tables/PipeTableParser.cs index 67411e146..eb380768f 100644 --- a/src/Markdig/Extensions/Tables/PipeTableParser.cs +++ b/src/Markdig/Extensions/Tables/PipeTableParser.cs @@ -443,6 +443,11 @@ public bool PostProcess(InlineProcessor state, Inline? root, Inline? lastChild, { var paragraph = (ParagraphBlock) cell[0]; state.PostProcessInlines(postInlineProcessorIndex + 1, paragraph.Inline, null, true); + if (paragraph.Inline?.LastChild is not null) + { + paragraph.Inline.Span.End = paragraph.Inline.LastChild.Span.End; + paragraph.UpdateSpanEnd(paragraph.Inline.LastChild.Span.End); + } } // Clear cells when we are done @@ -520,7 +525,7 @@ private static bool ParseHeaderString(Inline? inline, out TableColumnAlign? alig // Create aligns until we may have a header row aligns ??= new List(); - + aligns.Add(new TableColumnDefinition() { Alignment = align }); // If this is the last delimiter, we need to check the right side of the `|` delimiter diff --git a/src/Markdig/Parsers/InlineProcessor.cs b/src/Markdig/Parsers/InlineProcessor.cs index 7e3a3f8b8..c60cb1284 100644 --- a/src/Markdig/Parsers/InlineProcessor.cs +++ b/src/Markdig/Parsers/InlineProcessor.cs @@ -225,6 +225,7 @@ public void ProcessInlineLeaf(LeafBlock leafBlock) previousLineIndexForSliceOffset = 0; lineOffsets.Clear(); var text = leafBlock.Lines.ToSlice(lineOffsets); + var textEnd = text.Length; leafBlock.Lines.Release(); int previousStart = -1; @@ -319,7 +320,8 @@ public void ProcessInlineLeaf(LeafBlock leafBlock) var newLine = leafBlock.NewLine; if (newLine != NewLine.None) { - leafBlock.Inline.AppendChild(new LineBreakInline { NewLine = newLine }); + var position = GetSourcePosition(textEnd, out int line, out int column); + leafBlock.Inline.AppendChild(new LineBreakInline { NewLine = newLine, Line = line, Column = column, Span = { Start = position, End = position + (newLine == NewLine.CarriageReturnLineFeed ? 1 : 0) } }); } } } @@ -342,6 +344,12 @@ public void ProcessInlineLeaf(LeafBlock leafBlock) // DebugLog.WriteLine("** Dump after Emphasis:"); // leafBlock.Inline.DumpTo(DebugLog); //} + + if (leafBlock.Inline.LastChild is not null) + { + leafBlock.Inline.Span.End = leafBlock.Inline.LastChild.Span.End; + leafBlock.UpdateSpanEnd(leafBlock.Inline.Span.End); + } } public void PostProcessInlines(int startingIndex, Inline? root, Inline? lastChild, bool isFinalProcessing)