Prorammbeschreibung aktualisiert. Duplikate werden aus den zu übersetzenden Texten entfernt.
This commit is contained in:
+121
-9
@@ -13,15 +13,72 @@ from utils import check_environment_var
|
|||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Dieses Programm:
|
translate.py – Texte aus DXF extrahieren, übersetzen und DXF-Dateien neu beschriften.
|
||||||
- liest eine DXF Datei und sammelt alle TEXT und MTEXT Objekte
|
|
||||||
ODER liest Texte aus einer TXT Datei (ein Text pro Zeile)
|
Alle Ausgabedateien landen im PROJECT_WORK Verzeichnis.
|
||||||
ODER liest den 'untranslated' Block aus einer JSON Datei
|
Die Übersetzungs-Configs liegen in PROJECT_TRANSLATION/<LANG>.cfg (z.B. CS.cfg, EN.cfg).
|
||||||
ODER übersetzt TEXT/MTEXT direkt in einer DXF und erstellt neue übersetzte DXF
|
Beim Laden einer Config werden Selbstübersetzungen entfernt und Übersetzungsketten gemeldet.
|
||||||
- filtert die Texte basierend auf Mustern in translator.cfg
|
|
||||||
- übersetzt optional Texte mit Trigrammen, Bigrammen und Einzelwörtern aus translation/<LANG>.cfg
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
- schreibt die Ergebnisse in eine Excel-, JSON- oder Text-Datei
|
SCHRITT 1 – Texte aus DXF extrahieren und Roh-JSON erzeugen
|
||||||
- speichert die Ausgabedatei im PROJECT_WORK Verzeichnis
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
-e --extract -f myfile.dxf [-t json,excel,text] [-o output]
|
||||||
|
|
||||||
|
Liest alle TEXT/MTEXT-Objekte und Symbol-Attribute aus einer DXF/DWG-Datei,
|
||||||
|
filtert sie über translator.cfg und schreibt eine JSON-Datei mit drei Blöcken:
|
||||||
|
"translations": [] (leer – keine Sprache angegeben)
|
||||||
|
"untranslated": [...] (alle gefilterten Texte)
|
||||||
|
"ignored": [...] (herausgefilterte Texte)
|
||||||
|
Optional: zusätzliche Ausgabe als Excel oder Text (-t excel,json,text).
|
||||||
|
|
||||||
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
SCHRITT 2a – JSON auto-übersetzen (Drop auf tr2dxf_CS.bat / tr2dxf_EN.bat)
|
||||||
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
--retranslate-json myfile_texts.json --translate CS[,EN,...]
|
||||||
|
|
||||||
|
Liest eine bestehende JSON-Datei (Legacy-Flat oder Multilang), übersetzt
|
||||||
|
alle Texte aus 'untranslated' automatisch und verschiebt Treffer nach
|
||||||
|
'translations'. Bestehende Übersetzungen werden mit der aktuellen Config
|
||||||
|
aktualisiert. Duplikate zwischen und innerhalb der Listen werden bereinigt.
|
||||||
|
Ausgabe immer im Multilang-Format: "[CS]": { "translations": [...], ... }
|
||||||
|
Legacy-Dateien werden dabei automatisch ins Multilang-Format konvertiert.
|
||||||
|
|
||||||
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
SCHRITT 2b – Mehrere Sprachen gleichzeitig extrahieren und übersetzen
|
||||||
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
-e --extract -f myfile.dxf --translate CS,EN [-t json] [-o output]
|
||||||
|
|
||||||
|
Wie Schritt 1, aber mit sofortiger Auto-Übersetzung in eine oder mehrere
|
||||||
|
Sprachen. Ausgabe direkt im Multilang-Format. Wird die Ausgabedatei erneut
|
||||||
|
mit einer weiteren Sprache erzeugt, bleiben bestehende Sprachblöcke erhalten
|
||||||
|
(Merge): z.B. erst --translate CS, dann --translate EN → Datei enthält [CS] + [EN].
|
||||||
|
|
||||||
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
SCHRITT 3 – Übersetzte DXF erzeugen (Drop auf tr2dxf_CS.bat / tr2dxf_EN.bat)
|
||||||
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
-f myfile.dxf --todxf myfile_CS.dxf --translate CS
|
||||||
|
[-f myfile.dxf --todxf myfile_CS.dxf --translation-json custom_texts.json]
|
||||||
|
|
||||||
|
Liest die Übersetzungstabelle aus <filename>_texts.json (oder --translation-json),
|
||||||
|
übersetzt TEXT/MTEXT-Objekte und Symbol-Attribute direkt in der DXF-Datei
|
||||||
|
und schreibt eine neue DXF mit den Zielsprachen-Texten.
|
||||||
|
|
||||||
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
WEITERE EINGABEQUELLEN
|
||||||
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
--fromtxt FILE.txt Texte aus TXT-Datei lesen (ein Text pro Zeile)
|
||||||
|
--fromjson FILE.json Nur 'untranslated'-Block aus JSON lesen und
|
||||||
|
neu übersetzen (schreibt neue Ausgabedatei)
|
||||||
|
|
||||||
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
GEMEINSAME OPTIONEN
|
||||||
|
───────────────────────────────────────────────────────────────────────────────
|
||||||
|
--translate LANG[,LANG2,...] Zielsprache(n), z.B. CS oder EN,CS,FR
|
||||||
|
-t / --export-type TYPE[,TYPE] Ausgabeformat(e): json (Standard), excel, text
|
||||||
|
-o / --outname NAME Ausgabedateiname (ohne Pfad)
|
||||||
|
--lang_source LANG Quellsprache für Symbol-Attribute (Standard: DE)
|
||||||
|
--translation-json FILE.json Übersetzungs-JSON für --todxf (Standard: <name>_texts.json)
|
||||||
|
-d / --debug Debug-Ausgabe für Pattern-Matching
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@@ -1489,6 +1546,47 @@ def write_texts_to_text(texts: list[str], ignored_texts: list[str], output_path:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def _dedup_source_list(
|
||||||
|
entry_list: list,
|
||||||
|
seen_from_other: set[str],
|
||||||
|
label: str,
|
||||||
|
list_name: str,
|
||||||
|
other_name: str) -> tuple[list, set[str]]:
|
||||||
|
"""
|
||||||
|
Bereinigt eine Liste von {source, target}-Einträgen um Duplikate.
|
||||||
|
Das erste Vorkommen je source wird behalten.
|
||||||
|
|
||||||
|
Zwei Fälle werden gemeldet:
|
||||||
|
- source bereits in seen_from_other → Cross-Duplikat mit der anderen Liste
|
||||||
|
- source bereits in dieser Liste → internes Duplikat
|
||||||
|
|
||||||
|
Args:
|
||||||
|
entry_list: Zu prüfende Liste
|
||||||
|
seen_from_other: Sources aus der Gegenliste (für Cross-Duplikat-Check)
|
||||||
|
label: Block-Bezeichnung für Warnmeldungen, z.B. "[CS]"
|
||||||
|
list_name: Name dieser Liste, z.B. "'translations'"
|
||||||
|
other_name: Name der Gegenliste, z.B. "'untranslated'"
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple (bereinigte Liste, set der in dieser Liste gesehenen sources)
|
||||||
|
"""
|
||||||
|
seen: set[str] = set()
|
||||||
|
result = []
|
||||||
|
for entry in entry_list:
|
||||||
|
if not isinstance(entry, dict):
|
||||||
|
continue
|
||||||
|
source = entry.get('source', '')
|
||||||
|
if source in seen_from_other:
|
||||||
|
print(f" WARNUNG: {label} '{source}' aus {list_name} entfernt "
|
||||||
|
f"(bereits in {other_name})")
|
||||||
|
elif source in seen:
|
||||||
|
print(f" WARNUNG: {label} Duplikat in {list_name} entfernt: '{source}'")
|
||||||
|
else:
|
||||||
|
seen.add(source)
|
||||||
|
result.append(entry)
|
||||||
|
return result, seen
|
||||||
|
|
||||||
|
|
||||||
def _retranslate_language_block(
|
def _retranslate_language_block(
|
||||||
translations_list: list,
|
translations_list: list,
|
||||||
untranslated_list: list,
|
untranslated_list: list,
|
||||||
@@ -1500,6 +1598,11 @@ def _retranslate_language_block(
|
|||||||
"""
|
"""
|
||||||
Verarbeitet einen einzelnen Sprach-Block einer JSON-Übersetzungsdatei in-place.
|
Verarbeitet einen einzelnen Sprach-Block einer JSON-Übersetzungsdatei in-place.
|
||||||
|
|
||||||
|
Schritt 0 – Deduplizierung beider Listen (via _dedup_source_list):
|
||||||
|
Doppelte source-Einträge werden entfernt (erstes Vorkommen wird behalten).
|
||||||
|
Einträge, deren source bereits in translations_list vorkommt, werden aus
|
||||||
|
untranslated_list entfernt.
|
||||||
|
|
||||||
Schritt 1 – Re-übersetze bestehende Einträge in translations_list:
|
Schritt 1 – Re-übersetze bestehende Einträge in translations_list:
|
||||||
Jeder Eintrag wird mit der aktuellen Config neu übersetzt.
|
Jeder Eintrag wird mit der aktuellen Config neu übersetzt.
|
||||||
Wird keine Übersetzung mehr gefunden, wandert der Eintrag nach untranslated_list.
|
Wird keine Übersetzung mehr gefunden, wandert der Eintrag nach untranslated_list.
|
||||||
@@ -1526,6 +1629,15 @@ def _retranslate_language_block(
|
|||||||
unchanged = 0
|
unchanged = 0
|
||||||
newly = 0
|
newly = 0
|
||||||
|
|
||||||
|
# Schritt 0: Deduplizierung – erstes Vorkommen je source wird behalten
|
||||||
|
deduped_t, seen_t = _dedup_source_list(
|
||||||
|
translations_list, set(), label, "'translations'", "'untranslated'")
|
||||||
|
translations_list[:] = deduped_t
|
||||||
|
|
||||||
|
deduped_u, _ = _dedup_source_list(
|
||||||
|
untranslated_list, seen_t, label, "'untranslated'", "'translations'")
|
||||||
|
untranslated_list[:] = deduped_u
|
||||||
|
|
||||||
# Schritt 1: Re-übersetze bestehende translations-Einträge
|
# Schritt 1: Re-übersetze bestehende translations-Einträge
|
||||||
for entry in translations_list[:]: # Kopie für sicheres Entfernen
|
for entry in translations_list[:]: # Kopie für sicheres Entfernen
|
||||||
if not isinstance(entry, dict) or 'source' not in entry:
|
if not isinstance(entry, dict) or 'source' not in entry:
|
||||||
|
|||||||
Reference in New Issue
Block a user