Fix regression between autolink extension with html inline link a /regular or regular markdown links (issue #65)

This commit is contained in:
Alexandre Mutel
2016-10-11 14:44:50 +02:00
parent e6223f86d8
commit 81b8dce7a8
3 changed files with 140 additions and 2 deletions

View File

@@ -44,3 +44,27 @@ This is not a nhttp://www.google.com URL but this is (https://www.google.com)
.
<p>This is not a nhttp://www.google.com URL but this is (<a href="https://www.google.com">https://www.google.com</a>)</p>
````````````````````````````````
An autolink should not interfere with an `<a>` HTML inline:
```````````````````````````````` example
This is an HTML <a href="http://www.google.com">http://www.google.com</a> link
.
<p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
````````````````````````````````
or even within emphasis:
```````````````````````````````` example
This is an HTML <a href="http://www.google.com"> **http://www.google.com** </a> link
.
<p>This is an HTML <a href="http://www.google.com"> <strong>http://www.google.com</strong> </a> link</p>
````````````````````````````````
An autolink should not interfere with a markdown link:
```````````````````````````````` example
This is an HTML [http://www.google.com](http://www.google.com) link
.
<p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
````````````````````````````````

View File

@@ -20198,4 +20198,64 @@ namespace Markdig.Tests
TestParser.TestSpec("This is not a nhttp://www.google.com URL but this is (https://www.google.com)", "<p>This is not a nhttp://www.google.com URL but this is (<a href=\"https://www.google.com\">https://www.google.com</a>)</p>", "autolinks|advanced");
}
}
// An autolink should not interfere with an `<a>` HTML inline:
[TestFixture]
public partial class TestExtensionsAutoLinks
{
[Test]
public void Example004()
{
// Example 4
// Section: Extensions AutoLinks
//
// The following CommonMark:
// This is an HTML <a href="http://www.google.com">http://www.google.com</a> link
//
// Should be rendered as:
// <p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 4, "Extensions AutoLinks");
TestParser.TestSpec("This is an HTML <a href=\"http://www.google.com\">http://www.google.com</a> link", "<p>This is an HTML <a href=\"http://www.google.com\">http://www.google.com</a> link</p>", "autolinks|advanced");
}
}
// or even within emphasis:
[TestFixture]
public partial class TestExtensionsAutoLinks
{
[Test]
public void Example005()
{
// Example 5
// Section: Extensions AutoLinks
//
// The following CommonMark:
// This is an HTML <a href="http://www.google.com"> **http://www.google.com** </a> link
//
// Should be rendered as:
// <p>This is an HTML <a href="http://www.google.com"> <strong>http://www.google.com</strong> </a> link</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 5, "Extensions AutoLinks");
TestParser.TestSpec("This is an HTML <a href=\"http://www.google.com\"> **http://www.google.com** </a> link", "<p>This is an HTML <a href=\"http://www.google.com\"> <strong>http://www.google.com</strong> </a> link</p>", "autolinks|advanced");
}
}
// An autolink should not interfere with a markdown link:
[TestFixture]
public partial class TestExtensionsAutoLinks
{
[Test]
public void Example006()
{
// Example 6
// Section: Extensions AutoLinks
//
// The following CommonMark:
// This is an HTML [http://www.google.com](http://www.google.com) link
//
// Should be rendered as:
// <p>This is an HTML <a href="http://www.google.com">http://www.google.com</a> link</p>
Console.WriteLine("Example {0}" + Environment.NewLine + "Section: {0}" + Environment.NewLine, 6, "Extensions AutoLinks");
TestParser.TestSpec("This is an HTML [http://www.google.com](http://www.google.com) link", "<p>This is an HTML <a href=\"http://www.google.com\">http://www.google.com</a> link</p>", "autolinks|advanced");
}
}
}

View File

@@ -31,8 +31,6 @@ namespace Markdig.Extensions.AutoLinks
public override bool Match(InlineProcessor processor, ref StringSlice slice)
{
string match;
// Previous char must be a whitespace or a punctuation
var previousChar = slice.PeekCharExtra(-1);
if (!previousChar.IsAsciiPunctuation() && !previousChar.IsWhiteSpaceOrZero())
@@ -40,6 +38,12 @@ namespace Markdig.Extensions.AutoLinks
return false;
}
// Check that an autolink is possible in the current context
if (!IsAutoLinkValidInCurrentContext(processor))
{
return false;
}
var startPosition = slice.Start;
var c = slice.CurrentChar;
@@ -139,5 +143,55 @@ namespace Markdig.Extensions.AutoLinks
return true;
}
private bool IsAutoLinkValidInCurrentContext(InlineProcessor processor)
{
// Case where there is a pending HtmlInline <a>
var currentInline = processor.Inline;
while (currentInline != null)
{
var htmlInline = currentInline as HtmlInline;
if (htmlInline != null)
{
// If we have a </a> we don't expect nested <a>
if (htmlInline.Tag.StartsWith("</a", StringComparison.OrdinalIgnoreCase))
{
break;
}
// If there is a pending <a>, we can't allow a link
if (htmlInline.Tag.StartsWith("<a", StringComparison.OrdinalIgnoreCase))
{
return false;
}
}
// Check previous sibling and parents in the tree
currentInline = currentInline.PreviousSibling ?? currentInline.Parent;
}
// Check that we don't have any pending brackets opened (where we could have a possible markdown link)
// NOTE: This assume that [ and ] are used for links, otherwise autolink will not work properly
currentInline = processor.Inline;
int countBrackets = 0;
while (currentInline != null)
{
var linkDelimiterInline = currentInline as LinkDelimiterInline;
if (linkDelimiterInline != null && linkDelimiterInline.IsActive)
{
if (linkDelimiterInline.Type == DelimiterType.Open)
{
countBrackets++;
}
else if (linkDelimiterInline.Type == DelimiterType.Close)
{
countBrackets--;
}
}
currentInline = currentInline.Parent;
}
return countBrackets <= 0;
}
}
}