tef-innu

Transducteur à états finis de l’innu
git clone git://git.asteride.xyz/tef-innu.git
Journaux | Fichiers | Références

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:
M.gitignore | 1+
MMakefile | 14+++++++++-----
Abin/statef.py | 250+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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)