+ >>> print(chapter.verses["1"])
+ Généalogie de Jésus-Christ, fils de David, fils d'Abraham.
"""
soup = BeautifulSoup(chapter.content, "html.parser")
verse_dict: dict[VerseRef, str] = {}
@@ -1505,9 +1540,11 @@ def clean_content_html(raw_content: str) -> str:
if __name__ == "__main__":
# To run the doctests in this module, in the root of the project do:
- # python backend/document/domain/resource_lookup.py
+ # PYTHONPATH=backend python backend/doc/domain/parsing.py
# or
- # python backend/document/domain/resource_lookup.py -v
+ # PYTHONPATH=backend python backend/doc/domain/parsing.py -v
+ # These doctests are not collected by pytest: pyproject.toml sets
+ # testpaths = ["tests"] with no doctest collection, so run them by hand.
# See https://docs.python.org/3/library/doctest.html
# for more details.
import doctest
diff --git a/tests/unit/test_parsing.py b/tests/unit/test_parsing.py
index c3188321..39644fcd 100644
--- a/tests/unit/test_parsing.py
+++ b/tests/unit/test_parsing.py
@@ -5,8 +5,10 @@
ensure_chapter_label,
ensure_chapter_marker,
maybe_localized_book_name,
+ split_chapter_into_verses_with_formatting,
)
from doc.domain import model, resource_lookup
+from doc.domain.model import USFMChapter
def test_ensure_chapter_marker_unchanged_if_exists() -> None:
@@ -102,5 +104,143 @@ def test_fr_f10_book_name_lookup_prefs() -> None:
assert localized_book_name == expected
+# Sample content taken from fr f10 Matthew 1, which uses word-entry tags.
+FRENCH_WORD_ENTRY_HTML = """
+
+1
+ Généalogie
+
+ de
+ Jésus
+-
+ Christ
+,
+ fils
+ de
+ David
+,
+ fils
+ d'
+ Abraham
+.
+
+
+
+2
+ Abraham
+
+ engendra
+
+ Isaac
+;
+
+"""
+
+# Sample content in the shape produced for USFM without word-entry tags: a
+# footnote caller sup and a trailing sectionhead div follow the verse text.
+GALATIANS_HTML = """
+
+ 19
+For through the law I died to the law, so that I might live for God.
+
+
+
+
+20
+I have been crucified with Christ and I no longer live.
+
+
+
+"""
+
+
+def test_split_chapter_into_verses_with_formatting_keys() -> None:
+ chapter = USFMChapter(content=GALATIANS_HTML, verses=None)
+ verses = split_chapter_into_verses_with_formatting(chapter)
+ assert list(verses.keys()) == ["19", "20"]
+
+
+def test_split_chapter_into_verses_with_formatting_strips_verse_number_whitespace() -> (
+ None
+):
+ # The versemarker sup for verse 19 is written as " 19 ".
+ chapter = USFMChapter(content=GALATIANS_HTML, verses=None)
+ verses = split_chapter_into_verses_with_formatting(chapter)
+ assert "19" in verses
+ assert " 19 " not in verses
+
+
+def test_split_chapter_into_verses_with_formatting_removes_versemarker_only() -> None:
+ chapter = USFMChapter(content=GALATIANS_HTML, verses=None)
+ verses = split_chapter_into_verses_with_formatting(chapter)
+ for verse in verses.values():
+ assert "versemarker" not in verse
+ # Other markup inside the verse span survives.
+ assert verses["19"] == (
+ ' For through the law I died to the law, '
+ "so that I might live for God.\n"
+ '\n'
+ '\n'
+ )
+
+
+def test_split_chapter_into_verses_with_formatting_unwraps_word_entries() -> None:
+ chapter = USFMChapter(content=FRENCH_WORD_ENTRY_HTML, verses=None)
+ verses = split_chapter_into_verses_with_formatting(chapter)
+ assert list(verses.keys()) == ["1", "2"]
+ for verse in verses.values():
+ assert "word-entry" not in verse
+ # The wrapped text survives in place, with whitespace collapsed and
+ # whitespace before punctuation removed.
+ assert verses["1"] == (
+ ' Généalogie de Jésus-Christ, fils de David, '
+ "fils d'Abraham. "
+ )
+ assert verses["2"] == ' Abraham engendra Isaac;\n'
+
+
+def test_split_chapter_into_verses_with_formatting_collapses_hyphen_spacing() -> None:
+ """Spacing around a hyphen is intentionally collapsed (see clean_content_html)."""
+ chapter = USFMChapter(content=FRENCH_WORD_ENTRY_HTML, verses=None)
+ verses = split_chapter_into_verses_with_formatting(chapter)
+ assert "Jésus-Christ" in verses["1"]
+ assert "Jésus - Christ" not in verses["1"]
+
+
+def test_split_chapter_into_verses_with_formatting_skips_verses_without_versemarker() -> (
+ None
+):
+ html_content = """
+
+No versemarker sup at all here.
+
+
+
+An empty versemarker sup here.
+
+
+3
+A well formed verse.
+
+"""
+ chapter = USFMChapter(content=html_content, verses=None)
+ verses = split_chapter_into_verses_with_formatting(chapter)
+ assert list(verses.keys()) == ["3"]
+ assert verses["3"] == ' A well formed verse.\n'
+
+
+def test_split_chapter_into_verses_with_formatting_without_verse_spans() -> None:
+ chapter = USFMChapter(
+ content="Chapter content with no verse spans.
", verses=None
+ )
+ assert split_chapter_into_verses_with_formatting(chapter) == {}
+
+
+def test_split_chapter_into_verses_with_formatting_empty_content() -> None:
+ chapter = USFMChapter(content="", verses=None)
+ assert split_chapter_into_verses_with_formatting(chapter) == {}
+
+
if __name__ == "__main__":
pytest.main()