-
-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathParatextProjectTextUpdaterBase.cs
More file actions
132 lines (120 loc) · 4.96 KB
/
Copy pathParatextProjectTextUpdaterBase.cs
File metadata and controls
132 lines (120 loc) · 4.96 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
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace SIL.Machine.Corpora
{
public abstract class ParatextProjectTextUpdaterBase
{
private readonly ParatextProjectSettings _settings;
private readonly IParatextProjectFileHandler _paratextProjectFileHandler;
protected ParatextProjectTextUpdaterBase(
IParatextProjectFileHandler paratextProjectFileHandler,
ParatextProjectSettings settings
)
{
_settings = settings;
_paratextProjectFileHandler = paratextProjectFileHandler;
}
public string UpdateUsfm(
string bookId,
IReadOnlyList<UpdateUsfmRow> rows,
IReadOnlyList<int> chapters = null,
string fullName = null,
UpdateUsfmTextBehavior textBehavior = UpdateUsfmTextBehavior.PreferExisting,
UpdateUsfmMarkerBehavior paragraphBehavior = UpdateUsfmMarkerBehavior.Preserve,
UpdateUsfmMarkerBehavior embedBehavior = UpdateUsfmMarkerBehavior.Preserve,
UpdateUsfmMarkerBehavior styleBehavior = UpdateUsfmMarkerBehavior.Strip,
IEnumerable<string> preserveParagraphStyles = null,
IEnumerable<IUsfmUpdateBlockHandler> updateBlockHandlers = null,
IEnumerable<(int, string)> remarks = null,
Func<UsfmUpdateBlockHandlerException, bool> errorHandler = null,
bool compareSegments = false
)
{
string fileName = _settings.GetBookFileName(bookId);
if (!Exists(fileName))
return null;
string usfm;
using (var reader = new StreamReader(Open(fileName)))
{
usfm = reader.ReadToEnd();
}
var handler = new UpdateUsfmParserHandler(
rows,
fullName is null ? null : $"- {fullName}",
textBehavior,
paragraphBehavior,
embedBehavior,
styleBehavior,
preserveParagraphStyles,
updateBlockHandlers,
remarks,
errorHandler,
compareSegments
);
try
{
var tokenizer = new UsfmTokenizer(_settings.Stylesheet);
IReadOnlyList<UsfmToken> tokens = tokenizer.Tokenize(usfm);
tokens = FilterTokensByChapter(tokens, chapters);
UsfmParser.Parse(tokens, handler, _settings.Stylesheet, _settings.Versification);
return handler.GetUsfm(_settings.Stylesheet);
}
catch (Exception ex)
{
var sb = new StringBuilder();
sb.Append($"An error occurred while parsing the usfm for '{bookId}`");
if (!string.IsNullOrEmpty(_settings.Name))
sb.Append($" in project '{_settings.Name}'");
sb.Append($". Error: '{ex.Message}'");
throw new InvalidOperationException(sb.ToString(), ex);
}
}
/// <summary>
/// Filters tokens by the specified chapters.
/// </summary>
/// <param name="tokens">The tokens.</param>
/// <param name="chapters">The chapters. If null, all tokens are returned.</param>
/// <returns>The filtered tokens.</returns>
/// <remarks>This is marked internal so test classes can use it.</remarks>
internal static IReadOnlyList<UsfmToken> FilterTokensByChapter(
IReadOnlyList<UsfmToken> tokens,
IReadOnlyList<int> chapters = null
)
{
if (chapters is null)
return tokens;
var tokensWithinChapters = new List<UsfmToken>();
bool inChapter = false;
bool inIdMarker = false;
for (int index = 0; index < tokens.Count; index++)
{
UsfmToken token = tokens[index];
if (index == 0 && token.Marker == "id")
{
inIdMarker = true;
if (chapters.Contains(1))
inChapter = true;
}
else if (inIdMarker && token.Marker != null && token.Marker != "id")
{
inIdMarker = false;
}
else if (token.Type == UsfmTokenType.Chapter)
{
inChapter =
!string.IsNullOrEmpty(token.Data)
&& int.TryParse(token.Data, out int chapter)
&& chapters.Contains(chapter);
}
if (inIdMarker || inChapter)
tokensWithinChapters.Add(token);
}
return tokensWithinChapters;
}
private bool Exists(string fileName) => _paratextProjectFileHandler.Exists(fileName);
private Stream Open(string fileName) => _paratextProjectFileHandler.Open(fileName);
}
}