Initial commit
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace RobotNet10.ScriptEditor.Helpers.Monaco.Documentation;
|
||||
|
||||
public class DocumentationComment(
|
||||
string summaryText = "",
|
||||
DocumentationItem[]? typeParamElements = null,
|
||||
DocumentationItem[]? paramElements = null,
|
||||
string returnsText = "",
|
||||
string remarksText = "",
|
||||
string exampleText = "",
|
||||
string valueText = "",
|
||||
DocumentationItem[]? exception = null)
|
||||
{
|
||||
public string SummaryText { get; } = summaryText;
|
||||
public DocumentationItem[] TypeParamElements { get; } = typeParamElements ?? [];
|
||||
public DocumentationItem[] ParamElements { get; } = paramElements ?? [];
|
||||
public string ReturnsText { get; } = returnsText;
|
||||
public string RemarksText { get; } = remarksText;
|
||||
public string ExampleText { get; } = exampleText;
|
||||
public string ValueText { get; } = valueText;
|
||||
public DocumentationItem[] Exception { get; } = exception ?? [];
|
||||
|
||||
public static DocumentationComment? From(string xmlDocumentation, string lineEnding)
|
||||
{
|
||||
if (string.IsNullOrEmpty(xmlDocumentation))
|
||||
return Empty;
|
||||
|
||||
var reader = new StringReader("<docroot>" + xmlDocumentation + "</docroot>");
|
||||
var summaryText = new StringBuilder();
|
||||
var typeParamElements = new List<DocumentationItemBuilder>();
|
||||
var paramElements = new List<DocumentationItemBuilder>();
|
||||
var returnsText = new StringBuilder();
|
||||
var remarksText = new StringBuilder();
|
||||
var exampleText = new StringBuilder();
|
||||
var valueText = new StringBuilder();
|
||||
var exception = new List<DocumentationItemBuilder>();
|
||||
|
||||
using (var xml = XmlReader.Create(reader))
|
||||
{
|
||||
try
|
||||
{
|
||||
xml.Read();
|
||||
string? elementName = null;
|
||||
StringBuilder? currentSectionBuilder = null;
|
||||
do
|
||||
{
|
||||
if (xml.NodeType == XmlNodeType.Element)
|
||||
{
|
||||
elementName = xml.Name.ToLowerInvariant();
|
||||
switch (elementName)
|
||||
{
|
||||
case "filterpriority":
|
||||
xml.Skip();
|
||||
break;
|
||||
case "remarks":
|
||||
currentSectionBuilder = remarksText;
|
||||
break;
|
||||
case "example":
|
||||
currentSectionBuilder = exampleText;
|
||||
break;
|
||||
case "exception":
|
||||
DocumentationItemBuilder exceptionInstance = new(GetCref(xml["cref"]).TrimEnd());
|
||||
currentSectionBuilder = exceptionInstance.Documentation;
|
||||
exception.Add(exceptionInstance);
|
||||
break;
|
||||
case "returns":
|
||||
currentSectionBuilder = returnsText;
|
||||
break;
|
||||
case "summary":
|
||||
currentSectionBuilder = summaryText;
|
||||
break;
|
||||
case "see":
|
||||
if (currentSectionBuilder is null) continue;
|
||||
currentSectionBuilder.Append(GetCref(xml["cref"]));
|
||||
currentSectionBuilder.Append(xml["langword"]);
|
||||
break;
|
||||
case "seealso":
|
||||
if (currentSectionBuilder is null) continue;
|
||||
currentSectionBuilder.Append("See also: ");
|
||||
currentSectionBuilder.Append(GetCref(xml["cref"]));
|
||||
break;
|
||||
case "paramref":
|
||||
if (currentSectionBuilder is null) continue;
|
||||
currentSectionBuilder.Append(xml["name"]);
|
||||
currentSectionBuilder.Append(' ');
|
||||
break;
|
||||
case "param":
|
||||
|
||||
DocumentationItemBuilder paramInstance = new(TrimMultiLineString(xml["name"] ?? "", lineEnding));
|
||||
currentSectionBuilder = paramInstance.Documentation;
|
||||
paramElements.Add(paramInstance);
|
||||
break;
|
||||
case "typeparamref":
|
||||
if (currentSectionBuilder is null) continue;
|
||||
currentSectionBuilder.Append(xml["name"]);
|
||||
currentSectionBuilder.Append(' ');
|
||||
break;
|
||||
case "typeparam":
|
||||
DocumentationItemBuilder typeParamInstance = new(TrimMultiLineString(xml["name"] ?? "", lineEnding));
|
||||
currentSectionBuilder = typeParamInstance.Documentation;
|
||||
typeParamElements.Add(typeParamInstance);
|
||||
break;
|
||||
case "value":
|
||||
currentSectionBuilder = valueText;
|
||||
break;
|
||||
case "br":
|
||||
case "para":
|
||||
if (currentSectionBuilder is null) continue;
|
||||
currentSectionBuilder.Append(lineEnding);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (xml.NodeType == XmlNodeType.Text && currentSectionBuilder != null)
|
||||
{
|
||||
if (elementName == "code")
|
||||
{
|
||||
currentSectionBuilder.Append(xml.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentSectionBuilder.Append(TrimMultiLineString(xml.Value, lineEnding));
|
||||
}
|
||||
}
|
||||
} while (xml.Read());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new DocumentationComment(
|
||||
summaryText.ToString(),
|
||||
[.. typeParamElements.Select(s => s.ConvertToDocumentedObject())],
|
||||
[.. paramElements.Select(s => s.ConvertToDocumentedObject())],
|
||||
returnsText.ToString(),
|
||||
remarksText.ToString(),
|
||||
exampleText.ToString(),
|
||||
valueText.ToString(),
|
||||
[.. exception.Select(s => s.ConvertToDocumentedObject())]);
|
||||
}
|
||||
|
||||
private static string TrimMultiLineString(string input, string lineEnding)
|
||||
{
|
||||
var lines = input.Split(separator, StringSplitOptions.RemoveEmptyEntries);
|
||||
return string.Join(lineEnding, lines.Select(l => TrimStartRetainingSingleLeadingSpace(l)));
|
||||
}
|
||||
|
||||
private static string GetCref(string? cref)
|
||||
{
|
||||
if (cref == null || cref.Trim().Length == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
if (cref.Length < 2)
|
||||
{
|
||||
return cref;
|
||||
}
|
||||
if (cref.Substring(1, 1) == ":")
|
||||
{
|
||||
return string.Concat(cref.AsSpan(2, cref.Length - 2), " ");
|
||||
}
|
||||
return cref + " ";
|
||||
}
|
||||
|
||||
private static string TrimStartRetainingSingleLeadingSpace(string input)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return string.Empty;
|
||||
if (!char.IsWhiteSpace(input[0]))
|
||||
return input;
|
||||
return $" {input.TrimStart()}";
|
||||
}
|
||||
|
||||
public string GetParameterText(string name)
|
||||
=> Array.Find(ParamElements, parameter => parameter.Name == name)?.Documentation ?? string.Empty;
|
||||
|
||||
public string GetTypeParameterText(string name)
|
||||
=> Array.Find(TypeParamElements, typeParam => typeParam.Name == name)?.Documentation ?? string.Empty;
|
||||
|
||||
public static readonly DocumentationComment Empty = new();
|
||||
private static readonly string[] separator = ["\n", "\r\n"];
|
||||
}
|
||||
|
||||
class DocumentationItemBuilder(string name)
|
||||
{
|
||||
public string Name { get; set; } = name;
|
||||
public StringBuilder Documentation { get; set; } = new StringBuilder();
|
||||
|
||||
public DocumentationItem ConvertToDocumentedObject()
|
||||
{
|
||||
return new DocumentationItem(Name, Documentation.ToString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace RobotNet10.ScriptEditor.Helpers.Monaco.Documentation;
|
||||
|
||||
public class DocumentationItem(string name, string documentation)
|
||||
{
|
||||
public string Name { get; } = name;
|
||||
public string Documentation { get; } = documentation;
|
||||
}
|
||||
Reference in New Issue
Block a user