23from tkinter
import filedialog, messagebox, ttk
28 """Limpia el formato flexible de WaveDrom para hacerlo JSON estándar."""
29 texto = re.sub(
r'//.*',
'', texto)
30 texto = re.sub(
r',\s*([\]}])',
r'\1', texto)
31 texto = re.sub(
r'([{,]\s*)([a-zA-Z_]\w*)\s*:',
r'\1"\2":', texto)
32 texto = texto.replace(
"'",
'"')
36 """Calcula la duración máxima de las señales."""
38 with open(path,
'r', encoding=
'utf-8')
as f:
41 for sig
in data.get(
'signal', []):
43 max_ticks = max(max_ticks, len(sig[
'wave']))
49 """Aplica recorte, sincronización de datos y configuración visual."""
50 data_chars =
"23456789="
51 for sig
in data.get(
'signal', []):
53 wave_full = sig[
'wave']
54 skipped_data = sum(1
for char
in wave_full[:tick_start]
if char
in data_chars)
55 new_wave = wave_full[tick_start:tick_end]
56 keep_data = sum(1
for char
in new_wave
if char
in data_chars)
57 sig[
'wave'] = new_wave
58 if 'data' in sig
and isinstance(sig[
'data'], list):
59 sig[
'data'] = sig[
'data'][skipped_data : skipped_data + keep_data]
61 if 'head' not in data: data[
'head'] = {}
62 if 'foot' not in data: data[
'foot'] = {}
64 data[
'head'][
'text'] = config_ui[
'titulo']
65 data[
'foot'][
'text'] = config_ui[
'pie']
67 if 'config' not in data: data[
'config'] = {}
68 data[
'config'][
'hscale'] = int(config_ui[
'hscale'])
69 data[
'config'][
'skin'] = config_ui[
'skin']
70 data[
'head'][
'every'] = config_ui[
'every']
75 """Función corregida para evitar el error UnboundLocalError."""
76 archivo = filedialog.askopenfilename(filetypes=[(
"JSON files",
"*.json"), (
"All files",
"*.*")])
78 entry_file.delete(0, tk.END)
79 entry_file.insert(0, archivo)
81 lbl_info.config(text=f
"Duración: {duracion} ticks", fg=
"#1b5e20")
82 entry_end.delete(0, tk.END)
83 entry_end.insert(0, str(duracion))
86 """Genera el JSON y opcionalmente lo abre en la web."""
87 path = entry_file.get()
89 messagebox.showwarning(
"Aviso",
"Por favor, selecciona un archivo.")
93 with open(path,
'r', encoding=
'utf-8')
as f:
97 'titulo': entry_title.get(),
98 'pie': entry_foot.get(),
99 'hscale': spin_hscale.get(),
100 'skin': combo_skin.get(),
101 'every': int(spin_every.get())
104 resultado =
recortar_wavedrom(data, int(entry_start.get()), int(entry_end.get()), config_ui)
105 json_str = json.dumps(resultado, indent=2)
109 codigo_url = urllib.parse.quote(json_str)
110 webbrowser.open(f
"https://wavedrom.com/editor.html?{codigo_url}")
112 save_path = filedialog.asksaveasfilename(defaultextension=
".json")
114 with open(save_path,
'w', encoding=
'utf-8')
as f:
116 messagebox.showinfo(
"Éxito",
"Archivo guardado correctamente.")
118 except Exception
as e:
119 messagebox.showerror(
"Error", f
"Ocurrió un problema:\n{e}")
123root.title(
"WaveDrom Ultra Editor Pro")
124root.geometry(
"500x550")
127tk.Label(root, text=
"1. Selecciona tu archivo", font=(
'Arial', 10,
'bold')).pack(pady=(10,0))
128frame_file = tk.Frame(root)
129frame_file.pack(pady=5)
130entry_file = tk.Entry(frame_file, width=45)
131entry_file.pack(side=tk.LEFT, padx=5)
132tk.Button(frame_file, text=
"Buscar", command=seleccionar_archivo).pack(side=tk.LEFT)
133lbl_info = tk.Label(root, text=
"Sin archivo cargado")
137tk.Label(root, text=
"2. Títulos y Notas", font=(
'Arial', 10,
'bold')).pack(pady=(10,0))
138tk.Label(root, text=
"Título:").pack()
139entry_title = tk.Entry(root, width=50); entry_title.pack()
140tk.Label(root, text=
"Pie de página:").pack()
141entry_foot = tk.Entry(root, width=50); entry_foot.pack()
144frame_params = tk.LabelFrame(root, text=
" 3. Ajustes de Recorte y Estilo ", padx=10, pady=10)
145frame_params.pack(pady=15)
147tk.Label(frame_params, text=
"Estilo:").grid(row=0, column=0)
148combo_skin = ttk.Combobox(frame_params, values=[
"default",
"narrow"], width=10)
149combo_skin.set(
"default"); combo_skin.grid(row=0, column=1)
151tk.Label(frame_params, text=
"Escala (Hscale):").grid(row=0, column=2, padx=(10,0))
152spin_hscale = tk.Spinbox(frame_params, from_=1, to=10, width=5)
153spin_hscale.grid(row=0, column=3)
155tk.Label(frame_params, text=
"Tick Inicio:").grid(row=1, column=0, pady=10)
156entry_start = tk.Entry(frame_params, width=7); entry_start.insert(0,
"0")
157entry_start.grid(row=1, column=1)
159tk.Label(frame_params, text=
"Tick Fin:").grid(row=1, column=2)
160entry_end = tk.Entry(frame_params, width=7); entry_end.insert(0,
"20")
161entry_end.grid(row=1, column=3)
163tk.Label(frame_params, text=
"Numerar cada:").grid(row=2, column=0)
164spin_every = tk.Spinbox(frame_params, from_=1, to=100, width=7)
165spin_every.grid(row=2, column=1)
168btn_frame = tk.Frame(root)
169btn_frame.pack(pady=10)
171tk.Button(btn_frame, text=
"GUARDAR JSON", bg=
"#455a64", fg=
"white",
172 command=
lambda:
procesar(
False), padx=10, pady=10).pack(side=tk.LEFT, padx=5)
174tk.Button(btn_frame, text=
"VER EN NAVEGADOR", bg=
"#1e88e5", fg=
"white",
175 font=(
'Arial', 10,
'bold'), command=
lambda:
procesar(
True), padx=15, pady=10).pack(side=tk.LEFT, padx=5)
seleccionar_archivo()
Función corregida para evitar el error UnboundLocalError.
limpiar_formato_wavedrom( texto)
Limpia el formato flexible de WaveDrom para hacerlo JSON estándar.
obtener_info_archivo( path)
Calcula la duración máxima de las señales.
recortar_wavedrom( data, tick_start, tick_end, config_ui)
Aplica recorte, sincronización de datos y configuración visual.
procesar( abrir_navegador=False)
Genera el JSON y opcionalmente lo abre en la web.