From 1cc83f81bcdd4cd0091e9d111fb457bb97304e62 Mon Sep 17 00:00:00 2001
From: Fabrizio Ferri Benedetti
Date: Wed, 30 Jul 2025 22:51:30 +0200
Subject: [PATCH 1/2] Add example and logic for inline applies to
---
docs/syntax/applies.md | 2 +-
.../HeadingBlockWithSlugParser.cs | 23 +++++++++++++++----
tests/authoring/Inline/AppliesToRole.fs | 23 +++++++++++++++++++
3 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/docs/syntax/applies.md b/docs/syntax/applies.md
index 8de237b32..bd27cc178 100644
--- a/docs/syntax/applies.md
+++ b/docs/syntax/applies.md
@@ -268,7 +268,7 @@ observability: deprecated 9.0.0
### Inline
-#### In text
+#### In text {applies_to}`serverless: `
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas ut libero diam. Mauris sed eleifend erat,
sit amet auctor odio. Donec ac placerat nunc. {applies_to}`stack: preview` Aenean scelerisque viverra lectus
diff --git a/src/Elastic.Markdown/Myst/InlineParsers/HeadingBlockWithSlugParser.cs b/src/Elastic.Markdown/Myst/InlineParsers/HeadingBlockWithSlugParser.cs
index 236d4b8ab..297c5af06 100644
--- a/src/Elastic.Markdown/Myst/InlineParsers/HeadingBlockWithSlugParser.cs
+++ b/src/Elastic.Markdown/Myst/InlineParsers/HeadingBlockWithSlugParser.cs
@@ -29,9 +29,19 @@ public void Setup(MarkdownPipelineBuilder pipeline) =>
public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) { }
}
-public class HeadingBlockWithSlugParser : HeadingBlockParser
+public partial class HeadingBlockWithSlugParser : HeadingBlockParser
{
private static readonly Regex IconSyntax = IconParser.IconRegex();
+ private static readonly Regex AppliesToSyntax = AppliesToSyntaxRegex();
+
+ private static string StripAppliesToAnnotations(string text)
+ {
+ // Remove applies_to inline annotations from the text
+ return AppliesToSyntax.Replace(text, "").Trim();
+ }
+
+ [GeneratedRegex(@"\{applies_to\}`[^`]*`", RegexOptions.Compiled)]
+ private static partial Regex AppliesToSyntaxRegex();
public override bool Close(BlockProcessor processor, Block block)
{
@@ -39,8 +49,9 @@ public override bool Close(BlockProcessor processor, Block block)
return base.Close(processor, block);
var text = headingBlock.Lines.Lines[0].Slice.AsSpan();
- // Remove icon syntax from the heading text
- var cleanText = IconSyntax.Replace(text.ToString(), "").Trim();
+ // Remove icon syntax and applies_to annotations from the heading text
+ var cleanText = IconSyntax.Replace(text.ToString(), "");
+ cleanText = StripAppliesToAnnotations(cleanText);
headingBlock.SetData("header", cleanText);
if (!HeadingAnchorParser.MatchAnchorLine().IsMatch(text))
@@ -59,8 +70,10 @@ public override bool Close(BlockProcessor processor, Block block)
if (header.IndexOf('$') >= 0)
anchor = HeadingAnchorParser.MatchAnchor().Replace(anchor.ToString(), "");
headingBlock.SetData("anchor", anchor.ToString());
- // Remove icon syntax from the header text when setting it as data
- headingBlock.SetData("header", IconSyntax.Replace(header.ToString(), "").Trim());
+ // Remove icon syntax and applies_to annotations from the header text when setting it as data
+ var headerText = IconSyntax.Replace(header.ToString(), "");
+ headerText = StripAppliesToAnnotations(headerText);
+ headingBlock.SetData("header", headerText.Trim());
return base.Close(processor, block);
}
diff --git a/tests/authoring/Inline/AppliesToRole.fs b/tests/authoring/Inline/AppliesToRole.fs
index 42cc35a7f..b4ff8dd3b 100644
--- a/tests/authoring/Inline/AppliesToRole.fs
+++ b/tests/authoring/Inline/AppliesToRole.fs
@@ -162,3 +162,26 @@ If this functionality is unavailable or behaves differently when deployed on ECH
element.
"""
+
+type ``strips applies_to annotations from headings in table of contents`` () =
+ static let markdown = Setup.Markdown """
+# Main Title
+
+## Section with applies_to {applies_to}`stack: preview 9.1`
+
+### Another section {applies_to}`serverless: beta`
+
+Some content here.
+"""
+
+ []
+ let ``heading text is stripped of applies_to annotations`` () =
+ let document = markdown |> converts "index.md"
+ let tocItems = document.File.PageTableOfContent.Values |> Seq.toList
+
+ // Verify that the heading text doesn't contain the applies_to annotations
+ let sectionHeading = tocItems |> List.find (fun item -> item.Heading = "Section with applies_to")
+ let anotherSectionHeading = tocItems |> List.find (fun item -> item.Heading = "Another section")
+
+ test <@ sectionHeading.Heading = "Section with applies_to" @>
+ test <@ anotherSectionHeading.Heading = "Another section" @>
From 3bc2345d690ebef99665093566f1500f98ef4756 Mon Sep 17 00:00:00 2001
From: Fabrizio Ferri Benedetti
Date: Wed, 30 Jul 2025 23:11:38 +0200
Subject: [PATCH 2/2] Fix linter errors
---
.../Myst/InlineParsers/HeadingBlockWithSlugParser.cs | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/Elastic.Markdown/Myst/InlineParsers/HeadingBlockWithSlugParser.cs b/src/Elastic.Markdown/Myst/InlineParsers/HeadingBlockWithSlugParser.cs
index 297c5af06..cf28201d5 100644
--- a/src/Elastic.Markdown/Myst/InlineParsers/HeadingBlockWithSlugParser.cs
+++ b/src/Elastic.Markdown/Myst/InlineParsers/HeadingBlockWithSlugParser.cs
@@ -34,11 +34,9 @@ public partial class HeadingBlockWithSlugParser : HeadingBlockParser
private static readonly Regex IconSyntax = IconParser.IconRegex();
private static readonly Regex AppliesToSyntax = AppliesToSyntaxRegex();
- private static string StripAppliesToAnnotations(string text)
- {
+ private static string StripAppliesToAnnotations(string text) =>
// Remove applies_to inline annotations from the text
- return AppliesToSyntax.Replace(text, "").Trim();
- }
+ AppliesToSyntax.Replace(text, "").Trim();
[GeneratedRegex(@"\{applies_to\}`[^`]*`", RegexOptions.Compiled)]
private static partial Regex AppliesToSyntaxRegex();