linkture 4.0.0__py3-none-any.whl → 4.2.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/__main__.py +26 -19
- linkture/linkture.py +47 -26
- linkture/res/custom.json +1 -1
- {linkture-4.0.0.dist-info → linkture-4.2.0.dist-info}/METADATA +2 -1
- linkture-4.2.0.dist-info/RECORD +10 -0
- linkture-4.0.0.dist-info/RECORD +0 -10
- {linkture-4.0.0.dist-info → linkture-4.2.0.dist-info}/WHEEL +0 -0
- {linkture-4.0.0.dist-info → linkture-4.2.0.dist-info}/entry_points.txt +0 -0
- {linkture-4.0.0.dist-info → linkture-4.2.0.dist-info}/licenses/LICENSE +0 -0
linkture/__main__.py
CHANGED
@@ -26,7 +26,7 @@
|
|
26
26
|
SOFTWARE.
|
27
27
|
"""
|
28
28
|
|
29
|
-
import argparse
|
29
|
+
import argparse, sys, traceback
|
30
30
|
from .linkture import _available_languages, __app__, __version__, Scriptures
|
31
31
|
from ast import literal_eval
|
32
32
|
|
@@ -34,24 +34,31 @@ from ast import literal_eval
|
|
34
34
|
def main(args):
|
35
35
|
|
36
36
|
def switchboard(text):
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
37
|
+
try:
|
38
|
+
if args['l'] is not None:
|
39
|
+
prefix = '<a href="'
|
40
|
+
suffix = '">'
|
41
|
+
if len(args['l']) > 1 and args['l'][1] != '':
|
42
|
+
suffix = args['l'][1]
|
43
|
+
if len(args['l']) > 0 and args['l'][0] != '':
|
44
|
+
prefix = args['l'][0]
|
45
|
+
return s.link_scriptures(text, prefix, suffix)
|
46
|
+
elif args['c']:
|
47
|
+
return s.code_scriptures(text)
|
48
|
+
elif args['d']:
|
49
|
+
return s.decode_scriptures(literal_eval(text))
|
50
|
+
elif args['x']:
|
51
|
+
return s.list_scriptures(text)
|
52
|
+
elif args['t']:
|
53
|
+
return s.tag_scriptures(text)
|
54
|
+
else:
|
55
|
+
return s.rewrite_scriptures(text)
|
56
|
+
except Exception as e:
|
57
|
+
print("\n--- CRASH DETECTED ---", file=sys.stderr)
|
58
|
+
print("Input causing failure:", repr(text), file=sys.stderr)
|
59
|
+
print("Error:", str(e), file=sys.stderr)
|
60
|
+
traceback.print_exc()
|
61
|
+
raise
|
55
62
|
|
56
63
|
form = None
|
57
64
|
if args['standard']:
|
linkture/linkture.py
CHANGED
@@ -27,7 +27,7 @@
|
|
27
27
|
"""
|
28
28
|
|
29
29
|
__app__ = 'linkture'
|
30
|
-
__version__ = 'v4.
|
30
|
+
__version__ = 'v4.2.0'
|
31
31
|
|
32
32
|
|
33
33
|
import json, regex, sqlite3
|
@@ -97,19 +97,16 @@ class Scriptures():
|
|
97
97
|
normalized = regex.sub(r'\p{P}|\p{Z}', '', item.upper())
|
98
98
|
self._src_book_names[normalized] = row[0]
|
99
99
|
|
100
|
-
# Ranges: {(book, chapter): last} (chapter 0 -> num of chapters in book)
|
101
100
|
self._ranges = {}
|
102
101
|
for book, chapter, last in cur.execute("SELECT Book, Chapter, Last FROM Ranges;"):
|
103
102
|
self._ranges[(book, chapter)] = last
|
104
103
|
|
105
|
-
# Chapters: two-way mappings
|
106
104
|
self._chapters = {}
|
107
105
|
self._chapters_id = {}
|
108
106
|
for chapter_id, book, chapter in cur.execute("SELECT ChapterId, Book, Chapter FROM Chapters;"):
|
109
107
|
self._chapters[(book, chapter)] = chapter_id
|
110
108
|
self._chapters_id[chapter_id] = (book, chapter)
|
111
109
|
|
112
|
-
# Verses: two-way mappings
|
113
110
|
self._verses = {}
|
114
111
|
self._verses_id = {}
|
115
112
|
for verse_id, book, chapter, verse in cur.execute("SELECT VerseId, Book, Chapter, Verse FROM Verses;"):
|
@@ -276,27 +273,29 @@ class Scriptures():
|
|
276
273
|
def _code_scripture(self, scripture, bk_num, rest, last):
|
277
274
|
|
278
275
|
def reform_series(txt): # rewrite comma-separated consecutive sequences (1, 2, 3) as ranges (1-3)
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
276
|
+
numbers = []
|
277
|
+
for match in regex.finditer(r'\d+', txt):
|
278
|
+
numbers.append((int(match.group()), match.start(), match.end()))
|
279
|
+
if not numbers:
|
280
|
+
return txt
|
281
|
+
sequences = []
|
282
|
+
current_seq = [numbers[0]]
|
283
|
+
for i in range(1, len(numbers)):
|
284
|
+
current_num = numbers[i][0]
|
285
|
+
prev_num = current_seq[-1][0]
|
286
|
+
if current_num == prev_num + 1:
|
287
|
+
current_seq.append(numbers[i])
|
288
|
+
else:
|
289
|
+
if len(current_seq) >= 3:
|
290
|
+
sequences.append(current_seq)
|
291
|
+
current_seq = [numbers[i]]
|
292
|
+
if len(current_seq) >= 3:
|
293
|
+
sequences.append(current_seq)
|
294
|
+
for seq in sorted(sequences, key=lambda x: x[0][1], reverse=True):
|
295
|
+
start_pos = seq[0][1]
|
296
|
+
end_pos = seq[-1][2]
|
297
|
+
replacement = f"{seq[0][0]}-{seq[-1][0]}"
|
298
|
+
txt = txt[:start_pos] + replacement + txt[end_pos:]
|
300
299
|
return txt
|
301
300
|
|
302
301
|
def validate(b, ch, vs):
|
@@ -435,6 +434,26 @@ class Scriptures():
|
|
435
434
|
|
436
435
|
return None, None
|
437
436
|
|
437
|
+
def merge_ranges(ranges):
|
438
|
+
if not ranges:
|
439
|
+
return []
|
440
|
+
merged = []
|
441
|
+
current_start, current_end = ranges[0]
|
442
|
+
for start, end in ranges[1:]:
|
443
|
+
end_bk = int(current_end[:2])
|
444
|
+
end_ch = int(current_end[2:5])
|
445
|
+
end_vs = int(current_end[5:])
|
446
|
+
next_bk = int(start[:2])
|
447
|
+
next_ch = int(start[2:5])
|
448
|
+
next_vs = int(start[5:])
|
449
|
+
if (end_bk == next_bk and ((end_ch == next_ch and end_vs + 1 == next_vs) or (end_ch + 1 == next_ch and end_vs == self._ranges.get((end_bk, end_ch), 0) and next_vs == 1))):
|
450
|
+
current_end = end
|
451
|
+
else:
|
452
|
+
merged.append((current_start, current_end))
|
453
|
+
current_start, current_end = start, end
|
454
|
+
merged.append((current_start, current_end))
|
455
|
+
return merged
|
456
|
+
|
438
457
|
lst = []
|
439
458
|
if rest == '': # whole book
|
440
459
|
v = self._ranges.get((bk_num, last))
|
@@ -444,6 +463,7 @@ class Scriptures():
|
|
444
463
|
rest = f'1:1-{last}:{v}'
|
445
464
|
else:
|
446
465
|
rest = reform_series(rest)
|
466
|
+
all_ranges = []
|
447
467
|
for chunk in rest.split(';'):
|
448
468
|
ch = None
|
449
469
|
for bit in chunk.split(','):
|
@@ -454,7 +474,8 @@ class Scriptures():
|
|
454
474
|
if not tup:
|
455
475
|
self._error_report(scripture, f'"{bit.strip()}" OUT OF RANGE')
|
456
476
|
return None
|
457
|
-
|
477
|
+
all_ranges.append(tup)
|
478
|
+
lst = merge_ranges(all_ranges)
|
458
479
|
return lst
|
459
480
|
|
460
481
|
def code_scriptures(self, text):
|
linkture/res/custom.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: linkture
|
3
|
-
Version: 4.
|
3
|
+
Version: 4.2.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>
|
@@ -11,6 +11,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
14
15
|
Classifier: Development Status :: 5 - Production/Stable
|
15
16
|
Classifier: Environment :: Console
|
16
17
|
Classifier: Topic :: Religion
|
@@ -0,0 +1,10 @@
|
|
1
|
+
linkture-4.2.0.dist-info/METADATA,sha256=riCJFu9iG4egWkaYw0oq_7JGA2STaI-dtpMcX6SnadA,11701
|
2
|
+
linkture-4.2.0.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
|
3
|
+
linkture-4.2.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
4
|
+
linkture-4.2.0.dist-info/licenses/LICENSE,sha256=kPqKoVmo3Tx1HgQvqfjBZuYkjT1mZXnQ5R0KBbEeFfs,1064
|
5
|
+
linkture/__init__.py,sha256=-CsRDvXLUig8T6RvwkktRP8e8DWrpjlyqBcw26kOv1E,47
|
6
|
+
linkture/__main__.py,sha256=NC11m6wICSMyme8AVDLezTBH_XrnMG1MMtmr3ZDbxDk,6980
|
7
|
+
linkture/linkture.py,sha256=Kdu6ngFJv6BCJFCv21P3pH39adCTLoDJNbH-6LThc1E,25998
|
8
|
+
linkture/res/custom.json,sha256=DKoN6Q_PcZ9EF4UdqpBtpB4ckz_lOEJhjpivfzsqUl8,2144
|
9
|
+
linkture/res/resources.db,sha256=4CToCzX_3kkWFUpVF4RoRguIHDUwbzd5AjKgt4QPYKo,573440
|
10
|
+
linkture-4.2.0.dist-info/RECORD,,
|
linkture-4.0.0.dist-info/RECORD
DELETED
@@ -1,10 +0,0 @@
|
|
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,,
|
File without changes
|
File without changes
|
File without changes
|