Enonce info : generate pdf per question/solution
parent
dd0d757fc9
commit
95e944f983
116
enonce_info.py
116
enonce_info.py
|
|
@ -4,6 +4,83 @@ import glob
|
||||||
import json
|
import json
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import re
|
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_CAP = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"]
|
||||||
ROMANS_LOW = ["", "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:
|
with open(os.path.join(path, base_fname), 'w', encoding='utf-8') as f:
|
||||||
f.write(text)
|
f.write(text)
|
||||||
|
|
||||||
|
|
||||||
pattern = re.compile(r"(?m)^([ \t]+)([a-zA-Z0-9]+)\)")
|
pattern = re.compile(r"(?m)^([ \t]+)([a-zA-Z0-9]+)\)")
|
||||||
all_matches = list(pattern.finditer(text))
|
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:
|
with open(os.path.join(path, sub_fname), 'w', encoding='utf-8') as f:
|
||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
|
|
||||||
|
|
||||||
def process_directory(directory):
|
def process_directory(directory):
|
||||||
# Find the first .tex file in the directory
|
# Find the first .tex file in the directory
|
||||||
tex_files = glob.glob(os.path.join(directory, "*.tex"))
|
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
|
# Check if text until next SHEETINFO block contains \Roman
|
||||||
problem = r"\Roman" in block_content
|
problem = r"\Roman" in block_content
|
||||||
|
|
||||||
if not json_str:
|
if not json_str: continue
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = json.loads(json_str)
|
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
|
# Construct 'ids' parameter
|
||||||
ex_id = str(data['id'])
|
ex_id = str(data['id'])
|
||||||
selection = data.get('select')
|
selection = data.get('select')
|
||||||
|
|
@ -152,10 +217,27 @@ def process_directory(directory):
|
||||||
else:
|
else:
|
||||||
ids = ex_id
|
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)
|
# Construct URL (append pb=true if \Roman matched)
|
||||||
url = f"http://localhost:8080/exercices/emacs/{ids}?pretty=true&all=true&persp=true"
|
url = f"http://localhost:8080/exercices/emacs/{ids}?pretty=true&all=true&persp=true"
|
||||||
if problem:
|
# if problem:
|
||||||
url += "&pb=true"
|
# url += "&pb=true"
|
||||||
|
|
||||||
# Perform GET request
|
# Perform GET request
|
||||||
with urllib.request.urlopen(url) as response:
|
with urllib.request.urlopen(url) as response:
|
||||||
|
|
|
||||||
|
|
@ -1387,6 +1387,7 @@ ardu
|
||||||
are
|
are
|
||||||
arène
|
arène
|
||||||
arête
|
arête
|
||||||
|
arêtes
|
||||||
argent
|
argent
|
||||||
argenterie
|
argenterie
|
||||||
argile
|
argile
|
||||||
|
|
@ -19270,6 +19271,7 @@ suppléer
|
||||||
supplément
|
supplément
|
||||||
supplémentaire
|
supplémentaire
|
||||||
supplémentaires
|
supplémentaires
|
||||||
|
supplémentarité
|
||||||
suppliant
|
suppliant
|
||||||
supplication
|
supplication
|
||||||
supplice
|
supplice
|
||||||
|
|
@ -19778,6 +19780,7 @@ théoriciens
|
||||||
théorie
|
théorie
|
||||||
théories
|
théories
|
||||||
théorique
|
théorique
|
||||||
|
théorème
|
||||||
théoriquement
|
théoriquement
|
||||||
théoriques
|
théoriques
|
||||||
thérapeutique
|
thérapeutique
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue