namespace Core.Parsers.EventOccurrence; /// /// Classifies lines to determine if they should be skipped during parsing. /// public static class LineClassifier { /// /// Checks if a line is empty or contains only whitespace. /// public static bool IsEmptyLine(string line) { return string.IsNullOrWhiteSpace(line); } /// /// Checks if a line is a comment (starts with "#"). /// public static bool IsCommentLine(string line) { return EventOccurrenceGrammar.IsCommentLine(line); } /// /// Determines if a line is a continuation/wrapped line that should be skipped. /// These are typically lines that: /// - Start with lowercase or special characters (not event names) /// - Are parenthetical notes like "(Semifinalists only)" /// - Are informational text like "Schedule Posted on..." /// public static bool IsContinuationLine(string line) { var trimmed = line.Trim(); // Skip parenthetical notes if (trimmed.StartsWith("(", StringComparison.Ordinal) && trimmed.EndsWith(")", StringComparison.Ordinal)) return true; // Skip lines that are clearly continuation text (start with lowercase, common continuation words) if (trimmed.Length > 0 && char.IsLower(trimmed[0])) { // Check if it starts with common continuation words var continuationPrefixes = new[] { "be ", "the ", "and ", "or ", "to ", "a ", "an ", "will ", "may ", "can " }; foreach (var prefix in continuationPrefixes) { if (trimmed.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) return true; } } // Skip informational lines that don't contain dates/times if (trimmed.Contains("Schedule Posted", StringComparison.OrdinalIgnoreCase) || trimmed.Contains("Note:", StringComparison.OrdinalIgnoreCase)) return true; return false; } }