From 002b5e0bf1ae6aea645502dcb552fcbb9a61e56c Mon Sep 17 00:00:00 2001 From: mistangl Date: Tue, 10 Feb 2026 16:48:01 +0100 Subject: [PATCH] =?UTF-8?q?Prorammbeschreibung=20aktualisiert.=20Duplikate?= =?UTF-8?q?=20werden=20aus=20den=20zu=20=C3=BCbersetzenden=20Texten=20entf?= =?UTF-8?q?ernt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/translate.py | 130 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 121 insertions(+), 9 deletions(-) diff --git a/lib/translate.py b/lib/translate.py index f00ff0d..108a25c 100644 --- a/lib/translate.py +++ b/lib/translate.py @@ -13,15 +13,72 @@ from utils import check_environment_var """ -Dieses Programm: -- liest eine DXF Datei und sammelt alle TEXT und MTEXT Objekte - ODER liest Texte aus einer TXT Datei (ein Text pro Zeile) - ODER liest den 'untranslated' Block aus einer JSON Datei - ODER übersetzt TEXT/MTEXT direkt in einer DXF und erstellt neue übersetzte DXF -- filtert die Texte basierend auf Mustern in translator.cfg -- übersetzt optional Texte mit Trigrammen, Bigrammen und Einzelwörtern aus translation/.cfg -- schreibt die Ergebnisse in eine Excel-, JSON- oder Text-Datei -- speichert die Ausgabedatei im PROJECT_WORK Verzeichnis +translate.py – Texte aus DXF extrahieren, übersetzen und DXF-Dateien neu beschriften. + +Alle Ausgabedateien landen im PROJECT_WORK Verzeichnis. +Die Übersetzungs-Configs liegen in PROJECT_TRANSLATION/.cfg (z.B. CS.cfg, EN.cfg). +Beim Laden einer Config werden Selbstübersetzungen entfernt und Übersetzungsketten gemeldet. + +─────────────────────────────────────────────────────────────────────────────── +SCHRITT 1 – Texte aus DXF extrahieren und Roh-JSON erzeugen +─────────────────────────────────────────────────────────────────────────────── + -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 _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: _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) +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( translations_list: list, untranslated_list: list, @@ -1500,6 +1598,11 @@ def _retranslate_language_block( """ 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: Jeder Eintrag wird mit der aktuellen Config neu übersetzt. Wird keine Übersetzung mehr gefunden, wandert der Eintrag nach untranslated_list. @@ -1526,6 +1629,15 @@ def _retranslate_language_block( unchanged = 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 for entry in translations_list[:]: # Kopie für sicheres Entfernen if not isinstance(entry, dict) or 'source' not in entry: