linkture 3.3.0__py3-none-any.whl → 4.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
linkture/linkture.py CHANGED
@@ -27,11 +27,10 @@
27
27
  """
28
28
 
29
29
  __app__ = 'linkture'
30
- __version__ = 'v3.3.0'
30
+ __version__ = 'v4.0.0'
31
31
 
32
32
 
33
33
  import json, regex, sqlite3
34
- import pandas as pd
35
34
  from pathlib import Path
36
35
  from unidecode import unidecode
37
36
 
@@ -66,25 +65,27 @@ class Scriptures():
66
65
  form = 5
67
66
  else:
68
67
  form = 3
69
- self._src_book_names = {}
70
- path = Path(__file__).resolve().parent
71
68
 
72
- self._tr_book_names = ['Bible']
69
+ path = Path(__file__).resolve().parent
73
70
  con = sqlite3.connect(path / 'res/resources.db')
74
71
  cur = con.cursor()
75
- for rec in cur.execute(f"SELECT * FROM Books WHERE Language = '{translate}';").fetchall():
72
+
73
+ self._src_book_names = {}
74
+ self._tr_book_names = ['Bible']
75
+ for rec in cur.execute(f"SELECT * FROM Books WHERE Language = ?;", (translate,)).fetchall():
76
76
  if self._upper:
77
77
  tr = rec[form].upper()
78
78
  else:
79
79
  tr = rec[form]
80
80
  self._tr_book_names.insert(rec[2], tr)
81
- for rec in cur.execute(f"SELECT * FROM Books WHERE Language = '{language}';").fetchall():
81
+ for rec in cur.execute(f"SELECT * FROM Books WHERE Language = ?;", (language,)).fetchall():
82
82
  for i in range(3,6):
83
83
  item = rec[i]
84
84
  if not self._nl:
85
85
  item = unidecode(item)
86
86
  normalized = regex.sub(r'\p{P}|\p{Z}', '', item.upper())
87
87
  self._src_book_names[normalized] = rec[2]
88
+
88
89
  with open(path / 'res/custom.json', 'r', encoding='UTF-8') as json_file:
89
90
  b = json.load(json_file)
90
91
  if language in b.keys():
@@ -95,12 +96,30 @@ class Scriptures():
95
96
  item = unidecode(item)
96
97
  normalized = regex.sub(r'\p{P}|\p{Z}', '', item.upper())
97
98
  self._src_book_names[normalized] = row[0]
98
- self._ranges = pd.read_sql_query("SELECT * FROM Ranges;", con)
99
- self._verses = pd.read_sql_query("SELECT * FROM Verses;", con)
100
- self._chapters = pd.read_sql_query("SELECT * FROM Chapters;", con)
101
- self._headings = (3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 92, 98, 100, 101, 102, 103, 108, 109, 110, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 138, 139, 140, 141, 142, 143, 144, 145)
99
+
100
+ # Ranges: {(book, chapter): last} (chapter 0 -> num of chapters in book)
101
+ self._ranges = {}
102
+ for book, chapter, last in cur.execute("SELECT Book, Chapter, Last FROM Ranges;"):
103
+ self._ranges[(book, chapter)] = last
104
+
105
+ # Chapters: two-way mappings
106
+ self._chapters = {}
107
+ self._chapters_id = {}
108
+ for chapter_id, book, chapter in cur.execute("SELECT ChapterId, Book, Chapter FROM Chapters;"):
109
+ self._chapters[(book, chapter)] = chapter_id
110
+ self._chapters_id[chapter_id] = (book, chapter)
111
+
112
+ # Verses: two-way mappings
113
+ self._verses = {}
114
+ self._verses_id = {}
115
+ for verse_id, book, chapter, verse in cur.execute("SELECT VerseId, Book, Chapter, Verse FROM Verses;"):
116
+ self._verses[(book, chapter, verse)] = verse_id
117
+ self._verses_id[verse_id] = (book, chapter, verse)
118
+
102
119
  cur.close()
103
120
  con.close()
121
+
122
+ self._headings = (3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 92, 98, 100, 101, 102, 103, 108, 109, 110, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 138, 139, 140, 141, 142, 143, 144, 145)
104
123
  self._reported = []
105
124
  self._encoded = {}
106
125
  self._linked = {}
@@ -151,7 +170,6 @@ class Scriptures():
151
170
  """, flags=regex.VERBOSE | regex.IGNORECASE)
152
171
 
