Skip to content

Commit 90aba87

Browse files
committed
Fix callouts on api headers
1 parent 6a3abf6 commit 90aba87

File tree

5 files changed

+63
-16
lines changed

5 files changed

+63
-16
lines changed

docs/testing/index.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ The files in this directory are used for testing purposes. Do not edit these fil
3333
```
3434

3535
```console
36-
PUT metricbeat-2016.05.30/_doc/1?refresh
36+
PUT metricbeat-2016.05.30/_doc/1?refresh <1>
3737
{"system.cpu.idle.pct": 0.908}
38-
PUT metricbeat-2016.05.31/_doc/1?refresh
38+
PUT metricbeat-2016.05.31/_doc/1?refresh <2>
3939
{"system.cpu.idle.pct": 0.105}
4040
```
41+
1. test 1
42+
2. test 2
4143

4244
```console
4345
POST _reindex

src/Elastic.Markdown/Myst/CodeBlocks/Code.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
{
1414
@foreach (var segment in Model.ApiSegments)
1515
{
16-
<code class="language-apiheader">@segment.Header</code>
16+
<code class="language-apiheader">@segment.Header@(Model.RenderConsoleCallouts(segment.LineNumber))</code>
1717
@if (segment.ContentLines.Count > 0)
1818
{
1919
<code class="language-json">@string.Join("\n", segment.ContentLines)</code>

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,21 @@ public HtmlString RenderBlock()
2929
DocumentationObjectPoolProvider.HtmlRendererPool.Return(subscription);
3030
return new HtmlString(result);
3131
}
32+
33+
public HtmlString RenderConsoleCallouts(int lineNumber)
34+
{
35+
if (EnhancedCodeBlock?.CallOuts == null)
36+
return HtmlString.Empty;
37+
38+
var callouts = EnhancedCodeBlock.CallOuts.Where(c => c.Line == lineNumber);
39+
if (!callouts.Any())
40+
return HtmlString.Empty;
41+
42+
var html = new System.Text.StringBuilder();
43+
foreach (var callout in callouts)
44+
{
45+
_ = html.Append($"<span class=\"code-callout\" data-index=\"{callout.Index}\"></span>");
46+
}
47+
return new HtmlString(html.ToString());
48+
}
3249
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class ApiSegment
1414
{
1515
public string Header { get; set; } = "";
1616
public List<string> ContentLines { get; set; } = [];
17+
public int LineNumber { get; set; }
1718
}
1819

1920
public class EnhancedCodeBlock(BlockParser parser, ParserContext context)

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

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,14 +329,17 @@ private static void ProcessConsoleCodeBlock(
329329
// Check if this line is an HTTP verb (API call header)
330330
if (IsHttpVerb(lineText))
331331
{
332-
// If we have a current segment with content, save it
333332
if (!string.IsNullOrEmpty(currentSegment.Header) || currentSegment.ContentLines.Count > 0)
334333
codeBlock.ApiSegments.Add(currentSegment);
335334

336-
// Start a new segment
335+
// Process callouts before creating the segment to capture them on the original line
336+
if (codeBlockArgs.UseCallouts && codeBlock.OpeningFencedCharCount <= 3)
337+
ProcessCalloutsForLine(span, codeBlock, ref callOutIndex, originatingLine);
338+
337339
currentSegment = new ApiSegment
338340
{
339-
Header = lineText
341+
Header = lineText,
342+
LineNumber = originatingLine
340343
};
341344

342345
// Clear this line from the content since it's now a header
@@ -345,14 +348,12 @@ private static void ProcessConsoleCodeBlock(
345348
}
346349
else
347350
{
348-
// This is content for the current segment
349351
if (!string.IsNullOrEmpty(lineText.Trim()))
350352
currentSegment.ContentLines.Add(lineText);
351-
}
352353

353-
// Process callouts if enabled
354-
if (codeBlockArgs.UseCallouts && codeBlock.OpeningFencedCharCount <= 3)
355-
ProcessCalloutsForLine(span, codeBlock, ref callOutIndex, originatingLine);
354+
if (codeBlockArgs.UseCallouts && codeBlock.OpeningFencedCharCount <= 3)
355+
ProcessCalloutsForLine(span, codeBlock, ref callOutIndex, originatingLine);
356+
}
356357
}
357358

358359
// Add the last segment if it has content
@@ -413,12 +414,38 @@ private static void ProcessCalloutPostProcessing(StringLineGroup lines, Enhanced
413414
return acc;
414415
});
415416

416-
foreach (var callout in callouts.Values)
417+
// Console code blocks use ApiSegments for rendering, so we need to update headers directly
418+
// Note: console language gets converted to "json" for syntax highlighting
419+
if ((codeBlock.Language == "json" || codeBlock.Language == "console") && codeBlock.ApiSegments.Count > 0)
417420
{
418-
var line = lines.Lines[callout.Line - 1];
419-
var newSpan = line.Slice.AsSpan()[..callout.SliceStart];
420-
var s = new StringSlice(newSpan.ToString());
421-
lines.Lines[callout.Line - 1] = new StringLine(ref s);
421+
foreach (var callout in callouts.Values)
422+
{
423+
foreach (var segment in codeBlock.ApiSegments)
424+
{
425+
var calloutPattern = $"<{callout.Index}>";
426+
if (segment.Header.Contains(calloutPattern))
427+
{
428+
segment.Header = segment.Header.Replace(calloutPattern, "").Trim();
429+
break;
430+
}
431+
}
432+
}
433+
}
434+
else
435+
{
436+
foreach (var callout in callouts.Values)
437+
{
438+
var line = lines.Lines[callout.Line - 1];
439+
var span = line.Slice.AsSpan();
440+
441+
// Skip callouts on cleared lines to avoid ArgumentOutOfRangeException
442+
if (span.Length == 0 || callout.SliceStart >= span.Length)
443+
continue;
444+
445+
var newSpan = span[..callout.SliceStart];
446+
var s = new StringSlice(newSpan.ToString());
447+
lines.Lines[callout.Line - 1] = new StringLine(ref s);
448+
}
422449
}
423450
}
424451
}

0 commit comments

Comments
 (0)