DOCS/tools/status_split.py
2026-09-03 14:00:51 +02:00

109 lines
3.5 KiB
Python

"""Decoupe unique : STATUS.md -> index court + DOCS/status/<chantier>.md.
Les sections lourdes partent dans leur propre fichier. STATUS.md garde le titre
de chaque section, son chapeau verbatim, et un lien vers le detail.
Les liens relatifs des sections deplacees sont reecrits en ../
"""
import io
import os
import re
DOCS = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SRC = os.path.join(DOCS, "STATUS.md")
OUT_DIR = os.path.join(DOCS, "status")
# section (prefixe du titre) -> nom de fichier
EXTRACT = {
"1ter.": "postgres-v3.md",
"1quater.": "guide-ia-v1.md",
"1sexies.": "ordre-execution-v1.md",
"1quinquies.": "bascule-prod.md",
"2bis.": "parite-manager-visitapp.md",
"3.": "securite-dette-technique.md",
"5.": "roadmap-canaux.md",
"5bis.": "rayban-meta.md",
}
if os.path.isdir(OUT_DIR):
raise SystemExit(
"DOCS/status/ existe deja : le decoupage a deja eu lieu. "
"STATUS.md est maintenant un index maintenu a la main — relancer ce script "
"ecraserait les chapeaux rediges. Supprimer DOCS/status/ pour forcer."
)
raw = io.open(SRC, encoding="utf-8", newline="").read()
eol = "\r\n" if "\r\n" in raw else "\n"
lines = raw.replace("\r\n", "\n").split("\n")
starts = [i for i, l in enumerate(lines) if l.startswith("## ")]
bounds = list(zip(starts, starts[1:] + [len(lines)]))
os.makedirs(OUT_DIR, exist_ok=True)
def number_of(title):
return title[3:].split(" ", 1)[0]
def reroot_links(text):
"""Le fichier descend d'un niveau : tout lien relatif prend un ../ de plus."""
return re.sub(r"\]\((?!https?:|#|/)([^)]+)\)", r"](../\1)", text)
def lead_block(body):
"""Chapeau : le blockquote d'ouverture, sinon les 2 premieres lignes utiles."""
i = 0
while i < len(body) and not body[i].strip():
i += 1
if i < len(body) and body[i].startswith(">"):
j = i
while j < len(body) and (body[j].startswith(">") or not body[j].strip()):
if not body[j].strip() and j + 1 < len(body) and not body[j + 1].startswith(">"):
break
j += 1
return body[i:j]
kept = []
for line in body[i:]:
if not line.strip():
if kept:
break
continue
if line.startswith("#") or line.startswith("|") or line.startswith("- ["):
break
kept.append(line)
if len(kept) == 2:
break
return kept
out = lines[: starts[0]]
moved = []
for a, b in bounds:
title = lines[a]
num = number_of(title)
body = lines[a + 1 : b]
target = EXTRACT.get(num)
if not target:
out += [title] + body
continue
heading = title[3:]
io.open(os.path.join(OUT_DIR, target), "w", encoding="utf-8", newline=eol).write(
"# " + heading + "\n\n"
"> ← Section **§" + num.rstrip(".") + "** du tableau de bord : [STATUS.md](../STATUS.md)\n\n"
+ reroot_links("\n".join(body).strip())
+ "\n"
)
lead = lead_block(body)
stub = [title, ""] + (lead + [""] if lead else [])
stub += ["→ **Détail complet : [status/" + target + "](status/" + target + ")**", "", "---", ""]
out += stub
moved.append((num, target, sum(len(l) + 1 for l in body)))
io.open(SRC, "w", encoding="utf-8", newline=eol).write("\n".join(out).rstrip("\n") + "\n")
print("sections deplacees :")
for num, target, size in moved:
print(" §%-12s %-34s %6d o -> status/%s" % (num.rstrip("."), "", size, target))
print("STATUS.md : %d o" % os.path.getsize(SRC))