using System.Text; using System.Text.RegularExpressions; namespace BetterAmongUs.Modules; internal static class TextFileHandler { internal static bool CompareStringFilters(string filePath, string[] strings) { foreach (var content in ReadContents(filePath)) { foreach (var text in strings) { if (CheckFilterString(content, text)) { return true; } } } return false; } internal static bool CompareStringMatch(string filePath, string[] strings) { var stringSet = new HashSet( strings.Select(s => s.ToLower().Trim()), StringComparer.OrdinalIgnoreCase ); foreach (var content in ReadContents(filePath)) { string normalizedContent = content.ToLower().Trim(); if (stringSet.Contains(normalizedContent)) { return true; } } return false; } private static IEnumerable ReadContents(string filePath) { if (File.Exists(filePath)) { return File.ReadLines(filePath) .Where(line => !string.IsNullOrWhiteSpace(line) && !line.StartsWith("//")) .SelectMany(line => line.Split(',', StringSplitOptions.RemoveEmptyEntries) .Select(s => s.Trim())); } return []; } private static bool CheckFilterString(string filter, string text) { string pattern = filter switch { _ when filter.StartsWith("**") && filter.EndsWith("**") => Regex.Escape(filter.Trim('*')), // Contains anywhere _ when filter.StartsWith("**") => Regex.Escape(filter.TrimStart('*')) + "$", // Ends with _ when filter.EndsWith("**") => "^" + Regex.Escape(filter.TrimEnd('*')), // Starts with _ => "^" + Regex.Escape(filter) + "$" // Exact match }; return Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled); } internal static Dictionary ParseYaml(string input) { var result = new Dictionary(); var lines = input.Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries); string? currentKey = null; StringBuilder currentValue = new(); foreach (var line in lines) { var trimmedLine = line.Trim(); // Skip empty lines if (string.IsNullOrEmpty(trimmedLine)) continue; var separatorIndex = line.IndexOf(':'); // Check if this is a key-value line (has colon and is not in the middle of content) if (separatorIndex > -1 && IsKeyValueLine(line, separatorIndex)) { // Save previous key-value pair if it exists if (currentKey != null && currentValue.Length > 0) { result[currentKey] = currentValue.ToString().Trim(); currentValue.Clear(); } var key = line[..separatorIndex].Trim(); if (key.StartsWith('^')) { key = key[1..].Trim(); } var value = line[(separatorIndex + 1)..].Trim(); currentKey = key; if (!string.IsNullOrEmpty(value)) { currentValue.Append(value); } } else if (currentKey != null) { // This is a continuation line for the current value if (currentValue.Length > 0) currentValue.Append('\n'); currentValue.Append(line.Trim()); } } if (currentKey != null && currentValue.Length > 0) { result[currentKey] = currentValue.ToString().Trim(); } return result; } private static bool IsKeyValueLine(string line, int separatorIndex) { string keyPart = line[..separatorIndex].Trim(); if (!keyPart.StartsWith('^') || keyPart.Contains(' ') || keyPart.Contains('#') || keyPart.Contains('*') || keyPart.Contains('[') || keyPart.Contains('`')) return false; return true; } internal static string FormatToRichText(string text) { if (string.IsNullOrEmpty(text)) return text; text = ProcessHeaders(text); text = ProcessBlockQuotes(text); text = ProcessHorizontalRules(text); text = ProcessBoldAndItalic(text); text = ProcessStrikethrough(text); text = ProcessLinks(text); text = ProcessInlineCode(text); text = ProcessLineBreaks(text); return text; } private static string ProcessHeaders(string text) { var headerSizes = new Dictionary { {1, 200}, {2, 180}, {3, 160}, {4, 140}, {5, 120}, {6, 110} }; foreach (var header in headerSizes) { string pattern = @"^(#{1," + header.Key + @"})\s+(.+?)(?=\n|$)"; string replacement = $"$2\n"; text = Regex.Replace(text, pattern, replacement, RegexOptions.Multiline); } return text; } private static string ProcessBlockQuotes(string text) { return Regex.Replace(text, @"^>\s+(.+?)(?=\n|$)", "│ $1", RegexOptions.Multiline); } private static string ProcessHorizontalRules(string text) { return Regex.Replace(text, @"^\s*([-*_]){3,}\s*$", "───────────────────────────", RegexOptions.Multiline); } private static string ProcessBoldAndItalic(string text) { text = Regex.Replace(text, @"(\*\*|__)(?![*\s])(.*?)(?$2"); text = Regex.Replace(text, @"(\*|_)(?![*\s])(.*?)(?$2"); text = Regex.Replace(text, @"(\*\*\*|___)(?![*\s])(.*?)(?$2"); return text; } private static string ProcessStrikethrough(string text) { return Regex.Replace(text, @"~~(.+?)~~", "$1"); } private static string ProcessLinks(string text) { return Regex.Replace(text, @"\[([^\]]+)\]\(([^)]+)\)", " $1 "); } private static string ProcessInlineCode(string text) { return Regex.Replace(text, @"`([^`]+)`", "$1"); } private static string ProcessLineBreaks(string text) { return Regex.Replace(text, @"\n\s*\n", "\n\n"); } }