This commit is contained in:
2026-02-12 08:28:06 +01:00
2 changed files with 94 additions and 18 deletions
+83 -18
View File
@@ -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.")
+11
View File
@@ -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