XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using XFESystem.Documents;

if (args.Length is < 1 or > 2 || args.Length == 2 && args[1] != "--code-reference") throw new ArgumentException("Specify a fresh reference fixture directory and optional --code-reference.");
var output = Path.GetFullPath(args[0]);
if (Directory.Exists(output)) throw new IOException("The reference directory must be new.");
Directory.CreateDirectory(output);
var markdown = WebsiteAssets.ReadText("Fixtures/WebsiteParity.md");
var builder = new DocumentPreviewBuilder(new());
await File.WriteAllTextAsync(Path.Combine(output, "Fixture.md"), markdown);
await File.WriteAllTextAsync(Path.Combine(output, "Dark.html"), builder.MarkdownWeb(markdown, "Website parity", dark: true).Html);
await File.WriteAllTextAsync(Path.Combine(output, "Light.html"), builder.MarkdownWeb(markdown, "Website parity", dark: false).Html);
await File.WriteAllTextAsync(Path.Combine(output, "SourceManifest.json"), WebsiteAssets.ReadText("Exact/SourceManifest.json"));
if (args.Length == 2)
{
    string? root = AppContext.BaseDirectory;
    while (root is not null && !File.Exists(Path.Combine(root, "XFESystem.slnx"))) root = Path.GetDirectoryName(root);
    if (root is null) throw new InvalidOperationException("Cannot identify the production sample source.");
    var sourcePath = Path.Combine(root, "Source", "XFESystem.Browser", "BrowserResourceSource.cs");
    var sourceBytes = await File.ReadAllBytesAsync(sourcePath);
    var sourceText = Encoding.UTF8.GetString(sourceBytes);
    var literal = Regex.Match(sourceText, @"else if\(!globalThis\.xfeMonacoFileMode\)xfeMonacoEditor\.setValue\(language==='csharp'\?'((?:\\.|[^'\\])*)':");
    if (!literal.Success) throw new InvalidOperationException("The production C# sample shape changed; update the explicit reference extractor.");
    // This is a string decoder, not evaluation of either JavaScript or C#.
    var code = DecodeJavaScriptString(literal.Groups[1].Value);
    var codeSha = Convert.ToHexStringLower(SHA256.HashData(Encoding.UTF8.GetBytes(code)));
    await File.WriteAllTextAsync(Path.Combine(output, "CSharpSample.cs"), code);
    await File.WriteAllTextAsync(Path.Combine(output, "CodeDark.html"), builder.CodeWeb(code, "MonacoSample.cs", dark: true).Html);
    await File.WriteAllTextAsync(Path.Combine(output, "CodeLight.html"), builder.CodeWeb(code, "MonacoSample.cs", dark: false).Html);
    await File.WriteAllTextAsync(Path.Combine(output, "CSharpSample.json"), JsonSerializer.Serialize(new
    {
        Kind = "ProductionMonacoDefaultCSharpSample", Component = "WebsiteStaticCSharpCodeBlock",
        SourcePath = sourcePath, SourceSha256 = Convert.ToHexStringLower(SHA256.HashData(sourceBytes)),
        CodeSha256 = codeSha, LineCount = code.Split('\n').Length,
        ExtractedFrom = "xfeMonacoSetLanguage('csharp') default string; source code is not executed"
    }, new JsonSerializerOptions { WriteIndented = true }));
}
var resources = new List<object>();
foreach (var entry in WebsiteAssets.WebResources)
{
    var path = Path.Combine(output, "Assets", entry.AssetName.Replace('/', Path.DirectorySeparatorChar));
    Directory.CreateDirectory(Path.GetDirectoryName(path)!);
    using var stream = WebsiteAssets.Open(entry.AssetName);
    await using var file = File.Create(path);
    await stream.CopyToAsync(file);
    resources.Add(new { entry.UrlPath, entry.AssetName, entry.ContentType });
}
await File.WriteAllTextAsync(Path.Combine(output, "Resources.json"), JsonSerializer.Serialize(resources, new JsonSerializerOptions { WriteIndented = true }));
Console.WriteLine(output);

static string DecodeJavaScriptString(string literal)
{
    var decoded = new StringBuilder();
    for (int index = 0; index < literal.Length; index++)
    {
        char current = literal[index];
        if (current != '\\') { decoded.Append(current); continue; }
        if (++index == literal.Length) throw new FormatException("Incomplete sample string escape.");
        decoded.Append(literal[index] switch
        {
            'n' => '\n', 'r' => '\r', 't' => '\t', 'b' => '\b', 'f' => '\f', 'v' => '\v',
            '\\' => '\\', '\'' => '\'', '"' => '"',
            _ => throw new FormatException("Unsupported sample escape; do not guess or execute it.")
        });
    }
    return decoded.ToString();
}