diff --git a/CHANGELOG.md b/CHANGELOG.md index 0927888..5c29c40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- [Issue #168](https://github.com/avendesora/pythonbible/issues/168) - Parse references when book names are followed by periods. + ## [0.15.5] - 2026-01-24 ### Fixed diff --git a/pythonbible/pythonbible/parser.py b/pythonbible/pythonbible/parser.py index 4545fcb..a32dcf7 100644 --- a/pythonbible/pythonbible/parser.py +++ b/pythonbible/pythonbible/parser.py @@ -158,12 +158,18 @@ def _process_sub_references( start_chapter: int | None = None for sub_reference in reference.split(COMMA): - if (not sub_reference or sub_reference in {DASH, PERIOD}) and not references: + normalized_sub_reference = sub_reference.strip().lstrip(" .,:;-") + + if ( + not normalized_sub_reference or normalized_sub_reference in {DASH} + ) and not references: references.append(NormalizedReference(book, None, None, None, None, book)) continue start_chapter, start_verse, end_chapter, end_verse = _process_sub_reference( - sub_reference[:-1] if sub_reference.endswith(DASH) else sub_reference, + normalized_sub_reference[:-1] + if normalized_sub_reference.endswith(DASH) + else normalized_sub_reference, book, start_chapter, ) @@ -195,7 +201,8 @@ def _process_sub_reference( end_verse: int | None = None no_verses: bool = False - clean_sub_reference: str = sub_reference.replace(PERIOD, COLON) + clean_sub_reference: str = sub_reference.strip().lstrip(" .,:;-") + clean_sub_reference = clean_sub_reference.replace(PERIOD, COLON) chapter_and_verse_range: list[str] = clean_sub_reference.split(DASH) min_chapter_and_verse: list[str] = chapter_and_verse_range[0].strip().split(COLON) diff --git a/pythonbible/tests/parser/parser_test.py b/pythonbible/tests/parser/parser_test.py index fc3a46a..cadf09b 100644 --- a/pythonbible/tests/parser/parser_test.py +++ b/pythonbible/tests/parser/parser_test.py @@ -116,6 +116,76 @@ def test_normalize_reference_range_without_verse_numbers( ) +@pytest.mark.parametrize( + ("text", "expected"), + [ + ( + "Micah. 2", + [ + bible.NormalizedReference( + bible.Book.MICAH, + 2, + None, + 2, + None, + bible.Book.MICAH, + ) + ], + ), + ( + "Psalm. 46", + [ + bible.NormalizedReference( + bible.Book.PSALMS, + 46, + None, + 46, + None, + bible.Book.PSALMS, + ) + ], + ), + ( + "Psalms. 74", + [ + bible.NormalizedReference( + bible.Book.PSALMS, + 74, + None, + 74, + None, + bible.Book.PSALMS, + ) + ], + ), + ( + "1Peter. 1:22", + [ + bible.NormalizedReference( + bible.Book.PETER_1, + 1, + 22, + 1, + 22, + bible.Book.PETER_1, + ) + ], + ), + ], +) +def test_get_references_book_name_followed_by_period( + text: str, + expected: list[bible.NormalizedReference], +) -> None: + # Given a reference where a book name is immediately followed by a period + # When it is parsed + references: list[bible.NormalizedReference] = bible.get_references(text) + + # Then the reference is returned without crashing or discarding the chapter/verse + if references != expected: + raise AssertionError(f"Expected {expected!r}, got {references!r}") + + def test_get_references_roman_numerals( roman_numeral_references: str, normalized_references_complex: list[bible.NormalizedReference],