Skip to content

Commit 4ccd2f8

Browse files
committed
Merge branch 'main' of https://github.com/sillsdev/machine.py into main
2 parents 37fd1f5 + a359d10 commit 4ccd2f8

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

machine/scripture/parse.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
import re
12
from typing import Dict, List, Set, Union
23

34
from .canon import book_id_to_number
45
from .constants import ORIGINAL_VERSIFICATION
56
from .verse_ref import Versification
67

8+
COMMA_SEPARATED_BOOKS = re.compile(r"([A-Z\d]{3}|OT|NT)(, ?([A-Z\d]{3}|OT|NT))*")
9+
BOOK_RANGE = re.compile(r"[A-Z\d]{3}-[A-Z\d]{3}")
10+
CHAPTER_SELECTION = re.compile(r"[A-Z\d]{3} ?(\d+|\d+-\d+)(, ?(\d+|\d+-\d+))*")
11+
712

813
def get_books(books: Union[str, List[str]]) -> Set[int]:
914
if isinstance(books, str):
@@ -43,13 +48,29 @@ def get_chapters(
4348
chapters = {}
4449

4550
if isinstance(chapter_selections, str):
46-
if ";" not in chapter_selections and not any(
47-
s.isdigit() and (i == len(chapter_selections) - 1 or not chapter_selections[i + 1].isalpha())
48-
for i, s in enumerate(chapter_selections)
49-
): # Backwards compatibility with get_books syntax:
51+
chapter_selections = chapter_selections.strip()
52+
53+
if ";" in chapter_selections:
54+
chapter_selections = chapter_selections.split(";")
55+
elif re.fullmatch(COMMA_SEPARATED_BOOKS, chapter_selections) is not None:
5056
chapter_selections = chapter_selections.split(",")
57+
elif chapter_selections.startswith("-"):
58+
raise ValueError(f"Cannot subtract before adding sections: {chapter_selections}")
59+
elif re.search(BOOK_RANGE, chapter_selections):
60+
if len(chapter_selections) == 7:
61+
chapter_selections = [chapter_selections]
62+
else:
63+
raise ValueError(
64+
"Invalid syntax. If one of your selections is a range of books, \
65+
selections must be seprated with semicolons."
66+
)
67+
elif re.fullmatch(CHAPTER_SELECTION, chapter_selections) is None:
68+
raise ValueError(
69+
"Invalid syntax. If one of your selections includes specific chapters or subtraction, \
70+
selections must be separated with semicolons."
71+
)
5172
else:
52-
chapter_selections = chapter_selections.split(";")
73+
chapter_selections = [chapter_selections]
5374

5475
for section in chapter_selections:
5576
section = section.strip()

tests/scripture/test_parse.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ def test_get_chapters() -> None:
4343
whole_bible = {i: [] for i in range(1, 67)}
4444
assert get_chapters("NT,OT") == whole_bible
4545

46-
del whole_bible[2] # EXO
47-
del whole_bible[41] # MRK
48-
assert get_chapters("NT,OT,-MRK,-EXO") == whole_bible
49-
5046
assert get_chapters("MAT;MRK") == {40: [], 41: []}
5147
assert get_chapters("MAT; MRK") == {40: [], 41: []}
5248
assert get_chapters("MAT1,2,3") == {40: [1, 2, 3]}
@@ -57,7 +53,10 @@ def test_get_chapters() -> None:
5753
assert get_chapters("2JN-3JN;EXO1,8,3-5;GEN") == {1: [], 2: [1, 3, 4, 5, 8], 63: [], 64: []}
5854
assert get_chapters("1JN 1;1JN 2;1JN 3-5") == {62: []}
5955
assert get_chapters("MAT-ROM;-ACT4-28") == {40: [], 41: [], 42: [], 43: [], 44: [1, 2, 3], 45: []}
56+
assert get_chapters("2JN;-2JN 1") == {}
6057

58+
del whole_bible[2] # EXO
59+
del whole_bible[41] # MRK
6160
assert get_chapters("NT;OT;-MRK;-EXO") == whole_bible
6261
test_bible = {i: [] for i in range(40, 67)}
6362
test_chapters_mat = [1, 2] + [i for i in range(6, 17)] + [i for i in range(18, 29)]
@@ -110,3 +109,11 @@ def test_get_chapters() -> None:
110109
get_chapters("NT;OT;-ABC")
111110
with raises(ValueError):
112111
get_chapters("MAT;-ABC 1")
112+
113+
# mixing old (comma-separated) and new syntax
114+
with raises(ValueError):
115+
get_chapters("NT,OT,-MRK,-EXO")
116+
with raises(ValueError):
117+
get_chapters("OT,MAT1")
118+
with raises(ValueError):
119+
get_chapters("OT,MAT-LUK")

0 commit comments

Comments
 (0)