Initial commit
This commit is contained in:
@@ -0,0 +1,271 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.QuickInfo;
|
||||
using System.Collections.Immutable;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace RobotNet10.ScriptEditor.Helpers;
|
||||
|
||||
public enum MarkdownFormat
|
||||
{
|
||||
Default,
|
||||
Italicize,
|
||||
FirstLineAsCSharp,
|
||||
FirstLineDefaultRestCSharp,
|
||||
AllTextAsCSharp
|
||||
}
|
||||
|
||||
public static class MarkdownHelpers
|
||||
{
|
||||
private static readonly Regex EscapeRegex = new("([\\\\`\\*_\\{\\}\\[\\]\\(\\)#+\\-\\.!])", RegexOptions.Compiled);
|
||||
|
||||
private const string ContainerStart = "ContainerStart";
|
||||
|
||||
private const string ContainerEnd = "ContainerEnd";
|
||||
|
||||
public static string Escape(string markdown) => string.IsNullOrEmpty(markdown) ? string.Empty : EscapeRegex.Replace(markdown, "\\$1");
|
||||
|
||||
public static void AppendSection(this StringBuilder builder, QuickInfoSection section, MarkdownFormat format, ref bool lastLineBreak)
|
||||
{
|
||||
if (!lastLineBreak && section.TaggedParts.Length > 0 && section.TaggedParts[0].Tag != "LineBreak")
|
||||
{
|
||||
builder.Append("\n\n");
|
||||
}
|
||||
MarkdownHelpers.TaggedTextToMarkdown(section.TaggedParts, builder, "\n", format, out lastLineBreak);
|
||||
}
|
||||
|
||||
public static void TaggedTextToMarkdown(ImmutableArray<TaggedText> taggedParts, StringBuilder stringBuilder, string newLine, MarkdownFormat markdownFormat, out bool endedWithLineBreak)
|
||||
{
|
||||
bool isInCodeBlock = false;
|
||||
bool brokeLine = true;
|
||||
bool afterFirstLine = false;
|
||||
if (markdownFormat == MarkdownFormat.Italicize)
|
||||
{
|
||||
stringBuilder.Append('_');
|
||||
}
|
||||
|
||||
int num = 0;
|
||||
while (num < taggedParts.Length)
|
||||
{
|
||||
TaggedText taggedText = taggedParts[num];
|
||||
bool flag;
|
||||
if (brokeLine && markdownFormat != MarkdownFormat.Italicize)
|
||||
{
|
||||
brokeLine = false;
|
||||
if (!afterFirstLine)
|
||||
{
|
||||
if (markdownFormat != MarkdownFormat.FirstLineAsCSharp)
|
||||
{
|
||||
goto IL_00a2;
|
||||
}
|
||||
|
||||
flag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (markdownFormat != MarkdownFormat.FirstLineDefaultRestCSharp)
|
||||
{
|
||||
goto IL_00a2;
|
||||
}
|
||||
|
||||
flag = true;
|
||||
}
|
||||
|
||||
goto IL_00bf;
|
||||
}
|
||||
|
||||
goto IL_0279;
|
||||
IL_00a2:
|
||||
flag = markdownFormat == MarkdownFormat.AllTextAsCSharp;
|
||||
goto IL_00bf;
|
||||
IL_0279:
|
||||
switch (taggedText.Tag)
|
||||
{
|
||||
case "Text":
|
||||
if (!isInCodeBlock)
|
||||
{
|
||||
addText(taggedText.Text);
|
||||
break;
|
||||
}
|
||||
|
||||
endBlock();
|
||||
addText(taggedText.Text);
|
||||
break;
|
||||
case "Space":
|
||||
if (isInCodeBlock)
|
||||
{
|
||||
if (indexIsTag(num + 1, ["Text"]))
|
||||
{
|
||||
endBlock();
|
||||
}
|
||||
|
||||
addText(taggedText.Text);
|
||||
break;
|
||||
}
|
||||
|
||||
goto case "Punctuation";
|
||||
case "Punctuation":
|
||||
addText(taggedText.Text);
|
||||
break;
|
||||
case ContainerStart:
|
||||
addNewline();
|
||||
addText(taggedText.Text);
|
||||
break;
|
||||
case ContainerEnd:
|
||||
addNewline();
|
||||
break;
|
||||
case "LineBreak":
|
||||
if (stringBuilder.Length != 0 && !indexIsTag(num + 1, [ContainerStart, ContainerEnd]) && num + 1 != taggedParts.Length)
|
||||
{
|
||||
addNewline();
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
if (!isInCodeBlock)
|
||||
{
|
||||
isInCodeBlock = true;
|
||||
stringBuilder.Append('`');
|
||||
}
|
||||
|
||||
stringBuilder.Append(taggedText.Text);
|
||||
brokeLine = false;
|
||||
break;
|
||||
}
|
||||
|
||||
num++;
|
||||
continue;
|
||||
IL_00bf:
|
||||
bool flag2 = flag;
|
||||
if (!flag2)
|
||||
{
|
||||
for (int j = num; j < taggedParts.Length; flag2 = true, j++)
|
||||
{
|
||||
switch (taggedParts[j].Tag)
|
||||
{
|
||||
case "Text":
|
||||
flag2 = false;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
case ContainerStart:
|
||||
case ContainerEnd:
|
||||
case "LineBreak":
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flag2 = !indexIsTag(num,
|
||||
[
|
||||
ContainerStart,
|
||||
ContainerEnd,
|
||||
"LineBreak"
|
||||
]);
|
||||
}
|
||||
|
||||
if (flag2)
|
||||
{
|
||||
afterFirstLine = true;
|
||||
stringBuilder.Append("```csharp");
|
||||
stringBuilder.Append(newLine);
|
||||
while (true)
|
||||
{
|
||||
if (num < taggedParts.Length)
|
||||
{
|
||||
taggedText = taggedParts[num];
|
||||
if (taggedText.Tag == ContainerStart || taggedText.Tag == ContainerEnd || taggedText.Tag == "LineBreak")
|
||||
{
|
||||
stringBuilder.Append(newLine);
|
||||
if (markdownFormat != MarkdownFormat.AllTextAsCSharp && markdownFormat != MarkdownFormat.FirstLineDefaultRestCSharp)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stringBuilder.Append(taggedText.Text);
|
||||
}
|
||||
|
||||
num++;
|
||||
continue;
|
||||
}
|
||||
|
||||
stringBuilder.Append(newLine);
|
||||
stringBuilder.Append("```");
|
||||
endedWithLineBreak = false;
|
||||
return;
|
||||
}
|
||||
|
||||
stringBuilder.Append("```");
|
||||
}
|
||||
|
||||
goto IL_0279;
|
||||
}
|
||||
|
||||
if (isInCodeBlock)
|
||||
{
|
||||
endBlock();
|
||||
}
|
||||
|
||||
if (!brokeLine && markdownFormat == MarkdownFormat.Italicize)
|
||||
{
|
||||
stringBuilder.Append('_');
|
||||
}
|
||||
|
||||
endedWithLineBreak = brokeLine;
|
||||
void addNewline()
|
||||
{
|
||||
if (isInCodeBlock)
|
||||
{
|
||||
endBlock();
|
||||
}
|
||||
|
||||
if (markdownFormat == MarkdownFormat.Italicize)
|
||||
{
|
||||
stringBuilder.Append('_');
|
||||
}
|
||||
|
||||
stringBuilder.Append(newLine);
|
||||
stringBuilder.Append(newLine);
|
||||
brokeLine = true;
|
||||
if (markdownFormat == MarkdownFormat.Italicize)
|
||||
{
|
||||
stringBuilder.Append('_');
|
||||
}
|
||||
}
|
||||
|
||||
void addText(string text)
|
||||
{
|
||||
brokeLine = false;
|
||||
afterFirstLine = true;
|
||||
if (!isInCodeBlock)
|
||||
{
|
||||
text = Escape(text);
|
||||
}
|
||||
|
||||
stringBuilder.Append(text);
|
||||
}
|
||||
|
||||
void endBlock()
|
||||
{
|
||||
stringBuilder.Append('`');
|
||||
isInCodeBlock = false;
|
||||
}
|
||||
|
||||
bool indexIsTag(int i, string[] tags)
|
||||
{
|
||||
if (i < taggedParts.Length)
|
||||
{
|
||||
return tags.Contains(taggedParts[i].Tag);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user