153
172
  self._tagged = regex.compile(r'({{.*?}})')
154
-
155
173
  self._cv_cv = regex.compile(r'(\d+):(\d+)-(\d+):(\d+)')
156
174
  self._v_cv = regex.compile(r'(\d+)-(\d+):(\d+)')
157
175
  self._cv_v = regex.compile(r'(\d+):(\d+)-(\d+)')
@@ -162,7 +180,6 @@ class Scriptures():
162
180
  self._d_d = regex.compile(r'(\d+)-(\d+)(?!:)')
163
181
  self._dd = regex.compile(r'(\d+),(\d+)')
164
182
  self._d = regex.compile(r'(\d+)')
165
-
166
183
  self._chunk = regex.compile(r'([^,;\p{Z}]+.*)')
167
184
  self._sep = regex.compile(r'(?<!;)\s')
168
185
 
@@ -181,7 +198,7 @@ class Scriptures():
181
198
  return None, 0
182
199
  else:
183
200
  bk_num = self._src_book_names[bk_name]
184
- return self._ranges.loc[(self._ranges.Book == bk_num) & (self._ranges.Chapter.isnull()), ['Book', 'Last']].values[0]
201
+ return bk_num, self._ranges.get((bk_num, 0))
185
202
 
186
203
  reduced = regex.sub(r'\p{Z}', '', scripture)
187
204
  reduced = regex.sub(r'\p{Pd}', '-', reduced)
@@ -258,7 +275,7 @@ class Scriptures():
258
275
 
259
276
  def _code_scripture(self, scripture, bk_num, rest, last):
260
277
 
261
- def reform_series(txt): # rewrite comma-separated consecutive sequences as (1, 2, 3) as ranges (1-3)
278
+ def reform_series(txt): # rewrite comma-separated consecutive sequences (1, 2, 3) as ranges (1-3)
262
279
  for result in self._d_dd.finditer(txt, overlapped=True):
263
280
  end = result.group(3)
264
281
  mid = result.group(2)
@@ -287,13 +304,13 @@ class Scriptures():
287
304
  v = int(vs)
288
305
  if not (0 < b <= 66): # book out of range
289
306
  return None
290
- if not (0 < c <= self._ranges.loc[(self._ranges.Book == b) & (self._ranges.Chapter.isnull()), ['Last']].values[0]): # chapter out of range
307
+ if not (0 < c <= self._ranges.get((b, 0), 0)): # chapter out of range
291
308
  return None
292
309
  if b == 19 and c in self._headings:
293
310
  first = 0
294
311
  else:
295
312
  first = 1
296
- if not (first <= v <= self._ranges.loc[(self._ranges.Book == b) & (self._ranges.Chapter == c), ['Last']].values[0]): # verse out of range
313
+ if not (first <= v <= self._ranges.get((b, c), 0)): # verse out of range
297
314
  return None
298
315
  return True
299
316
 
@@ -376,7 +393,7 @@ class Scriptures():
376
393
  if not validate(book, c, v):
377
394
  return None, 0
378
395
  ch2 = c.zfill(3)
379
- v2 = str(self._ranges.loc[(self._ranges.Book == book) & (self._ranges.Chapter == int(ch2)), ['Last']].values[0][0]).zfill(3)
396
+ v2 = str(self._ranges.get((book, int(ch2)))).zfill(3)
380
397
  return (b+ch1+v1, b+ch2+v2), None
381
398
  else:
382
399
  c = 1
@@ -405,7 +422,7 @@ class Scriptures():
405
422
  v1 = '000'
406
423
  else:
407
424
  v1 = '001'
408
- v2 = str(self._ranges.loc[(self._ranges.Book == book) & (self._ranges.Chapter == int(ch1)), ['Last']].values[0][0]).zfill(3)
425
+ v2 = str(self._ranges.get((book, int(ch1)))).zfill(3)
409
426
  return (b+ch1+v1, b+ch1+v2), None
410
427
  else:
411
428
  c = 1
@@ -420,7 +437,7 @@ class Scriptures():
420
437
 
421
438
  lst = []
422
439
  if rest == '': # whole book
423
- v = self._ranges.loc[(self._ranges.Book == bk_num) & (self._ranges.Chapter == last), ['Last']].values[0][0]
440
+ v = self._ranges.get((bk_num, last))
424
441
  if last == 1:
425
442
  rest = f'1-{v}'
426
443
  else:
