// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Reflection; using System.Text.Json; using Microsoft.PowerToys.FilePreviewCommon.Monaco.Formatters; namespace Microsoft.PowerToys.FilePreviewCommon { public static class MonacoHelper { /// /// Name of the virtual host /// public const string VirtualHostName = "PowerToysLocalMonaco"; /// /// Formatters applied before rendering the preview /// public static readonly IReadOnlyCollection Formatters = new List { new JsonFormatter(), new XmlFormatter(), }.AsReadOnly(); private static readonly Lazy _monacoDirectory = new(GetRuntimeMonacoDirectory); /// /// Gets the path of the Monaco assets folder. /// public static string MonacoDirectory => _monacoDirectory.Value; private static string GetRuntimeMonacoDirectory() { string exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty; // If the executable is within "WinUI3Apps", correct the path first. if (Path.GetFileName(exePath) == "WinUI3Apps") { exePath = Path.Combine(exePath, ".."); } string monacoPath = Path.Combine(exePath, "Assets", "Monaco"); return Directory.Exists(monacoPath) ? monacoPath : throw new DirectoryNotFoundException($"Monaco assets directory not found at {monacoPath}"); } public static JsonDocument GetLanguages() { JsonDocument languageListDocument; using (StreamReader jsonFileReader = new StreamReader(new FileStream(MonacoDirectory + "\\monaco_languages.json", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { languageListDocument = JsonDocument.Parse(jsonFileReader.ReadToEnd()); jsonFileReader.Close(); } return languageListDocument; } /// /// Converts a file extension to a language monaco id. /// /// The extension of the file (without the dot). /// The monaco language id public static string GetLanguage(string fileExtension) { fileExtension = fileExtension.ToLower(CultureInfo.CurrentCulture); try { JsonDocument languageListDocument = GetLanguages(); JsonElement languageList = languageListDocument.RootElement.GetProperty("list"); foreach (JsonElement e in languageList.EnumerateArray()) { if (e.TryGetProperty("extensions", out var extensions)) { for (int j = 0; j < extensions.GetArrayLength(); j++) { if (extensions[j].ToString() == fileExtension) { return e.GetProperty("id").ToString(); } } } } return "plaintext"; } catch (Exception) { return "plaintext"; } } public static string ReadIndexHtml() { string html; using (StreamReader htmlFileReader = new StreamReader(new FileStream(MonacoDirectory + "\\index.html", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { html = htmlFileReader.ReadToEnd(); htmlFileReader.Close(); } return html; } } }