From 95e944f983bcbf67ed0558ad3d8ddbeb58605e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Miquel?= Date: Fri, 24 Apr 2026 08:22:42 +0200 Subject: [PATCH] Enonce info : generate pdf per question/solution --- enonce_info.py | 116 ++++++++++++++++++++++++++++++++++++++------- liste_francais.txt | 3 ++ 2 files changed, 102 insertions(+), 17 deletions(-) diff --git a/enonce_info.py b/enonce_info.py index 1090ca6..615f022 100644 --- a/enonce_info.py +++ b/enonce_info.py @@ -4,6 +4,83 @@ import glob import json import urllib.request import re +import subprocess +import tempfile +import shutil + +def compile_to_pdf(text, output_pdf_path): + """Wraps text in a standalone template and compiles it to PDF.""" + latex_template = f"""\\documentclass[varwidth=21cm,margin=0.2cm]{{standalone}} +\\usepackage[utf8]{{inputenc}} +\\usepackage[T1]{{fontenc}} +\\usepackage{{lmodern}} +\\usepackage{{amsmath, amssymb}} +\\usepackage{{commands}} +\\usepackage{{enumitem}} +\\begin{{document}} +{text} +\\end{{document}} +""" + with tempfile.TemporaryDirectory() as temp_dir: + tex_filename = 'text.tex' + pdf_filename = 'text.pdf' + tex_path = os.path.join(temp_dir, tex_filename) + + with open(tex_path, 'w', encoding='utf-8') as f: + f.write(latex_template) + + # Set TEXINPUTS so pdflatex can find commands.sty if it's in the current dir + # env = os.environ.copy() + # current_dir = os.getcwd() + # env['TEXINPUTS'] = f".:{current_dir}:" + + try: + subprocess.run( + ['pdflatex', '-interaction=nonstopmode', tex_filename], + cwd=temp_dir, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + check=False + ) + + generated_pdf = os.path.join(temp_dir, pdf_filename) + if os.path.exists(generated_pdf): + shutil.move(generated_pdf, output_pdf_path) + except Exception as e: + print(f"Compilation error for {output_pdf_path}: {e}") + +def fetch_and_save_sub_text(ex_id, indices, label, text_path): + """Fetches text for a specific sub-question and saves it to Text/{label}.tex""" + qinds = ",".join(map(str, indices)) + url = f"http://localhost:8080/exercices/exo_q_text/{ex_id}/{qinds}" + try: + with urllib.request.urlopen(url) as response: + content = response.read().decode('utf-8') + content = replace_dots(content.strip("\n")) + with open(os.path.join(text_path, f"{label}.tex"), 'w', encoding='utf-8') as f: + f.write(content) + # Compile PDF + pdf_file = os.path.join(text_path, f"{label}.pdf") + compile_to_pdf(content, pdf_file) + except Exception as e: + print(f"Error fetching sub-text from {url}: {e}") + +def fetch_and_save_sub_sol(ex_id, indices, label, sol_path): + """Fetches text for a specific sub-question and saves it to Text/{label}.tex""" + qinds = ",".join(map(str, indices)) + url = f"http://localhost:8080/exercices/exo_q_sol/{ex_id}/{qinds}" + try: + with urllib.request.urlopen(url) as response: + content = response.read().decode('utf-8') + content = replace_dots(content.strip("\n")) + with open(os.path.join(sol_path, f"{label}.tex"), 'w', encoding='utf-8') as f: + f.write(content) + # Compile PDF + pdf_file = os.path.join(sol_path, f"{label}.pdf") + compile_to_pdf(content, pdf_file) + except Exception as e: + print(f"Error fetching sub-text from {url}: {e}") + ROMANS_CAP = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"] ROMANS_LOW = ["", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x"] @@ -55,6 +132,7 @@ def save_split_content(text, path, base_fname, problem): with open(os.path.join(path, base_fname), 'w', encoding='utf-8') as f: f.write(text) + pattern = re.compile(r"(?m)^([ \t]+)([a-zA-Z0-9]+)\)") all_matches = list(pattern.finditer(text)) @@ -80,6 +158,7 @@ def save_split_content(text, path, base_fname, problem): with open(os.path.join(path, sub_fname), 'w', encoding='utf-8') as f: f.write(chunk) + def process_directory(directory): # Find the first .tex file in the directory tex_files = glob.glob(os.path.join(directory, "*.tex")) @@ -124,24 +203,10 @@ def process_directory(directory): # Check if text until next SHEETINFO block contains \Roman problem = r"\Roman" in block_content - if not json_str: - continue + if not json_str: continue try: data = json.loads(json_str) - - # 2. Handle Labels - indexes = data.get('indexes', []) - if not indexes: - f_labels.write(f"Ex {current_ex_num}\n") - else: - for item in indexes: - suffix = format_indices(item['indices'], problem) - if suffix != "": - f_labels.write(f"Ex {current_ex_num} : {suffix}\n") - else: - f_labels.write(f"Ex {current_ex_num}\n") - # Construct 'ids' parameter ex_id = str(data['id']) selection = data.get('select') @@ -152,10 +217,27 @@ def process_directory(directory): else: ids = ex_id + + # 2. Handle Labels + indexes = data.get('indexes', []) + if not indexes: + label = f"Ex {current_ex_num}" + f_labels.write(f"{label}\n") + fetch_and_save_sub_text(ids, [], label, paths['Text']) + fetch_and_save_sub_sol(ids, [], label, paths['Sol']) + else: + for item in indexes: + suffix = format_indices(item['indices'], problem) + label = f"Ex {current_ex_num}" + (f" : {suffix}" if suffix else "") + f_labels.write(f"{label}\n") + fetch_and_save_sub_text(ids, item['indices'], label, paths['Text']) + fetch_and_save_sub_sol(ids, item['indices'], label, paths['Sol']) + + # Construct URL (append pb=true if \Roman matched) url = f"http://localhost:8080/exercices/emacs/{ids}?pretty=true&all=true&persp=true" - if problem: - url += "&pb=true" + # if problem: + # url += "&pb=true" # Perform GET request with urllib.request.urlopen(url) as response: diff --git a/liste_francais.txt b/liste_francais.txt index 4804146..cbdd256 100644 --- a/liste_francais.txt +++ b/liste_francais.txt @@ -1387,6 +1387,7 @@ ardu are arène arête +arêtes argent argenterie argile @@ -19270,6 +19271,7 @@ suppléer supplément supplémentaire supplémentaires +supplémentarité suppliant supplication supplice @@ -19778,6 +19780,7 @@ théoriciens théorie théories théorique +théorème théoriquement théoriques thérapeutique