diff --git a/src/Elastic.Markdown/Myst/Directives/Button/ButtonBlock.cs b/src/Elastic.Markdown/Myst/Directives/Button/ButtonBlock.cs index dffe04570c..43a8bb9aeb 100644 --- a/src/Elastic.Markdown/Myst/Directives/Button/ButtonBlock.cs +++ b/src/Elastic.Markdown/Myst/Directives/Button/ButtonBlock.cs @@ -56,8 +56,8 @@ public partial class ButtonBlock(DirectiveBlockParser parser, ParserContext cont /// public bool IsInGroup { get; private set; } - // Regex to match a Markdown link: [text](url) - [GeneratedRegex(@"^\s*\[[^\]]+\]\([^\)]+\)\s*$", RegexOptions.Singleline)] + // Regex to match a single Markdown link, including reference-style links. + [GeneratedRegex(@"^\s*\[[^\]]*\](?:\([^\)]+\)|\[[^\]]+\]|\[\])\s*$", RegexOptions.Singleline)] private static partial Regex LinkPattern(); public override void FinalizeAndValidate(ParserContext context) @@ -94,14 +94,14 @@ private void ValidateContent() if (string.IsNullOrWhiteSpace(content)) { - this.EmitError("Button directive requires a link. Use: :::{button}\n[text](url)\n:::"); + this.EmitError("Button directive requires a link. Use: :::{button}\n[text](url)\n:::\nOr: :::{button}\n[text][ref]\n:::"); return; } // Check if content matches the link pattern if (!LinkPattern().IsMatch(content)) { - this.EmitError("Button directive must contain only a single Markdown link. Use: :::{button}\n[text](url)\n:::"); + this.EmitError("Button directive must contain only a single Markdown link. Use: :::{button}\n[text](url)\n:::\nOr: :::{button}\n[text][ref]\n:::"); } } diff --git a/tests/Elastic.Markdown.Tests/Directives/ButtonTests.cs b/tests/Elastic.Markdown.Tests/Directives/ButtonTests.cs index be60d19045..51c7df6f2c 100644 --- a/tests/Elastic.Markdown.Tests/Directives/ButtonTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/ButtonTests.cs @@ -81,6 +81,26 @@ public class ButtonExternalTests(ITestOutputHelper output) : DirectiveTest Html.Should().Contain("rel=\"noopener noreferrer\""); } +public class ButtonReferenceLinkTests(ITestOutputHelper output) : DirectiveTest(output, +""" +:::{button} +[Open][kibana-url] +::: + +[kibana-url]: +""" +) +{ + [Fact] + public void RendersReferencedLinkHref() => Html.Should().Contain("href=\"https://foo.example.com\""); + + [Fact] + public void RendersButtonText() => Html.Should().Contain(">Open<"); + + [Fact] + public void EmitsNoErrors() => Collector.Diagnostics.Should().BeEmpty(); +} + public class ButtonInvalidTypeTests(ITestOutputHelper output) : DirectiveTest(output, """ :::{button}