spb/uqo-imm1003
Public
JavaScript 68%
CSS 32%
1"""Test de conversion complet : 2 cours × (14 chapitres + 2 annexes) ; math KaTeX ; TikZ."""2import collections3import json4import os5import subprocess6import sys78sys.path.insert(0, os.path.dirname(__file__))9from latex2html import Ctx, convert_chapter # noqa: E40210from bib import parse_bib # noqa: E40211import tikz # noqa: E4021213ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))14COURSES = {15 "imm1003": "IMM1003-20_Elements_evaluation_immobiliere/IMM1003_Notes_de_cours/sources",16 "imm1033": "IMM1033-20_Methodes_du_cout/IMM1033_Notes_de_cours/sources",17}18do_tikz = "--tikz" in sys.argv1920all_tikz = []21for code, rel in COURSES.items():22 src = os.path.join(ROOT, rel)23 bib = parse_bib(open(os.path.join(src, "references.bib"), encoding="utf-8").read())24 ctx = Ctx(code.upper(), bib)25 results = []26 for i in range(1, 15):27 key = f"ch{i:02d}"28 tex = open(os.path.join(src, "chapters", key + ".tex"), encoding="utf-8").read()29 r = convert_chapter(ctx, key, str(i), f"/seance/{i:02d}/", tex)30 results.append(r)31 for key, num, url in (("annexe-formulaire", "A", "/aide-memoire/"), ("annexe-glossaire", "B", "/glossaire/")):32 tex = open(os.path.join(src, "chapters", key + ".tex"), encoding="utf-8").read()33 results.append(convert_chapter(ctx, key, num, url, tex))34 print(f"=== {code}: {len(results)} fichiers ; math={len(ctx.math)} tikz={len(ctx.tikz)} labels={len(ctx.labels)} "35 f"def={len(ctx.definitions)} form={len(ctx.formulas)} ex={len(ctx.examples)} exo={len(ctx.exercises)}")36 for r in results:37 print(f" {r.key:18s} {r.num:>2s} {r.title_text[:60]:60s} {r.counts}")38 warn = collections.Counter(w for w in ctx.warnings)39 print(" --- avertissements (dédupliqués) :", len(warn))40 for w, c in warn.most_common(60):41 print(f" {c:3d} × {w}")42 # renvois43 import re44 unresolved = set()45 for r in results:46 for m in re.finditer(r"@@REF\{([^}]*)\}@@", r.html):47 if m.group(1) not in ctx.labels:48 unresolved.add(m.group(1))49 print(" --- renvois non résolus :", sorted(unresolved))50 # math51 items = [{"mode": m, "tex": t} for m, t in ctx.math]52 p = subprocess.run(["node", os.path.join(os.path.dirname(__file__), "render_math.mjs")],53 input=json.dumps(items).encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)54 if p.returncode != 0:55 print(" node erreur:", p.stderr.decode()[:500])56 else:57 out = json.loads(p.stdout.decode())58 errs = [(items[i]["tex"], o["error"]) for i, o in enumerate(out) if o["error"]]59 print(f" --- KaTeX : {len(out)} formules, {len(errs)} erreurs")60 for tex, e in errs[:40]:61 print(" ERR:", e[:100], "||", tex[:120].replace("\n", " "))62 all_tikz.extend(ctx.tikz)63 # dump html pour inspection64 os.makedirs("/tmp/uqo-test", exist_ok=True)65 for r in results:66 open(f"/tmp/uqo-test/{code}-{r.key}.html", "w").write(r.html)6768if do_tikz:69 res = tikz.render_all(all_tikz, os.path.join(os.path.dirname(__file__), "..", "cache", "tikz"), workers=6,70 log_dir="/tmp/uqo-test/tikz-logs")71 bad = [r for r in res if not r["ok"]]72 print(f"=== TikZ : {len(res)} figures, {len(bad)} échecs")73 for r in bad[:20]:74 print(" ", r["hash"], r["err"][:300])75