# Méthodologie — hyph-malagasy Ce document consigne les décisions linguistiques et techniques prises pendant le développement, ainsi que les résultats d'exécutions réelles (pdfTeX/LuaTeX, TeX Live 2023) qui les ont validées ou invalidées. ## 1. Base phonologique Les consonnes prénasalisées (`mp`, `mb`, `nk`, `ng`, `nd`, `ndr`, `nj`, `nts`) et les digraphes/trigraphes (`ts`, `tr`, `dr`) sont traités comme des unités phonémiques uniques en attaque de syllabe, jamais scindées par la césure. Base : Dahl (1952), O'Neill (2015), Rakotofiringa (1982). Le cluster `ntsar` mentionné à l'origine du projet n'a pas été confirmé comme unité autonome dans la littérature consultée — traité comme `n` + `ts` (déjà couvert par `UNBREAKABLE_CLUSTERS`). **À valider avec un locuteur natif ou l'Academia Malgache avant de le considérer réglé.** ## 2. Contraintes TeX confirmées par exécution réelle - **`\patterns{}` n'est chargeable qu'en mode INITEX** sous pdfTeX (`tex -ini`). Sous LuaTeX, cette limitation n'existe pas : les motifs peuvent être chargés dynamiquement via `lang.new()` / `objet:patterns()` (API objet, pas `lang.patterns(id, ...)` avec un entier brut — erreur rencontrée : *"bad argument #1 to 'patterns' (luatex.lang expected, got number)"*). - **`plain.tex` (TeX Live 2023) précharge l'anglais sur `\language0`** (181 opérations de trie, `\lefthyphenmin=2`, `\righthyphenmin=3`) et `\patterns{}` **ajoute** à la trie existante au lieu de la remplacer. Le malgache doit être isolé sur son propre langage (`\newlanguage`/`lang.new()`), jamais sur `\language0`. - **`\lefthyphenmin`/`\righthyphenmin` sont des paramètres globaux**, pas stockés par langue dans le moteur TeX de base — à réappliquer explicitement à chaque changement de langue. C'est exactement ce que fait le mécanisme réel `\addlanguage{french}{loadhyph-fr.tex}{}{2}{2}` de `hyph-utf8` (les deux derniers chiffres sont lefthyphenmin/ righthyphenmin, réappliqués à chaque `\uselanguage`). - **Aucun numéro de langage fixe n'est à coder en dur.** L'intégration `hyph-utf8` enregistre les langues par nom (`\uselanguage{malagasy}`) via une déclaration `AddHyphen` dans le `.tlpsrc` du package ; TeX Live assigne le numéro dynamiquement à la génération du format. Notre usage de `\newlanguage` en test reproduit fidèlement ce principe. - **Piège réel** : des caractères accentués dans un commentaire Lua (`-- ... é/è ...`) à l'intérieur d'un `\directlua{...}` cassent le comptage de groupe de TeX et produisent des erreurs `Missing $ inserted` difficiles à diagnostiquer. Éviter les accents dans ces blocs. - **Ligatures typographiques** (`fi` → glyphe unique `fi`) : lors de l'extraction de texte depuis un nœud glyphe LuaTeX, il faut décomposer via le champ `.components`, sinon on récupère le code interne de la police plutôt que les caractères d'origine. - **Piège réel confirmé, plus grave que les accents** : tout commentaire Lua (`--`) à l'intérieur d'un bloc `\directlua{...}` corrompt silencieusement l'exécution du chunk, **sans aucune erreur visible** ni dans le terminal ni dans le `.log`. Selon la position du commentaire, l'effet varie : un commentaire placé avant le chargement des motifs fait échouer le chargement *et* le callback ; placé après, seul le code suivant (ex. l'enregistrement du callback) est perdu. La cause exacte n'a pas été élucidée avec certitude dans le temps disponible (piste la plus probable : interaction de catcode/expansion lors de la lecture de l'argument de `\directlua`, qui n'est pas un simple passage verbatim). **Règle pratique retenue : ne jamais mettre de commentaire `--` à l'intérieur d'un bloc `\directlua` ; documenter en TeX (`%`) juste avant/après le bloc à la place.** ## 3. Fiabilité de l'extraction (`\showhyphens` vs callback LuaTeX) Deux méthodes ont été testées réellement : | Méthode | Couverture | Limite | |---|---|---| | `\showhyphens{mot}` (pdfTeX) | Mot isolé | Simple et fiable, mais ne teste pas le comportement en contexte de paragraphe | | Messages `Overfull/Underfull \hbox` (pdfTeX, `\tracingparagraphs`) | Lignes de paragraphe **en dépassement seulement** | **Angle mort confirmé** : une ligne dont la badness est finie (`Loose \hbox`) n'a pas son contenu imprimé, même avec `\hbadness=0` | | Callback `post_linebreak_filter` (LuaTeX) | **Toutes les lignes**, sans exception | Nécessite LuaTeX ; légèrement plus complexe à mettre en place | **Conclusion retenue** : utiliser le callback LuaTeX pour toute validation en contexte de paragraphe (`test/sentences_lua.tex`) ; réserver `\showhyphens` aux tests mot-par-mot rapides (`test/words.tex`). ## 4. Limite majeure -- contamination croisée (RÉSOLUE le 2026-09-02) Le `PatternExtractor` générait initialement **toutes** les sous-chaînes de longueur 2 à 6 de chaque mot annoté, sans élagage (pas de logique patgen). Sur le corpus de 33 mots, cela produisait 623 motifs bruts. **Test réel ayant révélé le problème** : en appliquant ces 623 motifs à une phrase de test, deux mots **absents du corpus** (`momba`, `malagasy`) se sont retrouvés hyphénés à tort (`mo-mba`, `ma-la-ga-sy`), par coïncidence de sous-chaînes courtes provenant d'autres mots du corpus (ex. `la` extrait de `vola`). **Correction appliquée** : `PatternExtractor` n'émet désormais, par défaut (`whole_word_only=True`), qu'**un seul motif par mot**, ancré aux deux bouts par le caractère de frontière (`.mot.`). Un tel motif ne peut matcher que ce mot exact dans son intégralité — aucune contamination croisée n'est structurellement possible entre mots. **Contrepartie assumée** : généralisation nulle à des mots absents du corpus (ils restent simplement non hyphénés — comportement de repli sûr, pas une erreur). Le corpus passe de 623 motifs bruts à **29** motifs mot-entier. **Revalidation réelle après correctif** : - Les 10 mots-témoins du corpus se coupent toujours identiquement (`ma-ha-fi-na-ri-tra`, `tra-ndra-ka`, etc.) — aucune régression. - `momba` et `malagasy` restent intacts, en isolation **et** en contexte de paragraphe (`test/sentences_lua.tex`). - La sortie en contexte de paragraphe est identique, motif pour motif, à `test/expected/sentences.txt`. **Ancien comportement (`whole_word_only=False`)** conservé dans le code, désactivé par défaut, documenté comme dangereux en l'état. À ne réactiver qu'après implémentation d'un vrai algorithme d'élagage (patgen ou équivalent) sur un corpus nettement plus large avec des exemples positifs ET négatifs explicites. ## 5. État des fichiers de référence (`test/expected/`) - `words.txt` et `sentences.txt` sont générés à partir d'exécutions réelles (pas inventés), mais **non relus par un locuteur natif** — à valider avant de les considérer comme vérité de référence. - `\lefthyphenmin=2`/`\righthyphenmin=2` sont des valeurs de test, pas une décision linguistique validée pour le malgache.