mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-06-27 19:16:27 +00:00
Optimized
This commit is contained in:
parent
56805874c2
commit
2c54df46b9
@ -1,4 +1,5 @@
|
|||||||
using Markdig;
|
using Markdig;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace AIStudio.Tools;
|
namespace AIStudio.Tools;
|
||||||
|
|
||||||
@ -32,51 +33,117 @@ public static class Markdown
|
|||||||
if (string.IsNullOrWhiteSpace(value))
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
||||||
var normalized = value.Replace("\r\n", "\n");
|
return RemoveSharedIndentation(value.AsSpan());
|
||||||
var lines = normalized.Split('\n');
|
|
||||||
|
|
||||||
var firstContentLine = 0;
|
|
||||||
while (firstContentLine < lines.Length && string.IsNullOrWhiteSpace(lines[firstContentLine]))
|
|
||||||
firstContentLine++;
|
|
||||||
|
|
||||||
var lastContentLine = lines.Length - 1;
|
|
||||||
while (lastContentLine >= firstContentLine && string.IsNullOrWhiteSpace(lines[lastContentLine]))
|
|
||||||
lastContentLine--;
|
|
||||||
|
|
||||||
if (firstContentLine > lastContentLine)
|
|
||||||
return string.Empty;
|
|
||||||
|
|
||||||
var commonIndentation = int.MaxValue;
|
|
||||||
for (var i = firstContentLine; i <= lastContentLine; i++)
|
|
||||||
{
|
|
||||||
var line = lines[i];
|
|
||||||
if (string.IsNullOrWhiteSpace(line))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var indentation = 0;
|
|
||||||
while (indentation < line.Length && char.IsWhiteSpace(line[indentation]))
|
|
||||||
indentation++;
|
|
||||||
|
|
||||||
commonIndentation = Math.Min(commonIndentation, indentation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string RemoveSharedIndentation(ReadOnlySpan<char> value)
|
||||||
|
{
|
||||||
|
var firstContentLineStart = -1;
|
||||||
|
var lastContentLineStart = -1;
|
||||||
|
var lastContentLineEnd = -1;
|
||||||
|
var commonIndentation = int.MaxValue;
|
||||||
|
var position = 0;
|
||||||
|
|
||||||
|
while (TryGetNextLine(value, position, out var lineStart, out var currentLineEnd, out var nextPosition))
|
||||||
|
{
|
||||||
|
var lineContent = value[lineStart..currentLineEnd];
|
||||||
|
if (IsWhiteSpace(lineContent))
|
||||||
|
{
|
||||||
|
position = nextPosition;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstContentLineStart < 0)
|
||||||
|
firstContentLineStart = lineStart;
|
||||||
|
|
||||||
|
lastContentLineStart = lineStart;
|
||||||
|
lastContentLineEnd = currentLineEnd;
|
||||||
|
commonIndentation = Math.Min(commonIndentation, CountIndentation(lineContent));
|
||||||
|
position = nextPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstContentLineStart < 0)
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
if (commonIndentation == int.MaxValue)
|
if (commonIndentation == int.MaxValue)
|
||||||
commonIndentation = 0;
|
commonIndentation = 0;
|
||||||
|
|
||||||
for (var i = firstContentLine; i <= lastContentLine; i++)
|
var builder = new StringBuilder(lastContentLineEnd - firstContentLineStart);
|
||||||
|
var shouldAppendLineBreak = false;
|
||||||
|
position = firstContentLineStart;
|
||||||
|
|
||||||
|
while (TryGetNextLine(value, position, out var lineStart, out var lineEnd, out var nextPosition))
|
||||||
{
|
{
|
||||||
var line = lines[i];
|
var lineContent = value[lineStart..lineEnd];
|
||||||
if (string.IsNullOrWhiteSpace(line))
|
|
||||||
|
if (shouldAppendLineBreak)
|
||||||
|
builder.Append('\n');
|
||||||
|
|
||||||
|
if (IsWhiteSpace(lineContent))
|
||||||
|
shouldAppendLineBreak = true;
|
||||||
|
else if (lineContent.Length > commonIndentation)
|
||||||
{
|
{
|
||||||
lines[i] = string.Empty;
|
builder.Append(lineContent[commonIndentation..]);
|
||||||
|
shouldAppendLineBreak = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
shouldAppendLineBreak = true;
|
||||||
|
|
||||||
|
if (lineStart == lastContentLineStart)
|
||||||
|
break;
|
||||||
|
|
||||||
|
position = nextPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsWhiteSpace(ReadOnlySpan<char> value)
|
||||||
|
{
|
||||||
|
foreach (var character in value)
|
||||||
|
{
|
||||||
|
if (!char.IsWhiteSpace(character))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int CountIndentation(ReadOnlySpan<char> value)
|
||||||
|
{
|
||||||
|
var indentation = 0;
|
||||||
|
while (indentation < value.Length && char.IsWhiteSpace(value[indentation]))
|
||||||
|
indentation++;
|
||||||
|
|
||||||
|
return indentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryGetNextLine(ReadOnlySpan<char> value, int position, out int lineStart, out int lineEnd, out int nextPosition)
|
||||||
|
{
|
||||||
|
if (position > value.Length)
|
||||||
|
{
|
||||||
|
lineStart = 0;
|
||||||
|
lineEnd = 0;
|
||||||
|
nextPosition = position;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineStart = position;
|
||||||
|
for (var i = position; i < value.Length; i++)
|
||||||
|
{
|
||||||
|
if (value[i] != '\n')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
lineEnd = i > lineStart && value[i - 1] == '\r'
|
||||||
|
? i - 1
|
||||||
|
: i;
|
||||||
|
|
||||||
|
nextPosition = i + 1;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
lines[i] = line.Length <= commonIndentation
|
lineEnd = value.Length;
|
||||||
? string.Empty
|
nextPosition = value.Length + 1;
|
||||||
: line[commonIndentation..];
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
return string.Join('\n', lines[firstContentLine..(lastContentLine + 1)]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user