-
-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathUsfmStructureExtractor.cs
More file actions
184 lines (155 loc) · 6.95 KB
/
Copy pathUsfmStructureExtractor.cs
File metadata and controls
184 lines (155 loc) · 6.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
using System.Collections.Generic;
using SIL.Machine.Corpora;
using SIL.Scripture;
namespace SIL.Machine.PunctuationAnalysis
{
public class UsfmStructureExtractor : IUsfmParserHandler
{
private readonly List<TextSegment> _textSegments;
private TextSegment.Builder _nextTextSegmentBuilder;
public UsfmStructureExtractor()
{
_textSegments = new List<TextSegment>();
_nextTextSegmentBuilder = new TextSegment.Builder();
}
public void StartBook(UsfmParserState state, string marker, string code)
{
_nextTextSegmentBuilder.SetBook(code);
}
public void Chapter(UsfmParserState state, string number, string marker, string altNumber, string pubNumber)
{
_nextTextSegmentBuilder.AddPrecedingMarker(UsfmMarkerType.Chapter);
_nextTextSegmentBuilder.SetChapter(state.VerseRef.ChapterNum);
}
public void EndBook(UsfmParserState state, string marker) { }
public void EndCell(UsfmParserState state, string marker) { }
public void EndChar(UsfmParserState state, string marker, IReadOnlyList<UsfmAttribute> attributes, bool closed)
{
_nextTextSegmentBuilder.AddPrecedingMarker(UsfmMarkerType.Character);
}
public void EndNote(UsfmParserState state, string marker, bool closed)
{
_nextTextSegmentBuilder.AddPrecedingMarker(UsfmMarkerType.Embed);
}
public void EndPara(UsfmParserState state, string marker) { }
public void EndRow(UsfmParserState state, string marker) { }
public void EndSidebar(UsfmParserState state, string marker, bool closed)
{
_nextTextSegmentBuilder.AddPrecedingMarker(UsfmMarkerType.Embed);
}
public void EndTable(UsfmParserState state)
{
_nextTextSegmentBuilder.AddPrecedingMarker(UsfmMarkerType.Embed);
}
public void EndUsfm(UsfmParserState state) { }
public void GotMarker(UsfmParserState state, string marker) { }
public void Milestone(
UsfmParserState state,
string marker,
bool startMilestone,
IReadOnlyList<UsfmAttribute> attributes
) { }
public void OptBreak(UsfmParserState state) { }
public void Ref(UsfmParserState state, string marker, string display, string target)
{
_nextTextSegmentBuilder.AddPrecedingMarker(UsfmMarkerType.Embed);
}
public void StartCell(UsfmParserState state, string marker, string align, int colspan) { }
public void StartChar(
UsfmParserState state,
string markerWithoutPlus,
bool unknown,
IReadOnlyList<UsfmAttribute> attributes
)
{
_nextTextSegmentBuilder.AddPrecedingMarker(UsfmMarkerType.Character);
}
public void StartNote(UsfmParserState state, string marker, string caller, string category) { }
public void StartPara(
UsfmParserState state,
string marker,
bool unknown,
IReadOnlyList<UsfmAttribute> attributes
)
{
_nextTextSegmentBuilder.AddPrecedingMarker(UsfmMarkerType.Paragraph);
}
public void StartRow(UsfmParserState state, string marker) { }
public void StartSidebar(UsfmParserState state, string marker, string category) { }
public void StartTable(UsfmParserState state) { }
public void StartUsfm(UsfmParserState state) { }
public void Text(UsfmParserState state, string text)
{
if (!state.IsVerseText)
return;
if (text.Length > 0)
{
_nextTextSegmentBuilder.SetText(text);
TextSegment textSegment = _nextTextSegmentBuilder.Build();
// Don't look past verse boundaries, to enable identical functionality in the
// online one-verse-at-a-time (QuotationMarkDenormalizationScriptureUpdateBlockHandler)
// and offline whole-book-at-once settings (QuoteConventionDetector)
if (_textSegments.Count > 0 && !textSegment.MarkerIsInPrecedingContext(UsfmMarkerType.Verse))
{
_textSegments[_textSegments.Count - 1].NextSegment = textSegment;
textSegment.PreviousSegment = _textSegments[_textSegments.Count - 1];
}
_textSegments.Add(textSegment);
}
_nextTextSegmentBuilder = new TextSegment.Builder();
}
public void Unmatched(UsfmParserState state, string marker) { }
public void Verse(UsfmParserState state, string number, string marker, string altNumber, string pubNumber)
{
_nextTextSegmentBuilder.AddPrecedingMarker(UsfmMarkerType.Verse);
}
public List<Chapter> GetChapters(IReadOnlyDictionary<int, List<int>> includeChapters = null)
{
var chapters = new List<Chapter>();
int currentBook = 0;
int currentChapter = 0;
var currentChapterVerses = new List<Verse>();
var currentVerseSegments = new List<TextSegment>();
foreach (TextSegment textSegment in _textSegments)
{
if (textSegment.MarkerIsInPrecedingContext(UsfmMarkerType.Verse))
{
if (currentVerseSegments.Count > 0)
{
currentChapterVerses.Add(new Verse(currentVerseSegments));
}
currentVerseSegments = new List<TextSegment>();
}
if (textSegment.MarkerIsInPrecedingContext(UsfmMarkerType.Chapter))
{
if (currentChapterVerses.Count > 0)
{
chapters.Add(new Chapter(currentChapterVerses, currentChapter));
}
currentChapterVerses = new List<Verse>();
}
if (textSegment.Book != null)
currentBook = Canon.BookIdToNumber(textSegment.Book);
if (textSegment.Chapter > 0)
currentChapter = textSegment.Chapter;
if (includeChapters != null && currentBook > 0)
{
if (!includeChapters.TryGetValue(currentBook, out List<int> bookChapters))
continue;
if (currentChapter > 0 && bookChapters.Count > 0 && !bookChapters.Contains(currentChapter))
continue;
}
currentVerseSegments.Add(textSegment);
}
if (currentVerseSegments.Count > 0)
{
currentChapterVerses.Add(new Verse(currentVerseSegments));
}
if (currentChapterVerses.Count > 0)
{
chapters.Add(new Chapter(currentChapterVerses, currentChapter));
}
return chapters;
}
}
}