using Core.Parsers; namespace Core.Utility; public static class TextUtil { /// /// Sanitizes input by normalizing hyphens (en-dash, em-dash -> regular hyphen). /// This allows parsers to assume normalized input. /// /// The input string to sanitize. /// The sanitized string with normalized hyphens. public static string SanitizeInput(string input) { input = input.Replace("–", "-"); // en-dash input = input.Replace("—", "-"); // em-dash return input; } /// /// Parses a date from month name, day of month, and year. /// /// The month name (e.g., "January", "February"). Case-insensitive. /// The day of the month as a string (e.g., "15", "3"). /// The year (e.g., 2025). /// A representing the parsed date. /// Thrown when the month name is invalid. /// Thrown when the day of month cannot be parsed as an integer. /// Thrown when the resulting date is invalid (e.g., February 30). public static DateOnly ParseDate(string month, string dayOfMonth, int year) { // Use normalized MonthNames array from grammar var monthLower = month.ToLower(); var monthIndex = Array.FindIndex(EventOccurrenceGrammar.MonthNames, m => m.ToLower() == monthLower); if (monthIndex < 0) throw new ArgumentException($"Invalid month: {month}", nameof(month)); // Month index is 0-based, month number is 1-based int monthNum = monthIndex + 1; var day = int.Parse(dayOfMonth); return new DateOnly(year, monthNum, day); } /// /// Get the ordinal value of positive integers. /// /// /// Only works for english-based cultures. /// Code from: http://stackoverflow.com/questions/20156/is-there-a-quick-way-to-create-ordinals-in-c/31066#31066 /// With help: http://www.wisegeek.com/what-is-an-ordinal-number.htm /// /// The number. /// Ordinal value of positive integers, or if less than 1. /// https://stackoverflow.com/a/620504/99492 public static string Ordinal(this int number) { const string TH = "th"; string s = number.ToString(); // Negative and zero have no ordinal representation if (number < 1) { return s; } number %= 100; if ((number >= 11) && (number <= 13)) { return s + TH; } switch (number % 10) { case 1: return s + "st"; case 2: return s + "nd"; case 3: return s + "rd"; default: return s + TH; } } public static void ConsoleWriteTable( Func getVal, string rowHeader, int[] rowVars, string colHeader, int[] colVars) { var chl = $" {colHeader} 0".Length; var rhl = $"{rowHeader} 0".Length + 3; Console.Write(new string(' ', rhl)); foreach (var c in colVars) { Console.Write($" {colHeader} {c + 1}"); } Console.WriteLine(); Console.WriteLine(); foreach (var r in rowVars) { var rhead = $"{rowHeader} {r + 1}:"; Console.Write(rhead.PadRight(rhl)); foreach (var c in colVars) { var v = getVal(r, c) ? "1" : " "; Console.Write($"{v.PadLeft(chl)}"); } Console.WriteLine(); } Console.WriteLine(); } }