5
5
import java .util .Arrays ;
6
6
import java .util .BitSet ;
7
7
import java .util .Collection ;
8
+ import java .util .Comparator ;
9
+ import java .util .EnumMap ;
8
10
import java .util .EnumSet ;
11
+ import java .util .HashMap ;
9
12
import java .util .HashSet ;
10
13
import java .util .List ;
11
14
import java .util .Map ;
15
+ import java .util .Map .Entry ;
12
16
import java .util .Set ;
17
+ import java .util .regex .Matcher ;
18
+ import java .util .regex .Pattern ;
13
19
14
20
import biblemulticonverter .data .Bible ;
15
21
import biblemulticonverter .data .Book ;
16
22
import biblemulticonverter .data .BookID ;
17
23
import biblemulticonverter .data .Chapter ;
18
24
import biblemulticonverter .data .FormattedText ;
19
25
import biblemulticonverter .data .FormattedText .Visitor ;
26
+ import biblemulticonverter .data .Utils ;
20
27
import biblemulticonverter .data .Verse ;
21
28
import biblemulticonverter .data .VerseRange ;
22
29
import biblemulticonverter .data .VirtualVerse ;
@@ -32,13 +39,15 @@ public void doExport(Bible bible, String... exportArgs) throws Exception {
32
39
Set <String > totalVerses = new HashSet <String >();
33
40
boolean includeXref = exportArgs .length > 0 && exportArgs [0 ].equals ("-xref" );
34
41
Set <BookID > usedBooks = EnumSet .noneOf (BookID .class );
42
+ Map <BookID ,String > bookAbbrMap = new EnumMap <>(BookID .class );
35
43
XrefCountVisitor xcv = includeXref ? new XrefCountVisitor (schemes , totalVerses , usedBooks ) : null ;
36
44
int usedArgCount = (includeXref ? 1 : 0 );
37
45
boolean limitBooks = exportArgs .length > usedArgCount && exportArgs [usedArgCount ].equals ("-limitBooks" );
38
46
39
47
// fill missing verses
40
48
for (Book book : bible .getBooks ()) {
41
49
usedBooks .add (book .getId ());
50
+ bookAbbrMap .put (book .getId (), book .getAbbr ());
42
51
for (int cc = 0 ; cc < book .getChapters ().size (); cc ++) {
43
52
Chapter chapter = book .getChapters ().get (cc );
44
53
if (includeXref && chapter .getProlog () != null ) {
@@ -76,13 +85,14 @@ public void doExport(Bible bible, String... exportArgs) throws Exception {
76
85
77
86
// print them
78
87
System .out .print ("Best match: " );
79
- int totalVerseCount = totalVerses .size ();
80
- printScheme (schemes [0 ], totalVerseCount );
88
+ String verboseSchemasProperty = System .getProperty ("versificationdetector.verboseschemes" , "" );
89
+ Set <String > verboseSchemes = verboseSchemasProperty == null ? null : new HashSet <>(Arrays .asList (verboseSchemasProperty .split (", *" )));
90
+ printScheme (schemes [0 ], totalVerses , verboseSchemes , bookAbbrMap );
81
91
82
92
System .out .println ();
83
93
System .out .println ("Other options:" );
84
94
for (int i = 1 ; i < Math .min (11 , schemes .length ); i ++) {
85
- printScheme (schemes [i ], totalVerseCount );
95
+ printScheme (schemes [i ], totalVerses , verboseSchemes , bookAbbrMap );
86
96
if (schemes [i ].missingChapters .size () > schemes [0 ].missingChapters .size () + 2 ||
87
97
schemes [i ].missingVerses .size () > schemes [0 ].missingVerses .size () + 5 )
88
98
break ;
@@ -96,7 +106,7 @@ public void doExport(Bible bible, String... exportArgs) throws Exception {
96
106
boolean found = false ;
97
107
for (VersificationScheme scheme : schemes ) {
98
108
if (scheme .getName ().equals (exportArgs [i ])) {
99
- printScheme (scheme , totalVerseCount );
109
+ printScheme (scheme , totalVerses , verboseSchemes , bookAbbrMap );
100
110
found = true ;
101
111
break ;
102
112
}
@@ -134,13 +144,51 @@ protected boolean useTitleAsVerseZero() {
134
144
return false ;
135
145
}
136
146
137
- private void printScheme (VersificationScheme scheme , int totalVerseCount ) {
147
+ private void printScheme (VersificationScheme scheme , Set < String > totalVerses , Set < String > verboseSchemes , Map < BookID , String > bookAbbrMap ) {
138
148
if (scheme .getMissingChapters ().size () > 0 )
139
149
System .out .println (scheme .getName () + " (Missing chapters+verses: " + scheme .getMissingChapters ().size () + "+" + scheme .getMissingVerses ().size () + " " + scheme .getMissingChapters () + " " + scheme .getMissingVerses ());
140
150
else if (scheme .getMissingVerses ().size () > 0 )
141
151
System .out .println (scheme .getName () + " (Missing verses: " + scheme .getMissingVerses ().size () + " " + scheme .getMissingVerses () + ")" );
142
152
else
143
- System .out .println (scheme .getName () + " (All verses covered, and " + (scheme .getVerseCount () - totalVerseCount ) + " more)" );
153
+ System .out .println (scheme .getName () + " (All verses covered, and " + (scheme .getVerseCount () - totalVerses .size ()) + " more)" );
154
+ if (verboseSchemes != null && (verboseSchemes .contains (scheme .getName ()) || verboseSchemes .contains ("all" ))) {
155
+ Set <String > coveredVerses = new HashSet <>();
156
+ for (Entry <BookID , BitSet []> entry : scheme .coveredBooks .entrySet ()) {
157
+ String bookAbbr = bookAbbrMap .getOrDefault (entry .getKey (), entry .getKey ().getOsisID ());
158
+ for (int cnum = 1 ; cnum <= entry .getValue ().length ; cnum ++) {
159
+ BitSet verses = entry .getValue ()[cnum - 1 ];
160
+ for (int vnum = verses .nextSetBit (0 ); vnum != -1 ; vnum = verses .nextSetBit (vnum + 1 )) {
161
+ coveredVerses .add (bookAbbr + " " + cnum + ":" + vnum );
162
+ }
163
+ }
164
+ }
165
+ List <String > bookAbbrOrder = new ArrayList <>(bookAbbrMap .values ());
166
+ printVerbose ("\t -" , totalVerses , coveredVerses , bookAbbrOrder );
167
+ printVerbose ("\t +" , coveredVerses , totalVerses , bookAbbrOrder );
168
+ }
169
+ }
170
+
171
+ private void printVerbose (String prefix , Set <String > verseList , Set <String > removeList , List <String > bookAbbrOrder ) {
172
+ List <String > list = new ArrayList <>(verseList );
173
+ list .removeAll (removeList );
174
+ Map <String , int []> sortKey = new HashMap <>();
175
+ Pattern ptn = Pattern .compile ("(" + Utils .BOOK_ABBR_REGEX + ") ([0-9]+):([0-9]+)" );
176
+ for (String verse : list ) {
177
+ Matcher m = ptn .matcher (verse );
178
+ if (!m .matches ())
179
+ throw new RuntimeException ("Invalid verse reference: " + verse );
180
+ String abbr = m .group (1 );
181
+ int aidx = bookAbbrOrder .indexOf (abbr );
182
+ if (aidx == 0 ) {
183
+ aidx = bookAbbrOrder .size ();
184
+ bookAbbrOrder .add (abbr );
185
+ }
186
+ sortKey .put (verse , new int [] { aidx , Integer .parseInt (m .group (2 )), Integer .parseInt (m .group (3 )) });
187
+ }
188
+ list .sort (Comparator .comparing (v -> sortKey .get (v ), Comparator .<int [], Integer > comparing (a -> a [0 ]).thenComparing (a -> a [1 ]).thenComparing (a -> a [2 ])));
189
+ for (String verse : list ) {
190
+ System .out .println (prefix + verse );
191
+ }
144
192
}
145
193
146
194
public static final class VersificationScheme implements Comparable <VersificationScheme > {
0 commit comments