@@ -452,7 +469,7 @@ class Scriptures():
452
469
 
453
470
  def _decode_scripture(self, bcv_range, book='', chap=0, sep=';'):
454
471
  if not bcv_range:
455
- return None, '', 0, False
472
+ return None, '', 0, False, ''
456
473
  start, end = bcv_range
457
474
  sb = int(start[:2])
458
475
  sc = int(start[2:5])
@@ -462,22 +479,21 @@ class Scriptures():
462
479
  ev = int(end[5:])
463
480
 
464
481
  if not (sb == eb):
465
- return None, '', 0, False
482
+ return None, '', 0, False, ''
466
483
  if not ((0 < sb <= 66) & (sb == eb)): # book out of range
467
- return None, '', 0, False
468
- lc = self._ranges.loc[(self._ranges.Book == sb) & (self._ranges.Chapter.isnull()), ['Last']].values[0][0]
484
+ return None, '', 0, False, ''
485
+ lc = self._ranges.get((sb, 0), 0)
469
486
  if not (0 < sc <= ec <= lc): # chapter(s) out of range
470
- return None, '', 0, False
471
- se = self._ranges.loc[(self._ranges.Book == sb) & (self._ranges.Chapter == sc), ['Last']].values[0][0]
472
- le = self._ranges.loc[(self._ranges.Book == sb) & (self._ranges.Chapter == ec), ['Last']].values[0][0]
473
- minsv = minev = 1
474
- if sb == 19:
475
- if sc in self._headings: # some chapters start at verse 0
476
- minsv = 0
477
- if ec in self._headings:
478
- minev = 0
487
+ return None, '', 0, False, ''
488
+ se = self._ranges.get((sb, sc), 0)
489
+ le = self._ranges.get((sb, ec), 0)
490
+ minev = 1
491
+ minsv = 1
492
+ if sb == 19 and (sc in self._headings):
493
+ minsv = 0
494
+ le += 1
479
495
  if not ((minsv <= sv <= se) & (minev <= ev <= le)): # verse(s) out of range
480
- return None, '', 0, False
496
+ return None, '', 0, False, ''
481
497
  bk_name = self._tr_book_names[sb]
482
498
  if book == bk_name:
483
499
  cont = True
@@ -587,8 +603,9 @@ class Scriptures():
587
603
  sep = ';'
588
604
  for bcv_range in self._encoded[scripture]:
589
605
  scrip, bk, ch, _, sep = self._decode_scripture(bcv_range, bk, ch, sep)
590
- lnk = convert_range(bcv_range)
591
- output += regex.sub(self._chunk, r2, scrip)
606
+ if scrip:
607
+ lnk = convert_range(bcv_range)
608
+ output += regex.sub(self._chunk, r2, scrip)
592
609
  self._linked[scripture] = output.strip(' ;,')
593
610
  if self._upper:
594
611
  output = output.upper()
@@ -607,22 +624,22 @@ class Scriptures():
607
624
 
608
625
  def serial_chapter_number(self, bcv):
609
626
  try:
610
- return int(self._chapters.loc[(self._chapters['Book'] == int(bcv[0:2])) & (self._chapters['Chapter'] == int(bcv[2:5]))].values[0][0])
627
+ return self._chapters[(int(bcv[0:2]), int(bcv[2:5]))]
611
628
  except:
612
629
  self._error_report(bcv, 'OUT OF RANGE')
613
630
  return None
614
631
 
615
632
  def serial_verse_number(self, bcv):
616
633
  try:
617
- return int(self._verses.loc[(self._verses['Book'] == int(bcv[0:2])) & (self._verses['Chapter'] == int(bcv[2:5])) & (self._verses['Verse'] == int(bcv[5:]))].values[0][0]) + 1
634
+ return self._verses[(int(bcv[0:2]), int(bcv[2:5]), int(bcv[5:]))] + 1
618
635
  except:
619
636
  self._error_report(bcv, 'OUT OF RANGE')
620
637
  return None
621
638
 
622
639
  def code_chapter(self, chapter):
623
640
  try:
624
- book, chapter = self._chapters[self._chapters['ChapterId'] == int(chapter)].values[0][1:]
625
- last = self._ranges.loc[(self._ranges.Book == book) & (self._ranges.Chapter == chapter), ['Last']].values[0][0]
641
+ book, chapter = self._chapters_id[int(chapter)]
642
+ last = self._ranges.get((book, chapter))
626
643
  bc = str(book).zfill(2) + str(chapter).zfill(3)
