186 lines
6.5 KiB
Python
186 lines
6.5 KiB
Python
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()
|