import os import subprocess import tkinter as tk from tkinter import filedialog, messagebox, scrolledtext from pathlib import Path class MarkdownToPDFApp: def __init__(self, root): self.root = root self.root.title("Markdown → DOCX/PDF Converter") self.root.geometry("650x480") self.root.resizable(False, False) self.folder_path = tk.StringVar() self.output_name = tk.StringVar(value="manuale") self.template_path = tk.StringVar() self.use_template = tk.BooleanVar(value=False) self.generate_pdf = tk.BooleanVar(value=True) # --- UI --- tk.Label(root, text="Cartella Markdown:").pack( anchor="w", padx=10, pady=(10, 0) ) frame1 = tk.Frame(root) frame1.pack(fill="x", padx=10) tk.Entry(frame1, textvariable=self.folder_path, width=50).pack( side="left", fill="x", expand=True ) tk.Button(frame1, text="Sfoglia...", command=self.choose_folder).pack( side="right", padx=5 ) tk.Label(root, text="Nome base file output (senza estensione):").pack( anchor="w", padx=10, pady=(10, 0) ) tk.Entry(root, textvariable=self.output_name, width=40).pack(fill="x", padx=10) tk.Checkbutton( root, text="Usa template DOCX", variable=self.use_template, command=self.toggle_template, ).pack(anchor="w", padx=10, pady=(10, 0)) frame2 = tk.Frame(root) frame2.pack(fill="x", padx=10) tk.Entry( frame2, textvariable=self.template_path, width=50, state="disabled" ).pack(side="left", fill="x", expand=True) tk.Button( frame2, text="Seleziona template", command=self.choose_template, state="disabled", ).pack(side="right", padx=5) self.template_frame = frame2 tk.Checkbutton( root, text="Genera anche PDF finale", variable=self.generate_pdf ).pack(anchor="w", padx=10, pady=(10, 0)) tk.Button( root, text="Genera Documento", command=self.generate_output, bg="#3c9", fg="white", ).pack(pady=10) tk.Label(root, text="Log:").pack(anchor="w", padx=10) self.log_box = scrolledtext.ScrolledText(root, height=13, state="disabled") self.log_box.pack(fill="both", expand=True, padx=10, pady=(0, 10)) # --- Utility methods --- def log(self, text): self.log_box.configure(state="normal") self.log_box.insert(tk.END, text + "\n") self.log_box.configure(state="disabled") self.log_box.see(tk.END) self.root.update_idletasks() def choose_folder(self): folder = filedialog.askdirectory(title="Seleziona la cartella Markdown") if folder: self.folder_path.set(folder) def toggle_template(self): state = "normal" if self.use_template.get() else "disabled" for widget in self.template_frame.winfo_children(): widget.configure(state=state) def choose_template(self): file = filedialog.askopenfilename( title="Seleziona template DOCX", filetypes=[("Word Template", "*.docx")] ) if file: self.template_path.set(file) def generate_output(self): folder = self.folder_path.get().strip() output_name = self.output_name.get().strip() template = self.template_path.get().strip() use_template = self.use_template.get() make_pdf = self.generate_pdf.get() if not folder: messagebox.showwarning( "Attenzione", "Seleziona una cartella contenente i file Markdown." ) return folder_path = Path(folder) output_docx = folder_path / f"{output_name}.docx" output_pdf = folder_path / f"{output_name}.pdf" # Trova i file Markdown numerati md_files = sorted(folder_path.glob("[0-9][0-9]_*.md")) if not md_files: messagebox.showerror( "Errore", "Nessun file Markdown numerato trovato nella cartella." ) return self.log(f"Trovati {len(md_files)} file Markdown:") for f in md_files: self.log(f" - {f.name}") combined_md = folder_path / "_manuale_unico_temp.md" self.log(f"\nUnione dei file in {combined_md.name}...") try: with open(combined_md, "w", encoding="utf-8") as out: for f in md_files: out.write(f"\n\n# --- {f.name} ---\n\n") out.write(f.read_text(encoding="utf-8")) out.write("\n\n") self.log("File unito con successo.") except Exception as e: messagebox.showerror("Errore durante unione", str(e)) return # Comando Pandoc per generare DOCX cmd_docx = ["pandoc", str(combined_md), "-o", str(output_docx)] if use_template: if not Path(template).exists(): messagebox.showerror( "Template non trovato", f"Il file {template} non esiste." ) return cmd_docx.extend(["--reference-doc", str(template)]) self.log("\nEsecuzione Pandoc (DOCX)...") result = subprocess.run(cmd_docx, capture_output=True, text=True) if result.returncode != 0: self.log("❌ Errore Pandoc (DOCX):") self.log(result.stderr) messagebox.showerror("Errore Pandoc", result.stderr) return self.log(f"✅ DOCX generato correttamente: {output_docx}") # Generazione PDF opzionale if make_pdf: self.log("\nGenerazione PDF dal DOCX...") cmd_pdf = ["pandoc", str(output_docx), "-o", str(output_pdf)] result = subprocess.run(cmd_pdf, capture_output=True, text=True) if result.returncode == 0: self.log(f"✅ PDF generato: {output_pdf}") messagebox.showinfo("Completato", f"PDF generato: {output_pdf}") else: self.log("❌ Errore durante conversione PDF:") self.log(result.stderr) messagebox.showerror("Errore PDF", result.stderr) else: messagebox.showinfo("Completato", f"DOCX generato: {output_docx}") # Pulisce file temporaneo if combined_md.exists(): combined_md.unlink() if __name__ == "__main__": root = tk.Tk() app = MarkdownToPDFApp(root) root.mainloop()