Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,35 @@ public void Fallacies_Front_Conversions_Are_Ordered_MostSpecificFirst_To_Avoid_P
"Sous-Famille must be substituted before Famille to prevent partial overlap");
}


[Theory]
[InlineData("en")]
[InlineData("ru")]
[InlineData("pt")]
public void Memo_Back_Template_Subtitle_Is_Translated_And_Selector_Stays_FR(string destLang)
{
// Regression test for #358 / #443 — two bugs caught by ai-01 validation:
// Bug 1: apostrophe U+2019 in source vs U+0027 in template -> subtitle stays FR.
// Bug 2: converting text_fr->text_en in ifCond breaks family grouping (6/8 families vanish).
var original = ReadTemplate("Cards/Memo/Argumentum_Memo_Back_fr.json");
var loc = GetFallaciesLocalization();

// Apply FrontFieldConversions (Famille->Family etc.)
var translated = ApplyFrontSubstitution(loc, original, destLang);

// Apply StaticConversions (subtitle translation)
translated = loc.DoStaticConversions(translated, destLang);

// (a) Subtitle must be translated — no more FR "L'art de jamais avoir tort"
translated.Should().NotContain("L'art de jamais avoir tort",
$"{destLang} Memo Back must have a translated subtitle, not the FR original (#358)");

// (b) The ifCond selector must stay FR-invariant — text_fr must remain
// so that Famille(FR)==text_fr(FR) still groups all 8 families correctly.
translated.Should().Contain("text_fr ",
$"{destLang} Memo Back ifCond must keep text_fr (FR-invariant selector for family grouping)");
}

[Fact]
public void Rules_Localization_Is_Configured_For_All_Target_Languages()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,20 @@ public class AssetConverterConfig
BackFieldConversions = new List<(string sourceFieldName, List<(string Language, string destFieldName)> fieldConversions)>(new []{
("tagline_fr", new List<(string Language, string destFieldName)>(new []{("en", "tagline_en"), ("ru", "tagline_ru"), ("pt", "tagline_pt"), ("es", "tagline_es"), ("ar", "tagline_ar"), ("fa", "tagline_fa"), ("zh", "tagline_zh") }) ),
}),
// StaticConversions: handle hardcoded FR text in Memo templates that FrontFieldConversions
// cannot reach (text not wrapped in {{}}). Safe for Fallacies templates (no-op if absent).
StaticConversions = new List<(string sourceText, List<(string Language, string destText)> textConversions)>(new[]{
// Memo Back/Face subtitle: hardcoded FR subtitle, not a {{variable}} (#358).
("L'art de jamais avoir tort", new List<(string Language, string destText)>(new []{
("en", "The art of never being wrong"),
("ru", "Искусство никогда не ошибаться"),
("pt", "A arte de nunca estar errado"),
("es", "El arte de nunca estar equivocado"),
("ar", "فن أن لا تكون على خطأ"),
("fa", "هنر اشتباه نکردن"),
("zh", "永远不会错的艺术")
}) ),
}),
},
new CardSetLocalization()
{
Expand Down
4 changes: 2 additions & 2 deletions docs/publication/validation-guide.fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ La restructuration `Cards/Rules/Argumentum Rules - Cards.csv` **24 → 15 cartes
Le Mémo Face ne rendait que FR 7/7, EN 2/7 (cognats), PT/RU 0/7. **Cause = sélecteur `{{#ifCond Famille "==" text_fr}}` non localisé symétriquement** (bug de config, pas de traduction manquante). **Fix = 1 espace `text_fr }}`** → sélecteur FR‑vs‑FR language‑invariant. **Régén Debug : 7/7 familles dans les 4 langues** (EN 2→7, PT 0→7, RU 0→7), texte localisé. Réserve mineure RU (7ᵉ famille Обструкция en pied de carte, cyrillique verbeux — non bloquant, surveiller à l'impression). Dossier + 5 PNG AFTER + table de correspondance des 7 en‑têtes par langue (pour vérifier RU/PT sans les lire) : `docs/investigations/2026-06-04-memo-435-i18n-gap/`.
> **Note §2bis.** Le Mémo était **absent** du harnais #412 (qui couvre Fallacies‑Web / Rules / Scenarii / Virtues). Après merge #439 + régén, le Mémo rejoint la grille de validation.

### ⚠️ Question éditoriale ouverte (décision jsboige) — Mémo **Back**
Le Back rend désormais la taxonomie complète dans les 4 langues, MAIS il **affiche les clés de taxonomie** (`{{Famille}}`/`{{Sous-Famille}}`/`{{Soussousfamille}}`, aucun `desc_*`) → **en français dans les 4 langues** (pré‑existant, hors fix sélecteur, pas une régression). À trancher : référence FR assumée, ou localiser les clés (tâche contenu/config distincte) ?
### ✅ Mémo **Back** — localisé (décision jsboige 2026‑06‑05, PR #443)
Décision : **localiser** EN/RU/PT (pas FR‑assumé). Le sous‑titre figé « L'art de jamais avoir tort » est traduit via `StaticConversions` (`LocalizationConfig`), les labels `{{Famille}}`/`{{SousFamille}}`/`{{Soussousfamille}}` se localisent via les `FrontFieldConversions` existantes. Le sélecteur `ifCond` reste FR‑invariant (garantit le groupement 8/8 familles). PR #443.

### Séquence pour passer au vert (jeudi, au sign‑off #140)
1. Merge **#438 puis #439** (auth jsboige si ai‑01 denied).
Expand Down
Loading