627
644
  if book == 19 and chapter in self._headings: # some chapters start at verse 0
628
645
  v = '000'
@@ -636,9 +653,9 @@ class Scriptures():
636
653
  def code_verse(self, verse):
637
654
  bcv = ''
638
655
  try:
639
- for i in self._verses[self._verses['VerseId'] == int(verse)-1].values[0][1:]:
640
- bcv += str(i).zfill(3)
641
- return f"('{bcv[1:]}', '{bcv[1:]}')"
656
+ bk, ch, vs = self._verses_id[int(verse)-1]
657
+ bcv = f"{bk:02d}{ch:03d}{vs:03d}"
658
+ return f"('{bcv}', '{bcv}')"
642
659
  except:
643
660
  self._error_report(verse, 'OUT OF RANGE')
644
661
  return None
linkture/res/resources.db CHANGED
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: linkture
3
- Version: 3.3.0
3
+ Version: 4.0.0
4
4
  Summary: PARSE and PROCESS BIBLE SCRIPTURE REFERENCES: extract, tag, link, rewrite, translate, BCV-encode and decode
5
5
  Keywords: bible,scriptures,scripture-references,scripture-translation,scripture-parser,scripture-linker
6
6
  Author-Email: "Eryk J." <infiniti@inventati.org>
@@ -23,7 +23,6 @@ Requires-Dist: setuptools>=59.6.0
23
23
  Requires-Dist: argparse>=1.4.0
24
24
  Requires-Dist: regex>=2023.8.8
25
25
  Requires-Dist: unidecode>=1.3.8
26
- Requires-Dist: pandas==2.2.*
27
26
  Requires-Dist: pathlib>=1.0.1
28
27
  Description-Content-Type: text/markdown
29
28
 
@@ -0,0 +1,10 @@
1
+ linkture-4.0.0.dist-info/METADATA,sha256=l8Z9vxEgLZk2g_Yt0vjAfAg34aTDM68r0A7gEm5-4uI,11650
2
+ linkture-4.0.0.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ linkture-4.0.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
+ linkture-4.0.0.dist-info/licenses/LICENSE,sha256=kPqKoVmo3Tx1HgQvqfjBZuYkjT1mZXnQ5R0KBbEeFfs,1064
5
+ linkture/__init__.py,sha256=-CsRDvXLUig8T6RvwkktRP8e8DWrpjlyqBcw26kOv1E,47
6
+ linkture/__main__.py,sha256=IjxrpZGZKIr7mHPGs_mMVaB6ipou_ArYgvs4wRFkxXM,6607
7
+ linkture/linkture.py,sha256=398iSQwC0pSc_j5jRlJIRcRsWm2-YWyJGO1xTTGMMFk,25256
8
+ linkture/res/custom.json,sha256=ngpVe8OrnhBUTpJKcJc_W9rwxtEWq7qbt3_NPbGL6h0,2139
9
+ linkture/res/resources.db,sha256=4CToCzX_3kkWFUpVF4RoRguIHDUwbzd5AjKgt4QPYKo,573440
10
+ linkture-4.0.0.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- linkture-3.3.0.dist-info/METADATA,sha256=nePUbYNt7TwToC8ER7g_8NAtJVM7OGipcrJxFbPCxPw,11679
2
- linkture-3.3.0.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- linkture-3.3.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
- linkture-3.3.0.dist-info/licenses/LICENSE,sha256=kPqKoVmo3Tx1HgQvqfjBZuYkjT1mZXnQ5R0KBbEeFfs,1064
5
- linkture/__init__.py,sha256=-CsRDvXLUig8T6RvwkktRP8e8DWrpjlyqBcw26kOv1E,47
6
- linkture/__main__.py,sha256=IjxrpZGZKIr7mHPGs_mMVaB6ipou_ArYgvs4wRFkxXM,6607
7
- linkture/linkture.py,sha256=erB0sRVIKGQeRjnv_RYMOl_Ahb9TSMKTgwrixgsdIDY,25583
8
- linkture/res/custom.json,sha256=ngpVe8OrnhBUTpJKcJc_W9rwxtEWq7qbt3_NPbGL6h0,2139
9
- linkture/res/resources.db,sha256=MjQab_QQdfR2YfZpU6TWHOO3irLytnx00iy7YYASR6k,573440
10
- linkture-3.3.0.dist-info/RECORD,,