|
1 |
| -from typing import List, Union |
2 |
| - |
3 |
| -from .analysis.depth_based_quotation_mark_resolver import DepthBasedQuotationMarkResolver |
4 |
| -from .analysis.quotation_mark_finder import QuotationMarkFinder |
5 |
| -from .analysis.quotation_mark_resolver import QuotationMarkResolver |
6 |
| -from .analysis.quotation_mark_string_match import QuotationMarkStringMatch |
7 | 1 | from .analysis.quote_convention import QuoteConvention
|
8 |
| -from .analysis.quote_convention_set import QuoteConventionSet |
9 |
| -from .analysis.text_segment import TextSegment |
10 |
| -from .analysis.usfm_marker_type import UsfmMarkerType |
11 |
| -from .basic_quotation_mark_resolver import BasicQuotationMarkResolver |
12 |
| -from .quotation_denormalization_action import QuotationDenormalizationAction |
13 |
| -from .quotation_denormalization_resolution_settings import QuotationDenormalizationResolutionSettings |
14 |
| -from .quotation_denormalization_settings import QuotationDenormalizationSettings |
15 |
| -from .usfm_token import UsfmToken, UsfmTokenType |
16 |
| -from .usfm_update_block import UsfmUpdateBlock |
17 |
| -from .usfm_update_block_element import UsfmUpdateBlockElement, UsfmUpdateBlockElementType |
18 |
| -from .usfm_update_block_handler import UsfmUpdateBlockHandler |
| 2 | +from .quotation_mark_update_settings import QuotationMarkUpdateSettings |
| 3 | +from .quote_convention_changing_usfm_update_block_handler import QuoteConventionChangingUsfmUpdateBlockHandler |
19 | 4 |
|
20 | 5 |
|
21 |
| -class QuotationDenormalizationUsfmUpdateBlockHandler(UsfmUpdateBlockHandler): |
| 6 | +class QuotationDenormalizationUsfmUpdateBlockHandler(QuoteConventionChangingUsfmUpdateBlockHandler): |
22 | 7 |
|
23 | 8 | def __init__(
|
24 | 9 | self,
|
25 | 10 | source_quote_convention: QuoteConvention,
|
26 | 11 | target_quote_convention: QuoteConvention,
|
27 |
| - settings: QuotationDenormalizationSettings = QuotationDenormalizationSettings(), |
| 12 | + settings: QuotationMarkUpdateSettings = QuotationMarkUpdateSettings(), |
28 | 13 | ):
|
29 |
| - super().__init__() |
30 |
| - self._source_quote_convention: QuoteConvention = source_quote_convention |
31 |
| - self._target_quote_convention: QuoteConvention = target_quote_convention |
32 |
| - self._settings: QuotationDenormalizationSettings = settings |
33 |
| - |
34 |
| - self._quotation_mark_finder: QuotationMarkFinder = QuotationMarkFinder( |
35 |
| - QuoteConventionSet([self._source_quote_convention.normalize()]) |
36 |
| - ) |
37 |
| - self._next_scripture_text_segment_builder: TextSegment.Builder = TextSegment.Builder() |
38 |
| - |
39 |
| - resolution_settings = QuotationDenormalizationResolutionSettings( |
40 |
| - self._source_quote_convention, self._target_quote_convention |
41 |
| - ) |
42 |
| - |
43 |
| - # Each embed represents a separate context for quotation marks |
44 |
| - # (i.e. you can't open a quote in one context and close it in another) |
45 |
| - # so we need to keep track of the verse and embed contexts separately. |
46 |
| - self._verse_text_quotation_mark_resolver: DepthBasedQuotationMarkResolver = DepthBasedQuotationMarkResolver( |
47 |
| - resolution_settings |
48 |
| - ) |
49 |
| - self._embed_quotation_mark_resolver: DepthBasedQuotationMarkResolver = DepthBasedQuotationMarkResolver( |
50 |
| - resolution_settings |
51 |
| - ) |
52 |
| - self._simple_quotation_mark_resolver: BasicQuotationMarkResolver = BasicQuotationMarkResolver( |
53 |
| - resolution_settings |
54 |
| - ) |
55 |
| - self._current_denormalization_action = QuotationDenormalizationAction.APPLY_FULL |
56 |
| - self._current_chapter_number: int = 0 |
57 |
| - self._current_verse_number: int = 0 |
58 |
| - |
59 |
| - def process_block(self, block: UsfmUpdateBlock) -> UsfmUpdateBlock: |
60 |
| - self._check_for_chapter_change(block) |
61 |
| - self._check_for_verse_change(block) |
62 |
| - if self._current_denormalization_action is QuotationDenormalizationAction.SKIP: |
63 |
| - return block |
64 |
| - if self._current_denormalization_action is QuotationDenormalizationAction.APPLY_BASIC: |
65 |
| - return self._apply_simple_denormalization(block) |
66 |
| - return self._apply_full_denormalization(block) |
67 |
| - |
68 |
| - def _apply_simple_denormalization(self, block: UsfmUpdateBlock) -> UsfmUpdateBlock: |
69 |
| - for element in block._elements: |
70 |
| - self._process_scripture_element(element, self._simple_quotation_mark_resolver) |
71 |
| - return block |
72 |
| - |
73 |
| - def _apply_full_denormalization(self, block: UsfmUpdateBlock) -> UsfmUpdateBlock: |
74 |
| - for element in block._elements: |
75 |
| - if element.type == UsfmUpdateBlockElementType.EMBED: |
76 |
| - self._embed_quotation_mark_resolver.reset() |
77 |
| - self._process_scripture_element(element, self._embed_quotation_mark_resolver) |
78 |
| - else: |
79 |
| - self._process_scripture_element(element, self._verse_text_quotation_mark_resolver) |
80 |
| - |
81 |
| - return block |
82 |
| - |
83 |
| - def _process_scripture_element( |
84 |
| - self, element: UsfmUpdateBlockElement, quotation_mark_resolver: QuotationMarkResolver |
85 |
| - ) -> None: |
86 |
| - text_segments: List[TextSegment] = self._create_text_segments(element) |
87 |
| - quotation_mark_matches: List[QuotationMarkStringMatch] = ( |
88 |
| - self._quotation_mark_finder.find_all_potential_quotation_marks_in_text_segments(text_segments) |
89 |
| - ) |
90 |
| - for resolved_quotation_mark in quotation_mark_resolver.resolve_quotation_marks(quotation_mark_matches): |
91 |
| - resolved_quotation_mark.update_quotation_mark(self._target_quote_convention) |
92 |
| - |
93 |
| - def _create_text_segments(self, element: UsfmUpdateBlockElement) -> List[TextSegment]: |
94 |
| - text_segments: List[TextSegment] = [] |
95 |
| - for token in element.get_tokens(): |
96 |
| - if token.type == UsfmTokenType.VERSE: |
97 |
| - self._next_scripture_text_segment_builder.add_preceding_marker(UsfmMarkerType.VerseMarker) |
98 |
| - elif token.type == UsfmTokenType.PARAGRAPH: |
99 |
| - self._next_scripture_text_segment_builder.add_preceding_marker(UsfmMarkerType.ParagraphMarker) |
100 |
| - elif token.type == UsfmTokenType.CHARACTER: |
101 |
| - self._next_scripture_text_segment_builder.add_preceding_marker(UsfmMarkerType.CharacterMarker) |
102 |
| - elif token.type == UsfmTokenType.NOTE: |
103 |
| - self._next_scripture_text_segment_builder.add_preceding_marker(UsfmMarkerType.EmbedMarker) |
104 |
| - elif token.type == UsfmTokenType.TEXT: |
105 |
| - text_segment: Union[TextSegment, None] = self._create_text_segment(token) |
106 |
| - if text_segment is not None: |
107 |
| - text_segments.append(text_segment) |
108 |
| - return self._set_previous_and_next_for_segments(text_segments) |
109 |
| - |
110 |
| - def _create_text_segment(self, token: UsfmToken) -> Union[TextSegment, None]: |
111 |
| - self._next_scripture_text_segment_builder.set_usfm_token(token) |
112 |
| - if token.text is not None: |
113 |
| - self._next_scripture_text_segment_builder.set_text(token.text) |
114 |
| - text_segment_to_return: TextSegment = self._next_scripture_text_segment_builder.build() |
115 |
| - self._next_scripture_text_segment_builder = TextSegment.Builder() |
116 |
| - return text_segment_to_return |
117 |
| - else: |
118 |
| - self._next_scripture_text_segment_builder = TextSegment.Builder() |
119 |
| - |
120 |
| - def _set_previous_and_next_for_segments(self, text_segments: List[TextSegment]) -> List[TextSegment]: |
121 |
| - for i in range(len(text_segments)): |
122 |
| - if i > 0: |
123 |
| - text_segments[i].set_previous_segment(text_segments[i - 1]) |
124 |
| - if i < len(text_segments) - 1: |
125 |
| - text_segments[i].set_next_segment(text_segments[i + 1]) |
126 |
| - return text_segments |
127 |
| - |
128 |
| - def _check_for_chapter_change(self, block: UsfmUpdateBlock) -> None: |
129 |
| - for scripture_ref in block.refs: |
130 |
| - if scripture_ref.chapter_num != self._current_chapter_number: |
131 |
| - self._current_chapter_number = scripture_ref.chapter_num |
132 |
| - self._start_new_chapter(self._current_chapter_number) |
133 |
| - |
134 |
| - def _start_new_chapter(self, new_chapter_number: int) -> None: |
135 |
| - self._current_denormalization_action = self._settings.get_action_for_chapter(new_chapter_number) |
136 |
| - self._verse_text_quotation_mark_resolver.reset() |
137 |
| - self._next_scripture_text_segment_builder = TextSegment.Builder() |
138 |
| - self._next_scripture_text_segment_builder.add_preceding_marker(UsfmMarkerType.ChapterMarker) |
139 |
| - |
140 |
| - def _check_for_verse_change(self, block: UsfmUpdateBlock) -> None: |
141 |
| - for scripture_ref in block.refs: |
142 |
| - if ( |
143 |
| - scripture_ref.chapter_num == self._current_chapter_number |
144 |
| - and scripture_ref.verse_num != self._current_verse_number |
145 |
| - ): |
146 |
| - self._current_verse_number = scripture_ref.verse_num |
147 |
| - self._start_new_verse(self._current_verse_number) |
148 |
| - |
149 |
| - def _start_new_verse(self, new_chapter_number: int) -> None: |
150 |
| - self._next_scripture_text_segment_builder.add_preceding_marker(UsfmMarkerType.VerseMarker) |
| 14 | + super().__init__(source_quote_convention.normalize(), target_quote_convention, settings) |
0 commit comments