Add footnotes support to event occurrence parsing
This commit introduces a new property for capturing footnotes in both the EventOccurrenceParseResult and EventOccurrenceParserResult classes. The EventOccurrenceParser has been updated to handle footnotes, which are identified by lines starting with "*" or as parenthetical notes. The logic for processing these footnotes has been integrated into the parsing flow, ensuring that they are correctly associated with their respective event definitions. Additionally, the EventOccurrenceParserService has been modified to copy footnotes from the parser result, enhancing the overall event parsing functionality.
This commit is contained in:
@@ -52,6 +52,12 @@ public class EventOccurrenceParseResult
|
||||
/// </summary>
|
||||
public int SkippedHSEventCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Footnotes captured for each event definition. Footnotes are lines that start with "*" or are parenthetical notes.
|
||||
/// Multiple footnotes are concatenated into a single string. These provide additional context or information about the event occurrences.
|
||||
/// </summary>
|
||||
public IDictionary<EventDefinition, string> Footnotes { get; set; } = new Dictionary<EventDefinition, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Total number of event occurrences successfully parsed.
|
||||
/// </summary>
|
||||
|
||||
@@ -18,6 +18,11 @@ public class EventOccurrenceParserResult
|
||||
public List<string> SkippedMSSectionHeaders { get; set; } = new();
|
||||
public int SkippedMSEventCount { get; set; }
|
||||
public int SkippedHSEventCount { get; set; }
|
||||
/// <summary>
|
||||
/// Footnotes captured for each event definition. Footnotes are lines that start with "*" or are parenthetical notes.
|
||||
/// Multiple footnotes are concatenated into a single string.
|
||||
/// </summary>
|
||||
public IDictionary<EventDefinition, string> Footnotes { get; set; } = new Dictionary<EventDefinition, string>();
|
||||
}
|
||||
|
||||
public class EventOccurrenceParser
|
||||
@@ -38,8 +43,9 @@ public class EventOccurrenceParser
|
||||
var result = new EventOccurrenceParserResult();
|
||||
var occurrences = result.Occurrences;
|
||||
var issues = result.Issues;
|
||||
var footnotes = result.Footnotes;
|
||||
EventDefinition? currentEventDefinition = null;
|
||||
bool inContinuationMode = false;
|
||||
bool inFootnoteMode = false;
|
||||
SchoolLevel? currentSectionLevel = null;
|
||||
|
||||
var lines = File.ReadLines(_txtFile.FullName);
|
||||
@@ -52,16 +58,16 @@ public class EventOccurrenceParser
|
||||
// Skip empty lines
|
||||
if (EventOccurrenceParsers.LineClassifier.IsEmptyLine(normalizedLine))
|
||||
{
|
||||
// Empty lines break continuation mode
|
||||
inContinuationMode = false;
|
||||
// Empty lines break footnote mode
|
||||
inFootnoteMode = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip comment lines (starting with "#") - use grammar parser
|
||||
if (EventOccurrenceParsers.LineClassifier.IsCommentLine(normalizedLine))
|
||||
{
|
||||
// Comment lines break continuation mode
|
||||
inContinuationMode = false;
|
||||
// Comment lines break footnote mode
|
||||
inFootnoteMode = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -76,8 +82,8 @@ public class EventOccurrenceParser
|
||||
{
|
||||
var (eventNamePart, schoolLevel) = sectionHeader.Value;
|
||||
|
||||
// Section headers break continuation mode
|
||||
inContinuationMode = false;
|
||||
// Section headers break footnote mode
|
||||
inFootnoteMode = false;
|
||||
|
||||
// Convert string school level to enum
|
||||
var sectionSchoolLevel = SetCurrentSectionLevel(schoolLevel);
|
||||
@@ -115,8 +121,8 @@ public class EventOccurrenceParser
|
||||
// Check for General Schedule/Session using grammar parser
|
||||
if (EventOccurrenceParsers.SectionHeaderMatcher.IsGeneralSchedule(normalizedLine))
|
||||
{
|
||||
// General schedule breaks continuation mode
|
||||
inContinuationMode = false;
|
||||
// General schedule breaks footnote mode
|
||||
inFootnoteMode = false;
|
||||
currentSectionLevel = null; // Reset section level
|
||||
currentEventDefinition = EventDefinition.GeneralSchedule;
|
||||
continue;
|
||||
@@ -125,8 +131,8 @@ public class EventOccurrenceParser
|
||||
// Also check for simple "MS" or "HS" in line (backward compatibility)
|
||||
if (EventOccurrenceParsers.SectionHeaderMatcher.HasSchoolLevel(normalizedLine))
|
||||
{
|
||||
// Section headers break continuation mode
|
||||
inContinuationMode = false;
|
||||
// Section headers break footnote mode
|
||||
inFootnoteMode = false;
|
||||
|
||||
// Extract school level from line
|
||||
SchoolLevel? sectionSchoolLevel = null;
|
||||
@@ -165,15 +171,29 @@ public class EventOccurrenceParser
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if line starts with "*" to enter continuation mode
|
||||
// Check if line starts with "*" to enter footnote mode
|
||||
if (normalizedLine.TrimStart().StartsWith("*", StringComparison.Ordinal))
|
||||
{
|
||||
inContinuationMode = true;
|
||||
inFootnoteMode = true;
|
||||
}
|
||||
|
||||
// Skip continuation lines (in continuation mode OR line starts with "*" or is parenthetical)
|
||||
if (inContinuationMode || EventOccurrenceParsers.LineClassifier.IsContinuationLine(normalizedLine))
|
||||
// Capture footnote lines (in footnote mode OR line starts with "*" or is parenthetical)
|
||||
if (inFootnoteMode || EventOccurrenceParsers.LineClassifier.IsContinuationLine(normalizedLine))
|
||||
{
|
||||
// Capture footnote for current event definition if we have one
|
||||
if (currentEventDefinition != null)
|
||||
{
|
||||
if (!footnotes.ContainsKey(currentEventDefinition))
|
||||
{
|
||||
footnotes[currentEventDefinition] = string.Empty;
|
||||
}
|
||||
// Append footnote, adding a space if there's already content
|
||||
if (!string.IsNullOrEmpty(footnotes[currentEventDefinition]))
|
||||
{
|
||||
footnotes[currentEventDefinition] += " ";
|
||||
}
|
||||
footnotes[currentEventDefinition] += normalizedLine;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -192,8 +212,8 @@ public class EventOccurrenceParser
|
||||
continue;
|
||||
}
|
||||
|
||||
// Occurrence lines break continuation mode
|
||||
inContinuationMode = false;
|
||||
// Occurrence lines break footnote mode
|
||||
inFootnoteMode = false;
|
||||
|
||||
// Skip occurrences under sections that don't match the school level setting
|
||||
if (ShouldSkipOccurrence(currentSectionLevel, result))
|
||||
|
||||
@@ -115,6 +115,12 @@ public class EventOccurrenceParserService : IEventOccurrenceParserService
|
||||
result.SkippedMSEventCount = parserResult.SkippedMSEventCount;
|
||||
result.SkippedHSEventCount = parserResult.SkippedHSEventCount;
|
||||
|
||||
// Copy footnotes from parser result
|
||||
foreach (var kvp in parserResult.Footnotes)
|
||||
{
|
||||
result.Footnotes[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
// Add informational messages about skipped events
|
||||
if (parserResult.SkippedMSEventCount > 0)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user