Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better literal delimiter content string slice #736

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading