1- from typing import Dict , Optional
1+ from typing import Dict , List , Optional
22
33from testutils .memory_paratext_project_quote_convention_detector import MemoryParatextProjectQuoteConventionDetector
44
55from machine .corpora import ParatextProjectSettings , UsfmStylesheet
6- from machine .punctuation_analysis import ParatextProjectQuoteConventionDetector , QuoteConventionAnalysis
7- from machine .scripture import ORIGINAL_VERSIFICATION , Versification
6+ from machine .punctuation_analysis import (
7+ STANDARD_QUOTE_CONVENTIONS ,
8+ ParatextProjectQuoteConventionDetector ,
9+ QuoteConvention ,
10+ QuoteConventionAnalysis ,
11+ )
12+ from machine .scripture import ORIGINAL_VERSIFICATION , Versification , get_chapters
13+
14+ standard_english_quote_convention : Optional [QuoteConvention ] = STANDARD_QUOTE_CONVENTIONS .get_quote_convention_by_name (
15+ "standard_english"
16+ )
17+ standard_french_quote_convention : Optional [QuoteConvention ] = STANDARD_QUOTE_CONVENTIONS .get_quote_convention_by_name (
18+ "standard_french"
19+ )
820
921
1022def test_get_quote_convention () -> None :
1123 env = _TestEnvironment (
1224 files = {
13- "41MATTest.SFM" : r"""\id MAT
14- \c 1
15- \v 1 Someone said, “This is something I am saying!
16- \v 2 This is also something I am saying” (that is, “something I am speaking”).
17- \p
18- \v 3 Other text, and someone else said,
19- \q1
20- \v 4 “Things
21- \q2 someone else said!
22- \q3 and more things someone else said.”
23- \m That is why he said “things someone else said.”
24- \v 5 Then someone said, “More things someone said.”""" ,
25+ "41MATTest.SFM" : rf"""\id MAT
26+ { get_test_chapter (1 , standard_english_quote_convention )} """ ,
2527 }
2628 )
2729 analysis : Optional [QuoteConventionAnalysis ] = env .get_quote_convention ()
@@ -30,6 +32,64 @@ def test_get_quote_convention() -> None:
3032 assert analysis .best_quote_convention .name == "standard_english"
3133
3234
35+ def test_get_quote_convention_by_book () -> None :
36+ env = _TestEnvironment (
37+ files = {
38+ "41MATTest.SFM" : rf"""\id MAT
39+ { get_test_chapter (1 , standard_english_quote_convention )} """ ,
40+ "42MRKTest.SFM" : rf"""\id MRK
41+ { get_test_chapter (1 , standard_french_quote_convention )} """ ,
42+ }
43+ )
44+ analysis : Optional [QuoteConventionAnalysis ] = env .get_quote_convention ("MRK" )
45+ assert analysis is not None
46+ assert analysis .best_quote_convention_score > 0.8
47+ assert analysis .best_quote_convention .name == "standard_french"
48+
49+
50+ def test_get_quote_convention_by_chapter () -> None :
51+ env = _TestEnvironment (
52+ files = {
53+ "41MATTest.SFM" : rf"""\id MAT
54+ { get_test_chapter (1 , standard_english_quote_convention )} """ ,
55+ "42MRKTest.SFM" : rf"""\id MRK
56+ { get_test_chapter (1 , standard_english_quote_convention )}
57+ { get_test_chapter (2 , standard_french_quote_convention )}
58+ { get_test_chapter (3 , standard_english_quote_convention )}
59+ { get_test_chapter (4 , standard_english_quote_convention )}
60+ { get_test_chapter (5 , standard_french_quote_convention )} """ ,
61+ }
62+ )
63+ analysis : Optional [QuoteConventionAnalysis ] = env .get_quote_convention ("MRK2,4-5" )
64+ assert analysis is not None
65+ assert analysis .best_quote_convention_score > 0.66
66+ assert analysis .best_quote_convention .name == "standard_french"
67+
68+
69+ def test_get_quote_convention_by_chapter_indeterminate () -> None :
70+ env = _TestEnvironment (
71+ files = {
72+ "41MATTest.SFM" : rf"""\id MAT
73+ { get_test_chapter (1 , None )}
74+ { get_test_chapter (2 , standard_english_quote_convention )}
75+ { get_test_chapter (3 , None )} """ ,
76+ }
77+ )
78+ analysis : Optional [QuoteConventionAnalysis ] = env .get_quote_convention ("MAT1,3" )
79+ assert analysis is None
80+
81+
82+ def test_get_quote_convention_invalid_book_code () -> None :
83+ env = _TestEnvironment (
84+ files = {
85+ "41MATTest.SFM" : rf"""\id LUK
86+ { get_test_chapter (1 , standard_english_quote_convention )} """ ,
87+ }
88+ )
89+ analysis : Optional [QuoteConventionAnalysis ] = env .get_quote_convention ("MAT" )
90+ assert analysis is None
91+
92+
3393class _TestEnvironment :
3494 def __init__ (
3595 self ,
@@ -44,8 +104,27 @@ def __init__(
44104 def detector (self ) -> ParatextProjectQuoteConventionDetector :
45105 return self ._detector
46106
47- def get_quote_convention (self ) -> Optional [QuoteConventionAnalysis ]:
48- return self .detector .get_quote_convention_analysis ()
107+ def get_quote_convention (self , scripture_range : Optional [str ] = None ) -> Optional [QuoteConventionAnalysis ]:
108+ chapters : Optional [Dict [int , List [int ]]] = None
109+ if scripture_range is not None :
110+ chapters = get_chapters (scripture_range , ORIGINAL_VERSIFICATION )
111+ return self .detector .get_quote_convention_analysis (include_chapters = chapters )
112+
113+
114+ def get_test_chapter (number : int , quote_convention : Optional [QuoteConvention ]) -> str :
115+ left_quote : str = quote_convention .get_opening_quotation_mark_at_depth (1 ) if quote_convention else ""
116+ right_quote : str = quote_convention .get_closing_quotation_mark_at_depth (1 ) if quote_convention else ""
117+ return rf"""\c { number }
118+ \v 1 Someone said, { left_quote } This is something I am saying!
119+ \v 2 This is also something I am saying{ right_quote } (that is, { left_quote } something I am speaking{ right_quote } ).
120+ \p
121+ \v 3 Other text, and someone else said,
122+ \q1
123+ \v 4 { left_quote } Things
124+ \q2 someone else said!
125+ \q3 and more things someone else said.{ right_quote }
126+ \m That is why he said { left_quote } things someone else said.{ right_quote }
127+ \v 5 Then someone said, { left_quote } More things someone said.{ right_quote } """
49128
50129
51130class _DefaultParatextProjectSettings (ParatextProjectSettings ):
0 commit comments