Skip to content

Add AutoLinkOptions.AllowDomainWithoutPeriod #859

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

Merged
merged 4 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from 3 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
24 changes: 24 additions & 0 deletions src/Markdig.Tests/TestAutoLinks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Markdig.Extensions.AutoLinks;

namespace Markdig.Tests;

[TestFixture]
public class TestAutoLinks
{
[Test]
[TestCase("https://localhost", "<p><a href=\"https://localhost\">https://localhost</a></p>")]
[TestCase("http://localhost", "<p><a href=\"http://localhost\">http://localhost</a></p>")]
[TestCase("https://l", "<p><a href=\"https://l\">https://l</a></p>")]
[TestCase("www.l", "<p><a href=\"http://www.l\">www.l</a></p>")]
[TestCase("https://localhost:5000", "<p><a href=\"https://localhost:5000\">https://localhost:5000</a></p>")]
[TestCase("www.l:5000", "<p><a href=\"http://www.l:5000\">www.l:5000</a></p>")]
public void TestLinksWithAllowDomainWithoutPeriod(string markdown, string expected)
{
var pipeline = new MarkdownPipelineBuilder()
.UseAutoLinks(new AutoLinkOptions { AllowDomainWithoutPeriod = true })
.Build();
var html = Markdown.ToHtml(markdown, pipeline);

Assert.That(html, Is.EqualTo(expected).IgnoreWhiteSpace);
}
}
5 changes: 5 additions & 0 deletions src/Markdig/Extensions/AutoLinks/AutoLinkOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,9 @@ public AutoLinkOptions()
/// Should a www link be prefixed with https:// instead of http:// (false by default)
/// </summary>
public bool UseHttpsForWWWLinks { get; set; }

/// <summary>
/// Should auto-linking allow a domain with no period, e.g. https://localhost (false by default)
/// </summary>
public bool AllowDomainWithoutPeriod { get; set; }
}
2 changes: 1 addition & 1 deletion src/Markdig/Extensions/AutoLinks/AutoLinkParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public override bool Match(InlineProcessor processor, ref StringSlice slice)
}

// Do not need to check if a telephone number is a valid domain
if (c != 't' && !LinkHelper.IsValidDomain(link, domainOffset))
if (c != 't' && !LinkHelper.IsValidDomain(link, domainOffset, Options.AllowDomainWithoutPeriod))
{
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Markdig/Helpers/LinkHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,7 +1006,7 @@ private static bool IsEndOfUri(char c, bool isAutoLink)
return c == '\0' || c.IsSpaceOrTab() || c.IsControl() || (isAutoLink && c == '<'); // TODO: specs unclear. space is strict or relaxed? (includes tabs?)
}

public static bool IsValidDomain(string link, int prefixLength)
public static bool IsValidDomain(string link, int prefixLength, bool allowDomainWithoutPeriod)
{
// https://github.github.com/gfm/#extended-www-autolink
// A valid domain consists of alphanumeric characters, underscores (_), hyphens (-) and periods (.).
Expand Down Expand Up @@ -1052,7 +1052,7 @@ public static bool IsValidDomain(string link, int prefixLength)
segmentHasCharacters = true;
}

return segmentCount != 1 && // At least one dot was present
return (segmentCount != 1 || allowDomainWithoutPeriod) && // At least one dot was present
segmentHasCharacters && // Last segment has valid characters
segmentCount - lastUnderscoreSegment >= 2; // No underscores are present in the last two segments of the domain
}
Expand Down