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   665410 use 5.022;
  3         15  
5              
6 3     3   2021 use exact;
  3         196289  
  3         19  
7 3     3   14488 use exact::class;
  3         82575  
  3         20  
8              
9             our $VERSION = '1.19'; # 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   34 sub _build_bible_template ( $source_name, $new_name, $bibles, $books_cb = undef, $verses_cb = undef ) {
  7         18  
  7         16  
  7         13  
  7         16  
  7         16  
  7         11  
231 7         11 $bibles->{$new_name} = [ map { [ map { [@$_] } @$_ ] } @{ $bibles->{$source_name} } ];
  14         34  
  960         2716  
  7         26  
232 7 100       51 $books_cb->( $bibles->{$new_name}[0] ) if ($books_cb);
233 7 100       37 $verses_cb->( $bibles->{$new_name}[1] ) if ($verses_cb);
234 7         24 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 59430 sub bible ( $self, $name = undef ) {
  27         79  
  27         93  
  27         62  
347 27 100       158 return $self->_bible unless ($name);
348              
349 21   50     118 my $input = lc( $name || '' );
350 21         66 my ($bible) = grep { lc $_ eq $input } keys %{ $self->_bibles };
  128         656  
  21         104  
351              
352 21 100       337 croak "Could not determine a valid Bible type from input" unless ($bible);
353 20         114 $self->_bible($bible);
354              
355 20         193 my $books = [ map { [@$_] } @{ $self->_bibles->{ $self->_bible }[0] } ];
  1418         4820  
  20         71  
356              
357 20         93 my $bible_data;
358 20         70 for my $book_data (@$books) {
359 1418         3149 my ( $book, @acronyms ) = @$book_data;
360              
361 1418         4615 $bible_data->{book_to_acronym}{$book} = $acronyms[0];
362 1418         1901 push( @{ $bible_data->{books} }, $book );
  1418         3334  
363             }
364 20         46 my $book_count;
365 20         43 $bible_data->{book_order} = { map { $_ => ++$book_count } @{ $bible_data->{books} } };
  1418         3201  
  20         69  
366              
367 20         184 my $canonical = [ map { $_->[0] } @$books ];
  1418         2774  
368 20         113 my $options = { map { shift @$_ => $_ } @$books };
  1418         2967  
369             my $re_map = { map {
370 20         183 my $book = $_;
  1418         2462  
371 1418         2429 my $book_str = $_;
372 1418 50       7243 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         5339 my @letters = split( '', $book_str );
388 1418         2158 my $unique;
389 1418         3322 while (@letters) {
390 4463         35561 $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     13566 scalar( grep { index( $_, $prefix[-1] . ' ' . $unique ) == 0 } @$canonical ) == 1
      100        
398             )
399             );
400             }
401              
402 1418         3902 my @matches = $unique;
403 1418         9738 push( @matches, $unique .= shift @letters ) while (@letters);
404              
405             @matches = map {
406 1418         2855 my $match = $_;
  7190         11541  
407              
408 7190         10343 $match .= ')i?(';
409 7190         27911 $match =~ s/^(\w)/$1)i-?(/;
410              
411 7190 100       18963 (@prefix) ? ( map { ')' . $_ . ':i?(' . ' ' . $match } @prefix ) : $match;
  8112         18178  
412             } @matches;
413              
414             map {
415 16906         28728 my $re = reverse $_;
416              
417 16906         26957 $re =~ s/\*/'[A-z]+'/ge;
  2028         5096  
418 16906         34251 $re =~ s/\s+/'[\s_]*'/ge;
  9315         25958  
419              
420 16906         59802 $re => $book;
421 1418         2385 } @matches, @{ $options->{$book} };
  1418         4783  
422             } @$canonical };
423              
424 20         7822 my @re_parts = sort { length $b <=> length $a } keys %$re_map;
  136343         194468  
425              
426 20         1245 my $re_refs = '(?i:[\d:,;\s\-]|\bdna\b|\bro\b|&)*\.?';
427 20         65 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         141 my $re_refs_string = '\b(' . join( '|', map { $re_refs . $_ } @re_parts ) . ')\b';
  16906         39151  
