Skip to content

Commit af9c7e0

Browse files
authored
Support unique callouts for enhanced code blocks (#209)
1 parent 55f5768 commit af9c7e0

File tree

4 files changed

+40
-4
lines changed

4 files changed

+40
-4
lines changed

src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlock.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public class EnhancedCodeBlock(BlockParser parser, ParserContext context)
2222

2323
public List<CallOut>? CallOuts { get; set; }
2424

25+
public IReadOnlyCollection<CallOut> UniqueCallOuts => CallOuts?.DistinctBy(c => c.Index).ToList() ?? [];
26+
2527
public bool InlineAnnotations { get; set; }
2628

2729
public string Language { get; set; } = "unknown";

src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockHtmlRenderer.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ private static void RenderRazorSlice<T>(RazorSlice<T> slice, HtmlRenderer render
2525
}
2626
protected override void Write(HtmlRenderer renderer, EnhancedCodeBlock block)
2727
{
28-
var callOuts = block.CallOuts ?? [];
28+
var callOuts = block.UniqueCallOuts;
2929

3030
var slice = Code.Create(new CodeViewModel
3131
{
@@ -46,7 +46,7 @@ protected override void Write(HtmlRenderer renderer, EnhancedCodeBlock block)
4646
var siblingBlock = block.Parent[index + 1];
4747
if (siblingBlock is not ListBlock)
4848
block.EmitError("Code block with annotations is not followed by a list");
49-
if (siblingBlock is ListBlock l && l.Count != callOuts.Count)
49+
if (siblingBlock is ListBlock l && l.Count < callOuts.Count)
5050
{
5151
block.EmitError(
5252
$"Code block has {callOuts.Count} callouts but the following list only has {l.Count}");
@@ -84,7 +84,7 @@ protected override void Write(HtmlRenderer renderer, EnhancedCodeBlock block)
8484
else if (block.InlineAnnotations)
8585
{
8686
renderer.WriteLine("<ol class=\"code-callouts\">");
87-
foreach (var c in block.CallOuts ?? [])
87+
foreach (var c in block.UniqueCallOuts)
8888
{
8989
renderer.WriteLine("<li>");
9090
renderer.WriteLine(c.Text);

src/Elastic.Markdown/Myst/CodeBlocks/EnhancedCodeBlockParser.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,14 @@ public override bool Close(BlockProcessor processor, Block block)
172172

173173
callOutIndex++;
174174
var callout = span.Slice(match.Index + startIndex, match.Length - startIndex);
175+
var index = callOutIndex;
176+
if (!inlineCodeAnnotation && int.TryParse(callout.Trim(['<', '>']), out index))
177+
{
178+
179+
}
175180
return new CallOut
176181
{
177-
Index = callOutIndex,
182+
Index = index,
178183
Text = callout.TrimStart('/').TrimStart('#').TrimStart().ToString(),
179184
InlineCodeAnnotation = inlineCodeAnnotation,
180185
SliceStart = startIndex,

tests/Elastic.Markdown.Tests/CodeBlocks/CallOutTests.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,35 @@ public void RequiresContentToFollow() => Collector.Diagnostics.Should().HaveCoun
117117
.And.OnlyContain(c => c.Message.StartsWith("Code block has 2 callouts but the following list only has 1"));
118118
}
119119

120+
public class ClassicCallOutsReuseHighlights(ITestOutputHelper output) : CodeBlockCallOutTests(output, "csharp",
121+
"""
122+
var x = 1; <1>
123+
var y = x - 2; <2>
124+
var z = y - 2; <2>
125+
""",
126+
"""
127+
1. The first
128+
2. The second appears twice
129+
"""
130+
131+
)
132+
{
133+
[Fact]
134+
public void SeesTwoUniqueCallouts() => Block!.UniqueCallOuts
135+
.Should().NotBeNullOrEmpty()
136+
.And.HaveCount(2)
137+
.And.OnlyContain(c => c.Text.StartsWith("<"));
138+
139+
[Fact]
140+
public void ParsesAllForLineInformation() => Block!.CallOuts
141+
.Should().NotBeNullOrEmpty()
142+
.And.HaveCount(3)
143+
.And.OnlyContain(c => c.Text.StartsWith("<"));
144+
145+
[Fact]
146+
public void RequiresContentToFollow() => Collector.Diagnostics.Should().BeEmpty();
147+
}
148+
120149
public class ClassicCallOutWithTheRightListItems(ITestOutputHelper output) : CodeBlockCallOutTests(output, "csharp",
121150
"""
122151
var x = 1; <1>

0 commit comments

Comments
 (0)