utilities to fix LaTeX issues

This commit is contained in:
sebastien committed 2026-09-29 10:53:32 +02:00
1 parent 2a4c5f4f7c
commit a56fc6e680
7 files changed
+164 -2

No files matched your search

+106
View File
@@ -20,6 +20,7 @@ from copienator.platform import (
open_path,
validate_windows_labels,
)
from copienator.utils import LATEX_WARNING_MARKER
from .diagnostics import collect_diagnostics
from .batch_monitor import BatchMonitor
@@ -281,6 +282,8 @@ class CopienatorApp(tk.Tk):
self.pending_refaire_commands: list[list[str]] = []
self.refaire_command_index = 0
self._correction_progress_buffer = ""
self._latex_warning_buffer = ""
self._latex_warning_paths: list[Path] = []
self.title("Copienator — assistant de correction")
self.geometry("1180x820")
@@ -493,6 +496,13 @@ class CopienatorApp(tk.Tk):
clipboard_actions.grid(row=1, column=0, columnspan=6, sticky="w", pady=(5, 0))
ttk.Button(clipboard_actions, text="Copier la sélection", command=self._copy_console_selection).pack(side="left")
ttk.Button(clipboard_actions, text="Copier toute la sortie", command=self._copy_console_all).pack(side="left", padx=6)
self.latex_warning_button = ttk.Button(
clipboard_actions,
text="Problèmes LaTeX…",
command=self._show_current_latex_warnings,
)
self.latex_warning_button.pack(side="left", padx=6)
self.latex_warning_button.pack_forget()
ttk.Label(console_actions, text="Réponse au script").grid(row=0, column=0, padx=(0, 6))
self.stdin_var = tk.StringVar()
self.stdin_entry = ttk.Entry(console_actions, textvariable=self.stdin_var)
@@ -582,6 +592,7 @@ class CopienatorApp(tk.Tk):
messagebox.showerror("Dossier invalide", "Choisissez un dossier d’évaluation existant.")
return
self.batch_monitor.stop()
self._reset_latex_warnings()
self._save_current_form()
self.state_store.load(evaluation)
for step in self.steps:
@@ -1532,6 +1543,8 @@ class CopienatorApp(tk.Tk):
last_run_values=run_values,
)
self.active_step_id = step.id
if step.id == "statement":
self._reset_latex_warnings()
if step.id == "correction":
self._correction_progress_buffer = ""
self.info_var.set("Correction : préparation des groupes…")
@@ -1642,6 +1655,7 @@ class CopienatorApp(tk.Tk):
if event == "output":
output = str(payload)
self._track_correction_progress(output)
self._track_latex_warnings(output)
self._append_console(output)
elif event == "input_echo":
self._append_console(f"> {payload}")
@@ -1670,6 +1684,88 @@ class CopienatorApp(tk.Tk):
f"({percent} %)."
)
def _reset_latex_warnings(self) -> None:
self._latex_warning_buffer = ""
self._latex_warning_paths = []
if hasattr(self, "latex_warning_button"):
self.latex_warning_button.pack_forget()
def _track_latex_warnings(self, output: str, *, flush: bool = False) -> None:
if self.active_step_id != "statement":
return
combined = self._latex_warning_buffer + output
lines = combined.splitlines(keepends=True)
self._latex_warning_buffer = ""
if lines and not lines[-1].endswith(("\n", "\r")) and not flush:
self._latex_warning_buffer = lines.pop()
for line in lines:
marker_at = line.find(LATEX_WARNING_MARKER)
if marker_at < 0:
continue
raw_path = line[marker_at + len(LATEX_WARNING_MARKER):].strip()
if not raw_path:
continue
path = Path(raw_path).expanduser()
if not path.is_absolute() and self.evaluation:
path = self.evaluation / path
path = path.resolve()
if path not in self._latex_warning_paths:
self._latex_warning_paths.append(path)
if self._latex_warning_paths:
self.latex_warning_button.pack(side="left", padx=6)
def _show_current_latex_warnings(self) -> None:
if not self._latex_warning_paths:
messagebox.showinfo("Compilation LaTeX", "Aucun problème de compilation détecté.")
return
dialog = tk.Toplevel(self)
dialog.title("Problèmes de compilation LaTeX")
dialog.geometry("900x380")
dialog.transient(self)
dialog.columnconfigure(0, weight=1)
dialog.rowconfigure(1, weight=1)
ttk.Label(
dialog,
text=(
f"{len(self._latex_warning_paths)} fichier(s) n’ont pas été compilés "
"correctement. Sélectionnez-en un pour ouvrir ses éléments."
),
padding=10,
wraplength=850,
justify="left",
).grid(row=0, column=0, sticky="ew")
paths = tk.Listbox(dialog, exportselection=False)
for pdf_path in self._latex_warning_paths:
try:
label = str(pdf_path.relative_to(self.evaluation)) if self.evaluation else str(pdf_path)
except ValueError:
label = str(pdf_path)
paths.insert("end", label)
paths.grid(row=1, column=0, sticky="nsew", padx=10)
paths.selection_set(0)
actions = ttk.Frame(dialog, padding=10)
actions.grid(row=2, column=0, sticky="ew")
def selected_pdf() -> Path:
selection = paths.curselection()
index = selection[0] if selection else 0
return self._latex_warning_paths[index]
def open_folder() -> None:
self._open_desktop_path(selected_pdf().parent, "dossier de compilation")
def open_source() -> None:
self._open_desktop_path(selected_pdf().with_suffix(".tex"), "fichier source LaTeX")
def open_pdf() -> None:
self._open_desktop_path(selected_pdf(), "fichier PDF compilé")
ttk.Button(actions, text="Ouvrir le dossier", command=open_folder).pack(side="left")
ttk.Button(actions, text="Ouvrir le .tex", command=open_source).pack(side="left", padx=6)
ttk.Button(actions, text="Ouvrir le PDF", command=open_pdf).pack(side="left")
ttk.Button(actions, text="Fermer", command=dialog.destroy).pack(side="right")
def _batch_watch_status_changed(self, message: str) -> None:
self.batch_watch_status.set(message)
self._update_controls()
@@ -1710,6 +1806,8 @@ class CopienatorApp(tk.Tk):
step_id = self.active_step_id
if not step_id:
return
if step_id == "statement":
self._track_latex_warnings("", flush=True)
status = process_status(return_code, interrupted)
if status == "success" and self.pending_refaire_commands:
command = self.pending_refaire_commands.pop(0)
@@ -1790,9 +1888,17 @@ class CopienatorApp(tk.Tk):
title = self.step_by_id[step_id].title
self._append_console(f"\n[Terminé — code {return_code} — {STATUS_LABELS[status]}]\n")
self.info_var.set(f"{title} : {STATUS_LABELS[status].lower()} (code {return_code}).")
if step_id == "statement" and self._latex_warning_paths:
count = len(self._latex_warning_paths)
self.info_var.set(
f"{title} : {STATUS_LABELS[status].lower()} (code {return_code}) — "
f"{count} problème(s) LaTeX."
)
self.active_step_id = None
self._populate_tree()
self._update_controls()
if step_id == "statement" and self._latex_warning_paths:
self.after_idle(self._show_current_latex_warnings)
if step_id == "personal_read":
if status == "success":
self.info_var.set("Commande terminée. Poursuivez la relecture, puis cliquez sur « Marquer réussie ».")