Skip to content

Commit

Permalink
Merge pull request #736 from zickb/better_literal_delimiter_content_s…
Browse files Browse the repository at this point in the history
…tring_slice

Better literal delimiter content string slice
  • Loading branch information
xoofx authored Aug 30, 2023
2 parents f15e9f0 + dba94a2 commit 7d40bc1
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 9 deletions.
18 changes: 17 additions & 1 deletion src/Markdig.Tests/TestEmphasisPlus.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// 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 Markdig.Syntax.Inlines;

namespace Markdig.Tests;

[TestFixture]
Expand All @@ -18,4 +21,17 @@ public void NormalStrongNormal()
{
TestParser.TestSpec("normal ***Strong emphasis*** normal", "<p>normal <em><strong>Strong emphasis</strong></em> normal</p>", "");
}

[Test]
public void OpenEmphasisHasConvenientContentStringSlice()
{
var pipeline = new MarkdownPipelineBuilder().Build();

var document = Markdown.Parse("test*test", pipeline);

var emphasisDelimiterLiteral = (LiteralInline)((ParagraphBlock)document.LastChild).Inline.ElementAt(1);
Assert.That(emphasisDelimiterLiteral.Content.Text == "test*test");
Assert.That(emphasisDelimiterLiteral.Content.Start == 4);
Assert.That(emphasisDelimiterLiteral.Content.End == 4);
}
}
14 changes: 8 additions & 6 deletions src/Markdig/Parsers/Inlines/EmphasisInlineParser.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.

using System.Diagnostics;
Expand Down Expand Up @@ -109,7 +109,7 @@ public bool PostProcess(InlineProcessor state, Inline? root, Inline? lastChild,
var child = container.FirstChild;
while (child != null)
{
// Stop the search on the delimitation child
// Stop the search on the delimitation child
if (child == lastChild)
{
break;
Expand Down Expand Up @@ -197,7 +197,7 @@ public override bool Match(InlineProcessor processor, ref StringSlice slice)
if (canOpen) delimiterType |= DelimiterType.Open;
if (canClose) delimiterType |= DelimiterType.Close;

var delimiter = new EmphasisDelimiterInline(this, emphasisDesc)
var delimiter = new EmphasisDelimiterInline(this, emphasisDesc, new StringSlice(slice.Text, startPosition, slice.Start - 1))
{
DelimiterCount = delimiterCount,
Type = delimiterType,
Expand All @@ -221,7 +221,7 @@ private void ProcessEmphasis(InlineProcessor processor, List<EmphasisDelimiterIn

// TODO: Benchmark difference between using List and LinkedList here since there could be a few Remove calls

// Move current_position forward in the delimiter stack (if needed) until
// Move current_position forward in the delimiter stack (if needed) until
// we find the first potential closer with delimiter * or _. (This will be the potential closer closest to the beginning of the input – the first one in parse order.)
for (int i = 0; i < delimiters.Count; i++)
{
Expand All @@ -237,7 +237,7 @@ private void ProcessEmphasis(InlineProcessor processor, List<EmphasisDelimiterIn
{
while (true)
{
// Now, look back in the stack (staying above stack_bottom and the openers_bottom for this delimiter type)
// Now, look back in the stack (staying above stack_bottom and the openers_bottom for this delimiter type)
// for the first matching potential opener (“matching” means same delimiter).
EmphasisDelimiterInline? openDelimiter = null;
int openDelimiterIndex = -1;
Expand Down Expand Up @@ -307,8 +307,10 @@ private void ProcessEmphasis(InlineProcessor processor, List<EmphasisDelimiterIn
emphasis.Column = openDelimiter.Column;
emphasis.Span.End = closeDelimiter.Span.End - closeDelimitercount + delimiterDelta;

openDelimiter.Content.Start += delimiterDelta;
openDelimiter.Span.Start += delimiterDelta;
openDelimiter.Column += delimiterDelta;
closeDelimiter.Content.Start += delimiterDelta;
closeDelimiter.Span.Start += delimiterDelta;
closeDelimiter.Column += delimiterDelta;

Expand All @@ -331,7 +333,7 @@ private void ProcessEmphasis(InlineProcessor processor, List<EmphasisDelimiterIn
for (int k = i - 1; k >= openDelimiterIndex + 1; k--)
{
var literalDelimiter = delimiters[k];
literalDelimiter.ReplaceBy(literalDelimiter.AsLiteralInline());
literalDelimiter.ReplaceBy(literalDelimiter.AsLiteralInline());
delimiters.RemoveAt(k);
i--;
}
Expand Down
27 changes: 25 additions & 2 deletions src/Markdig/Syntax/Inlines/EmphasisDelimiterInline.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// This file is licensed under the BSD-Clause 2 license.
// This file is licensed under the BSD-Clause 2 license.
// See the license.txt file in the project root for more information.

using Markdig.Helpers;
Expand Down Expand Up @@ -27,6 +27,24 @@ public EmphasisDelimiterInline(InlineParser parser, EmphasisDescriptor descripto

Descriptor = descriptor;
DelimiterChar = descriptor.Character;
Content = new StringSlice(ToLiteral());
}

/// <summary>
/// Initializes a new instance of the <see cref="EmphasisDelimiterInline" /> class.
/// </summary>
/// <param name="parser">The parser.</param>
/// <param name="descriptor">The descriptor.</param>
/// <param name="content">The content.</param>
/// <exception cref="ArgumentNullException"></exception>
internal EmphasisDelimiterInline(InlineParser parser, EmphasisDescriptor descriptor, StringSlice content) : base(parser)
{
if (descriptor is null)
ThrowHelper.ArgumentNullException(nameof(descriptor));

Descriptor = descriptor;
DelimiterChar = descriptor.Character;
Content = content;
}

/// <summary>
Expand All @@ -44,6 +62,11 @@ public EmphasisDelimiterInline(InlineParser parser, EmphasisDescriptor descripto
/// </summary>
public int DelimiterCount { get; set; }

/// <summary>
/// The content as a <see cref="StringSlice"/>.
/// </summary>
public StringSlice Content;

public override string ToLiteral()
{
return DelimiterCount > 0 ? new string(DelimiterChar, DelimiterCount) : string.Empty;
Expand All @@ -53,7 +76,7 @@ public LiteralInline AsLiteralInline()
{
return new LiteralInline()
{
Content = new StringSlice(ToLiteral()),
Content = Content,
IsClosed = true,
Span = Span,
Line = Line,
Expand Down

0 comments on commit 7d40bc1

Please sign in to comment.