From 7354b822180857949d757f236f3966e32b31feb8 Mon Sep 17 00:00:00 2001 From: bookfere Date: Thu, 14 Mar 2024 22:49:09 +0800 Subject: [PATCH] refactor: Enhanced side-by-side translation position for ignored paragraphs. --- advanced.py | 4 +- components/engine.py | 2 + lib/conversion.py | 1 + lib/element.py | 69 ++++----- lib/translation.py | 4 +- tests/test_element.py | 353 ++++++++++++++++++++++++++++++++---------- 6 files changed, 310 insertions(+), 123 deletions(-) diff --git a/advanced.py b/advanced.py index 6e98770..da92cfa 100644 --- a/advanced.py +++ b/advanced.py @@ -559,11 +559,11 @@ def layout_control(self): title_layout = QHBoxLayout(title_group) custom_title = QCheckBox() ebook_title = QLineEdit() - ebook_title.setText(self.ebook.title) ebook_title.setToolTip( _('By default, title metadata will be translated.')) + ebook_title.setText(self.ebook.title) + ebook_title.setCursorPosition(0) ebook_title.setDisabled(True) - # ebook_title.setCursorPosition(0) title_layout.addWidget(custom_title) title_layout.addWidget(ebook_title) diff --git a/components/engine.py b/components/engine.py index 59aeed9..e65b6d3 100644 --- a/components/engine.py +++ b/components/engine.py @@ -230,6 +230,8 @@ def add_data(): custom_list.setCurrentText(name) custom_engine_data.setPlainText(template) self.custom_engines[name] = template + if len(self.custom_engines) < 1: + add_data() def restore_data(name=None): name = name or custom_list.currentText() diff --git a/lib/conversion.py b/lib/conversion.py index 8ab3e45..a8f2cc9 100644 --- a/lib/conversion.py +++ b/lib/conversion.py @@ -270,6 +270,7 @@ def translate_done(self, job): filename = '%s.%s' % (metadata.title, ebook.output_format) new_output_path = os.path.join(dirname, filename) os.rename(output_path, new_output_path) + output_path = new_output_path self.gui.status_bar.show_message( job.description + ' ' + _('completed'), 5000) diff --git a/lib/element.py b/lib/element.py index 789bdab..1d873b0 100644 --- a/lib/element.py +++ b/lib/element.py @@ -90,7 +90,6 @@ def add_translation( self.element[2] += '\n%s' % translation else: self.element[2] = '%s\n%s' % (translation, self.element[2]) - return self.element def get_translation(self): return '\n'.join(self.element) @@ -117,9 +116,10 @@ def add_translation( if position not in ('below', 'right'): content = reversed(content) self.element[1] = ' | '.join(content) - return self.element def get_translation(self): + if self.element[1] is None: + return self.element[0] return '{%s}' % self.element[1] @@ -145,7 +145,6 @@ def add_translation( else: self.element.content = '%s %s' %( self.element.content, translation) - return self.element class TocElement(Element): @@ -165,7 +164,6 @@ def add_translation( items = [self.element.title, translation] self.element.title = items[-1] if position == 'only' else ' '.join( reversed(items) if position in ('above', 'left') else items) - return self.element class PageElement(Element): @@ -223,16 +221,16 @@ def _polish_translation(self, translation): def add_translation( self, translation, position, translation_lang=None, original_color=None, translation_color=None): + if original_color is not None: + self.element.set('style', 'color:%s' % original_color) if translation is None: if position in ('left', 'right'): - if original_color is not None: - self.element_color.set( - 'style', 'color:%s' % original_color) self.element.addnext( self._create_table(position, self._element_copy())) - if position in ('only', 'left', 'right'): + if position in ('left', 'right'): self.delete() - return self.element + # return self.element + return # Escape the markups () to replace escaped markups. translation = xml_escape(translation) for rid, reserve in enumerate(self.reserve_elements): @@ -259,8 +257,6 @@ def add_translation( new_element.set(name, value) if translation_lang is not None: new_element.set('lang', translation_lang) - if original_color is not None: - self.element.set('style', 'color:%s' % original_color) if translation_color is not None: new_element.set('style', 'color:%s' % translation_color) @@ -268,8 +264,6 @@ def add_translation( if position in ('left', 'right'): element_copy = self._element_copy() - if original_color is not None: - element_copy.set('style', 'color:%s' % original_color) self.element.addnext( self._create_table(position, element_copy, new_element)) elif position == 'above': @@ -278,7 +272,6 @@ def add_translation( self.element.addnext(new_element) if position in ['left', 'right', 'only']: self.delete() - return new_element def _create_table(self, position, original, translation=None): # table = self.element.makeelement('table', attrib={'width': '100%'}) @@ -300,7 +293,9 @@ def _create_table(self, position, original, translation=None): td_middle.set('width', '%s%%' % value) td_right.set('width', width) else: + td_left.set('width', '50%') td_middle.text = '\xa0' * value + td_right.set('width', '50%') if position == 'left': if translation is not None: td_left.append(translation) @@ -378,8 +373,8 @@ def need_ignore(self, element): def extract_elements(self, page_id, root, elements=[]): priority_elements = ['p', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'] for element in root.findall('./*'): - if self.need_ignore(element): - continue + # if self.need_ignore(element): + # continue element_has_content = False if element.text is not None and trim(element.text) != '': element_has_content = True @@ -393,12 +388,15 @@ def extract_elements(self, page_id, root, elements=[]): element_has_content = True break if element_has_content: - elements.append(PageElement(element, page_id)) + page_element = PageElement(element, page_id) + page_element.set_ignored(self.need_ignore(element)) + elements.append(page_element) else: self.extract_elements(page_id, element, elements) # Return root if all children have no content - root = PageElement(root, page_id) - return elements if elements else [root] + page_element = PageElement(root, page_id) + page_element.set_ignored(self.need_ignore(root)) + return elements if elements else [page_element] def filter_content(self, element): # Ignore the element contains empty content @@ -449,12 +447,8 @@ def set_translation_color(self, color): self.translation_color = color def set_column_gap(self, values): - self.column_gap = values - - def remove_unused_elements(self): - if self.position == 'only': - for element in self.elements.values(): - element.delete() + if isinstance(values, tuple) and len(values) == 2: + self.column_gap = values def prepare_original(self, elements): count = 0 @@ -493,7 +487,9 @@ def add_translations(self, paragraphs): for eid, element in self.elements.copy().items(): if element.ignored: self.elements.pop(eid) - self.remove_unused_elements() + for element in self.elements.values(): + element.add_translation( + None, self.position, original_color=self.original_color) class ElementHandlerMerge(ElementHandler): @@ -501,18 +497,16 @@ def prepare_original(self, elements): raw = '' txt = '' oid = 0 - count = 0 - for element in elements: + for eid, element in enumerate(elements): + self.elements[eid] = element if element.ignored: continue element.set_placeholder(self.placeholder) if self.column_gap is not None: element.set_column_gap(self.column_gap) - self.elements[count] = element code = element.get_raw() content = element.get_content() self.base_originals.append(content) - count += 1 content += self.separator if len(txt + content) < self.merge_length: raw += code + self.separator @@ -535,16 +529,18 @@ def align_paragraph(self, paragraph): r'\s*%s\s*' % self.placeholder[1].format(r'(0|[^0]\d*)')) paragraph.original = pattern.sub( self.separator, paragraph.original) - paragraph.translation = pattern.sub( - self.separator, paragraph.translation) + if paragraph.translation is not None: + paragraph.translation = pattern.sub( + self.separator, paragraph.translation) # Ensure the translation count matches the actual elements count. originals = paragraph.original.strip().split(self.separator) + if paragraph.translation is None: + return list(zip(originals, [None] * len(originals))) pattern = re.compile('%s+' % self.separator) translation = pattern.sub(self.separator, paragraph.translation) translations = translation.strip().split(self.separator) offset = len(originals) - len(translations) if offset > 0: - # TODO: Merge the original and translation for the left and right. if self.position in ['left', 'right']: addition = [None] * offset translations += addition @@ -571,21 +567,23 @@ def add_translations(self, paragraphs): translations = dict(translations) for eid, element in self.elements.copy().items(): if element.ignored: + element.add_translation( + None, self.position, original_color=self.original_color) continue original = element.get_content() translation = translations.get(original) if translation is None: + element.add_translation( + None, self.position, original_color=self.original_color) continue element.add_translation( translation, self.position, self.translation_lang, self.original_color, self.translation_color) self.elements.pop(eid) - self.remove_unused_elements() def get_srt_elements(path): elements = [] - try: with open(path, 'r', newline=None) as f: content = f.read().strip() @@ -598,7 +596,6 @@ def get_srt_elements(path): time = lines.pop(0) content = '\n'.join(lines) elements.append(SrtElement([number, time, content])) - return elements diff --git a/lib/translation.py b/lib/translation.py index d85e615..ab942f8 100644 --- a/lib/translation.py +++ b/lib/translation.py @@ -154,9 +154,9 @@ def _translate_text(self, text, retry=0, interval=0): retry += 1 interval += 5 # Logging any errors that occur during translation. - text = text[:200] + '...' if len(text) > 200 else text + logged_text = text[:200] + '...' if len(text) > 200 else text error_message = '{0}\n{2}\n{1}\n{3}\n{1}\n{4}'.format( - sep(), sep('┈'), _('Original: {}').format(text), + sep(), sep('┈'), _('Original: {}').format(logged_text), _('Status: Failed {} times / Sleeping for {} seconds') .format(retry, interval), _('Error: {}').format(str(e))) self.log(error_message, True) diff --git a/tests/test_element.py b/tests/test_element.py index 4493534..a5a833e 100644 --- a/tests/test_element.py +++ b/tests/test_element.py @@ -9,7 +9,7 @@ from ..lib.cache import Paragraph from ..lib.element import ( get_string, get_name, Extraction, ElementHandler, ElementHandlerMerge, - Element, SrtElement, TocElement, PageElement, MetadataElement, + Element, SrtElement, PgnElement, TocElement, PageElement, MetadataElement, get_toc_elements, get_metadata_elements) from ..engines import DeeplFreeTranslate from ..engines.base import Base @@ -34,6 +34,12 @@ def test_get_name(self): xhtml = '

