92 lines
3.1 KiB
Python
92 lines
3.1 KiB
Python
"""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()
|