Add Sprache package and enhance event occurrence parsing with new grammar rules
This commit is contained in:
@@ -31,7 +31,7 @@ public class EventOccurrenceParser
|
||||
new (
|
||||
@"" + //
|
||||
@"(?<Name>^[^#].*)\s" +
|
||||
@"(?<Month>February|March|April|May|June|July)\s" +
|
||||
@"(?<Month>January|February|March|April|May|June|July|August|September|October|November|December)\s" +
|
||||
@"(?<DayOfMonth>\d{1,2});?\s" +
|
||||
@"(?<TimeAndLocation>.*)"
|
||||
);
|
||||
@@ -63,14 +63,50 @@ public class EventOccurrenceParser
|
||||
if (string.IsNullOrWhiteSpace(trimmedLine))
|
||||
continue;
|
||||
|
||||
// Skip comment lines (starting with "#")
|
||||
if (trimmedLine.StartsWith("#", StringComparison.Ordinal))
|
||||
// Skip comment lines (starting with "#") - use grammar parser
|
||||
if (EventOccurrenceGrammar.IsCommentLine(trimmedLine))
|
||||
continue;
|
||||
|
||||
var match = _re.Match(trimmedLine);
|
||||
if (!match.Success)
|
||||
{
|
||||
if (trimmedLine.Contains("MS"))
|
||||
// Try to parse section header using grammar parser
|
||||
var sectionHeader = EventOccurrenceGrammar.TryParseSectionHeader(trimmedLine);
|
||||
if (sectionHeader.HasValue)
|
||||
{
|
||||
var (eventNamePart, schoolLevel) = sectionHeader.Value;
|
||||
|
||||
// Use fuzzy matching to find the best matching event definition
|
||||
var evt =
|
||||
(from e in _events
|
||||
let rat = Fuzz.Ratio(e.Name, eventNamePart)
|
||||
where rat > 50
|
||||
orderby rat descending
|
||||
select e).FirstOrDefault();
|
||||
if (evt == null)
|
||||
{
|
||||
issues.Add(new ParsingIssue
|
||||
{
|
||||
LineNumber = index,
|
||||
LineContent = trimmedLine,
|
||||
IssueType = ParsingIssueType.UnmatchedLine,
|
||||
Message = $"Section header '{eventNamePart} – {schoolLevel}' found but no matching event definition (best match ratio: {Fuzz.Ratio(eventNamePart, _events.FirstOrDefault()?.Name ?? "")})"
|
||||
});
|
||||
continue;
|
||||
}
|
||||
currentEventDefinition = evt;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for General Schedule/Session using grammar parser
|
||||
if (EventOccurrenceGrammar.IsGeneralSchedule(trimmedLine))
|
||||
{
|
||||
currentEventDefinition = EventDefinition.GeneralSchedule;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Also check for simple "MS" or "HS" in line (backward compatibility)
|
||||
if (trimmedLine.Contains("MS") || trimmedLine.Contains("HS"))
|
||||
{
|
||||
var evt =
|
||||
(from e in _events
|
||||
@@ -85,18 +121,13 @@ public class EventOccurrenceParser
|
||||
LineNumber = index,
|
||||
LineContent = trimmedLine,
|
||||
IssueType = ParsingIssueType.UnmatchedLine,
|
||||
Message = $"Section header with 'MS' found but no matching event definition (best match ratio: {Fuzz.Ratio(trimmedLine, _events.FirstOrDefault()?.Name ?? "")})"
|
||||
Message = $"Section header with 'MS' or 'HS' found but no matching event definition (best match ratio: {Fuzz.Ratio(trimmedLine, _events.FirstOrDefault()?.Name ?? "")})"
|
||||
});
|
||||
continue;
|
||||
}
|
||||
currentEventDefinition = evt;
|
||||
continue;
|
||||
}
|
||||
if (trimmedLine == "General Schedule" || trimmedLine == "General Session")
|
||||
{
|
||||
currentEventDefinition = EventDefinition.GeneralSchedule;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip continuation lines (lines that look like they're continuing from previous line)
|
||||
// These are typically lines that:
|
||||
@@ -280,31 +311,25 @@ public class EventOccurrenceParser
|
||||
|
||||
private DateOnly ParseDate(string month, string dayOfMonth, int year)
|
||||
{
|
||||
int monthNum = 1;
|
||||
switch (month)
|
||||
int monthNum = month.ToLower() switch
|
||||
{
|
||||
case "February":
|
||||
monthNum = 2;
|
||||
break;
|
||||
case "March":
|
||||
monthNum = 3;
|
||||
break;
|
||||
case "April":
|
||||
monthNum = 4;
|
||||
break;
|
||||
case "May":
|
||||
monthNum = 5;
|
||||
break;
|
||||
case "June":
|
||||
monthNum = 6;
|
||||
break;
|
||||
case "July":
|
||||
monthNum = 7;
|
||||
break;
|
||||
}
|
||||
"january" => 1,
|
||||
"february" => 2,
|
||||
"march" => 3,
|
||||
"april" => 4,
|
||||
"may" => 5,
|
||||
"june" => 6,
|
||||
"july" => 7,
|
||||
"august" => 8,
|
||||
"september" => 9,
|
||||
"october" => 10,
|
||||
"november" => 11,
|
||||
"december" => 12,
|
||||
_ => throw new ArgumentException($"Invalid month: {month}", nameof(month))
|
||||
};
|
||||
|
||||
var day = int.Parse(dayOfMonth);
|
||||
return new DateOnly(year, monthNum, day); ;
|
||||
return new DateOnly(year, monthNum, day);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user