a

' self.assertEqual('p', get_name(etree.XML(xhtml))) + def test_get_srt_elements(self): + pass + + def test_get_pgn_elements(self): + pass + def test_get_toc_elements(self): toc = TOC() toc.add('a', 'a.html') @@ -127,28 +133,74 @@ def test_get_content(self): self.assertEqual('a', self.element.get_content()) def test_add_translation_none(self): - element = self.element.add_translation(None, 'below') - self.assertEqual('a', element[2]) + self.element.add_translation(None, 'below') + self.assertEqual('a', self.element.element[2]) def test_add_translation_below(self): - element = self.element.add_translation('A', 'below') - self.assertEqual('a\nA', element[2]) + self.element.add_translation('A', 'below') + self.assertEqual('a\nA', self.element.element[2]) def test_add_translation_right(self): - element = self.element.add_translation('A', 'right') - self.assertEqual('a\nA', element[2]) + self.element.add_translation('A', 'right') + self.assertEqual('a\nA', self.element.element[2]) def test_add_translation_above(self): - element = self.element.add_translation('A', 'above') - self.assertEqual('A\na', element[2]) + self.element.add_translation('A', 'above') + self.assertEqual('A\na', self.element.element[2]) def test_add_translation_left(self): - element = self.element.add_translation('A', 'left') - self.assertEqual('A\na', element[2]) + self.element.add_translation('A', 'left') + self.assertEqual('A\na', self.element.element[2]) + + def test_add_translation_only(self): + self.element.add_translation('A', 'only') + self.assertEqual('A', self.element.element[2]) + + +class TestPgnElement(unittest.TestCase): + def setUp(self): + self.item = ['{a}', None] + self.element = PgnElement(self.item) + + def test_create_element(self): + self.assertIsInstance(self.element, Element) + self.assertIsInstance(self.element, PgnElement) + + def test_get_raw(self): + self.assertEqual('{a}', self.element.get_raw()) + + def test_get_text(self): + self.assertEqual('a', self.element.get_text()) + + def test_test_content(self): + self.assertEqual('a', self.element.get_content()) def test_add_translation_only(self): - element = self.element.add_translation('A', 'only') - self.assertEqual('A', element[2]) + self.element.add_translation('A', position='only') + self.assertEqual('A', self.element.element[1]) + + def test_add_translation_below(self): + self.element.add_translation('A', position='below') + self.assertEqual('a | A', self.element.element[1]) + + def test_add_translation_right(self): + self.element.add_translation('A', position='right') + self.assertEqual('a | A', self.element.element[1]) + + def test_add_translation_above(self): + self.element.add_translation('A', position='above') + self.assertEqual('A | a', self.element.element[1]) + + def test_add_translation_left(self): + self.element.add_translation('A', position='left') + self.assertEqual('A | a', self.element.element[1]) + + def test_get_translation(self): + self.element.add_translation('A', position='below') + self.assertEqual('{a | A}', self.element.get_translation()) + + def test_get_translation_none(self): + self.assertEqual('{a}', self.element.get_translation()) class TestMetadataElement(unittest.TestCase): @@ -166,29 +218,28 @@ def test_get_content(self): self.assertEqual('a', self.element.get_content()) def test_add_translation_none(self): - self.assertIs( - self.element.element, - self.element.add_translation(None, 'below')) + self.element.add_translation(None, 'below') + self.assertEqual('a', self.element.element.content) def test_add_translation_below(self): - element = self.element.add_translation('A', 'below') - self.assertEqual('a A', element.content) + self.element.add_translation('A', 'below') + self.assertEqual('a A', self.element.element.content) def test_add_translation_right(self): - element = self.element.add_translation('A', 'right') - self.assertEqual('a A', element.content) + self.element.add_translation('A', 'right') + self.assertEqual('a A', self.element.element.content) def test_add_translation_above(self): - element = self.element.add_translation('A', 'above') - self.assertEqual('A a', element.content) + self.element.add_translation('A', 'above') + self.assertEqual('A a', self.element.element.content) def test_add_translation_left(self): - element = self.element.add_translation('A', 'left') - self.assertEqual('A a', element.content) + self.element.add_translation('A', 'left') + self.assertEqual('A a', self.element.element.content) def test_add_translation_only(self): - element = self.element.add_translation('A', 'only') - self.assertEqual('A', element.content) + self.element.add_translation('A', 'only') + self.assertEqual('A', self.element.element.content) class TestTocElement(unittest.TestCase): @@ -205,28 +256,28 @@ def test_get_content(self): self.assertEqual('a', self.element.get_content()) def test_add_translation_none(self): - element = self.element.add_translation(None, 'below') - self.assertEqual('a', element.title) + self.element.add_translation(None, 'below') + self.assertEqual('a', self.element.element.title) def test_add_translation_below(self): - element = self.element.add_translation('A', 'below') - self.assertEqual('a A', element.title) + self.element.add_translation('A', 'below') + self.assertEqual('a A', self.element.element.title) def test_add_translation_right(self): - element = self.element.add_translation('A', 'right') - self.assertEqual('a A', element.title) + self.element.add_translation('A', 'right') + self.assertEqual('a A', self.element.element.title) def test_add_translation_above(self): - element = self.element.add_translation('A', 'above') - self.assertEqual('A a', element.title) + self.element.add_translation('A', 'above') + self.assertEqual('A a', self.element.element.title) def test_add_translation_left(self): - element = self.element.add_translation('A', 'left') - self.assertEqual('A a', element.title) + self.element.add_translation('A', 'left') + self.assertEqual('A a', self.element.element.title) def test_add_translation_only(self): - element = self.element.add_translation('A', 'only') - self.assertEqual('A', element.title) + self.element.add_translation('A', 'only') + self.assertEqual('A', self.element.element.title) class TestPageElement(unittest.TestCase): @@ -290,15 +341,51 @@ def test_get_content(self): def test_get_attributes(self): self.assertEqual('{"class": "abc"}', self.element.get_attributes()) - def test_add_translation_none(self): - element = self.element.add_translation(None, 'below') - self.assertIs(element, self.element.element) + def test_add_translation_none_below(self): + self.element.add_translation(None, 'below', original_color='#ffff00') + elements = self.xhtml.findall('.//x:p', namespaces=ns) + self.assertEqual(1, len(elements)) + self.assertIn('style="color:#ffff00"', get_string(elements[0])) - def test_add_translation_none_with_left_position(self): - element = self.element.add_translation(None, 'left') - self.assertIs(element, self.element.element) + def test_add_translation_none_above(self): + self.element.add_translation(None, 'above', original_color='#ffff00') + elements = self.xhtml.findall('.//x:p', namespaces=ns) + self.assertEqual(1, len(elements)) + self.assertIn('style="color:#ffff00"', get_string(elements[0])) + + def test_add_translation_none_left(self): + self.element.set_column_gap(('space_count', 5)) + self.element.add_translation( + None, 'left', original_color='#ffff00') + + self.assertEqual(1, len(self.xhtml.findall('.//x:p', namespaces=ns))) + table = self.xhtml.find('.//x:table', namespaces=ns) + self.assertIsNotNone(table) + left_td, middle_td, right_td = table.findall('.//td') + self.assertEqual(0, len(list(left_td))) + self.assertIsNone(left_td.text) + self.assertEqual(0, len(list(middle_td))) + self.assertEqual('\xa0\xa0\xa0\xa0\xa0', middle_td.text) + self.assertEqual(1, len(list(right_td))) + self.assertIn('style="color:#ffff00"', get_string(list(right_td)[0])) + + def test_add_translation_none_right(self): + self.element.set_column_gap(('percentage', 20)) + self.element.add_translation( + None, 'right', original_color='#ff00ff') + + self.assertEqual(1, len(self.xhtml.findall('.//x:p', namespaces=ns))) table = self.xhtml.find('.//x:table', namespaces=ns) self.assertIsNotNone(table) + left_td, middle_td, right_td = table.findall('.//td') + self.assertEqual(1, len(list(left_td))) + self.assertEqual('40%', left_td.get('width')) + self.assertIn('style="color:#ff00ff"', get_string(list(left_td)[0])) + self.assertEqual(0, len(list(middle_td))) + self.assertEqual('20%', middle_td.get('width')) + self.assertEqual(0, len(list(right_td))) + self.assertEqual('40%', right_td.get('width')) + self.assertIsNone(right_td.text) def test_add_translation_with_placeholder(self): self.element.set_placeholder(Base.placeholder) @@ -307,7 +394,7 @@ def test_add_translation_with_placeholder(self): '{{id_00001}} Bbbbbbbbbbbbbbb C {{id_00002}} D E ' '{{id_00003}} F G {{id_00004}} H \n\n{{id_00005}} I ' '{{id_00006}} {{id_00007}} K{ { id _ 0 00 08 } }L') - new = self.element.add_translation(translation, position='below') + self.element.add_translation(translation, position='below') translation = ('

