File Coverage

blib/lib/Bible/Reference.pm
Criterion Covered Total %
statement 441 443 99.5
branch 158 180 87.7
condition 83 109 76.1
subroutine 27 27 100.0
pod 17 17 100.0
total 726 776 93.5


line stmt bran cond sub pod time code
1             package Bible::Reference;
2             # ABSTRACT: Simple Bible reference parser, tester, and canonicalizer
3              
4 3     3   611551 use 5.022;
  3         14  
5              
6 3     3   1922 use exact;
  3         161558  
  3         77  
7 3     3   13697 use exact::class;
  3         64820  
  3         21  
8              
9             our $VERSION = '1.20'; # VERSION
10              
11             has acronyms => 0;
12             has sorting => 1;
13             has require_chapter_match => 0;
14             has require_verse_match => 0;
15             has require_book_ucfirst => 0;
16             has minimum_book_length => 3;
17             has add_detail => 0;
18             has simplify => 0;
19              
20             my $bibles = {
21             ESV => [
22             [
23             [ 'Genesis', 'Ge', 'Gn', 'Gen' ],
24             [ 'Exodus', 'Ex', 'Exo' ],
25             [ 'Leviticus', 'Lv', 'Lev' ],
26             [ 'Numbers', 'Nu', 'Nm', 'Num' ],
27             [ 'Deuteronomy', 'Dt', 'Deu' ],
28             [ 'Joshua', 'Jsh', 'Jos', 'Josh' ],
29             [ 'Judges', 'Jdg', 'Judg' ],
30             [ 'Ruth', 'Ru', 'Rut' ],
31             [ '1 Samuel', '1Sa', '1Sm', '1Sam' ],
32             [ '2 Samuel', '2Sa', '2Sm', '2Sam' ],
33             [ '1 Kings', '1Ki', '1Kg', '1Kgs', '1Kin' ],
34             [ '2 Kings', '2Ki', '2Kg', '2Kgs', '2Kin' ],
35             [ '1 Chronicles', '1Ch', '1Cr', '1Chr' ],
36             [ '2 Chronicles', '2Ch', '2Cr', '2Chr' ],
37             [ 'Ezra', 'Ezr' ],
38             [ 'Nehemiah', 'Ne', 'Neh' ],
39             [ 'Esther', 'Est', 'Esth' ],
40             [ 'Job', 'Jb', 'Jo', 'Job' ],
41             [ 'Psalm', 'Ps', 'Psa', 'Psalms' ],
42             [ 'Proverbs', 'Pr', 'Prv', 'Pro', 'Prov' ],
43             [ 'Ecclesiastes', 'Ec', 'Ecc', 'Eccl' ],
44             [ 'Song of Solomon', 'SS', 'SoS', 'Song of Songs' ],
45             [ 'Isaiah', 'Is', 'Isa' ],
46             [ 'Jeremiah', 'Jr', 'Jer' ],
47             [ 'Lamentations', 'Lm', 'La', 'Lam' ],
48             [ 'Ezekiel', 'Ezk', 'Ez', 'Eze', 'Ezek' ],
49             [ 'Daniel', 'Da', 'Dn', 'Dan' ],
50             [ 'Hosea', 'Ho', 'Hs', 'Hos' ],
51             [ 'Joel', 'Jl', 'Joe', 'Joel' ],
52             [ 'Amos', 'Am', 'Amo' ],
53             [ 'Obadiah', 'Ob', 'Oba' ],
54             [ 'Jonah', 'Jnh', 'Jon', 'Jona' ],
55             [ 'Micah', 'Mi', 'Mic' ],
56             [ 'Nahum', 'Na', 'Nah' ],
57             [ 'Habakkuk', 'Hab' ],
58             [ 'Zephaniah', 'Zp', 'Zep', 'Zph', 'Zeph' ],
59             [ 'Haggai', 'Hg', 'Hag' ],
60             [ 'Zechariah', 'Zec', 'Zch', 'Zech' ],
61             [ 'Malachi', 'Ml', 'Mal' ],
62             [ 'Matthew', 'Mt', 'Mat', 'Matt' ],
63             [ 'Mark', 'Mk', 'Mr', 'Mc', 'Mark' ],
64             [ 'Luke', 'Lk', 'Lu', 'Luk' ],
65             [ 'John', 'Joh' ],
66             [ 'Acts', 'Ac', 'Act' ],
67             [ 'Romans', 'Ro', 'Rm', 'Rom', 'Roms' ],
68             [ '1 Corinthians', '1Co', '1Cor' ],
69             [ '2 Corinthians', '2Co', '2Cor' ],
70             [ 'Galatians', 'Ga', 'Gl', 'Gal' ],
71             [ 'Ephesians', 'Ep', 'Eph' ],
72             [ 'Philippians', 'Php', 'Phil' ],
73             [ 'Colossians', 'Cl', 'Col' ],
74             [ '1 Thessalonians', '1Th', '1The' ],
75             [ '2 Thessalonians', '2Th', '2The' ],
76             [ '1 Timothy', '1Ti', '1Tm', '1Tim' ],
77             [ '2 Timothy', '2Ti', '2Tm', '2Tim' ],
78             [ 'Titus', 'Ti', 'Tt' ],
79             [ 'Philemon', 'Phm', 'Phlm', 'Phile' ],
80             [ 'Hebrews', 'He', 'Heb' ],
81             [ 'James', 'Jam', 'Jms', 'Jas' ],
82             [ '1 Peter', '1Pt', '1Pe', '1Pet' ],
83             [ '2 Peter', '2Pt', '2Pe', '2Pet' ],
84             [ '1 John', '1Jn', '1Jo', '1Joh' ],
85             [ '2 John', '2Jn', '2Jo', '2Joh' ],
86             [ '3 John', '3Jn', '3Jo', '3Joh' ],
87             [ 'Jude', 'Jud', 'Jude' ],
88             [ 'Revelation', 'Rv', 'Rev' ],
89             ],
90             [
91             [
92             31, 25, 24, 26, 32, 22, 24, 22, 29, 32, 32, 20, 18, 24, 21, 16, 27, 33, 38, 18, 34, 24, 20,
93             67, 34, 35, 46, 22, 35, 43, 55, 32, 20, 31, 29, 43, 36, 30, 23, 23, 57, 38, 34, 34, 28, 34,
94             31, 22, 33, 26,
95             ],
96             [
97             22, 25, 22, 31, 23, 30, 25, 32, 35, 29, 10, 51, 22, 31, 27, 36, 16, 27, 25, 26, 36, 31, 33,
98             18, 40, 37, 21, 43, 46, 38, 18, 35, 23, 35, 35, 38, 29, 31, 43, 38,
99             ],
100             [
101             17, 16, 17, 35, 19, 30, 38, 36, 24, 20, 47, 8, 59, 57, 33, 34, 16, 30, 37, 27, 24, 33, 44,
102             23, 55, 46, 34,
103             ],
104             [
105             54, 34, 51, 49, 31, 27, 89, 26, 23, 36, 35, 16, 33, 45, 41, 50, 13, 32, 22, 29, 35, 41, 30,
106             25, 18, 65, 23, 31, 40, 16, 54, 42, 56, 29, 34, 13,
107             ],
108             [
109             46, 37, 29, 49, 33, 25, 26, 20, 29, 22, 32, 32, 18, 29, 23, 22, 20, 22, 21, 20, 23, 30, 25,
110             22, 19, 19, 26, 68, 29, 20, 30, 52, 29, 12,
111             ],
112             [
113             18, 24, 17, 24, 15, 27, 26, 35, 27, 43, 23, 24, 33, 15, 63, 10, 18, 28, 51, 9, 45, 34, 16,
114             33,
115             ],
116             [ 36, 23, 31, 24, 31, 40, 25, 35, 57, 18, 40, 15, 25, 20, 20, 31, 13, 31, 30, 48, 25 ],
117             [ 22, 23, 18, 22 ],
118             [
119             28, 36, 21, 22, 12, 21, 17, 22, 27, 27, 15, 25, 23, 52, 35, 23, 58, 30, 24, 42, 15, 23, 29,
120             22, 44, 25, 12, 25, 11, 31, 13,
121             ],
122             [
123             27, 32, 39, 12, 25, 23, 29, 18, 13, 19, 27, 31, 39, 33, 37, 23, 29, 33, 43, 26, 22, 51, 39,
124             25,
125             ],
126             [ 53, 46, 28, 34, 18, 38, 51, 66, 28, 29, 43, 33, 34, 31, 34, 34, 24, 46, 21, 43, 29, 53 ],
127             [
128             18, 25, 27, 44, 27, 33, 20, 29, 37, 36, 21, 21, 25, 29, 38, 20, 41, 37, 37, 21, 26, 20, 37,
129             20, 30,
130             ],
131             [
132             54, 55, 24, 43, 26, 81, 40, 40, 44, 14, 47, 40, 14, 17, 29, 43, 27, 17, 19, 8, 30, 19, 32,
133             31, 31, 32, 34, 21, 30,
134             ],
135             [
136             17, 18, 17, 22, 14, 42, 22, 18, 31, 19, 23, 16, 22, 15, 19, 14, 19, 34, 11, 37, 20, 12, 21,
137             27, 28, 23, 9, 27, 36, 27, 21, 33, 25, 33, 27, 23,
138             ],
139             [ 11, 70, 13, 24, 17, 22, 28, 36, 15, 44 ],
140             [ 11, 20, 32, 23, 19, 19, 73, 18, 38, 39, 36, 47, 31 ],
141             [ 22, 23, 15, 17, 14, 14, 10, 17, 32, 3 ],
142             [
143             22, 13, 26, 21, 27, 30, 21, 22, 35, 22, 20, 25, 28, 22, 35, 22, 16, 21, 29, 29, 34, 30, 17,
144             25, 6, 14, 23, 28, 25, 31, 40, 22, 33, 37, 16, 33, 24, 41, 30, 24, 34, 17,
145             ],
146             [
147             6, 12, 8, 8, 12, 10, 17, 9, 20, 18, 7, 8, 6, 7, 5, 11, 15, 50, 14, 9, 13, 31, 6,
148             10, 22, 12, 14, 9, 11, 12, 24, 11, 22, 22, 28, 12, 40, 22, 13, 17, 13, 11, 5, 26, 17, 11,
149             9, 14, 20, 23, 19, 9, 6, 7, 23, 13, 11, 11, 17, 12, 8, 12, 11, 10, 13, 20, 7, 35, 36,
150             5, 24, 20, 28, 23, 10, 12, 20, 72, 13, 19, 16, 8, 18, 12, 13, 17, 7, 18, 52, 17, 16, 15,
151             5, 23, 11, 13, 12, 9, 9, 5, 8, 28, 22, 35, 45, 48, 43, 13, 31, 7, 10, 10, 9, 8, 18,
152             19, 2, 29, 176, 7, 8, 9, 4, 8, 5, 6, 5, 6, 8, 8, 3, 18, 3, 3, 21, 26, 9, 8,
153             24, 13, 10, 7, 12, 15, 21, 10, 20, 14, 9, 6,
154             ],
155             [
156             33, 22, 35, 27, 23, 35, 27, 36, 18, 32, 31, 28, 25, 35, 33, 33, 28, 24, 29, 30, 31, 29, 35,
157             34, 28, 28, 27, 28, 27, 33, 31,
158             ],
159             [ 18, 26, 22, 16, 20, 12, 29, 17, 18, 20, 10, 14 ],
160             [ 17, 17, 11, 16, 16, 13, 13, 14 ],
161             [
162             31, 22, 26, 6, 30, 13, 25, 22, 21, 34, 16, 6, 22, 32, 9, 14, 14, 7, 25, 6, 17, 25, 18,
163             23, 12, 21, 13, 29, 24, 33, 9, 20, 24, 17, 10, 22, 38, 22, 8, 31, 29, 25, 28, 28, 25, 13,
164             15, 22, 26, 11, 23, 15, 12, 17, 13, 12, 21, 14, 21, 22, 11, 12, 19, 12, 25, 24,
165             ],
166             [
167             19, 37, 25, 31, 31, 30, 34, 22, 26, 25, 23, 17, 27, 22, 21, 21, 27, 23, 15, 18, 14, 30, 40,
168             10, 38, 24, 22, 17, 32, 24, 40, 44, 26, 22, 19, 32, 21, 28, 18, 16, 18, 22, 13, 30, 5, 28,
169             7, 47, 39, 46, 64, 34,
170             ],
171             [ 22, 22, 66, 22, 22 ],
172             [
173             28, 10, 27, 17, 17, 14, 27, 18, 11, 22, 25, 28, 23, 23, 8, 63, 24, 32, 14, 49, 32, 31, 49,
174             27, 17, 21, 36, 26, 21, 26, 18, 32, 33, 31, 15, 38, 28, 23, 29, 49, 26, 20, 27, 31, 25, 24,
175             23, 35,
176             ],
177             [ 21, 49, 30, 37, 31, 28, 28, 27, 27, 21, 45, 13 ],
178             [ 11, 23, 5, 19, 15, 11, 16, 14, 17, 15, 12, 14, 16, 9 ],
179             [ 20, 32, 21 ],
180             [ 15, 16, 15, 13, 27, 14, 17, 14, 15 ],
181             [ 21 ],
182             [ 17, 10, 10, 11 ],
183             [ 16, 13, 12, 13, 15, 16, 20 ],
184             [ 15, 13, 19 ],
185             [ 17, 20, 19 ],
186             [ 18, 15, 20 ],
187             [ 15, 23 ],
188             [ 21, 13, 10, 14, 11, 15, 14, 23, 17, 12, 17, 14, 9, 21 ],
189             [ 14, 17, 18, 6 ],
190             [
191             25, 23, 17, 25, 48, 34, 29, 34, 38, 42, 30, 50, 58, 36, 39, 28, 27, 35, 30, 34, 46, 46, 39,
192             51, 46, 75, 66, 20,
193             ],
194             [ 45, 28, 35, 41, 43, 56, 37, 38, 50, 52, 33, 44, 37, 72, 47, 20 ],
195             [
196             80, 52, 38, 44, 39, 49, 50, 56, 62, 42, 54, 59, 35, 35, 32, 31, 37, 43, 48, 47, 38, 71, 56,
197             53,
198             ],
199             [ 51, 25, 36, 54, 47, 71, 53, 59, 41, 42, 57, 50, 38, 31, 27, 33, 26, 40, 42, 31, 25 ],
200             [
201             26, 47, 26, 37, 42, 15, 60, 40, 43, 48, 30, 25, 52, 28, 41, 40, 34, 28, 41, 38, 40, 30, 35,
202             27, 27, 32, 44, 31,
203             ],
204             [ 32, 29, 31, 25, 21, 23, 25, 39, 33, 21, 36, 21, 14, 23, 33, 27 ],
205             [ 31, 16, 23, 21, 13, 20, 40, 13, 27, 33, 34, 31, 13, 40, 58, 24 ],
206             [ 24, 17, 18, 18, 21, 18, 16, 24, 15, 18, 33, 21, 14 ],
207             [ 24, 21, 29, 31, 26, 18 ],
208             [ 23, 22, 21, 32, 33, 24 ],
209             [ 30, 30, 21, 23 ],
210             [ 29, 23, 25, 18 ],
211             [ 10, 20, 13, 18, 28 ],
212             [ 12, 17, 18 ],
213             [ 20, 15, 16, 16, 25, 21 ],
214             [ 18, 26, 17, 22 ],
215             [ 16, 15, 15 ],
216             [ 25 ],
217             [ 14, 18, 19, 16, 14, 20, 28, 13, 28, 39, 40, 29, 25 ],
218             [ 27, 26, 18, 17, 20 ],
219             [ 25, 25, 22, 19, 14 ],
220             [ 21, 22, 18 ],
221             [ 10, 29, 24, 21, 21 ],
222             [ 13 ],
223             [ 15 ],
224             [ 25 ],
225             [ 20, 29, 22, 11, 14, 17, 17, 13, 21, 11, 19, 17, 18, 20, 8, 21, 18, 24, 21, 15, 27, 21 ],
226             ],
227             ],
228             };
229              
230 7     7   31 sub _build_bible_template ( $source_name, $new_name, $bibles, $books_cb = undef, $verses_cb = undef ) {
  7         19  
  7         15  
  7         16  
  7         19  
  7         14  
  7         13  
231 7         14 $bibles->{$new_name} = [ map { [ map { [@$_] } @$_ ] } @{ $bibles->{$source_name} } ];
  14         43  
  960         3013  
  7         26  
232 7 100       51 $books_cb->( $bibles->{$new_name}[0] ) if ($books_cb);
233 7 100       67 $verses_cb->( $bibles->{$new_name}[1] ) if ($verses_cb);
234 7         23 return;
235             }
236              
237             _build_bible_template(
238             'ESV' => 'RSVCE',
239             $bibles,
240             sub ($books) {
241             splice( @$books, 25, 0,
242             [ 'Baruch', 'Ba', 'Br', 'Bar' ],
243             );
244              
245             splice( @$books, 22, 0,
246             [ 'Wisdom', 'Wi', 'Ws', 'Wis' ],
247             [ 'Sirach', 'Si', 'Sr', 'Sir' ],
248             );
249              
250             splice( @$books, 17, 0,
251             [ '1 Maccabees', '1Ma', '1Mac' ],
252             [ '2 Maccabees', '2Ma', '2Mac' ],
253             );
254              
255             splice( @$books, 16, 0,
256             [ 'Tobit', 'Tb', 'Tob' ],
257             [ 'Judith', 'Judi' ],
258             );
259             },
260             sub ($verses) {
261             push( @{ $verses->[26] }, 64, 42 );
262             splice( @$verses, 25, 0, [ 21, 35, 37, 37, 9, 73 ] );
263             splice( @$verses, 22, 0,
264             [ 16, 24, 19, 20, 23, 25, 30, 21, 18, 21, 26, 27, 19, 31, 19, 29, 21, 25, 22 ],
265             [
266             30, 18, 31, 31, 15, 37, 36, 19, 18, 31, 34, 18, 26, 27, 20, 30, 32, 33, 30, 31, 28, 27, 27,
267             34, 26, 29, 30, 26, 28, 25, 31, 24, 31, 26, 20, 26, 31, 34, 35, 30, 23, 25, 33, 23, 26, 20,
268             25, 25, 16, 29, 30,
269             ],
270             );
271             splice( @$verses, 16, 1,
272             [ 22, 14, 17, 21, 22, 17, 18, 21, 6, 12, 19, 22, 18, 15 ],
273             [ 16, 28, 10, 15, 24, 21, 32, 36, 14, 23, 23, 20, 20, 19, 13, 25 ],
274             [ 22, 23, 15, 19, 14, 14, 10, 17, 32, 1 ],
275             [ 64, 70, 60, 61, 68, 63, 50, 32, 73, 89, 74, 53, 53, 49, 41, 24 ],
276             [ 36, 32, 40, 50, 27, 31, 42, 36, 29, 38, 38, 45, 26, 46, 39 ],
277             );
278             },
279             );
280              
281             _build_bible_template(
282             'ESV' => 'RSV',
283             $bibles,
284             sub ($books) {
285             push( @$books,
286             [ 'Tobit', 'Tb', 'Tob' ],
287             [ 'Judith', 'Judi', 'Jdt' ],
288             [ 'Greek Esther', 'GkEsth' ],
289             [ 'Wisdom', 'Wi', 'Ws', 'Wis', 'Wisdom of Solomon' ],
290             [ 'Sirach', 'Si', 'Sr', 'Sir', 'Ben Sira', 'Wisdom of Ben Sira' ],
291             [ 'Baruch', 'Ba', 'Br', 'Bar' ],
292             [ 'Letter of Jeremiah', 'LJ', 'Let', 'EpJer' ],
293             [ 'Song of the Three Young Men', 'SgThr', 'Three', 'Prayer of Azariah' ],
294             [ 'Susanna', 'Sus' ],
295             [ 'Bel and the Dragon', 'Bel' ],
296             [ '1 Maccabees', '1Ma', '1Mac', '1Macc' ],
297             [ '2 Maccabees', '2Ma', '2Mac', '2Macc' ],
298             [ '1 Esdras', '1Es', '1Esd', '1Esdr' ],
299             [ 'Prayer of Manasseh', 'PM', 'Pra', 'Man', 'PrMan' ],
300             [ 'Psalm 151', 'Ps151', 'Psa151' ],
301             [ '3 Maccabees', '3Ma', '3Mac', '3Macc' ],
302             [ '2 Esdras', '2Es', '2Esd', '2Esdr' ],
303             [ '4 Maccabees', '4Ma', '4Mac', '4Macc' ],
304             );
305             },
306             sub ($verses) {
307             push( @$verses,
308             [ 22, 14, 17, 21, 21, 17, 18, 21, 6, 12, 19, 22, 18, 15 ],
309             [ 16, 28, 10, 15, 24, 21, 32, 36, 14, 23, 23, 20, 20, 19, 13, 25 ],
310             [ 22, 23, 15, 19, 14, 14, 10, 17, 32, 1 ],
311             [ 16, 24, 19, 20, 23, 25, 30, 21, 18, 21, 26, 27, 19, 31, 19, 29, 21, 25, 22 ],
312             [
313             30, 18, 31, 31, 15, 37, 36, 19, 18, 31, 34, 18, 26, 27, 20, 30, 32, 33, 30, 31, 28, 27, 27,
314             34, 26, 29, 30, 26, 28, 25, 31, 24, 31, 26, 20, 26, 31, 34, 35, 30, 23, 25, 33, 23, 26, 20,
315             25, 25, 16, 29, 30,
316             ],
317             [ 21, 35, 37, 37, 9 ],
318             [ 73 ],
319             [ 68 ],
320             [ 64 ],
321             [ 42 ],
322             [ 64, 70, 60, 61, 68, 63, 50, 32, 73, 89, 74, 53, 53, 49, 41, 24 ],
323             [ 36, 32, 40, 50, 27, 31, 42, 36, 29, 38, 38, 45, 26, 46, 39 ],
324             [ 58, 30, 24, 63, 73, 34, 15, 96, 55 ],
325             [ 15 ],
326             [ 7 ],
327             [ 29, 33, 30, 21, 51, 41, 23 ],
328             [ 40, 48, 36, 52, 56, 59, 140, 63, 47, 59, 46, 51, 58, 48, 63, 78 ],
329             [ 35, 24, 21, 26, 38, 35, 23, 29, 32, 21, 27, 19, 27, 20, 32, 25, 24, 24 ],
330             );
331             },
332             );
333              
334             $bibles->{Protestant} = $bibles->{ESV};
335             $bibles->{Catholic} = $bibles->{RSVCE};
336             $bibles->{Orthodox} = $bibles->{RSV};
337              
338             has _bible => 'Protestant';
339             has _bible_data => sub { {} };
340             has _data => sub { [] };
341             has _cache => sub { {} };
342             has _bibles => sub {
343             return { map { $_ => [ map { [ map { [ @$_] } @$_ ] } @{ $bibles->{$_} } ] } keys %$bibles };
344             };
345              
346 27     27 1 50724 sub bible ( $self, $name = undef ) {
  27         67  
  27         75  
  27         61  
347 27 100       129 return $self->_bible unless ($name);
348              
349 21   50     101 my $input = lc( $name || '' );
350 21         53 my ($bible) = grep { lc $_ eq $input } keys %{ $self->_bibles };
  128         583  
  21         103  
351              
352 21 100       372 croak "Could not determine a valid Bible type from input" unless ($bible);
353 20         130 $self->_bible($bible);
354              
355 20         188 my $books = [ map { [@$_] } @{ $self->_bibles->{ $self->_bible }[0] } ];
  1418         4688  
  20         70  
356              
357 20         86 my $bible_data;
358 20         69 for my $book_data (@$books) {
359 1418         3148 my ( $book, @acronyms ) = @$book_data;
360              
361 1418         4511 $bible_data->{book_to_acronym}{$book} = $acronyms[0];
362 1418         1837 push( @{ $bible_data->{books} }, $book );
  1418         3309  
363             }
364 20         41 my $book_count;
365 20         44 $bible_data->{book_order} = { map { $_ => ++$book_count } @{ $bible_data->{books} } };
  1418         3012  
  20         67  
366              
367 20         160 my $canonical = [ map { $_->[0] } @$books ];
  1418         2490  
368 20         111 my $options = { map { shift @$_ => $_ } @$books };
  1418         2946  
369             my $re_map = { map {
370 20         186 my $book = $_;
  1418         2632  
371 1418         2269 my $book_str = $_;
372 1418 50       6682 my @prefix = (
    100          
    100          
    100          
    100          
373             ( $book_str =~ s/^(\d)\s// ) ? (
374             (
375             (
376             ( $1 == 1 ) ? ( qw( I First ) ) :
377             ( $1 == 2 ) ? ( qw( II Second ) ) :
378             ( $1 == 3 ) ? ( qw( III Third ) ) :
379             ( $1 == 4 ) ? ( qw( IV Fourth ) ) : ()
380             ),
381             $1 . '*',
382             ),
383             $1,
384             ) : ()
385             );
386              
387 1418         5445 my @letters = split( '', $book_str );
388 1418         2179 my $unique;
389 1418         3277 while (@letters) {
390 4463         33575 $unique .= shift @letters;
391             last if (
392             length $unique >= $self->minimum_book_length
393             and (
394             not @prefix and
395             scalar( grep { index( $_, $unique ) == 0 } @$canonical ) == 1 or
396             @prefix and
397 4463 100 100     11996 scalar( grep { index( $_, $prefix[-1] . ' ' . $unique ) == 0 } @$canonical ) == 1
      100        
398             )
399             );
400             }
401              
402 1418         3813 my @matches = $unique;
403 1418         8933 push( @matches, $unique .= shift @letters ) while (@letters);
404              
405             @matches = map {
406 1418         2758 my $match = $_;
  7190         11091  
407              
408 7190         9760 $match .= ')i?(';
409 7190         26837 $match =~ s/^(\w)/$1)i-?(/;
410              
411 7190 100       17642 (@prefix) ? ( map { ')' . $_ . ':i?(' . ' ' . $match } @prefix ) : $match;
  8112         17222  
412             } @matches;
413              
414             map {
415 16906         27910 my $re = reverse $_;
416              
417 16906         25980 $re =~ s/\*/'[A-z]+'/ge;
  2028         4969  
418 16906         34179 $re =~ s/\s+/'[\s_]*'/ge;
  9315         24410  
419              
420 16906         57048 $re => $book;
421 1418         2347 } @matches, @{ $options->{$book} };
  1418         4771  
422             } @$canonical };
423              
424 20         7729 my @re_parts = sort { length $b <=> length $a } keys %$re_map;
  136587         188124  
425              
426 20         1126 my $re_refs = '(?i:[\d:,;\s\-]|\bdna\b|\bro\b|&)*\.?';
427 20         59 my $re_refs_req =
428             '(?i:[\d:,;\s\-]|\bdna\b|\bro\b|&)*' .
429             '(?:\d\s*:\s*\d)' .
430             '(?i:[\d:,;\s\-]|\bdna\b|\bro\b|&)*\.?';
431              
432 20         149 my $re_refs_string = '\b(' . join( '|', map { $re_refs . $_ } @re_parts ) . ')\b';
  16906         39306  
433 20         1499 my $re_refs_req_string = '\b(' . join( '|', map { $re_refs_req . $_ } @re_parts ) . ')\b';
  16906         40767  
434              
435 20         987963 $bible_data->{re_refs_s} = qr/$re_refs_string/;
436 20         5363840 $bible_data->{re_refs_sr} = qr/$re_refs_req_string/;
437 20         26141 $bible_data->{re_books_s} = [ map { [ qr/\b$_\b/, $re_map->{$_} ] } @re_parts ];
  16906         349183  
438              
439 20         22706 $re_refs_string =~ s/\(\?\-?i\)//g;
440 20         24189 $re_refs_req_string =~ s/\(\?\-?i\)//g;
441              
442 20         925255 $bible_data->{re_refs_i} = qr/$re_refs_string/i;
443 20         4760667 $bible_data->{re_refs_ir} = qr/$re_refs_req_string/i;
444             $bible_data->{re_books_i} = [ map {
445 20         22783 my $this_book = $re_map->{$_};
  16906         42123  
446 16906         61760 s/\(\?\-?i\)//g;
447 16906         341265 [ qr/\b$_\b/i, $this_book ];
448             } @re_parts ];
449              
450             $bible_data->{lengths} = {
451             map {
452 1418         15242 $bible_data->{books}[$_] => [ @{ $self->_bibles->{$bible}[1][$_] } ]
  1418         2629  
453 20         622 } 0 .. @{ $bible_data->{books} } - 1
  20         211  
454             };
455              
456 20         1372 $self->_bible_data($bible_data);
457 20         80160 return $bible;
458             }
459              
460 4     4 1 495333 sub new ( $self, %params ) {
  4         9  
  4         10  
  4         8  
461 4         64 $self = $self->SUPER::new(%params);
462 4   33     3479 $self->bible( $params{bible} || $self->_bible );
463 4         39 return $self;
464             }
465              
466 213     213   441 sub _list ( $start, $stop ) {
  213         395  
  213         341  
  213         313  
467 213 50       682 $start++ if ( $start == 0 );
468 213 50       562 $stop++ if ( $stop == 0 );
469              
470 213         1241 my ( $x, $y ) = sort { $a <=> $b } $start, $stop;
  426         797  
471 213         745 my @list = $x .. $y;
472 213 100       634 @list = reverse(@list) if ( $x < $start );
473              
474 213         2030 return @list;
475             };
476              
477 187     187 1 432 sub expand_ranges ( $self, $book, $text, $compress = 0 ) {
  187         531  
  187         306  
  187         712  
  187         410  
  187         342  
478 189     189   302 my $expand = sub ( $start, $stop ) {
  189         502  
  189         419  
  189         314  
479 189 100       799 my $start_ch = ( $start =~ s/(\d+):// ) ? $1 : 0;
480 189 100       738 my $stop_ch = ( $stop =~ s/(\d+):// ) ? $1 : 0;
481              
482 189 100 100     995 if ( not $start_ch and $stop_ch and $start > $stop_ch ) {
      100        
483             # A: "5-3:4" = translated to "5:1-3:4"
484              
485 1         3 $start_ch = $start;
486 1         3 $start = 1;
487             }
488              
489 189         332 my $skip_chapter_assumption_check = 0;
490 189 100 100     981 if ( $start_ch and $stop_ch and $start and $stop and $start_ch == $stop_ch ) {
      66        
      66        
      66        
491 2 100       8 if ( $start <= $stop ) {
492             # B: "3:4-3:7" = translated to "3:4-7"
493              
494 1         3 $stop_ch = 0;
495             }
496             else {
497             # Q: "3:37-3:4" is the reverse of 3:4-3:37
498              
499 1         2 $stop_ch = 0;
500 1         1 $skip_chapter_assumption_check = 1;
501             }
502             }
503              
504 189         355 my $expance = '';
505              
506 189 100 100     1294 if ( not $start_ch and not $stop_ch ) {
    100 100        
    100 66        
    50 33        
507             # C: "3-3" = consider as "3"
508             # D: "3-5" = consider as a simple range
509             # E: "5-3" = consider as a simple reversed range
510              
511 101         337 $expance = join( ',', _list( $start, $stop ) );
512             }
513              
514             elsif ( $start_ch and not $stop_ch ) {
515             # F: "1:3-15" = consider 3-15 as verses
516             # G: "1:15-3" = consider 3 a chapter
517             # H: "1:3-3" = consider the second 3 a chapter
518             # I: "3:2-3" = consider 2-3 as verses
519             # J: "3:3-2" = consider 3-2 as verses
520              
521 71 100 100     350 if ( $start >= $stop and $stop > $start_ch and not $skip_chapter_assumption_check ) {
      100        
522 4         8 $stop_ch = $stop;
523 4         16 $stop = $self->_bible_data->{lengths}{$book}[ $start_ch - 1 ];
524             }
525              
526 71 100       303 $expance = join( ';', grep { defined }
  142         460  
527             $start_ch . ':' . join( ',', _list( $start, $stop ) ),
528             ( ($stop_ch) ? join( ';', _list( $start_ch + 1, $stop_ch ) ) : undef ),
529             );
530             }
531              
532             elsif ( not $start_ch and $stop_ch ) {
533             # K: "3-5:2" = 3-4 are full chapters; plus 5:1-5:2
534             # L: "3-3:2" = interpretted as "3:1-2"
535              
536 10         34 $start_ch = $start;
537 10         25 $start = 1;
538              
539 10         54 $expance = join( ':',
540             join( ';', _list( $start_ch, $stop_ch ) ),
541             join( ',', _list( $start, $stop ) ),
542             );
543             }
544              
545             elsif ( $start_ch and $stop_ch ) {
546             # M: "3:4-4:7" becomes "3:4-*;4:1-7"
547             # N: "4:7-3:4" becomes reverse of "3:4-*;4:1-7"
548             # O: "3:4-5:2" becomes "3:4-*;4;5:1-2"
549             # P: "5:2-3:4" becomes reverse of "3:4-*;4;5:2-*"
550              
551 7         11 my $reversed = 0;
552 7 100       15 if ( $start_ch >= $stop_ch ) {
553 3         13 ( $start_ch, $stop_ch, $start, $stop ) = ( $stop_ch, $start_ch, $stop, $start );
554 3         6 $reversed = 1;
555             }
556              
557 7 100       30 my $reverse = sub { ($reversed) ? reverse(@_) : @_ };
  24         205  
558              
559 21         68 $expance = join( ';', grep { defined }
560             $reverse->(
561             $start_ch . ':' . join( ',', $reverse->( _list(
562             $start,
563 7 100       38 $self->_bible_data->{lengths}{$book}[ $start_ch - 1 ],
564             ) ) ),
565             (
566             ( $stop_ch - $start_ch > 1 )
567             ? join( ',', $reverse->( _list( $start_ch + 1, $stop_ch - 1 ) ) )
568             : undef
569             ),
570             $stop_ch . ':' . join( ',', $reverse->( _list( 1, $stop ) ) ),
571             ),
572             );
573             }
574              
575 189         1410 $expance;
576 187         2525 };
577              
578 187         1245 $text =~ s/[\s,]+/,/g;
579 187         765 $text =~ s/^,//g;
580 187         1214 $text =~ s/(\d+(?::\d+)?)\-(\d+(?::\d+)?)/ $expand->( $1, $2 ) /ge;
  189         608  
581 187 50       747 $text =~ s/([,;])/$1 /g unless $compress;
582              
583 187         4780 return $text;
584             };
585              
586 26     26 1 9500 sub in ( $self, @input ) {
  26         55  
  26         134  
  26         51  
587 26 50       155 return $self unless (@input);
588              
589             my $re_refs = $self->_bible_data->{
590 26 100       186 're_refs_' .
    100          
591             ( ( $self->require_book_ucfirst ) ? 's' : 'i' ) .
592             ( ( $self->require_verse_match ) ? 'r' : '' )
593             };
594              
595             my $re_books = ( $self->require_book_ucfirst )
596             ? $self->_bible_data->{re_books_s}
597 26 100       1309 : $self->_bible_data->{re_books_i};
598              
599 26         471 for my $string (@input) {
600 175   100     971 $string = scalar( reverse $string // '' );
601 175         382 my @processed;
602 175         477 while (1) {
603 516         1259011 my ( $pre, $ref, $post ) = split( /$re_refs/, $string, 2 );
604 516 100       3366 last unless ($ref);
605              
606 341         1389 $ref =~ s/(\d)([[:alpha:]])/$1 $2/;
607              
608 341         758 $string = $post;
609              
610 341 100       2572 my $space = ( $ref =~ s/^((?i:\W|\bdna\b|\bro\b|&)+)// ) ? $1 : '';
611 341         1919 $ref =~ s/\s+/ /g;
612 341         843 $pre = $pre . $space;
613 341         1053 push( @processed, $pre );
614              
615 341         819 my $orig_ref = $ref;
616              
617 341         620 my $book;
618 341         1149 for (@$re_books) {
619 154841 100       566892 if ( $ref =~ /$_->[0]/ ) {
620 341         1153 $book = $_->[1];
621 341         922 last;
622             }
623             }
624              
625 341         1112 my $ref_out = [$book];
626 341         807 my $numbers = [];
627              
628 341         2087 $ref =~ s/(?:\bdna\b|\bro\b|&)/,/g;
629 341         1315 $ref = scalar reverse $ref;
630              
631 341 100       1964 if ( $ref =~ /([\d:,;\s\-]+)$/ ) {
632 166         1247 my $range = $self->expand_ranges( $book, $1, 1 );
633              
634 166         431 my $verse_context = 0;
635 166         412 my $last_d = 0;
636              
637 166         1288 while ( $range =~ s/^(\d+)([:,;]?)\D*//g ) {
638 1422   100     5205 my ( $d, $s ) = ( $1, $2 || '' );
639              
640 1422 100 100     4640 $verse_context = 0 if ( $s eq ':' or $d <= $last_d );
641              
642 1422 100       2543 unless ($verse_context) {
643 685         1933 push( @$numbers, [$d] );
644             }
645             else {
646 737 100       1006 push( @{ $numbers->[-1] }, [] ) unless ( @{ $numbers->[-1] } > 1 );
  138         473  
  737         1776  
647 737         1128 push( @{ $numbers->[-1][-1] }, $d );
  737         1584  
648             }
649              
650 1422 100       2494 $last_d = ($verse_context) ? $d : 0;
651              
652 1422 100       2848 $verse_context = 1 if ( $s eq ':' );
653 1422 100       6714 $verse_context = 0 if ( $s eq ';' );
654             }
655             }
656              
657 341 100 100     2503 if ( @$numbers or not $self->require_chapter_match ) {
658 340 100       4151 push( @$ref_out, $numbers ) if (@$numbers);
659 340         1126 push( @processed, $ref_out );
660             }
661             else {
662 1         34 $processed[-1] .= $orig_ref;
663             }
664             }
665              
666 175         647 push( @processed, $string );
667             push(
668 175         1397 @{ $self->_data },
669 175 100       365 [ grep { length } map { ( ref $_ ) ? $_ : scalar reverse $_ } reverse @processed ],
  856         2596  
  856         5990  
670             );
671             }
672              
673 26         246 return $self;
674             }
675              
676 23     23 1 90420 sub clear ($self) {
  23         80  
  23         43  
677 23         138 $self->_data([]);
678 23         1912 return $self;
679             }
680              
681 4     4 1 942 sub books ($self) {
  4         29  
  4         11  
682 4 50       17 return (wantarray) ? @{ $self->_bible_data->{books} } : $self->_bible_data->{books};
  4         24  
683             }
684              
685 60     60 1 121015 sub as_array ( $self, $data = undef ) {
  60         107  
  60         116  
  60         95  
686 60 50 100     291 if (
      0        
      66        
687             $data or
688             not $self->_cache->{data} or
689             not (
690             $self->_cache->{sorting} and $self->_cache->{sorting} == $self->sorting and
691             $self->_cache->{acronyms} and $self->_cache->{acronyms} == $self->acronyms
692             )
693             ) {
694 60   100     648 $data //= [ map { grep { ref } @$_ } @{ $self->_data } ];
  202         495  
  946         1496  
  20         78  
695             $data = [
696 60         189 map { [
697             map {
698 450         753 ( ref $_ ) ? [
699             map {
700 666 100       1663 ( ref $_ ) ? [
701             map {
702 923 100       1792 ( ref $_ ) ? [
  1099 50       4075  
703             @$_
704             ] : $_
705             } @$_
706             ] : $_
707             } @$_
708             ] : $_
709             } @$_
710             ] }
711             @$data
712             ];
713              
714             $data = [ map {
715 60 100       277 my $book = $_->[0];
  43         112  
716              
717 43 100       58 if ( ref $_->[1] ) {
718             $_->[1] = [ map {
719 100   100     211 $_->[1] //= [ 1 .. ( $self->_bible_data->{lengths}{$book}[ $_->[0] - 1 ] || 0 ) ];
      100        
720 100         860 $_;
721 23         28 } @{ $_->[1] } ];
  23         29  
722             }
723             else {
724 20         17 my $chapter;
725 20         16 $_->[1] = [ map { [ ++$chapter, [ 1 .. $_ ] ] } @{ $self->_bible_data->{lengths}{$book} } ];
  209         833  
  20         30  
726             }
727              
728 43         75 $_;
729             } @$data ] if ( $self->add_detail );
730              
731 60 100       885 if ( $self->sorting ) {
732 58         652 my $data_by_book = {};
733 58 100       166 push( @{ $data_by_book->{ $_->[0] } }, @{ $_->[1] || [] } ) for (@$data);
  410         920  
  410         1344  
734              
735             $data = [
736             map {
737 257         1099 my $book = [ $_->[1] ];
738              
739 257         373 my $dedup;
740 257         353 for my $chapter ( @{ $data_by_book->{ $_->[1] } } ) {
  257         548  
741 1049   100     3851 $dedup->{ $chapter->[0] } //= {};
742 1049         1251 $dedup->{ $chapter->[0] }{$_} = 1 for ( @{ $chapter->[1] } );
  1049         7396  
743             }
744              
745             my $chapters = [
746             map {
747 928         1694 my $chapter = [$_];
748 928         1192 my @verses = keys %{ $dedup->{$_} };
  928         2417  
749 928 100       2063 push( @$chapter, [ sort { $a <=> $b } @verses ] ) if @verses;
  26151         25858  
750 928         1862 $chapter;
751             }
752 257         852 sort { $a <=> $b }
  2427         2995  
753             keys %$dedup
754             ];
755              
756 257 100       668 push( @$book, $chapters ) if (@$chapters);
757              
758 257         2976 $book;
759             }
760 671         997 sort { $a->[0] <=> $b->[0] }
761 58         236 map { [ $self->_bible_data->{book_order}{$_}, $_ ] }
  257         1816  
762             keys %$data_by_book
763             ];
764             }
765              
766             $data = [ map {
767 60 100       424 my $book = $_->[0];
  4         51  
768              
769 4 50       16 if ( my $chapters = $_->[1] ) {
770 4         12 for my $chapter (@$chapters) {
771             pop @$chapter if (
772             $chapter->[1] and
773 18         114 join( ',', @{ $chapter->[1] } ) eq
774 18 50 50     504 join( ',', 1 .. ( $self->_bible_data->{lengths}{$book}[ $chapter->[0] - 1 ] || 0 ) )
      33        
775             );
776             }
777              
778             pop @$_ if (
779 18         42 join( ',', map { $_->[0] } grep { @$_ == 1 } @$chapters ) eq
  18         43  
780 4 100       99 join( ',', 1 .. scalar @{ $self->_bible_data->{lengths}{$book} } )
  4         14  
781             );
782             }
783              
784 4         91 $_;
785             } @$data ] if ( $self->simplify );
786              
787 60 100       916 if ( $self->acronyms ) {
788 1         14 for (@$data) {
789 22         222 $_->[0] = $self->_bible_data->{book_to_acronym}{ $_->[0] };
790             }
791             }
792              
793 60         750 $self->_cache->{data} = $data;
794             }
795              
796 60 100       1813 return (wantarray) ? @{ $self->_cache->{data} } : $self->_cache->{data};
  1         4  
797             }
798              
799 1     1 1 21 sub as_hash ( $self, $data = undef ) {
  1         2  
  1         3  
  1         3  
800 1         2 my $build = {};
801              
802 1         6 for my $book_block ( $self->as_array($data) ) {
803 22         35 my ( $book_name, $chapters ) = @$book_block;
804              
805 22         45 $build->{$book_name} = {};
806 22         28 for (@$chapters) {
807 77 100       71 push( @{ $build->{$book_name}{ $_->[0] } }, @{ $_->[1] || [] } );
  77         104  
  77         151  
808             }
809             }
810              
811 1 50       6 return (wantarray) ? %$build : $build;
812             }
813              
814 88     88   184 sub _compress_range ( $items = [] ) {
  88         137  
  88         186  
815 88         154 my ( $last, @items, @range );
816              
817             my $flush_range = sub {
818 202 100   202   485 if (@range) {
819 74         124 pop @items;
820 74         224 push( @items, join( '-', $range[0], $range[-1] ) );
821 74         183 @range = ();
822             }
823 88         398 };
824              
825 88         210 for my $item (@$items) {
826 504 100 100     1501 if ( not $last or $last + 1 != $item ) {
827 114         288 $flush_range->();
828 114         244 push( @items, $item );
829             }
830             else {
831 390         685 push( @range, $last, $item );
832             }
833              
834 504         853 $last = $item;
835             }
836 88         214 $flush_range->();
837              
838 88 50       663 return (wantarray) ? @items : join( ', ', @items );
839             }
840              
841 55     55   94 sub _as_type ( $self, $type, $data = undef ) {
  55         119  
  55         104  
  55         114  
  55         90  
842 55         182 $data = $self->as_array($data);
843              
844             return [
845             map {
846 55         603 my $book = $_->[0];
  170         337  
847              
848 170 100       351 if ( $_->[1] ) {
849 74         130 my ( @build, @buffer );
850              
851             my $flush_buffer = sub {
852 83 100   83   237 if (@buffer) {
853 27         79 push( @build, join( '; ', _compress_range(\@buffer) ) );
854 27         78 @buffer = ();
855             }
856 74         388 };
857              
858 74         128 for ( @{ $_->[1] } ) {
  74         186  
859 478         750 my $chapter = $_->[0];
860              
861 478 100       862 if ( $_->[1] ) {
862 72 100       225 if ( $type eq 'verses' ) {
    100          
    100          
863 11         12 push( @build, map { "$book $chapter:$_" } @{ $_->[1] } );
  58         114  
  11         14  
864             }
865             elsif ( $type eq 'runs' ) {
866 11         25 push( @build, map { "$book $chapter:$_" } _compress_range( $_->[1] ) );
  14         43  
867             }
868             elsif ( $type eq 'chapters' ) {
869 11         28 push( @build, "$book $chapter:" . join( ', ', _compress_range( $_->[1] ) ) );
870             }
871             else {
872 39         105 $flush_buffer->();
873 39         107 push( @build, $chapter . ':' . join( ', ', _compress_range( $_->[1] ) ) );
874             }
875             }
876             else {
877 406 100       721 unless ( $type eq 'books' ) {
878 198         308 push( @build, "$book $chapter" );
879             }
880             else {
881 208         440 push( @buffer, $chapter );
882             }
883             }
884             }
885              
886 74 100       179 unless ( $type eq 'books' ) {
887 30         313 @build;
888             }
889             else {
890 44         116 $flush_buffer->();
891 44         382 $book . ' ' . join( '; ', @build );
892             }
893             }
894             else {
895 96         214 $book;
896             }
897             } @$data
898             ];
899             }
900              
901 1     1 1 20 sub as_verses ( $self, $data = undef ) {
  1         1  
  1         8  
  1         1  
902 1         6 my $items = $self->_as_type( 'verses', $data );
903 1 50       7 return (wantarray) ? @$items : $items;
904             }
905              
906 1     1 1 29 sub as_runs ( $self, $data = undef ) {
  1         2  
  1         4  
  1         3  
907 1         14 my $items = $self->_as_type( 'runs', $data );
908 1 50       13 return (wantarray) ? @$items : $items;
909             }
910              
911 1     1 1 20 sub as_chapters ( $self, $data = undef ) {
  1         3  
  1         2  
  1         2  
912 1         5 my $items = $self->_as_type( 'chapters', $data );
913 1 50       7 return (wantarray) ? @$items : $items;
914             }
915              
916 52     52 1 131 sub as_books ( $self, $data = undef ) {
  52         106  
  52         92  
  52         114  
917 52         167 my $items = $self->_as_type( 'books', $data );
918 52 100       462 return (wantarray) ? @$items : $items;
919             }
920              
921 45     45 1 620 sub refs ( $self, $data = undef ) {
  45         87  
  45         78  
  45         81  
922 45         136 return join( '; ', $self->as_books($data) );
923             }
924              
925 2     2 1 35 sub as_text ($self) {
  2         7  
  2         5  
926             my @text = map {
927 19 100       75 join( '', map { ( ref $_ ) ? $self->refs([$_]) : $_ } @$_ );
  96         387  
928 2         5 } @{ $self->_data };
  2         16  
929              
930             return
931 2 100 66     44 ( @text > 1 and wantarray ) ? @text :
    50 66        
932             ( @text > 1 and not wantarray ) ? \@text : join( ' ', @text );
933             }
934              
935 4     4 1 2749 sub set_bible_data ( $self, $bible = undef, $book_data = undef, $verse_data = undef ) {
  4         10  
  4         9  
  4         8  
  4         6  
  4         9  
936 4 50 66     265 croak 'First argument to set_bible_data() must be a Bible name string'
      66        
937             unless ( $bible and not ref $bible and length $bible > 0 );
938 3 100 66     220 croak 'Second argument to set_bible_data() must be an arrayref of arrayrefs'
939             unless ( $book_data and ref $book_data eq 'ARRAY' );
940              
941 2         6 for (@$book_data) {
942 41 50 66     611 croak 'Second argument to set_bible_data() does not appear valid' unless (
      66        
      66        
      33        
943             ref $_ eq 'ARRAY' and
944             not ref $_->[0] and length $_->[0] > 0 and
945             not ref $_->[1] and length $_->[1] > 0
946             );
947             }
948              
949 1 50       7 unless ($verse_data) {
950 1         9 _build_bible_template( 'Orthodox' => $bible, $self->_bibles );
951 1         8 $self->_bibles->{$bible}[0] = $book_data;
952             }
953             else {
954 0         0 $self->_bibles->{$bible}[0] = $book_data;
955 0         0 $self->_bibles->{$bible}[1] = $verse_data;
956             }
957              
958 1         162 $self->bible($bible);
959 1         11 return $self;
960             }
961              
962 1     1 1 2912 sub get_bible_structure ( $self, $bible = undef ) {
  1         4  
  1         3  
  1         2  
963 1 50       8 $self->bible($bible) if ($bible);
964 1         6 return [ map { [ $_, $self->_bible_data->{lengths}{$_} ] } @{ $self->_bible_data->{books} } ];
  84         967  
  1         7  
965             }
966              
967 2     2 1 4441 sub identify_bible ( $self, @books ) {
  2         5  
  2         5  
  2         5  
968 2 100       243 croak('No books supplied; must supply at least 1 input') unless (@books);
969              
970 1         7 my $obj = $self->new( minimum_book_length => $self->minimum_book_length );
971             my $bibles = [
972 9         13 sort { $b->{count} <=> $a->{count} }
973             map {
974 6         45 $obj->bible($_);
975 6         44 my $books = scalar( $obj->clear->in(@books)->as_books );
976             {
977 6         44 name => $_,
978             books => $books,
979             count => scalar(@$books),
980             };
981             }
982 1         6 keys %{ $obj->_bibles }
  1         9  
983             ];
984              
985 6         14 $bibles = [ grep { $bibles->[0]{count} == $_->{count} } @$bibles ]
986 1 50       8 if ( $bibles->[0]{count} != $bibles->[-1]{count} );
987              
988 1         3934 return $bibles;
989             }
990              
991             1;
992              
993             __END__