# 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 `ﬁ`) : 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.
