/
pattern_replacer.py
158 lines (116 loc) · 4.65 KB
/
pattern_replacer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import tkinter as tk
from tkinter import messagebox
import re
import json
import os
import threading
MEMORY_FILE = "pattern_replacer_memory.json"
def replace_all():
global undo_stack
save_memory()
try:
text = text_input.get(1.0, tk.END)
undo_stack.append(text)
for pattern_entry, replacement_entry, _ in regex_replacements: # Add an underscore to unpack the third value
pattern = pattern_entry.get()
replacement = replacement_entry.get()
text = re.sub(pattern, replacement, text)
text_input.delete(1.0, tk.END)
text_input.insert(tk.END, text)
except re.error:
messagebox.showerror("Error", "Invalid regular expression")
undo()
def undo():
global undo_stack
if undo_stack:
text_input.delete(1.0, tk.END)
text_input.insert(tk.END, undo_stack.pop())
def update_window_size():
base_height = 550
row_height = 35
num_rows = len(regex_replacements) + 1
window.geometry(f"800x{base_height + num_rows * row_height}")
def validate_regex(event, entry_widget=None):
if entry_widget is None:
entry_widget = event.widget
try:
re.compile(entry_widget.get())
entry_widget.configure(bg="#98FB98") # Light green
except re.error:
entry_widget.configure(bg="#F08080") # Light coral (a soft red shade)
def add_regex_pair(pattern="", replacement=""):
row_index = len(regex_replacements) + 2
pattern_entry = tk.Entry(window)
replacement_entry = tk.Entry(window)
remove_pair_button = tk.Button(window, text="Remove Pair", command=lambda: remove_regex_pair(row_index))
pattern_entry.insert(tk.END, pattern)
replacement_entry.insert(tk.END, replacement)
pattern_entry.grid(row=row_index, column=0, padx=5, pady=5)
replacement_entry.grid(row=row_index, column=1, padx=5, pady=5)
remove_pair_button.grid(row=row_index, column=2, padx=5, pady=5)
pattern_entry.bind('<KeyRelease>', validate_regex) # Bind the validate_regex function to the KeyRelease event
validate_regex(tk.Event(), pattern_entry) # Call the validate_regex function to set the initial background color
regex_replacements.append((pattern_entry, replacement_entry, remove_pair_button))
update_window_size()
def remove_regex_pair(row_index):
pair = None
for p in regex_replacements:
if p[0].grid_info()["row"] == row_index:
pair = p
break
if pair:
regex_replacements.remove(pair)
pair[0].grid_forget()
pair[1].grid_forget()
pair[2].grid_forget()
update_window_size()
def save_memory():
memory = {
"text": text_input.get(1.0, tk.END),
"regex_replacements": [(pair[0].get(), pair[1].get()) for pair in regex_replacements],
}
with open(MEMORY_FILE, "w") as f:
json.dump(memory, f)
def load_memory():
if os.path.exists(MEMORY_FILE):
with open(MEMORY_FILE, "r") as f:
memory = json.load(f)
text_input.insert(tk.END, memory.get("text", ""))
regex_replacements_data = memory.get("regex_replacements", [])
if not regex_replacements_data: # Add an empty pair if there are no regex replacement pairs in memory
add_regex_pair()
for pattern, replacement in regex_replacements_data:
add_regex_pair(pattern, replacement)
else:
add_regex_pair() # Add an empty pair if the memory file does not exist
def schedule_memory_save():
global stop_event
if not stop_event.is_set():
save_memory()
stop_event.wait(60) # Wait for 60 seconds or until the stop_event is set
schedule_memory_save()
def close_window():
global stop_event
save_memory()
stop_event.set() # Set the stop_event to stop the schedule_memory_save function
window.destroy()
stop_event = threading.Event()
undo_stack = []
regex_replacements = []
window = tk.Tk()
window.title("Pattern Replacer")
window.geometry("800x600")
text_input = tk.Text(window, wrap=tk.WORD)
text_input.grid(row=0, column=0, columnspan=2, padx=5, pady=5)
replace_button = tk.Button(window, text="Replace All", command=replace_all)
replace_button.grid(row=1, column=0, padx=5, pady=5)
undo_button = tk.Button(window, text="Undo", command=undo)
undo_button.grid(row=1, column=1, padx=5, pady=5)
add_pair_button = tk.Button(window, text="Add Pair", command=add_regex_pair)
add_pair_button.grid(row=1000, column=0, padx=5, pady=5)
load_memory()
window.protocol("WM_DELETE_WINDOW", close_window)
# Run schedule_memory_save in a separate thread
save_memory_thread = threading.Thread(target=schedule_memory_save)
save_memory_thread.start()
window.mainloop()