diff --git a/lib/translate.py b/lib/translate.py index ff52738..cf04ef1 100644 --- a/lib/translate.py +++ b/lib/translate.py @@ -342,6 +342,49 @@ def load_translation_config(translation_lang: str, translation_dir: Path) -> tup return multi, trigramme, bigramme, single +def load_transfer_terms(translation_lang: str, translation_dir: Path) -> set[str]: + """ + Lädt die Transfer-Begriffe aus einer Übersetzungs-Config-Datei (Abschnitt [transfer]). + + Transfer-Begriffe werden beim Übersetzen von Symbol-Attributen (Block-Inserts) ohne + Übersetzung direkt in das Ziel-Attribut übernommen. Für TEXT/MTEXT-Objekte gilt + diese Regel nicht. + + Einträge im Abschnitt [transfer] stehen einzeln pro Zeile (ohne Wert/Gleichheitszeichen). + + Args: + translation_lang: Sprach-Code (z.B. "CS", "EN", "FR") + translation_dir: Verzeichnis mit Übersetzungs-Configs (aus PROJECT_TRANSLATION) + + Returns: + Set mit den Transfer-Begriffen (Groß-/Kleinschreibung wie in der Config) + """ + config_file = translation_dir / f"{translation_lang}.cfg" + + if not config_file.exists(): + return set() + + config = RawConfigParser(allow_no_value=True) + config.optionxform = str + try: + config.read(config_file, encoding='utf-8') + except Exception as e: + print(f"Warnung: Fehler beim Lesen der Transfer-Begriffe aus {config_file}: {e}") + return set() + + transfer: set[str] = set() + if config.has_section('transfer'): + for key in config['transfer']: + term = key.strip() + if term and not term.startswith('#'): + transfer.add(term) + + if transfer: + print(f" Transfer-Begriffe ({translation_lang}): {len(transfer)} ({', '.join(sorted(transfer))})") + + return transfer + + def load_symbol_attribute_mapping(cfg_path: Path) -> dict[str, str]: """ Liest die Zuordnung von Sprachcodes zu Symbol-Attributnamen aus der translator.cfg Datei. @@ -1084,7 +1127,8 @@ def translate_block_attribute(entity, required_attributes: set[str], text_source_attr: str, text_target_attr: str, - target_layer: str | None = None) -> tuple[int, int, int]: + target_layer: str | None = None, + transfer_terms: set[str] | None = None) -> tuple[int, int, int, int]: """ Übersetzt Text-Attribute eines einzelnen Block-Inserts (INSERT entity). @@ -1098,12 +1142,13 @@ def translate_block_attribute(entity, text_source_attr: Quell-Attributname (z.B. "TEXT-D", "TEXT-EN") text_target_attr: Ziel-Attributname (z.B. "TEXT-EN", "TEXT-CS") target_layer: Ziel-Layername für das Ziel-Attribut (aus [symbol_layer]) + transfer_terms: Begriffe die ohne Übersetzung direkt übernommen werden (aus [transfer]) Returns: - Tuple mit (translated_count, skipped_count, ignored_count) für diesen Block + Tuple mit (translated_count, skipped_count, ignored_count, transferred_count) für diesen Block """ if not entity.has_attrib: - return 0, 0, 0 + return 0, 0, 0, 0 # Sammle alle vorhandenen Attribute des Blocks block_attributes = {} @@ -1119,25 +1164,30 @@ def translate_block_attribute(entity, # Prüfe ob Block alle erforderlichen Attribute hat if not (required_attributes.issubset(block_attributes.keys()) and text_source_attrib): - return 0, 0, 0 + return 0, 0, 0, 0 original_text = text_source_attrib.dxf.text.strip() if text_source_attrib.dxf.text else None if not original_text: - return 0, 0, 0 + return 0, 0, 0, 0 # Prüfe ob Text ignoriert werden soll if should_ignore_text(original_text, wildcard_patterns, regex_patterns): - return 0, 0, 1 + return 0, 0, 1, 0 - # Suche Übersetzung - if original_text not in translations: - return 0, 1, 0 + # Bestimme Zieltext: Transfer (1:1 übernehmen) oder Übersetzung + is_transfer = transfer_terms is not None and original_text in transfer_terms + if is_transfer: + target_text = original_text + elif original_text in translations: + target_text = translations[original_text] + else: + return 0, 1, 0, 0 - # Schreibe Übersetzung in Ziel-Attribut + # Schreibe Zieltext in Ziel-Attribut if text_target_attrib: # Ziel-Attribut existiert bereits, aktualisiere es - text_target_attrib.dxf.text = translations[original_text] + text_target_attrib.dxf.text = target_text # Layer ggf. anpassen if target_layer: text_target_attrib.dxf.layer = target_layer @@ -1148,7 +1198,7 @@ def translate_block_attribute(entity, # Ziel-Attribut existiert nicht, erstelle es basierend auf Quell-Attribut new_attrib = entity.add_attrib( tag=text_target_attr, - text=translations[original_text], + text=target_text, insert=text_source_attrib.dxf.insert, ) # Kopiere weitere Eigenschaften @@ -1166,7 +1216,9 @@ def translate_block_attribute(entity, elif text_source_attrib.dxf.hasattr('layer'): new_attrib.dxf.layer = text_source_attrib.dxf.layer - return 1, 0, 0 + if is_transfer: + return 0, 0, 0, 1 + return 1, 0, 0, 0 def translate_dxf_texts(input_dxf: Path, @@ -1176,7 +1228,8 @@ def translate_dxf_texts(input_dxf: Path, regex_patterns: list[str], text_source_attr: str = 'TEXT-D', text_target_attr: str = 'TEXT-CS', - target_layer: str | None = None): + target_layer: str | None = None, + transfer_terms: set[str] | None = None): """ Übersetzt alle TEXT, MTEXT Objekte und Text-Attribute in Blöcken einer DXF-Datei. @@ -1184,6 +1237,7 @@ def translate_dxf_texts(input_dxf: Path, - Liest die Übersetzung aus dem Quell-Attribut (z.B. TEXT-D) - Schreibt die Übersetzung in das Ziel-Attribut (z.B. TEXT-EN, TEXT-CS) (erstellt das Attribut falls nicht vorhanden) - Das Quell-Attribut bleibt unverändert (Original wird bewahrt) + - Begriffe aus transfer_terms werden ohne Übersetzung direkt übernommen (nur bei Block-Attributen) Args: input_dxf: Pfad zur Quell-DXF @@ -1193,6 +1247,7 @@ def translate_dxf_texts(input_dxf: Path, regex_patterns: Regex-Muster zum Filtern text_source_attr: Quell-Attributname für Texte in Blöcken (z.B. "TEXT-D", "TEXT-EN"). Standard: "TEXT-D" text_target_attr: Ziel-Attributname für Übersetzungen in Blöcken (z.B. "TEXT-EN", "TEXT-CS"). Standard: "TEXT-CS" + transfer_terms: Begriffe die in Symbol-Attributen ohne Übersetzung übernommen werden (aus [transfer]) """ # Attribute die ein Block haben muss, damit das Text-Attribut übersetzt wird required_attributes = {'IO', 'ID', 'VERW', 'BEZEICHNUNG', 'KENNZEICHNUNG', text_source_attr} @@ -1210,6 +1265,7 @@ def translate_dxf_texts(input_dxf: Path, block_translated = 0 block_skipped = 0 block_ignored = 0 + block_transferred = 0 # Übersetze TEXT Objekte for entity in msp.query('TEXT'): @@ -1247,7 +1303,7 @@ def translate_dxf_texts(input_dxf: Path, # Übersetze Text-Attribute in Blöcken for entity in msp.query('INSERT'): - translated, skipped, ignored = translate_block_attribute( + translated, skipped, ignored, transferred = translate_block_attribute( entity, doc, translations, @@ -1257,10 +1313,12 @@ def translate_dxf_texts(input_dxf: Path, text_source_attr, text_target_attr, target_layer, + transfer_terms, ) block_translated += translated block_skipped += skipped block_ignored += ignored + block_transferred += transferred # Speichere neue DXF doc.saveas(output_dxf) @@ -1272,9 +1330,9 @@ def translate_dxf_texts(input_dxf: Path, print(f"\nDXF-Übersetzung abgeschlossen:") print(f" TEXT übersetzt: {text_translated}, übersprungen: {text_skipped}, ignoriert: {text_ignored}") print(f" MTEXT übersetzt: {mtext_translated}, übersprungen: {mtext_skipped}, ignoriert: {mtext_ignored}") - print(f" {text_target_attr} (Blöcke) erstellt/aktualisiert: {block_translated}, übersprungen: {block_skipped}, ignoriert: {block_ignored}") - print(f" Gesamt: {translated_count} übersetzt, {skipped_count} übersprungen, {ignored_count} ignoriert") - print(f" Hinweis: Übersetzungen in Blöcken wurden in {text_target_attr} geschrieben, TEXT-D bleibt unverändert") + print(f" {text_target_attr} (Blöcke) erstellt/aktualisiert: {block_translated}, übersprungen: {block_skipped}, ignoriert: {block_ignored}, übernommen (transfer): {block_transferred}") + print(f" Gesamt: {translated_count} übersetzt, {block_transferred} übernommen, {skipped_count} übersprungen, {ignored_count} ignoriert") + print(f" Hinweis: Übersetzungen in Blöcken wurden in {text_target_attr} geschrieben, {text_source_attr} bleibt unverändert") print(f" Ausgabe-Datei: {output_dxf}") except Exception as e: @@ -1978,6 +2036,12 @@ def _run_todxf( target_lang = translation_languages[0] if translation_languages else None translations = load_translations_from_json(translation_json, target_lang) + # Transfer-Begriffe aus der Sprachkonfiguration laden (nur für Symbol-Attribute) + transfer_terms: set[str] | None = None + if target_lang: + translation_dir = check_environment_var('PROJECT_TRANSLATION') + transfer_terms = load_transfer_terms(target_lang, translation_dir) + output_dxf_name = args.todxf if not output_dxf_name.lower().endswith(('.dxf', '.dwg')): output_dxf_name += '.dxf' @@ -1994,6 +2058,7 @@ def _run_todxf( source_attr_name, target_attr_name, target_layer_name, + transfer_terms, ) print("\nVerarbeitung erfolgreich abgeschlossen.") diff --git a/translation/CS.cfg b/translation/CS.cfg index 1c53569..0349a18 100644 --- a/translation/CS.cfg +++ b/translation/CS.cfg @@ -257,3 +257,14 @@ Waste=Odpad Weight=Hmotnost wheel=kolo Workstation=Pracovní stanice +Lechtdrucktaster=Osvětlené tlačítko +LDT=TS +DRUCKTASTER=Tlačítko +DT=TL +LEUCHTMELDER=Signální svítidlo +LM=SS + +[transfer] +RESET +reset +