Skip to content

Commit 69fdd21

Browse files
authored
Fix indentation when code block is in a list (#345)
* Fix indentation when code block is in a list * Format
1 parent f2b80ec commit 69fdd21

File tree

2 files changed

+85
-2
lines changed

2 files changed

+85
-2
lines changed

docs/testing/index.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,29 @@ The files in this directory are used for testing purposes. Do not edit these fil
55

66
###### [#synthetics-config-file]
77

8-
% [Non Existing Link](./non-existing.md)
8+
% [Non Existing Link](./non-existing.md)
9+
10+
```json
11+
{
12+
"key": "value"
13+
}
14+
```
15+
16+
```json
17+
{
18+
"key": "value"
19+
}
20+
```
21+
22+
1. this is a list
23+
```json
24+
{
25+
"key": "value"
26+
}
27+
```
28+
1. this is a sub-list
29+
```json
30+
{
31+
"key": "value"
32+
}
33+
```

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

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Elastic.Markdown.Diagnostics;
66
using Elastic.Markdown.Myst.Directives;
77
using Elastic.Markdown.Slices.Directives;
8+
using Markdig.Helpers;
89
using Markdig.Renderers;
910
using Markdig.Renderers.Html;
1011
using Markdig.Syntax;
@@ -14,15 +15,72 @@ namespace Elastic.Markdown.Myst.CodeBlocks;
1415

1516
public class EnhancedCodeBlockHtmlRenderer : HtmlObjectRenderer<EnhancedCodeBlock>
1617
{
18+
private const int TabWidth = 4;
1719

1820
private static void RenderRazorSlice<T>(RazorSlice<T> slice, HtmlRenderer renderer, EnhancedCodeBlock block)
1921
{
2022
var html = slice.RenderAsync().GetAwaiter().GetResult();
2123
var blocks = html.Split("[CONTENT]", 2, StringSplitOptions.RemoveEmptyEntries);
2224
renderer.Write(blocks[0]);
23-
renderer.WriteLeafRawLines(block, true, true, false);
25+
RenderCodeBlockLines(renderer, block);
2426
renderer.Write(blocks[1]);
2527
}
28+
29+
/// <summary>
30+
/// Renders the code block lines while also removing the common indentation level.
31+
/// Required because EnableTrackTrivia preserves extra indentation.
32+
/// </summary>
33+
private static void RenderCodeBlockLines(HtmlRenderer renderer, EnhancedCodeBlock block)
34+
{
35+
var commonIndent = GetCommonIndent(block);
36+
for (var i = 0; i < block.Lines.Count; i++)
37+
{
38+
var line = block.Lines.Lines[i];
39+
var slice = line.Slice;
40+
var indent = CountIndentation(slice);
41+
if (indent >= commonIndent)
42+
slice.Start += commonIndent;
43+
RenderCodeBlockLine(renderer, block, slice, i);
44+
}
45+
}
46+
47+
private static void RenderCodeBlockLine(HtmlRenderer renderer, EnhancedCodeBlock block, StringSlice slice, int i)
48+
{
49+
renderer.WriteEscape(slice);
50+
renderer.WriteLine();
51+
}
52+
53+
private static int GetCommonIndent(EnhancedCodeBlock block)
54+
{
55+
var commonIndent = int.MaxValue;
56+
for (var i = 0; i < block.Lines.Count; i++)
57+
{
58+
var line = block.Lines.Lines[i].Slice;
59+
if (line.IsEmptyOrWhitespace())
60+
continue;
61+
var indent = CountIndentation(line);
62+
commonIndent = Math.Min(commonIndent, indent);
63+
}
64+
return commonIndent;
65+
}
66+
67+
68+
private static int CountIndentation(StringSlice slice)
69+
{
70+
var indentCount = 0;
71+
for (var i = slice.Start; i <= slice.End; i++)
72+
{
73+
var c = slice.Text[i];
74+
if (c == ' ')
75+
indentCount++;
76+
else if (c == '\t')
77+
indentCount += TabWidth;
78+
else
79+
break;
80+
}
81+
return indentCount;
82+
}
83+
2684
protected override void Write(HtmlRenderer renderer, EnhancedCodeBlock block)
2785
{
2886
var callOuts = block.UniqueCallOuts;

0 commit comments

Comments
 (0)