diff --git a/bin/extract.bat b/bin/extract.bat new file mode 100644 index 0000000..c1b56a3 --- /dev/null +++ b/bin/extract.bat @@ -0,0 +1,46 @@ +@echo off + +if [%1]==[] goto usage +for %%i in ("%~1") do ( + set "FILENAME=%%~ni" + set "EXT=%%~xi" + set "DIR=%%~dpi" +) +call C:\10-develop\gitea\kabellaengen\bin\setenv.bat + +REM echo Dateiname ohne Erweiterung: %FILENAME% +REM echo Erweiterung: %EXT% +REM echo Verzeichnis: %DIR% +REM +REM Namen der Ergebnisdateien +set RESULT_EXCEL=%FILENAME%_texts.xlsx + +if exist "%~dp0_setenv.bat" ( + echo Lade lokale Umgebungseinstellungen aus _setenv.bat... + call "%~dp0_setenv.bat" +) +REM Zielverzeichnis +set TARGET_DIR=%PROJECT_WORK% +mkdir "%TARGET_DIR%" + +echo. +echo === Extracting TEXT and MTEXT from DXF === +call translate.bat --filename %FILENAME%%EXT% --extract --outname %RESULT_EXCEL% +if not exist "%PROJECT_WORK%\%RESULT_EXCEL% +" ( + @echo == failed: extracting texts + pause + goto :eof +) +echo. +echo === Translation file created: %PROJECT_WORK%\%RESULT_EXCEL% === +pause +goto :eof + + +:usage +@echo Usage: %0 ^ +exit /B 1 +goto :eof + + diff --git a/cfg/translator.cfg b/cfg/translator.cfg index 4658a06..db4925c 100644 --- a/cfg/translator.cfg +++ b/cfg/translator.cfg @@ -15,16 +15,21 @@ coord_y = Y=* coord_z = Z=* + [ignore_pattern_regex] # Reguläre Ausdrücke für Texte die NICHT in die Excel Datei geschrieben werden sollen # Ein Ausdruck pro Zeile (Python regex Syntax) # Format: pattern_name = regex -# Formeln wie =A1 +AB12 -formula = ^=A\d\s*\+[A-Z]{2}\d+ +# Angaben wie =A1 +AB12 oder =A2+UZ304 +anlagen_nr = ^=A\d\s*\+[A-Z]{2}\d+ +anlagen_nr3 = ^=A\d\+UZ\d{3} + +ein_zeichen = ^[A-F]$ # Technische Angaben -height = ^\\H1.875x +h1875 = ^\\H1.875x +h1875ff = ^\\H1.875x;.*$ millimeter = ^\d+\s*mm$ m_numbers = ^M\d{3}$ @@ -32,4 +37,12 @@ m_numbers = ^M\d{3}$ coord_arrows = ^\+\d{1,3}(?:[.,]\d{3})\s*(?:<<<|>>>)\s*\+\d{1,3}(?:[.,]\d{3})$ # +UC3206\P3 x ET200 SP DI16 402.0 uc4 = ^\+UC\d{4} -uc2 = ^=A\d\+UC\d{2} \ No newline at end of file +uc2 = ^=A\d\+UC\d{2} +uc3 = ^=A\d\+UC\d{3} +uz2 = ^=A\d\+UZ\d{2} +uz3 = ^=A\d\+UZ\d{3} + +ip_adresse = ^\\fArial Narrow.*(\d{1,3}\.){3}\d{1,3}$ +tunnel = ^\\fArial.*TUNNEL\d+-\d{4}$ + +kr = ^KR-\d{3,4}$ diff --git a/lib/translate.py b/lib/translate.py index 59dc953..8f1e30e 100644 --- a/lib/translate.py +++ b/lib/translate.py @@ -3,7 +3,7 @@ import os import re import sys from pathlib import Path -from configparser import ConfigParser +from configparser import RawConfigParser from fnmatch import fnmatch import ezdxf @@ -46,7 +46,8 @@ def load_ignore_patterns(cfg_path: Path) -> tuple[list[str], list[str]]: print(f"Bitte erstellen Sie die Datei 'translator.cfg' im Verzeichnis: {cfg_path}") sys.exit(1) - config = ConfigParser() + # RawConfigParser verhindert dass Backslashes in Regex-Mustern escaped werden + config = RawConfigParser() try: config.read(config_file, encoding='utf-8') except Exception as e: @@ -81,7 +82,7 @@ def load_ignore_patterns(cfg_path: Path) -> tuple[list[str], list[str]]: return wildcard_patterns, regex_patterns -def should_ignore_text(text: str, wildcard_patterns: list[str], regex_patterns: list[str]) -> bool: +def should_ignore_text(text: str, wildcard_patterns: list[str], regex_patterns: list[str], debug: bool = False) -> bool: """ Prüft ob ein Text ignoriert werden soll basierend auf den Mustern. @@ -89,6 +90,7 @@ def should_ignore_text(text: str, wildcard_patterns: list[str], regex_patterns: text: Zu prüfender Text wildcard_patterns: Liste der Wildcard-Muster (*,?) regex_patterns: Liste der regulären Ausdrücke + debug: Wenn True, gibt Debug-Informationen aus Returns: True wenn Text ignoriert werden soll, False sonst @@ -96,12 +98,16 @@ def should_ignore_text(text: str, wildcard_patterns: list[str], regex_patterns: # Prüfe Wildcard-Muster for pattern in wildcard_patterns: if fnmatch(text, pattern): + if debug: + print(f" DEBUG: '{text}' matched wildcard '{pattern}'") return True # Prüfe Regex-Muster for pattern in regex_patterns: try: if re.search(pattern, text): + if debug: + print(f" DEBUG: '{text}' matched regex '{pattern}'") return True except re.error: # Falls ungültiger Regex, ignoriere dieses Muster @@ -111,7 +117,7 @@ def should_ignore_text(text: str, wildcard_patterns: list[str], regex_patterns: return False -def extract_text_from_dxf(filename: Path, wildcard_patterns: list[str], regex_patterns: list[str]) -> list[str]: +def extract_text_from_dxf(filename: Path, wildcard_patterns: list[str], regex_patterns: list[str], debug: bool = False) -> list[str]: """ Extrahiert alle TEXT und MTEXT Objekte aus einer DXF Datei. Verwendet ein Set, um Duplikate zu vermeiden. @@ -120,6 +126,7 @@ def extract_text_from_dxf(filename: Path, wildcard_patterns: list[str], regex_pa filename: Pfad zur DXF Datei wildcard_patterns: Liste der Wildcard-Muster zum Filtern regex_patterns: Liste der Regex-Muster zum Filtern + debug: Wenn True, gibt Debug-Informationen aus Returns: Alphabetisch sortierte Liste mit allen gefundenen Texten (nach Filterung, ohne Duplikate) @@ -136,8 +143,14 @@ def extract_text_from_dxf(filename: Path, wildcard_patterns: list[str], regex_pa for entity in msp.query('TEXT'): if entity.dxf.text: total_count += 1 - text = entity.dxf.text - if should_ignore_text(text, wildcard_patterns, regex_patterns): + text = entity.dxf.text.strip() # Entferne führende/nachfolgende Leerzeichen + + # Ignoriere leere Texte + if not text: + ignored_count += 1 + continue + + if should_ignore_text(text, wildcard_patterns, regex_patterns, debug): ignored_count += 1 else: texts_set.add(text) @@ -146,8 +159,14 @@ def extract_text_from_dxf(filename: Path, wildcard_patterns: list[str], regex_pa for entity in msp.query('MTEXT'): if entity.text: total_count += 1 - text = entity.text - if should_ignore_text(text, wildcard_patterns, regex_patterns): + text = entity.text.strip() # Entferne führende/nachfolgende Leerzeichen + + # Ignoriere leere Texte + if not text: + ignored_count += 1 + continue + + if should_ignore_text(text, wildcard_patterns, regex_patterns, debug): ignored_count += 1 else: texts_set.add(text) @@ -221,6 +240,11 @@ if __name__ == '__main__': help='Name der Ausgabedatei (ohne Pfad, mit oder ohne .xlsx Endung)', metavar='output.xlsx' ) + parser.add_argument( + '-d', '--debug', + action='store_true', + help='Aktiviert Debug-Ausgabe für Pattern-Matching' + ) args = parser.parse_args() @@ -251,7 +275,9 @@ if __name__ == '__main__': # Extrahiere Texte aus DXF if args.extract: print(f"Lese DXF Datei: {filename}") - texts = extract_text_from_dxf(filename, wildcard_patterns, regex_patterns) + if args.debug: + print("DEBUG-Modus aktiviert") + texts = extract_text_from_dxf(filename, wildcard_patterns, regex_patterns, args.debug) # Erstelle Output-Dateinamen if args.outname: