supervertaler 1.9.203__py3-none-any.whl → 1.9.204__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of supervertaler might be problematic. Click here for more details.
- Supervertaler.py +100 -54
- {supervertaler-1.9.203.dist-info → supervertaler-1.9.204.dist-info}/METADATA +1 -1
- {supervertaler-1.9.203.dist-info → supervertaler-1.9.204.dist-info}/RECORD +7 -7
- {supervertaler-1.9.203.dist-info → supervertaler-1.9.204.dist-info}/WHEEL +0 -0
- {supervertaler-1.9.203.dist-info → supervertaler-1.9.204.dist-info}/entry_points.txt +0 -0
- {supervertaler-1.9.203.dist-info → supervertaler-1.9.204.dist-info}/licenses/LICENSE +0 -0
- {supervertaler-1.9.203.dist-info → supervertaler-1.9.204.dist-info}/top_level.txt +0 -0
Supervertaler.py
CHANGED
|
@@ -32,7 +32,7 @@ License: MIT
|
|
|
32
32
|
"""
|
|
33
33
|
|
|
34
34
|
# Version Information.
|
|
35
|
-
__version__ = "1.9.
|
|
35
|
+
__version__ = "1.9.204"
|
|
36
36
|
__phase__ = "0.9"
|
|
37
37
|
__release_date__ = "2026-02-03"
|
|
38
38
|
__edition__ = "Qt"
|
|
@@ -7945,19 +7945,36 @@ class SupervertalerQt(QMainWindow):
|
|
|
7945
7945
|
import_menu.addAction(import_review_table_action)
|
|
7946
7946
|
|
|
7947
7947
|
export_menu = file_menu.addMenu("&Export")
|
|
7948
|
-
|
|
7948
|
+
|
|
7949
|
+
# --- Monolingual (target-only) exports at top ---
|
|
7950
|
+
export_target_docx_action = QAction("&Target Only (DOCX)...", self)
|
|
7951
|
+
export_target_docx_action.triggered.connect(self.export_target_only_docx)
|
|
7952
|
+
export_menu.addAction(export_target_docx_action)
|
|
7953
|
+
|
|
7954
|
+
export_txt_action = QAction("Simple &Text File - Translated (TXT)...", self)
|
|
7955
|
+
export_txt_action.triggered.connect(self.export_simple_txt)
|
|
7956
|
+
export_menu.addAction(export_txt_action)
|
|
7957
|
+
|
|
7958
|
+
export_ai_action = QAction("📄 &AI-Readable Markdown (.md)...", self)
|
|
7959
|
+
export_ai_action.triggered.connect(self.export_bilingual_table_markdown)
|
|
7960
|
+
export_ai_action.setToolTip("Export segments in [SEGMENT] format for AI translation/review")
|
|
7961
|
+
export_menu.addAction(export_ai_action)
|
|
7962
|
+
|
|
7963
|
+
export_menu.addSeparator()
|
|
7964
|
+
|
|
7965
|
+
# --- Bilingual CAT tool exports ---
|
|
7949
7966
|
export_memoq_action = QAction("memoQ &Bilingual Table - Translated (DOCX)...", self)
|
|
7950
7967
|
export_memoq_action.triggered.connect(self.export_memoq_bilingual)
|
|
7951
7968
|
export_menu.addAction(export_memoq_action)
|
|
7952
|
-
|
|
7969
|
+
|
|
7953
7970
|
export_memoq_xliff_action = QAction("memoQ &XLIFF - Translated (.mqxliff)...", self)
|
|
7954
7971
|
export_memoq_xliff_action.triggered.connect(self.export_memoq_xliff)
|
|
7955
7972
|
export_menu.addAction(export_memoq_xliff_action)
|
|
7956
|
-
|
|
7973
|
+
|
|
7957
7974
|
export_cafetran_action = QAction("&CafeTran Bilingual Table - Translated (DOCX)...", self)
|
|
7958
7975
|
export_cafetran_action.triggered.connect(self.export_cafetran_bilingual)
|
|
7959
7976
|
export_menu.addAction(export_cafetran_action)
|
|
7960
|
-
|
|
7977
|
+
|
|
7961
7978
|
# Trados submenu - group all Trados exports together
|
|
7962
7979
|
trados_export_submenu = export_menu.addMenu("&Trados Studio")
|
|
7963
7980
|
|
|
@@ -7978,20 +7995,7 @@ class SupervertalerQt(QMainWindow):
|
|
|
7978
7995
|
export_dejavu_action = QAction("&Déjà Vu X3 Bilingual - Translated (RTF)...", self)
|
|
7979
7996
|
export_dejavu_action.triggered.connect(self.export_dejavu_bilingual)
|
|
7980
7997
|
export_menu.addAction(export_dejavu_action)
|
|
7981
|
-
|
|
7982
|
-
export_target_docx_action = QAction("&Target Only (DOCX)...", self)
|
|
7983
|
-
export_target_docx_action.triggered.connect(self.export_target_only_docx)
|
|
7984
|
-
export_menu.addAction(export_target_docx_action)
|
|
7985
|
-
|
|
7986
|
-
export_txt_action = QAction("Simple &Text File - Translated (TXT)...", self)
|
|
7987
|
-
export_txt_action.triggered.connect(self.export_simple_txt)
|
|
7988
|
-
export_menu.addAction(export_txt_action)
|
|
7989
|
-
|
|
7990
|
-
export_ai_action = QAction("📄 &AI-Readable Markdown (.md)...", self)
|
|
7991
|
-
export_ai_action.triggered.connect(self.export_bilingual_table_markdown)
|
|
7992
|
-
export_ai_action.setToolTip("Export segments in [SEGMENT] format for AI translation/review")
|
|
7993
|
-
export_menu.addAction(export_ai_action)
|
|
7994
|
-
|
|
7998
|
+
|
|
7995
7999
|
export_menu.addSeparator()
|
|
7996
8000
|
|
|
7997
8001
|
# Multi-file folder export
|
|
@@ -11257,8 +11261,10 @@ class SupervertalerQt(QMainWindow):
|
|
|
11257
11261
|
text = re.sub(r'</?li>', '', text) # <li>, </li>
|
|
11258
11262
|
text = re.sub(r'</?[biu]>', '', text) # <b>, </b>, <i>, </i>, <u>, </u>
|
|
11259
11263
|
text = re.sub(r'</?bi>', '', text) # <bi>, </bi>
|
|
11264
|
+
text = re.sub(r'</?sub>', '', text) # <sub>, </sub>
|
|
11265
|
+
text = re.sub(r'</?sup>', '', text) # <sup>, </sup>
|
|
11260
11266
|
return text.strip()
|
|
11261
|
-
|
|
11267
|
+
|
|
11262
11268
|
def clean_special_chars(text):
|
|
11263
11269
|
"""Remove problematic Unicode characters like object replacement char"""
|
|
11264
11270
|
# Remove Unicode Object Replacement Character (U+FFFC) and similar
|
|
@@ -11272,34 +11278,48 @@ class SupervertalerQt(QMainWindow):
|
|
|
11272
11278
|
"""
|
|
11273
11279
|
Replace paragraph text with tagged text, applying bold/italic/underline formatting.
|
|
11274
11280
|
Parses tags like <b>, <i>, <u>, <bi> and creates appropriate runs.
|
|
11281
|
+
Preserves original font name and size from the first run.
|
|
11275
11282
|
"""
|
|
11276
11283
|
# Clean special characters first
|
|
11277
11284
|
text = clean_special_chars(tagged_text)
|
|
11278
|
-
|
|
11285
|
+
|
|
11279
11286
|
# Strip list tags - they don't affect formatting
|
|
11280
11287
|
text = re.sub(r'</?li-[bo]>', '', text)
|
|
11281
11288
|
text = re.sub(r'</?li>', '', text)
|
|
11282
|
-
|
|
11289
|
+
|
|
11290
|
+
# Capture original font properties BEFORE clearing runs
|
|
11291
|
+
original_font_name = None
|
|
11292
|
+
original_font_size = None
|
|
11293
|
+
original_all_caps = None
|
|
11294
|
+
if para.runs:
|
|
11295
|
+
first_run = para.runs[0]
|
|
11296
|
+
if first_run.font:
|
|
11297
|
+
original_font_name = first_run.font.name
|
|
11298
|
+
original_font_size = first_run.font.size
|
|
11299
|
+
original_all_caps = first_run.font.all_caps
|
|
11300
|
+
|
|
11283
11301
|
# Clear existing runs
|
|
11284
11302
|
for run in para.runs:
|
|
11285
11303
|
run.clear()
|
|
11286
11304
|
# Remove the cleared runs
|
|
11287
11305
|
for run in list(para.runs):
|
|
11288
11306
|
run._element.getparent().remove(run._element)
|
|
11289
|
-
|
|
11307
|
+
|
|
11290
11308
|
# Parse tags and create runs with formatting
|
|
11291
11309
|
# Pattern matches tags or text between tags
|
|
11292
|
-
tag_pattern = re.compile(r'(</?(?:b|i|u|bi)>)')
|
|
11310
|
+
tag_pattern = re.compile(r'(</?(?:b|i|u|bi|sub|sup)>)')
|
|
11293
11311
|
parts = tag_pattern.split(text)
|
|
11294
|
-
|
|
11312
|
+
|
|
11295
11313
|
is_bold = False
|
|
11296
11314
|
is_italic = False
|
|
11297
11315
|
is_underline = False
|
|
11298
|
-
|
|
11316
|
+
is_subscript = False
|
|
11317
|
+
is_superscript = False
|
|
11318
|
+
|
|
11299
11319
|
for part in parts:
|
|
11300
11320
|
if not part:
|
|
11301
11321
|
continue
|
|
11302
|
-
|
|
11322
|
+
|
|
11303
11323
|
# Check if this is a tag
|
|
11304
11324
|
if part == '<b>':
|
|
11305
11325
|
is_bold = True
|
|
@@ -11319,6 +11339,14 @@ class SupervertalerQt(QMainWindow):
|
|
|
11319
11339
|
elif part == '</bi>':
|
|
11320
11340
|
is_bold = False
|
|
11321
11341
|
is_italic = False
|
|
11342
|
+
elif part == '<sub>':
|
|
11343
|
+
is_subscript = True
|
|
11344
|
+
elif part == '</sub>':
|
|
11345
|
+
is_subscript = False
|
|
11346
|
+
elif part == '<sup>':
|
|
11347
|
+
is_superscript = True
|
|
11348
|
+
elif part == '</sup>':
|
|
11349
|
+
is_superscript = False
|
|
11322
11350
|
else:
|
|
11323
11351
|
# This is text content - create a run with current formatting
|
|
11324
11352
|
if part.strip() or part: # Include whitespace
|
|
@@ -11326,6 +11354,17 @@ class SupervertalerQt(QMainWindow):
|
|
|
11326
11354
|
run.bold = is_bold
|
|
11327
11355
|
run.italic = is_italic
|
|
11328
11356
|
run.underline = is_underline
|
|
11357
|
+
if is_subscript:
|
|
11358
|
+
run.font.subscript = True
|
|
11359
|
+
if is_superscript:
|
|
11360
|
+
run.font.superscript = True
|
|
11361
|
+
# Restore original font properties
|
|
11362
|
+
if original_font_name:
|
|
11363
|
+
run.font.name = original_font_name
|
|
11364
|
+
if original_font_size:
|
|
11365
|
+
run.font.size = original_font_size
|
|
11366
|
+
if original_all_caps:
|
|
11367
|
+
run.font.all_caps = original_all_caps
|
|
11329
11368
|
|
|
11330
11369
|
# Build a mapping of source text (without tags) to raw target text (with tags)
|
|
11331
11370
|
text_map = {}
|
|
@@ -11338,16 +11377,14 @@ class SupervertalerQt(QMainWindow):
|
|
|
11338
11377
|
if source_clean and target_raw:
|
|
11339
11378
|
text_map[source_clean] = target_raw
|
|
11340
11379
|
|
|
11341
|
-
def
|
|
11342
|
-
"""Replace all matching segments in text,
|
|
11380
|
+
def replace_segments_in_text_with_tags(original_text, text_map):
|
|
11381
|
+
"""Replace all matching segments in text, preserving formatting tags."""
|
|
11343
11382
|
result = original_text
|
|
11344
11383
|
# Sort by length (longest first) to avoid partial replacement issues
|
|
11345
11384
|
for source_clean, target_raw in sorted(text_map.items(), key=lambda x: len(x[0]), reverse=True):
|
|
11346
11385
|
if source_clean in result:
|
|
11347
|
-
#
|
|
11348
|
-
|
|
11349
|
-
target_clean = clean_special_chars(target_clean)
|
|
11350
|
-
result = result.replace(source_clean, target_clean)
|
|
11386
|
+
# Keep target WITH tags for formatting preservation
|
|
11387
|
+
result = result.replace(source_clean, target_raw)
|
|
11351
11388
|
return result
|
|
11352
11389
|
|
|
11353
11390
|
replaced_count = 0
|
|
@@ -11363,17 +11400,13 @@ class SupervertalerQt(QMainWindow):
|
|
|
11363
11400
|
replaced_count += 1
|
|
11364
11401
|
else:
|
|
11365
11402
|
# Try partial replacement (paragraph contains multiple segments)
|
|
11366
|
-
new_text =
|
|
11403
|
+
new_text = replace_segments_in_text_with_tags(para_text, text_map)
|
|
11367
11404
|
if new_text != para_text:
|
|
11368
|
-
# Text was changed -
|
|
11369
|
-
#
|
|
11370
|
-
|
|
11371
|
-
run.clear()
|
|
11372
|
-
for run in list(para.runs):
|
|
11373
|
-
run._element.getparent().remove(run._element)
|
|
11374
|
-
para.add_run(new_text)
|
|
11405
|
+
# Text was changed - use apply_formatted_text_to_paragraph
|
|
11406
|
+
# to preserve inline formatting tags (bold, italic, sub, sup, etc.)
|
|
11407
|
+
apply_formatted_text_to_paragraph(para, new_text)
|
|
11375
11408
|
replaced_count += 1
|
|
11376
|
-
|
|
11409
|
+
|
|
11377
11410
|
# Replace text in tables
|
|
11378
11411
|
for table in doc.tables:
|
|
11379
11412
|
for row in table.rows:
|
|
@@ -11388,15 +11421,12 @@ class SupervertalerQt(QMainWindow):
|
|
|
11388
11421
|
replaced_count += 1
|
|
11389
11422
|
else:
|
|
11390
11423
|
# Try partial replacement
|
|
11391
|
-
new_text =
|
|
11424
|
+
new_text = replace_segments_in_text_with_tags(para_text, text_map)
|
|
11392
11425
|
if new_text != para_text:
|
|
11393
|
-
|
|
11394
|
-
|
|
11395
|
-
for run in list(para.runs):
|
|
11396
|
-
run._element.getparent().remove(run._element)
|
|
11397
|
-
para.add_run(new_text)
|
|
11426
|
+
# Use apply_formatted_text_to_paragraph to preserve formatting
|
|
11427
|
+
apply_formatted_text_to_paragraph(para, new_text)
|
|
11398
11428
|
replaced_count += 1
|
|
11399
|
-
|
|
11429
|
+
|
|
11400
11430
|
doc.save(file_path)
|
|
11401
11431
|
self.log(f"✓ Replaced {replaced_count} text segments in original document structure")
|
|
11402
11432
|
|
|
@@ -11412,8 +11442,10 @@ class SupervertalerQt(QMainWindow):
|
|
|
11412
11442
|
text = re.sub(r'</?li>', '', text) # <li>, </li>
|
|
11413
11443
|
text = re.sub(r'</?[biu]>', '', text) # <b>, </b>, <i>, </i>, <u>, </u>
|
|
11414
11444
|
text = re.sub(r'</?bi>', '', text) # <bi>, </bi>
|
|
11445
|
+
text = re.sub(r'</?sub>', '', text) # <sub>, </sub>
|
|
11446
|
+
text = re.sub(r'</?sup>', '', text) # <sup>, </sup>
|
|
11415
11447
|
return text.strip()
|
|
11416
|
-
|
|
11448
|
+
|
|
11417
11449
|
def clean_special_chars(text):
|
|
11418
11450
|
"""Remove problematic Unicode characters"""
|
|
11419
11451
|
text = text.replace('\ufffc', '') # Object Replacement Character
|
|
@@ -11432,13 +11464,15 @@ class SupervertalerQt(QMainWindow):
|
|
|
11432
11464
|
text = re.sub(r'</?li>', '', text)
|
|
11433
11465
|
|
|
11434
11466
|
# Parse and apply formatting
|
|
11435
|
-
tag_pattern = re.compile(r'(</?(?:b|i|u|bi)>)')
|
|
11467
|
+
tag_pattern = re.compile(r'(</?(?:b|i|u|bi|sub|sup)>)')
|
|
11436
11468
|
parts = tag_pattern.split(text)
|
|
11437
|
-
|
|
11469
|
+
|
|
11438
11470
|
is_bold = False
|
|
11439
11471
|
is_italic = False
|
|
11440
11472
|
is_underline = False
|
|
11441
|
-
|
|
11473
|
+
is_subscript = False
|
|
11474
|
+
is_superscript = False
|
|
11475
|
+
|
|
11442
11476
|
for part in parts:
|
|
11443
11477
|
if not part:
|
|
11444
11478
|
continue
|
|
@@ -11460,13 +11494,25 @@ class SupervertalerQt(QMainWindow):
|
|
|
11460
11494
|
elif part == '</bi>':
|
|
11461
11495
|
is_bold = False
|
|
11462
11496
|
is_italic = False
|
|
11497
|
+
elif part == '<sub>':
|
|
11498
|
+
is_subscript = True
|
|
11499
|
+
elif part == '</sub>':
|
|
11500
|
+
is_subscript = False
|
|
11501
|
+
elif part == '<sup>':
|
|
11502
|
+
is_superscript = True
|
|
11503
|
+
elif part == '</sup>':
|
|
11504
|
+
is_superscript = False
|
|
11463
11505
|
else:
|
|
11464
11506
|
if part:
|
|
11465
11507
|
run = para.add_run(part)
|
|
11466
11508
|
run.bold = is_bold
|
|
11467
11509
|
run.italic = is_italic
|
|
11468
11510
|
run.underline = is_underline
|
|
11469
|
-
|
|
11511
|
+
if is_subscript:
|
|
11512
|
+
run.font.subscript = True
|
|
11513
|
+
if is_superscript:
|
|
11514
|
+
run.font.superscript = True
|
|
11515
|
+
|
|
11470
11516
|
doc = Document()
|
|
11471
11517
|
|
|
11472
11518
|
for seg in segments:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: supervertaler
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.204
|
|
4
4
|
Summary: Professional AI-enhanced translation workbench with multi-LLM support, glossary system, TM, spellcheck, voice commands, and PyQt6 interface. Batteries included (core).
|
|
5
5
|
Home-page: https://supervertaler.com
|
|
6
6
|
Author: Michael Beijer
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Supervertaler.py,sha256=
|
|
1
|
+
Supervertaler.py,sha256=ZCV8QknOZhHpUGJ_t4ONW_wq7zS1L_0nlHAuw8x0ybo,2398568
|
|
2
2
|
modules/__init__.py,sha256=G58XleS-EJ2sX4Kehm-3N2m618_W2Es0Kg8CW_eBG7g,327
|
|
3
3
|
modules/ai_actions.py,sha256=i5MJcM-7Y6CAvKUwxmxrVHeoZAVtAP7aRDdWM5KLkO0,33877
|
|
4
4
|
modules/ai_attachment_manager.py,sha256=juZlrW3UPkIkcnj0SREgOQkQROLf0fcu3ShZcKXMxsI,11361
|
|
@@ -80,9 +80,9 @@ modules/unified_prompt_manager_qt.py,sha256=y7xAIM9X7f1afXGE1tOcAc5EY7BKFy53Rgqi
|
|
|
80
80
|
modules/voice_commands.py,sha256=iBb-gjWxRMLhFH7-InSRjYJz1EIDBNA2Pog8V7TtJaY,38516
|
|
81
81
|
modules/voice_dictation.py,sha256=QmitXfkG-vRt5hIQATjphHdhXfqmwhzcQcbXB6aRzIg,16386
|
|
82
82
|
modules/voice_dictation_lite.py,sha256=jorY0BmWE-8VczbtGrWwt1zbnOctMoSlWOsQrcufBcc,9423
|
|
83
|
-
supervertaler-1.9.
|
|
84
|
-
supervertaler-1.9.
|
|
85
|
-
supervertaler-1.9.
|
|
86
|
-
supervertaler-1.9.
|
|
87
|
-
supervertaler-1.9.
|
|
88
|
-
supervertaler-1.9.
|
|
83
|
+
supervertaler-1.9.204.dist-info/licenses/LICENSE,sha256=m28u-4qL5nXIWnJ6xlQVw__H30rWFtRK3pCOais2OuY,1092
|
|
84
|
+
supervertaler-1.9.204.dist-info/METADATA,sha256=zcv2fcgWU60pLclQn-I23GvrLuXf-z9vVFzElk6hIXw,5725
|
|
85
|
+
supervertaler-1.9.204.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
86
|
+
supervertaler-1.9.204.dist-info/entry_points.txt,sha256=NP4hiCvx-_30YYKqgr-jfJYQvHr1qTYBMfoVmKIXSM8,53
|
|
87
|
+
supervertaler-1.9.204.dist-info/top_level.txt,sha256=9tUHBYUSfaE4S2E4W3eavJsDyYymkwLfeWAHHAPT6Dk,22
|
|
88
|
+
supervertaler-1.9.204.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|