Normalize Chinese Part ordinals and support resumable complete-book translation
This commit is contained in:
@@ -228,3 +228,40 @@ def test_calibre_resolves_parent_part_destination(tmp_path,mode):
|
||||
assert part['frag']=='part'
|
||||
assert part['dest_exists'] is True
|
||||
assert part['children'][0]['dest_exists'] is True
|
||||
|
||||
|
||||
@pytest.mark.parametrize('mode', ['target_only', 'bilingual'])
|
||||
def test_chinese_part_number_uses_uniform_ordinal_style(tmp_path, mode):
|
||||
from src.preprocessing.format_extractor import FormatExtractor
|
||||
source, work, structure, entries = fixture(tmp_path)
|
||||
part = next(r for r in structure.resources.values() if r.href == 'Text/part.xhtml')
|
||||
part.content = '<html><body><h1 id="part">PART <span class="c1">1</span><span class="heading_breakp">BOY GENIUS</span></h1></body></html>'
|
||||
entry = next(e for e in entries if e.element_id == 'part')
|
||||
_, text, mapping, _, _ = FormatExtractor().extract(str(BeautifulSoup(part.content, 'html.parser').h1))
|
||||
entry.original_text = text
|
||||
entry.placeholders = mapping
|
||||
entry.translated_text = text.replace('PART ', '第').replace('BOY GENIUS', '天才少年')
|
||||
# Preserve placeholder indices; insert the ordinal suffix after the number span.
|
||||
closing = 'φ' + next(k for k, v in mapping.items() if v == '</span>') + 'φ'
|
||||
entry.translated_text = entry.translated_text.replace(closing, closing + '部', 1)
|
||||
asyncio.run(RestorationEngine().restore_entries([entry], force=True))
|
||||
asyncio.run(BackfillEngine().backfill(structure, entries, mode))
|
||||
soup = BeautifulSoup(part.content, 'html.parser')
|
||||
translated = soup.find('h1', class_='translation')
|
||||
assert translated.find('span', class_='c1')['data-translation-ordinal'] == 'true'
|
||||
assert translated.find('span', class_='heading_breakp').get_text() == '天才少年'
|
||||
assert not translated.find('span', class_='heading_breakp').has_attr('data-translation-ordinal')
|
||||
if mode == 'bilingual':
|
||||
assert not soup.find('h1', id='part').find('span', class_='c1').has_attr('data-translation-ordinal')
|
||||
|
||||
|
||||
def test_complete_book_includes_backmatter_and_non_spine_documents(tmp_path):
|
||||
_, _, structure, _ = fixture(tmp_path)
|
||||
notes = next(r for r in structure.resources.values() if r.href == 'Text/notes.xhtml')
|
||||
structure.resources['supplement'] = notes.model_copy(update={'href': 'Text/footnotes.xhtml'})
|
||||
standard = FineGrainedExtractor().extract(structure)
|
||||
complete = FineGrainedExtractor(complete_book=True).extract(structure)
|
||||
assert not any(e.file_path == 'Text/footnotes.xhtml' for e in standard)
|
||||
assert any(e.file_path == 'Text/footnotes.xhtml' and 'Note text' in e.original_text for e in complete)
|
||||
assert FineGrainedExtractor(complete_book=True)._classify_document('index.xhtml') == 'core'
|
||||
assert FineGrainedExtractor(complete_book=True)._classify_document('nav.xhtml') == 'toc'
|
||||
|
||||
Reference in New Issue
Block a user