Files
veye-lalwa/pipeline/parseurs/analyses.py
T

92 lines
3.1 KiB
Python
Raw Normal View History

"""Lecture des analyses transversales (`research/lois-2026_insight.md`).
Sept analyses, chacune au format ::
## Insight 3 — Le 1er septembre 2026 : « big bang » silencieux …
**Dérivé de :** dim08, dim09, dim02, dim12, dim03.
<corps>
**Implications :** …
**Confiance : high.**
Elles alimentent l'encart « point de veille » du tableau de bord. Elles ne
portent aucune source primaire propre — la table de correspondance de la
bibliographie le dit — et ne sont donc jamais présentées comme des faits
sourcés, mais comme des lectures d'ensemble.
"""
from __future__ import annotations
import re
from pipeline.journal import logger
from pipeline.modeles import Insight
from pipeline.parseurs.markdown import decouper_sections, nettoyer
log = logger("parseur.analyses")
_TITRE = re.compile(r"^Insight\s+(\d+)\s*[—–-]\s*(.+)$", re.IGNORECASE)
_DERIVE = re.compile(r"\*\*Dérivé de\s*:\*\*\s*(.+)", re.IGNORECASE)
_IMPLICATIONS = re.compile(r"\*\*Implications\s*:\*\*\s*(.+)", re.IGNORECASE)
_CONFIANCE = re.compile(r"\*\*Confiance\s*:\s*([a-zé-]+)", re.IGNORECASE)
_DIMENSION = re.compile(r"\b(dim\d{2}|phase\s?5)\b", re.IGNORECASE)
def parser(markdown: str) -> list[Insight]:
"""Extrait les analyses transversales du fichier d'insights."""
analyses: list[Insight] = []
for section in decouper_sections(markdown, niveau_max=2):
entete = _TITRE.match(section.titre.strip())
if not entete:
continue
corps_brut = section.corps
implications = None
if trouve := _IMPLICATIONS.search(corps_brut):
implications = nettoyer(trouve.group(1))
confiance = "medium"
if trouve := _CONFIANCE.search(corps_brut):
brut = trouve.group(1).lower()
confiance = {"high": "high", "élevée": "high", "medium": "medium", "low": "low"}.get(
brut, "medium"
)
derive_de: list[str] = []
if trouve := _DERIVE.search(corps_brut):
derive_de = [
d.lower().replace(" ", "") for d in _DIMENSION.findall(trouve.group(1))
]
corps = _corps_utile(corps_brut)
analyses.append(
Insight(
numero=int(entete.group(1)),
titre=nettoyer(entete.group(2)),
corps=corps,
implications=implications,
confiance=confiance,
derive_de=derive_de,
fichier_origine="research/lois-2026_insight.md",
)
)
log.info("analyses transversales lues", analyses=len(analyses))
return analyses
def _corps_utile(corps: str) -> str:
"""Corps de l'analyse, sans les lignes de métadonnées."""
lignes: list[str] = []
for ligne in corps.splitlines():
depouillee = ligne.strip()
if not depouillee:
continue
if _DERIVE.match(depouillee) or _IMPLICATIONS.match(depouillee):
continue
if _CONFIANCE.match(depouillee):
continue
lignes.append(nettoyer(depouillee))
return " ".join(lignes).strip()