Skip to content
This repository was archived by the owner on Dec 21, 2023. It is now read-only.

Commit 53e14cc

Browse files
committed
CodeBlock: Replace trimming implementation
1 parent 258c82d commit 53e14cc

File tree

1 file changed

+28
-29
lines changed

1 file changed

+28
-29
lines changed
Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Linq;
3+
using System.Text.RegularExpressions;
44
using System.Threading.Tasks;
55
using Microsoft.AspNetCore.Html;
66
using Microsoft.AspNetCore.Mvc.Rendering;
@@ -17,53 +17,52 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu
1717
{
1818
output.TagName = "pre";
1919

20-
var content = await output.GetChildContentAsync();
21-
var innerHtml = content.GetContent().Trim('\n');
22-
var body = TrimPreceding(innerHtml, ' ');
20+
var rawContent = (await output.GetChildContentAsync()).GetContent();
21+
var body = TrimBaseIndentation(rawContent);
2322

2423
var code = new TagBuilder("code");
2524
code.AddCssClass($"language-{Language}");
26-
code.InnerHtml.SetHtmlContent(body);
25+
code.InnerHtml.SetHtmlContent($"{body}\n");
2726

2827
output.Content.SetHtmlContent(code);
2928
}
3029

31-
private string TrimPreceding(string value, char character)
30+
private string TrimBaseIndentation(string content)
3231
{
33-
var lines = value.Split(Environment.NewLine);
34-
var preceding = CountPreceding(lines, character);
35-
var trimmedLines = from line in lines
36-
select TrimPrecedingLine(line, character, preceding);
32+
var endsTrimmedContent = TrimStartRegex.Replace(content.TrimEnd(), "$1", 1);
33+
var lines = endsTrimmedContent.Split(Environment.NewLine);
34+
var baseIndentationLength = CountIndentation(lines[0]);
3735

38-
return string.Join(Environment.NewLine, trimmedLines);
39-
}
40-
41-
private int CountPreceding(IEnumerable<string> lines, char leadingCharacter)
42-
{
43-
foreach (var line in lines)
36+
for (int i = 0; i != lines.Length; i++)
4437
{
45-
// Make sure that the line actually starts with the leading character
46-
if (line.StartsWith(leadingCharacter) == false)
47-
continue;
38+
var line = lines[i];
4839

49-
// Determine last index of leading character, return if something else is found
50-
for (var i = 0; i < line.Length; i++)
40+
var indentationLength = CountIndentation(line);
41+
if (indentationLength < baseIndentationLength)
5142
{
52-
var character = line[i];
53-
if (character != leadingCharacter)
54-
return i;
43+
if (indentationLength == line.Length)
44+
{
45+
lines[i] = "";
46+
continue;
47+
}
48+
49+
return endsTrimmedContent;
5550
}
5651

57-
// Assume that this line is the template for trimming
58-
return line.Length;
52+
lines[i] = line.Substring(Math.Min(baseIndentationLength, line.Length)).TrimEnd();
5953
}
6054

61-
throw new ArgumentException("No lines match the target leading character.", nameof(lines));
55+
return String.Join(Environment.NewLine, lines);
6256
}
6357

64-
private string TrimPrecedingLine(string line, char character, int amount)
58+
private static Regex TrimStartRegex = new Regex("^\\s*\n(\\s*)(?=\\S*)", RegexOptions.Compiled);
59+
60+
private int CountIndentation(string line)
6561
{
66-
return line.StartsWith(character) ? new string(line.Skip(amount).ToArray()) : line;
62+
for (var i = 0; i < line.Length; i++)
63+
if (!char.IsWhiteSpace(line[i]))
64+
return i;
65+
return int.MaxValue;
6766
}
6867
}
6968
}

0 commit comments

Comments
 (0)