import streamlit as st import requests import re from config import GITEA_TOKEN from utils.gitea import charger_arborescence_fiches from utils.tickets_fiche import gerer_tickets_fiche import markdown from bs4 import BeautifulSoup from latex2mathml.converter import convert as latex_to_mathml from utils.fiche_utils import load_seuils, render_fiche_markdown from utils.fiche_dynamic import build_dynamic_sections, build_ivc_sections, build_ihh_sections, build_isg_sections, build_assemblage_sections import os from utils.gitea import recuperer_date_dernier_commit from datetime import datetime, timezone import yaml from config import GITEA_URL, ORGANISATION, DEPOT_FICHES, ENV def remplacer_latex_par_mathml(markdown_text): def remplacer_bloc_display(match): formule_latex = match.group(1).strip() try: mathml = latex_to_mathml(formule_latex, display='block') return f'
{mathml}
' except Exception as e: return f"
Erreur LaTeX block: {e}
" def remplacer_bloc_inline(match): formule_latex = match.group(1).strip() try: mathml = latex_to_mathml(formule_latex, display='inline') return f'{mathml}' except Exception as e: return f"Erreur LaTeX inline: {e}" # Important : d'abord les $$...$$, ensuite les $...$ markdown_text = re.sub(r"\$\$(.*?)\$\$", remplacer_bloc_display, markdown_text, flags=re.DOTALL) markdown_text = re.sub(r"(? str: # Extraire bloc YAML d'en-tête front_match = re.match(r"(?s)^---\n(.*?)\n---\n", md_source) context = {} if front_match: context = yaml.safe_load(front_match.group(1)) #md_source = md_source[front_match.end():] # retirer le front-matter du corps # Traitement conditionnel selon type type_fiche = context.get("type_fiche") if type_fiche == "indice": if context.get("indice_court") == "ICS": md_source = build_dynamic_sections(md_source) elif context.get("indice_court") == "IVC": md_source = build_ivc_sections(md_source) elif context.get("indice_court") == "IHH": md_source = build_ihh_sections(md_source) elif context.get("indice_court") == "ISG": md_source = build_isg_sections(md_source) elif type_fiche == "assemblage" or type_fiche == "fabrication": md_source = build_assemblage_sections(md_source) # Rendu markdown principal contenu_md = render_fiche_markdown(md_source, seuils) #st.code(md_source) #md_pairs = build_dynamic_sections(md_source) #contenu_md = render_fiche_markdown(md_pairs, seuils) # Sauvegarde .md md_path = os.path.join("Fiches", dossier, nom_fichier) os.makedirs(os.path.dirname(md_path), exist_ok=True) with open(md_path, "w", encoding="utf-8") as f: f.write(contenu_md) # Traitement en sections lignes = contenu_md.split('\n') sections_n1 = [] section_n1_actuelle = {"titre": None, "intro": [], "sections_n2": {}} dans_section_n1 = False section_n2_actuelle = None for ligne in lignes: if re.match(r'^#[^#]', ligne): if section_n1_actuelle["titre"] or section_n1_actuelle["intro"] or section_n1_actuelle["sections_n2"]: sections_n1.append(section_n1_actuelle) section_n1_actuelle = { "titre": ligne.strip('# ').strip(), "intro": [], "sections_n2": {} } section_n2_actuelle = None dans_section_n1 = True elif re.match(r'^##[^#]', ligne): section_n2_actuelle = ligne.strip('# ').strip() section_n1_actuelle["sections_n2"][section_n2_actuelle] = [f"## {section_n2_actuelle}"] elif section_n2_actuelle: section_n1_actuelle["sections_n2"][section_n2_actuelle].append(ligne) elif dans_section_n1: section_n1_actuelle["intro"].append(ligne) if section_n1_actuelle["titre"] or section_n1_actuelle["intro"] or section_n1_actuelle["sections_n2"]: sections_n1.append(section_n1_actuelle) # Génération HTML bloc_titre = sections_n1[0]["titre"] if sections_n1 and sections_n1[0]["titre"] else "fiche" titre_id = re.sub(r'\W+', '-', bloc_titre.lower()).strip('-') html_output = [f'
', f'

{sections_n1[0]["titre"]}

'] for bloc in sections_n1: if bloc["titre"] and bloc["titre"] != sections_n1[0]["titre"]: html_output.append(f"

{bloc['titre']}

") if bloc["intro"]: intro_md = remplacer_latex_par_mathml("\n".join(bloc["intro"])) html_intro = markdown_to_html_rgaa(intro_md, caption_text=None) html_output.append(html_intro) for sous_titre, contenu in bloc["sections_n2"].items(): contenu_md = remplacer_latex_par_mathml("\n".join(contenu)) contenu_html = markdown_to_html_rgaa(contenu_md, caption_text=sous_titre) html_output.append(f"
{sous_titre}{contenu_html}
") html_output.append("
") html_dir = os.path.join("HTML", dossier) os.makedirs(html_dir, exist_ok=True) html_path = os.path.join(html_dir, os.path.splitext(nom_fichier)[0] + ".html") with open(html_path, "w", encoding="utf-8") as f: f.write("\n".join(html_output)) return html_path def afficher_fiches(): if "fiches_arbo" not in st.session_state: st.session_state["fiches_arbo"] = charger_arborescence_fiches() arbo = st.session_state.get("fiches_arbo", {}) if not arbo: st.warning("Aucune fiche disponible pour le moment.") return dossiers = sorted(arbo.keys(), key=lambda x: x.lower()) dossier_choisi = st.selectbox("Choisissez un dossier", ["-- Sélectionner un dossier --"] + dossiers) if dossier_choisi and dossier_choisi != "-- Sélectionner un dossier --": fiches = arbo.get(dossier_choisi, []) noms_fiches = [f['nom'] for f in fiches] fiche_choisie = st.selectbox("Choisissez une fiche", ["-- Sélectionner une fiche --"] + noms_fiches) if fiche_choisie and fiche_choisie != "-- Sélectionner une fiche --": fiche_info = next((f for f in fiches if f["nom"] == fiche_choisie), None) if fiche_info: try: headers = {"Authorization": f"token {GITEA_TOKEN}"} reponse_fiche = requests.get(fiche_info["download_url"], headers=headers) reponse_fiche.raise_for_status() md_source = reponse_fiche.text if "seuils" not in st.session_state: SEUILS = load_seuils("assets/config.yaml") st.session_state["seuils"] = SEUILS elif "seuils" in st.session_state: SEUILS = st.session_state["seuils"] html_path = os.path.join("HTML", dossier_choisi, os.path.splitext(fiche_choisie)[0] + ".html") path_relative = f"Documents/{dossier_choisi}/{fiche_choisie}" commits_url = f"{GITEA_URL}/repos/{ORGANISATION}/{DEPOT_FICHES}/commits?path={path_relative}&sha={ENV}" regenerate = True if os.path.exists(html_path): remote_last_modified = recuperer_date_dernier_commit(commits_url) local_last_modified = datetime.fromtimestamp(os.path.getmtime(html_path), tz=timezone.utc) regenerate = not remote_last_modified or remote_last_modified > local_last_modified if regenerate: st.info("DEBUG : Régénération de la fiche") html_path = creer_fiche(md_source, dossier_choisi, fiche_choisie, SEUILS) else: st.info("DEBUG : Pas de régénération") with open(html_path, "r", encoding="utf-8") as f: st.markdown(f.read(), unsafe_allow_html=True) gerer_tickets_fiche(fiche_choisie) except Exception as e: st.error(f"Erreur lors du chargement de la fiche : {e}")