def test_moustache_tag(self) -> None: """Itemize moustache tags.""" self.assertEqual(('Hello {0}', { '0': '{var:firstName:"Marie"}' }), extract_mailjet_strings.itemize_html_and_mjml_tags( 'Hello {{var:firstName:"Marie"}}'))
def test_br_tag(self) -> None: """Itemize HTML tags with a br tag implicitely self closing.""" self.assertEqual(('One <0/>self closing tag', { '0': 'br' }), extract_mailjet_strings.itemize_html_and_mjml_tags( 'One <br>self closing tag'))
def test_self_closing_tag(self) -> None: """Itemize HTML tags with a self closing tag.""" self.assertEqual(('One <0/>self closing tag', { '0': 'br /' }), extract_mailjet_strings.itemize_html_and_mjml_tags( 'One <br />self closing tag'))
def test_simple_html_tag(self) -> None: """Itemize HTML tags with one tag.""" self.assertEqual(('One <0>tag</0>', { '0': 'span style="font-weight: 500"' }), extract_mailjet_strings.itemize_html_and_mjml_tags( 'One <span style="font-weight: 500">tag</span>'))
def test_mjml_branch_tag(self) -> None: """Itemize MJML branch tag.""" self.assertEqual( ('{0}Hello{1}Hi{2} you', { '0': '%if var:foo="bar"%', '1': '%else%', '2': '%endif%' }), extract_mailjet_strings.itemize_html_and_mjml_tags( '{%if var:foo="bar"%}Hello{%else%}Hi{%endif%} you'))
def test_multiple_tags(self) -> None: """Itemize HTML tags with multiple nested tags.""" self.assertEqual( ('<0>Multiple <1>nested</1><2/>tags</0>', { '0': 'p', '1': 'strong', '2': 'br /' }), extract_mailjet_strings.itemize_html_and_mjml_tags( '<p>Multiple <strong>nested</strong><br />tags</p>'))
def test_no_html(self) -> None: """Itemize HTML tags with no tags.""" self.assertEqual( 'No tags', extract_mailjet_strings.itemize_html_and_mjml_tags('No tags')[0])
def translate_html_tags(html_soup: str, translate: Callable[[str], str], with_outer_tag: bool = True) -> str: """Translate an HTML soup. e.g. '<p style="foo"><a>Hello</a><br />World</p>', and '<1>Hello</1><2/>World' => '<1>Bonjour</1><2/>monde' => ''<p style="foo"><a>Bonjour</a><br />monde</p>' """ if with_outer_tag: before, content, after = extract_mailjet_strings.breaks_outer_tags_html( html_soup) if before: for value, attr in extract_mailjet_strings.extract_i18n_from_html_attrs( before): translated_value = translate_html_tags(value, translate, with_outer_tag=False) if translated_value != value: before = before.replace(f'{attr}="{value}"', f'{attr}="{translated_value}"') else: before, content, after = '', html_soup, '' simplified, items = extract_mailjet_strings.itemize_html_and_mjml_tags( content) if extract_mailjet_strings.has_i18n_content(html_soup): translated_simplified = translate(simplified) else: translated_simplified = simplified tokens = extract_mailjet_strings.tokenize_html_and_mjml( translated_simplified) translated_items = dict(items) for string, item, attr in extract_mailjet_strings.extract_i18n_from_html_attrs_in_items( items): translated_value = translate_html_tags(string, translate, with_outer_tag=False) if translated_value != string: translated_items[item] = \ items[item].replace(f'{attr}="{string}"', f'{attr}="{translated_value}"') translated = '' for token, token_type in tokens: if not token: continue if token_type == 'content': translated += token continue # Self-closing tag. if token_type == 'self-closing': item = token[1:-2] translated += f'<{translated_items[item]}>' continue # Closing tag. if token_type == 'closing': item = token[2:-1] translated += f'</{translated_items[item].split(" ")[0]}>' continue item = token[1:-1] # MJML tag. if token_type == 'mjml': if item in translated_items: translated += f'{{{translated_items[item]}}}' elif item.startswith('{') and item.endswith('}'): translated += f'{{{item}}}' else: raise KeyError( f'The translation refers to {{{item}}} that is not in the original string' ) continue # Opening tag. translated += f'<{translated_items[item]}>' return before + translated + after