' ' Aaaaa ' 'Bbbbb C D E ' @@ -315,10 +402,12 @@ def test_add_translation_with_placeholder(self): r'{\D} I ' r' App\Http ' 'K
L

') - self.assertEqual(translation, get_string(new)) - self.assertIsNone(new.get('lang')) - self.assertIsNone(new.get('style')) - self.assertEqual('abc', new.get('class')) + elements = self.xhtml.findall('.//x:p', namespaces=ns) + self.assertEqual(2, len(elements)) + self.assertEqual(translation, get_string(elements[1])) + self.assertIsNone(elements[1].get('lang')) + self.assertIsNone(elements[1].get('style')) + self.assertEqual('abc', elements[1].get('class')) def test_add_translation_with_markup(self): self.element.set_placeholder(DeeplFreeTranslate.placeholder) @@ -326,7 +415,7 @@ def test_add_translation_with_markup(self): translation = (' A B C D ' 'E F G H ' 'I KL') - new = self.element.add_translation(translation, position='below') + self.element.add_translation(translation, position='below') translation = ('

' ' A ' 'B C D E ' @@ -334,36 +423,71 @@ def test_add_translation_with_markup(self): r'{\D} I ' r' App\Http ' 'K
L

') - self.assertEqual(translation, get_string(new)) + elements = self.xhtml.findall('.//x:p', namespaces=ns) + self.assertEqual(2, len(elements)) + self.assertEqual(translation, get_string(elements[1])) def test_add_translation_below(self): - new = self.element.add_translation('test', position='next') - self.assertEqual(self.paragraph, new.getprevious()) - self.assertIn('>test<', get_string(new)) + self.element.add_translation( + 'test', position='next', original_color='red', + translation_color='blue') + original, translation = self.xhtml.findall('.//x:p', namespaces=ns) + self.assertEqual('color:red', original.get('style')) + self.assertEqual('color:blue', translation.get('style')) + self.assertIn('>test<', get_string(translation)) + + def test_add_translation_above(self): + self.element.add_translation( + 'test', position='above', original_color='red', + translation_color='blue') + translation, original = self.xhtml.findall('.//x:p', namespaces=ns) + self.assertEqual('color:blue', translation.get('style')) + self.assertEqual('color:red', original.get('style')) + self.assertIn('>test<', get_string(translation)) def test_add_translation_right(self): - new = self.element.add_translation('test', position='right') + self.element.add_translation('test', position='right') + + self.assertEqual(2, len(self.xhtml.findall('.//x:p', namespaces=ns))) table = self.xhtml.find('.//x:table', namespaces=ns) self.assertIsNotNone(table) - self.assertIn('>test<', get_string(new)) - - def test_add_translation_above(self): - new = self.element.add_translation('test', position='above') - self.assertEqual(self.paragraph, new.getnext()) - self.assertIn('>test<', get_string(new)) + left_td, middle_td, right_td = table.findall('.//td') + self.assertEqual(1, len(list(left_td))) + self.assertEqual('45%', left_td.get('width')) + self.assertEqual(0, len(list(middle_td))) + self.assertEqual('10%', middle_td.get('width')) + self.assertIsNone(middle_td.text) + self.assertEqual(1, len(list(right_td))) + self.assertEqual('45%', right_td.get('width')) + self.assertIn('>test<', get_string(right_td)) def test_add_translation_left(self): - new = self.element.add_translation('test', position='left') + self.element.add_translation( + 'test', position='left', original_color='red', + translation_color='blue') + + self.assertEqual(2, len(self.xhtml.findall('.//x:p', namespaces=ns))) table = self.xhtml.find('.//x:table', namespaces=ns) self.assertIsNotNone(table) - self.assertIn('>test<', get_string(new)) + left_td, middle_td, right_td = table.findall('.//td') + self.assertEqual(1, len(list(left_td))) + self.assertEqual('45%', left_td.get('width')) + self.assertIn('>test<', get_string(left_td)) + self.assertEqual(0, len(list(middle_td))) + self.assertEqual('10%', middle_td.get('width')) + self.assertIsNone(middle_td.text) + self.assertEqual(1, len(list(right_td))) + self.assertEqual('45%', right_td.get('width')) def test_add_translation_only(self): - new = self.element.add_translation('test', position='only') - self.assertIsNone(new.getprevious()) - self.assertIsNone(new.getnext()) - self.assertIn('>test<', get_string(new)) - + self.element.add_translation( + 'test', position='only', translation_color='blue') + elements = self.xhtml.findall('.//x:p', namespaces=ns) + self.assertEqual(1, len(elements)) + self.assertEqual('color:blue', elements[0].get('style')) + self.assertIn('>test<', get_string(elements[0])) + + def test_add_translation_only_keep_anchor(self): # Test for the anchor element that is a sibling of the paragraph. xhtml = etree.XML(rb""" @@ -376,20 +500,27 @@ def test_add_translation_only(self): """) element = PageElement(xhtml.find('.//x:a[1]', namespaces=ns), 'p1') - new = element.add_translation('A', position='only') - self.assertIsNone(new.get('href')) + element.add_translation('A', position='only') + a = xhtml.find('.//x:a[1]', namespaces=ns) + self.assertIsNone(a.get('href')) + self.assertEqual('A', a.text) element = PageElement(xhtml.find('.//x:a[2]', namespaces=ns), 'p1') - new = element.add_translation('A', position='only') - self.assertEqual('abc', new.get('href')) + element.add_translation('A', position='only') + a = xhtml.find('.//x:a[2]', namespaces=ns) + self.assertEqual('abc', a.get('href')) + self.assertEqual('A', a.text) def test_add_translation_attr(self): - new = self.element.add_translation( + self.element.add_translation( 'test', position='below', translation_lang='zh', original_color='green', translation_color='red') - self.assertEqual('zh', new.get('lang')) + + elements = self.xhtml.findall('.//x:p', namespaces=ns) + self.assertEqual(2, len(elements)) + self.assertEqual('zh', elements[1].get('lang')) self.assertEqual('color:green', self.element.element.get('style')) - self.assertEqual('color:red', new.get('style')) + self.assertEqual('color:red', elements[1].get('style')) class TestExtraction(unittest.TestCase): @@ -504,9 +635,13 @@ def test_extract_elements(self): """) root = xhtml.find('x:body', namespaces=ns) elements = self.extraction.extract_elements('p1', root, []) - self.assertEqual(8, len(elements)) + self.assertEqual(9, len(elements)) self.assertEqual('h2', elements[0].get_name()) + self.assertFalse(elements[0].ignored) + self.assertEqual('pre', elements[-2].get_name()) + self.assertTrue(elements[-2].ignored) self.assertEqual('p', elements[-1].get_name()) + self.assertFalse(elements[-1].ignored) xhtml = etree.XML(b""" @@ -515,8 +650,9 @@ def test_extract_elements(self): 123456789 """) root = xhtml.find('x:body', namespaces=ns) - self.assertEqual( - 1, len(self.extraction.extract_elements('test', root, []))) + elements = self.extraction.extract_elements('test', root, []) + self.assertEqual(1, len(elements)) + self.assertEqual('123456789', elements[0].element.text) def test_filter_content(self): def elements(markups): @@ -618,6 +754,45 @@ def setUp(self): self.handler = ElementHandler( Base.placeholder, Base.separator, 'below') + def test_create_element_handler_merge(self): + self.assertIsInstance(self.handler, ElementHandler) + self.assertEqual(Base.placeholder, self.handler.placeholder) + self.assertEqual(Base.separator, self.handler.separator) + self.assertEqual('below', self.handler.position) + self.assertEqual(0, self.handler.merge_length) + self.assertIsNone(self.handler.translation_lang) + self.assertIsNone(self.handler.original_color) + self.assertIsNone(self.handler.translation_color) + self.assertIsNone(self.handler.column_gap) + self.assertEqual({}, self.handler.elements) + self.assertEqual([], self.handler.originals) + self.assertEqual([], self.handler.base_originals) + + def test_get_merge_length(self): + self.assertEqual(0, self.handler.merge_length) + + def test_set_translation_lang(self): + self.handler.set_translation_lang('zh') + self.assertEqual('zh', self.handler.translation_lang) + + def test_set_original_color(self): + self.handler.set_original_color('#ff00ff') + self.assertEqual('#ff00ff', self.handler.original_color) + + def test_set_translation_color(self): + self.handler.set_translation_color('#ff00ff') + self.assertEqual('#ff00ff', self.handler.translation_color) + + def test_set_column_gap(self): + self.handler.set_column_gap('test') + self.assertIsNone(self.handler.column_gap) + + self.handler.set_column_gap(('percentage',)) + self.assertIsNone(self.handler.column_gap) + + self.handler.set_column_gap(('percentage', 2)) + self.assertEqual(('percentage', 2), self.handler.column_gap) + @patch('calibre_plugins.ebook_translator.lib.element.uid') def test_prepare_original(self, mock_uid): mock_uid.side_effect = ['m1', 'm2', 'm3', 'm4', 'm5'] @@ -707,6 +882,11 @@ def setUp(self): self.handler = ElementHandlerMerge( Base.placeholder, Base.separator, 'below', 1000) + def test_create_element_handler_merge(self): + self.assertIsInstance(self.handler, ElementHandler) + self.assertIsInstance(self.handler, ElementHandlerMerge) + self.assertEqual(1000, self.handler.merge_length) + def test_align_paragraph(self): self.handler.prepare_original(self.elements) @@ -758,6 +938,14 @@ def test_align_paragraph(self): # self.assertEqual( # ['A', 'B'], self.handler.align_paragraph(paragraph)) + paragraph = Paragraph( + 0, 'm1', '