433 20         1616 my $re_refs_req_string = '\b(' . join( '|', map { $re_refs_req . $_ } @re_parts ) . ')\b';
  16906         42330  
434              
435 20         1071412 $bible_data->{re_refs_s} = qr/$re_refs_string/;
436 20         5519545 $bible_data->{re_refs_sr} = qr/$re_refs_req_string/;
437 20         28052 $bible_data->{re_books_s} = [ map { [ qr/\b$_\b/, $re_map->{$_} ] } @re_parts ];
  16906         342982  
438              
439 20         23069 $re_refs_string =~ s/\(\?\-?i\)//g;
440 20         23581 $re_refs_req_string =~ s/\(\?\-?i\)//g;
441              
442 20         901169 $bible_data->{re_refs_i} = qr/$re_refs_string/i;
443 20         4868222 $bible_data->{re_refs_ir} = qr/$re_refs_req_string/i;
444             $bible_data->{re_books_i} = [ map {
445 20         24846 my $this_book = $re_map->{$_};
  16906         43890  
446 16906         68322 s/\(\?\-?i\)//g;
447 16906         364075 [ qr/\b$_\b/i, $this_book ];
448             } @re_parts ];
449              
450             $bible_data->{lengths} = {
451             map {
452 1418         17431 $bible_data->{books}[$_] => [ @{ $self->_bibles->{$bible}[1][$_] } ]
  1418         2981  
453 20         699 } 0 .. @{ $bible_data->{books} } - 1
  20         158  
454             };
455              
456 20         1680 $self->_bible_data($bible_data);
457 20         86876 return $bible;
458             }
459              
460 4     4 1 561840 sub new ( $self, %params ) {
  4         13  
  4         15  
  4         9  
461 4         59 $self = $self->SUPER::new(%params);
462 4   33     4619 $self->bible( $params{bible} || $self->_bible );
463 4         41 return $self;
464             }
465              
466 213     213   460 sub _list ( $start, $stop ) {
  213         359  
  213         349  
  213         288  
467 213 50       601 $start++ if ( $start == 0 );
468 213 50       459 $stop++ if ( $stop == 0 );
469              
470 213         1183 my ( $x, $y ) = sort { $a <=> $b } $start, $stop;
  426         742  
471 213         636 my @list = $x .. $y;
472 213 100       535 @list = reverse(@list) if ( $x < $start );
473              
474 213         1755 return @list;
475             };
476              
477 187     187 1 489 sub expand_ranges ( $self, $book, $text, $compress = 0 ) {
  187         372  
  187         339  
  187         668  
  187         402  
  187         299  
478 189     189   296 my $expand = sub ( $start, $stop ) {
  189         531  
  189         399  
  189         298  
479 189 100       874 my $start_ch = ( $start =~ s/(\d+):// ) ? $1 : 0;
480 189 100       576 my $stop_ch = ( $stop =~ s/(\d+):// ) ? $1 : 0;
481              
482 189 100 100     1023 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         4 $start_ch = $start;
486 1         4 $start = 1;
487             }
488              
489 189         305 my $skip_chapter_assumption_check = 0;
490 189 100 100     749 if ( $start_ch and $stop_ch and $start and $stop and $start_ch == $stop_ch ) {
      66        
      66        
      66        
491 2 100       12 if ( $start <= $stop ) {
492             # B: "3:4-3:7" = translated to "3:4-7"
493              
494 1         54 $stop_ch = 0;
495             }
496             else {
497             # Q: "3:37-3:4" is the reverse of 3:4-3:37
498              
499 1         4 $stop_ch = 0;
500 1         3 $skip_chapter_assumption_check = 1;
501             }
502             }
503              
504 189         415 my $expance = '';
505              
506 189 100 100     1418 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         322 $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     332 if ( $start >= $stop and $stop > $start_ch and not $skip_chapter_assumption_check ) {
      100        
522 4         9 $stop_ch = $stop;
523 4         24 $stop = $self->_bible_data->{lengths}{$book}[ $start_ch - 1 ];
524             }
525              
526 71 100       335 $expance = join( ';', grep { defined }
  142         394  
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         27 $start_ch = $start;
537 10         25 $start = 1;
538              
539 10         44 $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         14 my $reversed = 0;
552 7 100       20 if ( $start_ch >= $stop_ch ) {
553 3         44 ( $start_ch, $stop_ch, $start, $stop ) = ( $stop_ch, $start_ch, $stop, $start );
554 3         8 $reversed = 1;
555             }
556              
557 7 100       38 my $reverse = sub { ($reversed) ? reverse(@_) : @_ };
  24         230  
558              
559 21         83 $expance = join( ';', grep { defined }
560             $reverse->(
561             $start_ch . ':' . join( ',', $reverse->( _list(
562             $start,
563 7 100       40 $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         1187 $expance;
576 187         2257 };
577              
578 187         1253 $text =~ s/[\s,]+/,/g;
579 187         694 $text =~ s/^,//g;
580 187         1127 $text =~ s/(\d+(?::\d+)?)\-(\d+(?::\d+)?)/ $expand->( $1, $2 ) /ge;
  189         484  
581 187 50       673 $text =~ s/([,;])/$1 /g unless $compress;
582              
583 187         4122 return $text;
584             };
585              
586 26     26 1 14934 sub in ( $self, @input ) {
  26         66  
  26         178  
  26         288  
587 26 50       134 return $self unless (@input);
588              
589             my $re_refs = $self->_bible_data->{
590 26 100       121 '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       1026 : $self->_bible_data->{re_books_i};
598              
599 26         564 for my $string (@input) {
600 175   100     938 $string = scalar( reverse $string // '' );
601 175         324 my @processed;
602 175         387 while (1) {
603 516         1388553 my ( $pre, $ref, $post ) = split( /$re_refs/, $string, 2 );
604 516 100       3478 last unless ($ref);
605              
606 341         1313 $ref =~ s/(\d)([[:alpha:]])/$1 $2/;
607              
608 341         754 $string = $post;
609              
610 341 100       2310 my $space = ( $ref =~ s/^((?i:\W|\bdna\b|\bro\b|&)+)// ) ? $1 : '';
611 341         1670 $ref =~ s/\s+/ /g;
612 341         896 $pre = $pre . $space;
613 341         902 push( @processed, $pre );
614              
615 341         680 my $orig_ref = $ref;
616              
617 341         669 my $book;
618 341         1050 for (@$re_books) {
619 154913 100       535388 if ( $ref =~ /$_->[0]/ ) {
620 341         1147 $book = $_->[1];
621 341         862 last;
622             }
623             }
624              
625 341         1118 my $ref_out = [$book];
626 341         701 my $numbers = [];
627              
628 341         2037 $ref =~ s/(?:\bdna\b|\bro\b|&)/,/g;
629 341         1031 $ref = scalar reverse $ref;
630              
631 341 100       1641 if ( $ref =~ /([\d:,;\s\-]+)$/ ) {
632 166         967 my $range = $self->expand_ranges( $book, $1, 1 );
633              
634 166         365 my $verse_context = 0;
635 166         308 my $last_d = 0;
636              
637 166         1243 while ( $range =~ s/^(\d+)([:,;]?)\D*//g ) {
638 1422   100     4670 my ( $d, $s ) = ( $1, $2 || '' );
639              
640 1422 100 100     4513 $verse_context = 0 if ( $s eq ':' or $d <= $last_d );
641              
642 1422 100       2236 unless ($verse_context) {
643 685         2049 push( @$numbers, [$d] );
644             }
645             else {
646 737 100       835 push( @{ $numbers->[-1] }, [] ) unless ( @{ $numbers->[-1] } > 1 );
  138         410  
  737         1630  
647 737         960 push( @{ $numbers->[-1][-1] }, $d );
  737         1462  
648             }
649              
650 1422 100       2530 $last_d = ($verse_context) ? $d : 0;
651              
652 1422 100       2626 $verse_context = 1 if ( $s eq ':' );
653 1422 100       5858 $verse_context = 0 if ( $s eq ';' );
654             }
655             }
656              
657 341 100 100     2121 if ( @$numbers or not $self->require_chapter_match ) {
658 340 100       3598 push( @$ref_out, $numbers ) if (@$numbers);
659 340         1238 push( @processed, $ref_out );
660             }
661             else {
662 1         18 $processed[-1] .= $orig_ref;
663             }
664             }
665              
666 175         631 push( @processed, $string );
667             push(
668 175         1200 @{ $self->_data },
669 175 100       338 [ grep { length } map { ( ref $_ ) ? $_ : scalar reverse $_ } reverse @processed ],
  856         2469  
  856         5397  
670             );
671             }
672              
673 26         334 return $self;
674             }
675              
676 23     23 1 124157 sub clear ($self) {
  23         62  
  23         51  
677 23         159 $self->_data([]);
678 23         2270 return $self;
679             }
680              
681 4     4 1 731 sub books ($self) {
  4         10  
  4         8  
682 4 50       18 return (wantarray) ? @{ $self->_bible_data->{books} } : $self->_bible_data->{books};
  4         24  
683             }
684              
685 60     60 1 197209 sub as_array ( $self, $data = undef ) {
  60         129  
  60         112  
  60         96  
686 60 50 100     300 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     828 $data //= [ map { grep { ref } @$_ } @{ $self->_data } ];
  202         643  
  946         2021  
  20         85  
695             $data = [
696 60         145 map { [
697             map {
698 450         843 ( ref $_ ) ? [
699             map {
700 666 100       1884 ( ref $_ ) ? [
701             map {
702 923 100       2047 ( ref $_ ) ? [
  1099 50       4684  
703             @$_
704             ] : $_
705             } @$_
706             ] : $_
707             } @$_
708             ] : $_
709             } @$_
710             ] }
711             @$data
712             ];
713              
714             $data = [ map {
715 60 100       276 my $book = $_->[0];
  43         120  
716              
717 43 100       94 if ( ref $_->[1] ) {
718             $_->[1] = [ map {
719 100   100     330 $_->[1] //= [ 1 .. ( $self->_bible_data->{lengths}{$book}[ $_->[0] - 1 ] || 0 ) ];
      100        
720 100         1415 $_;
721 23         34 } @{ $_->[1] } ];
  23         48  
722             }
723             else {
724 20         36 my $chapter;
725 20         32 $_->[1] = [ map { [ ++$chapter, [ 1 .. $_ ] ] } @{ $self->_bible_data->{lengths}{$book} } ];
  209         1474  
  20         63  
726             }
727              
728 43         119 $_;
729             } @$data ] if ( $self->add_detail );
730              
731 60 100       774 if ( $self->sorting ) {
732 58         551 my $data_by_book = {};
733 58 100       138 push( @{ $data_by_book->{ $_->[0] } }, @{ $_->[1] || [] } ) for (@$data);
  410         1125  
  410         1638  
734              
735             $data = [
736             map {
737 257         1005 my $book = [ $_->[1] ];
738              
739 257         424 my $dedup;
740 257         384 for my $chapter ( @{ $data_by_book->{ $_->[1] } } ) {
  257         608  
741 1049   100     5135 $dedup->{ $chapter->[0] } //= {};
742 1049         1503 $dedup->{ $chapter->[0] }{$_} = 1 for ( @{ $chapter->[1] } );
  1049         11582  
743             }
744              
745             my $chapters = [
746             map {
747 928         2061 my $chapter = [$_];
748 928         1374 my @verses = keys %{ $dedup->{$_} };
  928         3600  
749 928 100       2570 push( @$chapter, [ sort { $a <=> $b } @verses ] ) if @verses;
  26365         42008  
750 928         2543 $chapter;
751             }
752 257         1055 sort { $a <=> $b }
  2447         3964  
753             keys %$dedup
754             ];
755              
756 257 100       850 push( @$book, $chapters ) if (@$chapters);
757              
758 257         3712 $book;
759             }
760 673         1297 sort { $a->[0] <=> $b->[0] }
761 58         225 map { [ $self->_bible_data->{book_order}{$_}, $_ ] }
  257         2401  
762             keys %$data_by_book
763             ];
764             }
765              
766             $data = [ map {
767 60 100       431 my $book = $_->[0];
  4         26  
768              
769 4 50       9 if ( my $chapters = $_->[1] ) {
770 4         8 for my $chapter (@$chapters) {
771             pop @$chapter if (
772             $chapter->[1] and
773 18         56 join( ',', @{ $chapter->[1] } ) eq
774 18 50 50     204 join( ',', 1 .. ( $self->_bible_data->{lengths}{$book}[ $chapter->[0] - 1 ] || 0 ) )
      33        
775             );
776             }
777              
778             pop @$_ if (
779 18         23 join( ',', map { $_->[0] } grep { @$_ == 1 } @$chapters ) eq
  18         23  
780 4 100       50 join( ',', 1 .. scalar @{ $self->_bible_data->{lengths}{$book} } )
  4         8  
781             );
782             }
783              
784 4         78 $_;
785             } @$data ] if ( $self->simplify );
786              
787 60 100       727 if ( $self->acronyms ) {
788 1         15 for (@$data) {
789 22         242 $_->[0] = $self->_bible_data->{book_to_acronym}{ $_->[0] };
790             }
791             }
792              
793 60         602 $self->_cache->{data} = $data;
794             }
795              
796 60 100       1925 return (wantarray) ? @{ $self->_cache->{data} } : $self->_cache->{data};
  1         8  
797             }
798              
799 1     1 1 28 sub as_hash ( $self, $data = undef ) {
  1         3  
  1         2  
  1         4  
800 1         3 my $build = {};
801              
802 1         7 for my $book_block ( $self->as_array($data) ) {
803 22         69 my ( $book_name, $chapters ) = @$book_block;
804              
805 22         49 $build->{$book_name} = {};
806 22         48 for (@$chapters) {
807 77 100       111 push( @{ $build->{$book_name}{ $_->[0] } }, @{ $_->[1] || [] } );
  77         186  
  77         350  
808             }
809             }
810              
811 1 50       11 return (wantarray) ? %$build : $build;
812             }
813              
814 88     88   212 sub _compress_range ( $items = [] ) {
  88         129  
  88         105  
815 88         122 my ( $last, @items, @range );
816              
817             my $flush_range = sub {
818 202 100   202   348 if (@range) {
819 74         125 pop @items;
820 74         173 push( @items, join( '-', $range[0], $range[-1] ) );
821 74         187 @range = ();
822             }
823 88         250 };
824              
825 88         207 for my $item (@$items) {
826 504 100 100     1257 if ( not $last or $last + 1 != $item ) {
827 114         231 $flush_range->();
828 114         185 push( @items, $item );
829             }
830             else {
831 390         611 push( @range, $last, $item );
832             }
833              
834 504         697 $last = $item;
835             }
836 88         217 $flush_range->();
837              
838 88 50       577 return (wantarray) ? @items : join( ', ', @items );
839             }
840              
841 55     55   90 sub _as_type ( $self, $type, $data = undef ) {
  55         78  
  55         107  
  55         114  
  55         82  
842 55         154 $data = $self->as_array($data);
843              
844             return [
845             map {
846 55         495 my $book = $_->[0];
  170         292  
847              
848 170 100       308 if ( $_->[1] ) {
849 74         124 my ( @build, @buffer );
850              
851             my $flush_buffer = sub {
852 83 100   83   178 if (@buffer) {
853 27         86 push( @build, join( '; ', _compress_range(\@buffer) ) );
854 27         87 @buffer = ();
855             }
856 74         286 };
857              
858 74         113 for ( @{ $_->[1] } ) {
  74         171  
859 478         689 my $chapter = $_->[0];
860              
861 478 100       748 if ( $_->[1] ) {
862 72 100       242 if ( $type eq 'verses' ) {
    100          
    100          
863 11         19 push( @build, map { "$book $chapter:$_" } @{ $_->[1] } );
  58         155  
  11         26  
864             }
865             elsif ( $type eq 'runs' ) {
866 11         28 push( @build, map { "$book $chapter:$_" } _compress_range( $_->[1] ) );
  14         51  
867             }
868             elsif ( $type eq 'chapters' ) {
869 11         26 push( @build, "$book $chapter:" . join( ', ', _compress_range( $_->[1] ) ) );
870             }
871             else {
872 39         95 $flush_buffer->();
873 39         89 push( @build, $chapter . ':' . join( ', ', _compress_range( $_->[1] ) ) );
874             }
875             }
876             else {
877 406 100       621 unless ( $type eq 'books' ) {
878 198         426 push( @build, "$book $chapter" );
879             }
880             else {
881 208         309 push( @buffer, $chapter );
882             }
883             }
884             }
885              
886 74 100       209 unless ( $type eq 'books' ) {
887 30         387 @build;
888             }
889             else {
890 44         89 $flush_buffer->();
891 44         301 $book . ' ' . join( '; ', @build );
892             }
893             }
894             else {
895 96         199 $book;
896             }
897             } @$data
898             ];
899             }
900              
901 1     1 1 28 sub as_verses ( $self, $data = undef ) {
  1         3  
  1         3  
  1         2  
902 1         12 my $items = $self->_as_type( 'verses', $data );
903 1 50       12 return (wantarray) ? @$items : $items;
904             }
905              
906 1     1 1 26 sub as_runs ( $self, $data = undef ) {
  1         4  
  1         3  
  1         2  
907 1         10 my $items = $self->_as_type( 'runs', $data );
908 1 50       11 return (wantarray) ? @$items : $items;
909             }
910              
911 1     1 1 27 sub as_chapters ( $self, $data = undef ) {
  1         4  
  1         3  
  1         2  
912 1         11 my $items = $self->_as_type( 'chapters', $data );
913 1 50       7 return (wantarray) ? @$items : $items;
914             }
915              
916 52     52 1 104 sub as_books ( $self, $data = undef ) {
  52         73  
  52         82  
  52         70  
917 52         154 my $items = $self->_as_type( 'books', $data );
918 52 100       254 return (wantarray) ? @$items : $items;
919             }
920              
921 45     45 1 587 sub refs ( $self, $data = undef ) {
  45         74  
  45         66  
  45         55  
922 45         115 return join( '; ', $self->as_books($data) );
923             }
924              
925 2     2 1 52 sub as_text ($self) {
  2         6  
  2         12  
926             my @text = map {
927 19 100       67 join( '', map { ( ref $_ ) ? $self->refs([$_]) : $_ } @$_ );
  96         328  
928 2         5 } @{ $self->_data };
  2         11  
929              
930             return
931 2 100 66     60 ( @text > 1 and wantarray ) ? @text :
    50 66        
932             ( @text > 1 and not wantarray ) ? \@text : join( ' ', @text );
933             }
934              
935 4     4 1 4708 sub set_bible_data ( $self, $bible = undef, $book_data = undef, $verse_data = undef ) {
  4         10  
  4         10  
  4         9  
  4         8  
  4         7  
936 4 50 66     281 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     269 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         7 for (@$book_data) {
942 41 50 66     706 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         11 _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         79 $self->bible($bible);
959 1         11 return $self;
960             }
961              
962 1     1 1 3820 sub get_bible_structure ( $self, $bible = undef ) {
  1         2  
  1         2  
  1         2  
963 1 50       6 $self->bible($bible) if ($bible);
964 1         6 return [ map { [ $_, $self->_bible_data->{lengths}{$_} ] } @{ $self->_bible_data->{books} } ];
  84         957  
  1         8  
965             }
966              
967 2     2 1 5544 sub identify_bible ( $self, @books ) {
  2         7  
  2         5  
  2         4  
968 2 100       289 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 11         17 sort { $b->{count} <=> $a->{count} }
973             map {
974 6         44 $obj->bible($_);
975 6         58 my $books = scalar( $obj->clear->in(@books)->as_books );
976             {
977 6         52 name => $_,
978             books => $books,
979             count => scalar(@$books),
980             };
981             }
982 1         3 keys %{ $obj->_bibles }
  1         3  
983             ];
984              
985 6         13 $bibles = [ grep { $bibles->[0]{count} == $_->{count} } @$bibles ]
986 1 50       7 if ( $bibles->[0]{count} != $bibles->[-1]{count} );
987              
988 1         5102 return $bibles;
989             }
990              
991             1;
992              
993             __END__