""" Module de génération des fiches pour l'application. Fonctions principales : 1. `remplacer_latex_par_mathml` 2. `markdown_to_html_rgaa` 3. `rendu_html` 4. `generer_fiche` Toutes ces fonctions gèrent la conversion et le rendu de contenu Markdown vers du HTML structuré avec des mathématiques, respectant les règles RGAA. """ import re import os import yaml import markdown from bs4 import BeautifulSoup from latex2mathml.converter import convert as latex_to_mathml import pypandoc import streamlit as st from app.fiches.utils import ( build_dynamic_sections, build_ivc_sections, build_ihh_sections, build_isg_sections, build_production_sections, build_minerai_sections, render_fiche_markdown ) # === Fonctions de transformation === def remplacer_latex_par_mathml(markdown_text: str) -> str: """ Remplace les formules LaTeX par des blocs MathML. Args: markdown_text (str): Texte Markdown contenant du LaTeX. Returns: str: Le même texte avec les formules LaTeX converties en MathML. """ def remplacer_bloc_display(match): formule_latex = match.group(1).strip() try: mathml = latex_to_mathml(formule_latex, display='block') 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}"
markdown_text = re.sub(r"\$\$(.*?)\$\$", remplacer_bloc_display, markdown_text, flags=re.DOTALL)
markdown_text = re.sub(r"(? str:
"""
Convertit un texte Markdown en HTML structuré accessible.
Args:
markdown_text (str): Texte Markdown à convertir.
caption_text (str, optional): Titre du tableau si applicable.
Returns:
str: Le HTML structuré avec des attributs de contraintes ARIA.
"""
html = markdown.markdown(markdown_text, extensions=['tables'])
soup = BeautifulSoup(html, "html.parser")
for i, table in enumerate(soup.find_all("table"), start=1):
table["role"] = "table"
table["summary"] = caption_text
if caption_text:
caption = soup.new_tag("caption")
caption.string = caption_text
table.insert(len(table.contents), caption)
for th in table.find_all("th"):
th["scope"] = "col"
return str(soup)
def rendu_html(contenu_md: str) -> list[str]:
"""
Rend le contenu Markdown en HTML avec une structure spécifique.
Args:
contenu_md (str): Texte Markdown à formater.
Returns:
list[str]: Liste d'étapes de construction du HTML final.
"""
lignes = contenu_md.split('\n')
sections_n1 = []
section_n1_actuelle = {"titre": None, "intro": [], "sections_n2": {}}
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
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)
else:
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)
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'