a

b

c

', + 'a\n\nb\n\nc\n\n', False, None, None, None, + 'ENGINE', 'LANG') + self.assertEqual( + [('a', None), ('b', None), ('c', None)], + self.handler.align_paragraph(paragraph)) + paragraph = Paragraph( 0, 'm1', '

a

b

c

', 'a\n\nb\n\nc\n\n', False, None, None, 'A\n\nB\n\n', @@ -949,11 +1137,10 @@ def test_add_translations_merge_placeholder_only_missing_id(self): 'A B {{id_1}} C {{id_3}}', 'ENGINE', 'LANG')]) elements = self.xhtml.findall('./x:body/*', namespaces=ns) - - self.assertEqual(3, len(elements)) + self.assertEqual(5, len(elements)) self.assertEqual( '

A B

C

', - get_string(elements[1], True)) + get_string(elements[-2], True)) def test_add_translations_merge_separator_only_missing_id(self): self.handler.position = 'only' @@ -967,7 +1154,7 @@ def test_add_translations_merge_separator_only_missing_id(self): elements = self.xhtml.findall('./x:body/*', namespaces=ns) - self.assertEqual(3, len(elements)) + self.assertEqual(5, len(elements)) self.assertEqual( '

A B

C

', - get_string(elements[1], True)) + get_string(elements[-2], True))