4
4
import java .io .File ;
5
5
import java .io .FileInputStream ;
6
6
import java .io .FileOutputStream ;
7
- import java .io .FileWriter ;
8
7
import java .io .IOException ;
9
8
import java .io .OutputStreamWriter ;
10
9
import java .nio .charset .StandardCharsets ;
11
10
import java .util .ArrayList ;
12
11
import java .util .Arrays ;
12
+ import java .util .HashMap ;
13
13
import java .util .List ;
14
+ import java .util .Map ;
15
+ import java .util .Map .Entry ;
14
16
import java .util .NoSuchElementException ;
15
17
import java .util .Properties ;
16
18
@@ -42,6 +44,7 @@ public class AugmentGrammar implements ExportFormat {
42
44
" S: Read Strongs and augment Morphology" ,
43
45
" I: Read Indices and augment Morphology" ,
44
46
" SI: Read Strongs and augment Indices" ,
47
+ " SLI: Read Strongs that exist more than once as list and augment Indices" ,
45
48
" IS: Read Indices and augment Strongs" ,
46
49
"" ,
47
50
"Database can only be used to augment using a mode if the mode was also present when analyzing."
@@ -62,7 +65,7 @@ public void doExport(Bible bible, String... exportArgs) throws Exception {
62
65
if (exportArgs [0 ].equals ("dump" )) {
63
66
boolean humanStrongs = exportArgs .length > 2 && exportArgs [2 ].equals ("humanStrongs" );
64
67
try (BufferedWriter bw = new BufferedWriter (new OutputStreamWriter (new FileOutputStream (exportArgs [1 ]), StandardCharsets .UTF_8 ))) {
65
- runOperation (bible , new GrammarOperation () {
68
+ runOperation (bible , null , new GrammarOperation () {
66
69
67
70
private int counter = 0 ;
68
71
private Reference lastReference = null ;
@@ -91,7 +94,7 @@ public Visitor<RuntimeException> handleGrammar(Reference reference, Visitor<Runt
91
94
} else if (exportArgs [0 ].equals ("dumpwords" )) {
92
95
boolean humanStrongs = exportArgs .length > 2 && exportArgs [2 ].equals ("humanStrongs" );
93
96
try (BufferedWriter bw = new BufferedWriter (new OutputStreamWriter (new FileOutputStream (exportArgs [1 ]), StandardCharsets .UTF_8 ))) {
94
- runOperation (bible , new GrammarOperation () {
97
+ runOperation (bible , null , new GrammarOperation () {
95
98
96
99
private int counter = 0 ;
97
100
private Reference lastReference = null ;
@@ -130,7 +133,8 @@ public boolean visitEnd() {
130
133
props .load (in );
131
134
}
132
135
}
133
- runOperation (bible , new GrammarOperation () {
136
+ Map <String ,List <String >> strongsLists = new HashMap <>();
137
+ runOperation (bible , null , new GrammarOperation () {
134
138
135
139
private void analyze (Reference reference , char separator , String [] srcVals , String suffix , String [] dstVals ) {
136
140
if (srcVals != null && dstVals != null && srcVals .length == dstVals .length ) {
@@ -164,16 +168,35 @@ public Visitor<RuntimeException> handleGrammar(Reference reference, Visitor<Runt
164
168
analyze (reference , '@' , idxStrings , "" , rmac );
165
169
break ;
166
170
case INDEX2STRONGS :
167
- analyze (reference , '*' , fullStrongs , "@" , idxStrings );
171
+ analyze (reference , '@' , idxStrings , "@" , fullStrongs );
172
+ break ;
173
+ case STRONGSLIST2INDEX :
174
+ if (idxStrings != null && fullStrongs != null && idxStrings .length == fullStrongs .length ) {
175
+ for (int i = 0 ; i < idxStrings .length ; i ++) {
176
+ String key = reference .getBook ().getOsisID () + "." + reference .getChapter () + "." + reference .getVerse () + '*' + fullStrongs [i ] + "@L" ;
177
+ strongsLists .computeIfAbsent (key , x -> new ArrayList <>()).add (idxStrings [i ]);
178
+ }
179
+ }
168
180
break ;
169
181
case STRONGS2INDEX :
170
- analyze (reference , '@ ' , idxStrings , "@" , fullStrongs );
182
+ analyze (reference , '* ' , fullStrongs , "@" , idxStrings );
171
183
break ;
172
184
}
173
185
}
174
186
return next .visitGrammarInformation (strongsPrefixes , strongs , rmac , sourceIndices );
175
187
}
176
188
});
189
+ for (Entry <String , List <String >> entry : strongsLists .entrySet ()) {
190
+ if (entry .getValue ().size () == 1 )
191
+ continue ;
192
+ String key = entry .getKey ();
193
+ String value = String .join ("," , entry .getValue ());
194
+ String oldVal = props .getProperty (key );
195
+ if (oldVal == null )
196
+ props .setProperty (key , value );
197
+ else if (!oldVal .equals (value ))
198
+ props .setProperty (key , "*" );
199
+ }
177
200
try (FileOutputStream out = new FileOutputStream (exportArgs [1 ])) {
178
201
props .store (out , "AugmentGrammar database" );
179
202
}
@@ -182,7 +205,28 @@ public Visitor<RuntimeException> handleGrammar(Reference reference, Visitor<Runt
182
205
try (FileInputStream in = new FileInputStream (exportArgs [1 ])) {
183
206
props .load (in );
184
207
}
185
- runOperation (bible , new GrammarOperation () {
208
+ final Map <String ,int []> strongsCounters = new HashMap <>();
209
+ GrammarOperation prepare = null ;
210
+ if (modes .contains (Mode .STRONGSLIST2INDEX )) {
211
+ prepare = new GrammarOperation () {
212
+ @ Override
213
+ public void reset () {
214
+ strongsCounters .clear ();
215
+ }
216
+
217
+ @ Override
218
+ public Visitor <RuntimeException > handleGrammar (Reference reference , Visitor <RuntimeException > next , char [] strongsPrefixes , int [] strongs , String [] rmac , int [] sourceIndices ) {
219
+ String [] fullStrongs = buildFullStrongs (reference , strongsPrefixes , strongs , false );
220
+ if (fullStrongs != null ) {
221
+ for (String entry : fullStrongs ) {
222
+ strongsCounters .computeIfAbsent (entry , x -> new int [2 ])[0 ]++;
223
+ }
224
+ }
225
+ return next .visitGrammarInformation (strongsPrefixes , strongs , rmac , sourceIndices );
226
+ }
227
+ };
228
+ }
229
+ runOperation (bible , prepare , new GrammarOperation () {
186
230
@ Override
187
231
public Visitor <RuntimeException > handleGrammar (Reference reference , Visitor <RuntimeException > next , char [] strongsPrefixes , int [] strongs , String [] rmac , int [] sourceIndices ) {
188
232
String [] fullStrongs = buildFullStrongs (reference , strongsPrefixes , strongs , false );
@@ -229,12 +273,28 @@ public Visitor<RuntimeException> handleGrammar(Reference reference, Visitor<Runt
229
273
}
230
274
}
231
275
break ;
276
+ case STRONGSLIST2INDEX :
277
+ if (fullStrongs != null && sourceIndices == null ) {
278
+ sourceIndices = new int [fullStrongs .length ];
279
+ for (int i = 0 ; i < fullStrongs .length ; i ++) {
280
+ String value = props .getProperty (keyPrefix + "*" + fullStrongs [i ] + "@L" , "*" );
281
+ String [] parts = value .equals ("*" ) ? null : value .split ("," );
282
+ int [] cnt = strongsCounters .get (fullStrongs [i ]);
283
+ if (value .equals ("*" ) || parts .length != cnt [0 ]) {
284
+ sourceIndices = null ;
285
+ break ;
286
+ }
287
+ sourceIndices [i ] = Integer .parseInt (parts [cnt [1 ]]);
288
+ cnt [1 ]++;
289
+ }
290
+ }
291
+ break ;
232
292
case STRONGS2INDEX :
233
293
if (fullStrongs != null && sourceIndices == null ) {
234
294
sourceIndices = new int [fullStrongs .length ];
235
295
for (int i = 0 ; i < fullStrongs .length ; i ++) {
236
296
String value = props .getProperty (keyPrefix + "*" + fullStrongs [i ] + "@" , "*" );
237
- if (rmac [ i ] .equals ("*" )) {
297
+ if (value .equals ("*" )) {
238
298
sourceIndices = null ;
239
299
break ;
240
300
}
@@ -252,7 +312,7 @@ public Visitor<RuntimeException> handleGrammar(Reference reference, Visitor<Runt
252
312
exportFormat .doExport (bible , Arrays .copyOfRange (exportArgs , 3 , exportArgs .length ));
253
313
254
314
} else if (exportArgs [0 ].equals ("addsourceindex" )) {
255
- runOperation (bible , new GrammarOperation () {
315
+ runOperation (bible , null , new GrammarOperation () {
256
316
private int counter = 0 ;
257
317
private Reference lastReference = null ;
258
318
@@ -290,15 +350,20 @@ private static String[] buildFullStrongs(Versification.Reference reference, char
290
350
return result ;
291
351
}
292
352
293
- protected <T extends Throwable > void runOperation (Bible bible , GrammarOperation operation ) throws T {
353
+ protected <T extends Throwable > void runOperation (Bible bible , GrammarOperation prepare , GrammarOperation operation ) throws T {
294
354
for (Book book : bible .getBooks ()) {
295
355
int cnum = 0 ;
296
356
for (Chapter chapter : book .getChapters ()) {
297
357
cnum ++;
298
358
List <Verse > verses = chapter .getVerses ();
299
359
for (int i = 0 ; i < verses .size (); i ++) {
300
360
Verse v1 = verses .get (i );
361
+ if (prepare != null ) {
362
+ prepare .reset ();
363
+ v1 .accept (new GrammarOperationVisitor (new FormattedText ().getAppendVisitor (), new Versification .Reference (book .getId (), cnum , v1 .getNumber ()), prepare ));
364
+ }
301
365
Verse v2 = new Verse (v1 .getNumber ());
366
+ operation .reset ();
302
367
v1 .accept (new GrammarOperationVisitor (v2 .getAppendVisitor (), new Versification .Reference (book .getId (), cnum , v1 .getNumber ()), operation ));
303
368
v2 .finished ();
304
369
verses .set (i , v2 );
@@ -308,7 +373,7 @@ protected <T extends Throwable> void runOperation(Bible bible, GrammarOperation
308
373
}
309
374
310
375
private static enum Mode {
311
- STRONGS2MORPH ("S" ), INDEX2MORPH ("I" ), STRONGS2INDEX ("SI" ), INDEX2STRONGS ("IS" );
376
+ STRONGS2MORPH ("S" ), INDEX2MORPH ("I" ), STRONGS2INDEX ("SI" ), STRONGSLIST2INDEX ( "SLI" ), INDEX2STRONGS ("IS" );
312
377
313
378
private final String code ;
314
379
@@ -326,6 +391,7 @@ private static Mode fromCode(String code) {
326
391
}
327
392
328
393
private static interface GrammarOperation {
394
+ public default void reset () {}
329
395
public abstract Visitor <RuntimeException > handleGrammar (Versification .Reference reference , Visitor <RuntimeException > next , char [] strongsPrefixes , int [] strongs , String [] rmac , int [] sourceIndices );
330
396
}
331
397
0 commit comments