commit 0c7e3c974c300d47c09228f65a2bde5f96208c89
parent 527b39c8d8d757838d779cfd3870dc5bf2381190
Auteur: Loïc Daignault-Pichette <loic@asteride.xyz>
Date: Tue, 25 Nov 2025 10:53:49 -0500
[chm] Créer une interface web
Le programme bin/statef.py génère pour chaque verbe une page statique
contenant les tableaux de conjugaison de formes supportées, ainsi qu’un
index de ces verbes.
Diffstat:
3 fichiers modifiés, 260 insertions(+), 5 suppressions(-)
diff --git a/.gitignore b/.gitignore
@@ -2,4 +2,5 @@
*.fst
*.att
*.ext
+web
verbes/rapport.txt
diff --git a/Makefile b/Makefile
@@ -8,15 +8,18 @@
.att.ext:
bin/extension.py "$<" | sort > "$@"
-tous: verbes/verbes.fst
+tous: verbes/verbes.fst web
rap: verbes/rapport.txt
-verbes/rapport.txt: verbes/verbes.ext verbes/verbes.ech verbes/verbes.pre
+web: verbes/verbes.ext
+ mkdir -p web
+ bin/statef.py verbes/verbes.ext web
+
+verbes/rapport.txt: verbes/verbes.ext verbes/verbes.ech
./bin/rapport.py verbes/verbes.ext \
verbes/verbes.ech \
- verbes/verbes.pre \
- | tee verbes/rapport.txt
+ | tee verbes/rapport.txt | less
verbes/verbes.err: verbes/verbes.fst verbes/verbes.ech
@@ -28,5 +31,6 @@ net:
-name '*.err' \
-o -name '*.att' \
-o -name '*.ext' \
- -o -name 'verbes/rapport.txt' | \
+ -o -name 'verbes/rapport.txt' \
+ -o -name 'web/*' | \
xargs rm
diff --git a/bin/statef.py b/bin/statef.py
@@ -0,0 +1,250 @@
+#!/usr/bin/env python3
+
+import sys
+import os
+
+# Lire un fichier
+def lire(fichier):
+
+ # Séparer le deux champs d’une ligne
+ def sep(ligne):
+ return ligne.split("\t")[0:2]
+
+ def convpers(pers):
+ dico = {('1', 'Pl', 'Ex', '>', '2', 'Pl') : "1pe->2p",
+ ('1', 'Pl', 'Ex', '>', '2', 'Sg') : "1pe->2s",
+ ('1', 'Pl', 'Ex', '>', '3', 'Pl', 'Ntr') : "1pe->3p",
+ ('1', 'Pl', 'Ex', '>', '3', 'Pl', 'Obv') : "1pe->4p",
+ ('1', 'Pl', 'Ex', '>', '3', 'Sg', 'Ntr') : "1pe->3s",
+ ('1', 'Pl', 'Ex', '>', '3', 'Sg', 'Obv') : "1pe->4s",
+ ('1', 'Pl', 'Ex') : "1pe",
+ ('1', 'Pl', 'In', '>', '3', 'Pl', 'Ntr') : "1pi->3p",
+ ('1', 'Pl', 'In', '>', '3', 'Pl', 'Obv') : "1pi->4p",
+ ('1', 'Pl', 'In', '>', '3', 'Sg', 'Ntr') : "1pi->3s",
+ ('1', 'Pl', 'In', '>', '3', 'Sg', 'Obv') : "1pi->4s",
+ ('1', 'Pl', 'In') : "1pi",
+ ('1', 'Sg', '>', '2', 'Pl') : "1s->2p",
+ ('1', 'Sg', '>', '2', 'Sg') : "1s->2s",
+ ('1', 'Sg', '>', '3', 'Pl', 'Ntr') : "1s->3p",
+ ('1', 'Sg', '>', '3', 'Pl', 'Obv') : "1s->4p",
+ ('1', 'Sg', '>', '3', 'Sg', 'Ntr') : "1s->3s",
+ ('1', 'Sg', '>', '3', 'Sg', 'Obv') : "1s->4s",
+ ('1', 'Sg') : "1s",
+ ('2', 'Pl', '>', '1', 'Pl', 'Ex') : "2p->1pe",
+ ('2', 'Pl', '>', '1', 'Sg') : "2p->1s",
+ ('2', 'Pl', '>', '3', 'Pl', 'Ntr') : "2p->3p",
+ ('2', 'Pl', '>', '3', 'Pl', 'Obv') : "2p->4p",
+ ('2', 'Pl', '>', '3', 'Sg', 'Ntr') : "2p->3s",
+ ('2', 'Pl', '>', '3', 'Sg', 'Obv') : "2p->4s",
+ ('2', 'Pl') : "2p",
+ ('2', 'Sg', '>', '1', 'Pl', 'Ex') : "2s->1pe",
+ ('2', 'Sg', '>', '1', 'Sg') : "2s->1s",
+ ('2', 'Sg', '>', '3', 'Pl', 'Ntr') : "2s->3p",
+ ('2', 'Sg', '>', '3', 'Pl', 'Obv') : "2s->4p",
+ ('2', 'Sg', '>', '3', 'Sg', 'Ntr') : "2s->3s",
+ ('2', 'Sg', '>', '3', 'Sg', 'Obv') : "2s->4s",
+ ('2', 'Sg') : "2s",
+ ('3', 'Pl', 'Ntr', '>', '1', 'Pl', 'Ex') : "3p->1pe",
+ ('3', 'Pl', 'Ntr', '>', '1', 'Pl', 'In') : "3p->1pi",
+ ('3', 'Pl', 'Ntr', '>', '1', 'Sg') : "3p->1s",
+ ('3', 'Pl', 'Ntr', '>', '2', 'Pl') : "3p->2p",
+ ('3', 'Pl', 'Ntr', '>', '2', 'Sg') : "3p->2s",
+ ('3', 'Pl', 'Ntr', '>', '3', 'Pl', 'Obv') : "3p->4p",
+ ('3', 'Pl', 'Ntr', '>', '3', 'Pl', 'Obv2') : "3p->5p",
+ ('3', 'Pl', 'Ntr', '>', '3', 'Sg', 'Obv') : "3p->4s",
+ ('3', 'Pl', 'Ntr', '>', '3', 'Sg', 'Obv2') : "3p->5s",
+ ('3', 'Pl', 'Ntr') : "3p",
+ ('3', 'Pl', 'Obv', '>', '1', 'Pl', 'Ex') : "4p->1pe",
+ ('3', 'Pl', 'Obv', '>', '1', 'Pl', 'In') : "4p->1pi",
+ ('3', 'Pl', 'Obv', '>', '1', 'Sg') : "4p->1s",
+ ('3', 'Pl', 'Obv', '>', '2', 'Pl') : "4p->2p",
+ ('3', 'Pl', 'Obv', '>', '2', 'Sg') : "4p->2s",
+ ('3', 'Pl', 'Obv', '>', '3', 'Pl', 'Ntr') : "4p->3p",
+ ('3', 'Pl', 'Obv', '>', '3', 'Pl', 'Obv2') : "4p->5p",
+ ('3', 'Pl', 'Obv', '>', '3', 'Pl', 'Obv3') : "4p->6p",
+ ('3', 'Pl', 'Obv', '>', '3', 'Sg', 'Ntr') : "4p->3s",
+ ('3', 'Pl', 'Obv', '>', '3', 'Sg', 'Obv2') : "4p->5s",
+ ('3', 'Pl', 'Obv', '>', '3', 'Sg', 'Obv3') : "4p->6s",
+ ('3', 'Pl', 'Obv') : "4p",
+ ('3', 'Pl', 'Obv2', '>', '3', 'Pl', 'Obv') : "4p->4p",
+ ('3', 'Pl', 'Obv2', '>', '3', 'Sg', 'Obv') : "4p->4s",
+ ('3', 'Sg', 'Ntr', '>', '1', 'Pl', 'Ex') : "3s->1pe",
+ ('3', 'Sg', 'Ntr', '>', '1', 'Pl', 'In') : "3s->1pi",
+ ('3', 'Sg', 'Ntr', '>', '1', 'Sg') : "3s->1s",
+ ('3', 'Sg', 'Ntr', '>', '2', 'Pl') : "3s->2p",
+ ('3', 'Sg', 'Ntr', '>', '2', 'Sg') : "3s->2s",
+ ('3', 'Sg', 'Ntr', '>', '3', 'Pl', 'Obv') : "3s->4p",
+ ('3', 'Sg', 'Ntr', '>', '3', 'Pl', 'Obv2') : "3s->5p",
+ ('3', 'Sg', 'Ntr', '>', '3', 'Sg', 'Obv') : "3s->4s",
+ ('3', 'Sg', 'Ntr', '>', '3', 'Sg', 'Obv2') : "3s->5s",
+ ('3', 'Sg', 'Ntr') : "3s",
+ ('3', 'Sg', 'Obv', '>', '1', 'Pl', 'Ex') : "4s->1pe",
+ ('3', 'Sg', 'Obv', '>', '1', 'Pl', 'In') : "4s->1pi",
+ ('3', 'Sg', 'Obv', '>', '1', 'Sg') : "4s->1s",
+ ('3', 'Sg', 'Obv', '>', '2', 'Pl') : "4s->2p",
+ ('3', 'Sg', 'Obv', '>', '2', 'Sg') : "4s->2s",
+ ('3', 'Sg', 'Obv', '>', '3', 'Pl', 'Ntr') : "4s->3p",
+ ('3', 'Sg', 'Obv', '>', '3', 'Pl', 'Obv2') : "4s->5p",
+ ('3', 'Sg', 'Obv', '>', '3', 'Pl', 'Obv3') : "4s->6p",
+ ('3', 'Sg', 'Obv', '>', '3', 'Sg', 'Ntr') : "4s->3s",
+ ('3', 'Sg', 'Obv', '>', '3', 'Sg', 'Obv2') : "4s->5s",
+ ('3', 'Sg', 'Obv', '>', '3', 'Sg', 'Obv3') : "4s->6s",
+ ('3', 'Sg', 'Obv') : "4s",
+ ('3', 'Sg', 'Obv2', '>', '3', 'Pl', 'Obv') : "5p->4p",
+ ('3', 'Sg', 'Obv2', '>', '3', 'Sg', 'Obv') : "5p->4s"}
+
+ return dico[pers]
+
+ # Analyser la description abstraite
+ def descabstr(desc):
+ resultat = [None, None, None, None, None]
+ liste = "+>".join(desc.split(">")).split("+")
+ resultat[0] = liste[0] # Forme de citation
+ liste = liste[1:]
+ resultat[1] = liste[0] # Classe de verbe
+ liste = liste[1:]
+ resultat[2] = liste[0] # Dialecte
+ liste = liste[1:]
+ if liste[0] == "Indép":
+ liste[0] = "Indépendant"
+ if liste[1] == "Ind":
+ liste[1] = "indicatif"
+ if liste[1] == "Indir":
+ liste[1] = "indirect"
+ if liste[1] == "Dub":
+ liste[1] = "dubitatif"
+ if liste[2] == "Prés":
+ liste[2] = "présent"
+ if liste[2] == "Pas":
+ liste[2] = "passé"
+ resultat[3] = " ".join(liste[:3]) # Tiroir
+ resultat[4] = convpers(tuple(liste[3:]))
+ return resultat
+
+ info = {}
+
+ for ligne in fichier:
+ champs = sep(ligne.strip())
+ desc = descabstr(champs[0])
+ if desc[1] not in info:
+ info[desc[1]] = {}
+ if desc[0] not in info[desc[1]]:
+ info[desc[1]][desc[0]] = {}
+ if desc[3] not in info[desc[1]][desc[0]]:
+ info[desc[1]][desc[0]][desc[3]] = {}
+ if desc[4] not in info[desc[1]][desc[0]][desc[3]]:
+ info[desc[1]][desc[0]][desc[3]][desc[4]] = ["-", "-"]
+ if desc[2] == "Est":
+ i = 0
+ else:
+ i = 1
+ info[desc[1]][desc[0]][desc[3]][desc[4]][i] = champs[1]
+
+ return info
+
+def page_verbe(info, nom, classe):
+
+ ordre = {
+ "VII": ["3s", "4s", "3p", "4p"],
+ "VAI": ["1s", "2s", "3s", "4s", "1pe", "1pi", "2p", "3p", "4p"],
+ "VTI": ["1s", "2s", "3s", "4s", "1pe", "1pi", "2p", "3p", "4p"],
+ "VTA": ["1s->2s", "1s->3s", "1s->4s", "1s->2p", "1s->3p", "1s->4p",
+ "2s->1s", "2s->3s", "2s->4s", "2s->1pe", "2s->3p", "2s->4p",
+ "3s->1s", "3s->2s", "3s->4s", "3s->5s",
+ "3s->1pe", "3s->1pi", "3s->2p", "3s->4p", "3s->5p",
+ "1pe->2s", "1pe->3s", "1pe->4s", "1pe->3p",
+ "1pe->4p", "1pe->2p",
+ "1pi->3s", "1pi->4s", "1pi->3p", "1pi->4p",
+ "2p->1s", "2p->3s", "2p->4s", "2p->1pe", "2p->3p", "2p->4p",
+ "3p->1s", "3p->2s", "3p->4s", "3p->5s",
+ "3p->1pe", "3p->1pi", "3p->2p", "3p->4p", "3p->5p",
+ "4p->1s", "4p->2s", "4p->3s", "4p->4s", "4p->5s", "4p->6s",
+ "4p->1pe", "4p->1pi", "4p->2p", "4p->3p",
+ "4p->4p", "4p->5p", "4p->6p",
+ "4s->1s", "4s->2s", "4s->3s", "4s->5s", "4s->6s",
+ "4s->1pe", "4s->1pi", "4s->2p", "4s->3p", "4s->5p", "4s->6p",
+ "5p->4s", "5p->4p"]}
+
+ def tableau(info, titre, ordre):
+ texte = "<table>\n"
+ texte = texte + f"<caption><b>{titre}</b></caption>\n"
+ for pers in ordre:
+ formes = ["-", "-"]
+ if pers in info:
+ formes[0] = info[pers][0]
+ formes[1] = info[pers][1]
+ texte = texte + "<tr>\n"
+ texte = texte + f"<td>{pers}</td><td>"
+ if formes[0] == formes[1]:
+ texte = texte + f"{formes[0]}"
+ else:
+ texte = texte + f"{formes[0] + "/" + formes[1]}"
+ texte = texte + "</td></tr>\n"
+ texte = texte + "</table>\n"
+ return texte
+
+ texte = "<!DOCTYPE html>\n" +\
+ "<html>\n" +\
+ "<head>\n" +\
+ f"<title>{nom}</title>\n" +\
+ "<meta charset=\"UTF-8\">\n" +\
+ "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\n" +\
+ "<style>\n" +\
+ "body { margin: auto; text-align: center; }\n" +\
+ ".horiz { display: flex; justify-content: space-around; " +\
+ "flex-flow: row wrap; }\n" +\
+ "ul { list-style-type:none; padding: 0; margin: 0; }\n" +\
+ "table { padding: 1rem; }\n" +\
+ "</style>\n" +\
+ "</head>\n" +\
+ "<body>\n"
+ texte = texte + f"<h1>{nom}</h1>\n"
+ texte = texte + "<p><a href=\".\">Liste de verbes</a></p>\n" +\
+ "<div class=\"horiz\">"
+ for t in info:
+ texte = texte + "<div>" + tableau(info[t], t, ordre[classe]) + "</div>"
+ texte = texte + "</div></body>\n</html>\n"
+
+ return texte
+
+def pages_verbe(info, dst):
+ for classe in info:
+ for verbe in info[classe]:
+ with open(os.path.join(dst, classe + "_" + verbe + ".html"), "w") as f:
+ f.write(page_verbe(info[classe][verbe], verbe, classe))
+
+def index(info, dst):
+ texte = "<!DOCTYPE html>\n" +\
+ "<html>\n" +\
+ "<head>\n" +\
+ "<title>Verbes innus</title>\n" +\
+ "<meta charset=\"UTF-8\">\n" +\
+ "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\n" +\
+ "<style>\n" +\
+ "body { max-width: 760px; margin: auto; text-align: center; }\n" +\
+ ".horiz { display: flex; justify-content: space-around; " +\
+ "flex-flow: row wrap;}\n" +\
+ "ul { list-style-type:none; padding: 0; margin: 0; }\n" +\
+ "table { padding: 1rem; }\n" +\
+ "</style>\n" +\
+ "</head>\n" +\
+ "<body>\n" +\
+ "<h1>Verbes innus</h1>\n" +\
+ "<div class=\"horiz\">\n"
+ for classe in info:
+ texte = texte + f"<div>\n<h2>{classe}</h2>\n<ul>\n"
+ for verbe in info[classe]:
+ texte = texte + f"<li><a href=\"{classe + "_" + verbe + ".html"}\">{verbe}</a></li>\n"
+ texte = texte + "</ul>\n</div>\n"
+ texte = texte + "</div></body>\n</html>\n"
+ with open(os.path.join(dst, "index.html"), "w") as f:
+ f.write(texte)
+
+if __name__ == "__main__":
+ dst = sys.argv[2]
+ with open(sys.argv[1], "r") as f:
+ info = lire(f)
+ print(info["VII"]["nipiu"])
+ print(info["VII"]["nipiun"])
+ index(info, dst)
+ pages_verbe(info, dst)