1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2021 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees\Module; 21 22use Fisharebest\Localization\Locale\LocaleFr; 23use Fisharebest\Localization\Locale\LocaleInterface; 24use Fisharebest\Webtrees\Relationship; 25 26/** 27 * Class LanguageFrench. 28 */ 29class LanguageFrench extends AbstractModule implements ModuleLanguageInterface 30{ 31 use ModuleLanguageTrait; 32 33 protected const SYMMETRIC_COUSINS = [ 34 1 => [ 35 'F' => ['cousine germaine', '$s de la cousine germaine'], 36 'M' => ['cousin germain', '$s du cousin germain'], 37 'U' => ['cousin germain', '%s du cousin germain' ] 38 ], 39 2 => [ 40 'F' => ['cousine issue de germain', '$s de la cousine issue de germain'], 41 'M' => ['cousin issu de germain', '$s du cousin issu de germain'], 42 'U' => ['cousin issu de germain', '%s du cousin issu de germain' ] 43 ] 44 ]; 45 46 protected const ASYMMETRIC_COUSINS = [ 47 1 => [ 48 'F' => ['down', 'petite-', 'cousine', 'de la ', 'de la '], 49 'M' => ['down', 'petit-', 'cousin', 'du ', 'du '], 50 'U' => ['down', 'petit-', 'cousin', 'du ', 'du '] 51 ], 52 -1 => [ 53 'F' => ['up', 'grand-', 'cousine', 'de la ', 'de la '], 54 'M' => ['up', 'grand-', 'cousin', 'du ', 'du '], 55 'U' => ['up', 'grand-', 'cousin', 'du ', 'du '] 56 ], 57 ]; 58 59 /** 60 * @return LocaleInterface 61 */ 62 public function locale(): LocaleInterface 63 { 64 return new LocaleFr(); 65 } 66 67 /** 68 * Pour les traducteurs français, certaines configurations peuvent avoir plusieurs traduction françaises possibles, 69 * ou aucune. Voici les choix qui ont été faits (mais complètement ouvert à discussion): 70 * 71 * - je n'ai aucune intention de rentrer dans le débat de l'écriture inclusive, mais malheureusement un choix doit 72 * être fait: lorsque nécessaire dans les choix des articles ou accords, je m'en suis tenu à la recommandation de 73 * l'Académie Française d'utiliser la forme non marquée (et donc le masculin) pour le genre neutre. 74 * - dans le cas de frère/sœur jumeau, j'évite le problème en utiliseant le substantif `jumeau` lorsque le sexe 75 * n'est pas connu, alors que j'utilise la structure `frère jumeau`/`sœur jum elle` lorsque le sexe est connu. 76 * - `conjoint` a été choisi pour un couple non marié (`époux`/`épouse` lorsque les conjoints sont mariés). 77 * Une alternative est `partenaire`, mais `conjoint` est le terme déjà utilisé dans les traductions françaises. 78 * - la notion de `foster` (qui peut traduire plusieurs réalités différentes en français) a été traduite dans le 79 * cadre de la `famille d'accueil`. Les suggestions sont les bienvenues. 80 * - La situation des enfants dans les familles recomposées a été traduites: 81 * - `frère`/`sœur` pour les enfants dont les deux parents sont les mêmes 82 * - `demi-frère`/`demi-sœur` pour les enfants qui ont un parent en commun 83 * - `quasi-frère`/`quasi-sœur` pour les enfants qui ne partagent aucun parent en commun, mais dont les parents 84 * sont en couple 85 * - la notion d'âge entre frères/sœurs a été traduite par `grand frère`/`petit frère`, plutôt que des variants sur 86 * `frère aîné`/`frère cadet` ou `frère plus âgé`/`frère plus jeune` 87 * - De manière arbitraire, au delà de deux `arrière-`, la forme est raccourcie par `arrière-(xN)-` avec N décrivant 88 * le nombre de degré. Techniquement, en français, il n'existe pas de forme raccourcie, mais je ne pense pas que 89 * ce soit une bonne idée de multiplier les `arrière-`. On pourrait utiliser les termes `quadrisaïeul` / 90 * `quinquisaïeul` /`sextaïeul` / `septaïeul` /... mais ils me semblent assez peu usités. 91 * - Pour les cousins, c'est la description selon le droit canon qui a été choisie (principalement car elle donne 92 * une meilleure visibilité de la distance à l'ancêtre commun que la description en droit civil), donc: 93 * - l'enfant d'un oncle/tante est un `cousin germain`/`cousine germaine` (= cousins au 1er degré) 94 * - les enfants de cousins germains sont des `cousins issus de germain` (= cousins au 2e degré) 95 * - pour les enfants des cousins issus de germains, et ainsi de suite, la relation est décrite suivant le nombre 96 * de degré séparant les cousins de l'ancêtre commun: 97 * - en cas de symétrie des chemins, ils sont dits `cousins au N-ème degré` 98 * - en cas d'asymétrie des chemins, ils sont dit `cousins du N-ème au M-ème degré` 99 * - de plus, les notions de `grand-cousin` et `petit-cousin` ont été implémentées comme suit: 100 * - un `(arrière-)grand-cousin` est l'enfant d'un `(arrière-)grand-oncle`/`grand-tante` (= cousin du 1er au N-ème degré) 101 * - un `(arrière-)petit-cousin` est un `(arrière-)petit-neveu`/`petite-nièce` d'un parent (= cousin du Ner au 1er degré) 102 * 103 * @return array<Relationship> 104 */ 105 public function relationships(): array 106 { 107 $genitive = fn (string $s, string $genitive_link): array => [$s, '%s ' . $genitive_link . $s]; 108 109 $great = fn (int $n, string $suffix, string $genitive_link): array => $genitive( 110 ($n > 2 ? 'arrière-(x' . $n . ')-' : str_repeat('arrière-', max($n, 0))) . $suffix, 111 $n === 0 ? $genitive_link : 'de l’' 112 ); 113 114 $compoundgreat = 115 fn (int $n, string $first_level, string $suffix, string $genitive_none, string $genitive_first): array => 116 $great($n - 1, ($n > 0 ? $first_level : '') . $suffix, $n === 0 ? $genitive_none : $genitive_first); 117 118 $symmetricCousin = fn (int $n, string $sex): array => self::SYMMETRIC_COUSINS[$n][$sex] ?? $genitive( 119 $sex === 'F' ? 'cousine au ' . $n . '<sup>e</sup> degré' : 'cousin au ' . $n . '<sup>e</sup> degré', 120 $sex === 'F' ? 'de la ' : 'du ' 121 ); 122 123 $asymmetricCousin = 124 static function (int $up, int $down, string $sex) use ($symmetricCousin, $compoundgreat, $genitive): array { 125 if ($up === $down) { 126 return $symmetricCousin($up, $sex); 127 } 128 $fixed = self::ASYMMETRIC_COUSINS[$up][$sex] ?? self::ASYMMETRIC_COUSINS[-$down][$sex] ?? null; 129 if ($fixed !== null) { 130 $fixed[0] = $fixed[0] === 'up' ? $up - 1 : $down - 1; 131 return $compoundgreat(...$fixed); 132 } 133 return $genitive( 134 $sex === 'F' ? 135 'cousine du ' . $down . '<sup>e</sup> au ' . $up . '<sup>e</sup> degré' : 136 'cousin du ' . $down . '<sup>e</sup> au ' . $up . '<sup>e</sup> degré', 137 $sex === 'F' ? 'de la ' : 'du ' 138 ); 139 }; 140 141 return [ 142 // Adopted 143 Relationship::fixed('mère adoptive', '%s de la mère adoptive')->adoptive()->mother(), 144 Relationship::fixed('père adoptif', '%s du père adoptif')->adoptive()->father(), 145 Relationship::fixed('parent adoptif', '%s du parent adoptif')->adoptive()->parent(), 146 Relationship::fixed('fille adoptive', '%s de la fille adoptive')->adopted()->daughter(), 147 Relationship::fixed('fils adoptif', '%s du fils adoptif')->adopted()->son(), 148 Relationship::fixed('enfant adoptif', '%s de l’enfant adoptif')->adopted()->child(), 149 // Fostered 150 Relationship::fixed('mère d’accueil', '%s de la mère d’acceuil')->fostering()->mother(), 151 Relationship::fixed('père d’accueil', '%s du père d’acceuil')->fostering()->father(), 152 Relationship::fixed('parent d’accueil', '%s du parent d’acceuil')->fostering()->parent(), 153 Relationship::fixed('fille accueillie', '%s de la fille accueillie')->fostered()->daughter(), 154 Relationship::fixed('fils accueilli', '%s du fils accueilli')->fostered()->son(), 155 Relationship::fixed('enfant accueilli', '%s de l’enfant accueilli')->fostered()->child(), 156 // Parents 157 Relationship::fixed('mère', '%s de la mère')->mother(), 158 Relationship::fixed('père', '%s du père')->father(), 159 Relationship::fixed('parent', '%s du parent')->parent(), 160 // Children 161 Relationship::fixed('fille', '%s de la fille')->daughter(), 162 Relationship::fixed('fils', '%s du fils')->son(), 163 Relationship::fixed('enfant', '%s de l’enfant')->child(), 164 // Siblings 165 Relationship::fixed('sœur jumelle', '%s de la sœur jumelle')->twin()->sister(), 166 Relationship::fixed('frère jumeau', '%s du frère jumeau')->twin()->brother(), 167 Relationship::fixed('jumeau', '%s du jumeau')->twin()->sibling(), 168 Relationship::fixed('grande sœur', '%s de la grande sœur')->older()->sister(), 169 Relationship::fixed('grand frère', '%s du grand frère')->older()->brother(), 170 Relationship::fixed('grand frère/sœur', '%s du grand frère/sœur')->older()->sibling(), 171 Relationship::fixed('petite sœur', '%s de la petite sœur')->younger()->sister(), 172 Relationship::fixed('petit frère', '%s du petit-frère')->younger()->brother(), 173 Relationship::fixed('petit frère/sœur', '%s du petit frère/sœur')->younger()->sibling(), 174 Relationship::fixed('sœur', '%s de la sœur')->sister(), 175 Relationship::fixed('frère', '%s du frère')->brother(), 176 Relationship::fixed('frère/sœur', '%s du frère/sœur')->sibling(), 177 // Half-family 178 Relationship::fixed('demi-sœur', '%s de la demi-sœur')->parent()->daughter(), 179 Relationship::fixed('demi-frère', '%s du demi-frère')->parent()->son(), 180 Relationship::fixed('demi-frère/sœur', '%s du demi-frère/sœur')->parent()->child(), 181 // Stepfamily 182 Relationship::fixed('belle-mère', '%s de la belle-mère')->parent()->wife(), 183 Relationship::fixed('beau-père', '%s du beau-père')->parent()->husband(), 184 Relationship::fixed('beau-parent', '%s du beau-parent')->parent()->married()->spouse(), 185 Relationship::fixed('belle-fille', '%s de la belle-fille')->married()->spouse()->daughter(), 186 Relationship::fixed('beau-fils', '%s du beau-fils')->married()->spouse()->son(), 187 Relationship::fixed('beau-fils/fille', '%s du beau-fils/fille')->married()->spouse()->child(), 188 Relationship::fixed('quasi-sœur', '%s de la quasi-sœur')->parent()->spouse()->daughter(), 189 Relationship::fixed('quasi-frère', '%s du quasi-frère')->parent()->spouse()->son(), 190 Relationship::fixed('quasi-frère/sœur', '%s du quasi-frère/sœur')->parent()->spouse()->child(), 191 // Partners 192 Relationship::fixed('ex-épouse', '%s de l’ex-épouse')->divorced()->partner()->female(), 193 Relationship::fixed('ex-époux', '%s de l’ex-époux')->divorced()->partner()->male(), 194 Relationship::fixed('ex-conjoint', '%s de l’ex-conjoint')->divorced()->partner(), 195 Relationship::fixed('fiancée', '%s de la fiancée')->engaged()->partner()->female(), 196 Relationship::fixed('fiancé', '%s du fiancé')->engaged()->partner()->male(), 197 Relationship::fixed('épouse', '%s de l’épouse')->wife(), 198 Relationship::fixed('époux', '%s de l’époux')->husband(), 199 Relationship::fixed('époux', '%s de l’époux')->spouse(), 200 Relationship::fixed('conjoint', '%s du conjoint')->partner(), 201 // In-laws 202 Relationship::fixed('belle-mère', '%s de la belle-mère')->married()->spouse()->mother(), 203 Relationship::fixed('beau-père', '%s du beau-père')->married()->spouse()->father(), 204 Relationship::fixed('beau-parent', '%s du beau-parent')->married()->spouse()->parent(), 205 Relationship::fixed('belle-fille', '%s de la belle-fille')->child()->wife(), 206 Relationship::fixed('beau-fils', '%s du beau-fils')->child()->husband(), 207 Relationship::fixed('beau-fils/belle-fille', '%s du beau-fils/belle-fille')->child()->married()->spouse(), 208 Relationship::fixed('belle-sœur', '%s de la belle-sœur')->spouse()->sister(), 209 Relationship::fixed('beau-frère', '%s du beau-frère')->spouse()->brother(), 210 Relationship::fixed('beau-frère/belle-sœur', '%s du beau-frère/belle-sœur')->spouse()->sibling(), 211 Relationship::fixed('belle-sœur', '%s de la belle-sœur')->sibling()->wife(), 212 Relationship::fixed('beau-frère', '%s du beau-frère')->sibling()->husband(), 213 Relationship::fixed('beau-frère/belle-sœur', '%s du beau-frère/belle-sœur')->sibling()->spouse(), 214 // Grandparents and above 215 Relationship::dynamic(fn (int $n) => $great($n - 1, 'grand-mère maternelle', 'de la '))->mother()->ancestor()->female(), 216 Relationship::dynamic(fn (int $n) => $great($n - 1, 'grand-père maternel', 'du '))->mother()->ancestor()->male(), 217 Relationship::dynamic(fn (int $n) => $great($n - 1, 'grand-mère paternelle', 'de la '))->father()->ancestor()->female(), 218 Relationship::dynamic(fn (int $n) => $great($n - 1, 'grand-père paternel', 'du '))->father()->ancestor()->male(), 219 Relationship::dynamic(fn (int $n) => $great($n - 2, 'grand-mère', 'de la '))->ancestor()->female(), 220 Relationship::dynamic(fn (int $n) => $great($n - 2, 'grand-père', 'du '))->ancestor()->male(), 221 Relationship::dynamic(fn (int $n) => $great($n - 2, 'grand-parent', 'du '))->ancestor(), 222 // Grandchildren and below 223 Relationship::dynamic(fn (int $n) => $great($n - 2, 'petite-fille', 'de la '))->descendant()->female(), 224 Relationship::dynamic(fn (int $n) => $great($n - 2, 'petit-fils', 'du '))->descendant()->male(), 225 Relationship::dynamic(fn (int $n) => $great($n - 2, 'petit-enfant', 'du'))->descendant(), 226 // Collateral relatives 227 Relationship::dynamic(fn (int $n) => $compoundgreat($n - 1, 'grand-', 'tante', 'de la ', 'de la '))->ancestor()->sister(), 228 Relationship::dynamic(fn (int $n) => $compoundgreat($n - 1, 'grand-', 'tante par alliance', 'de la ', 'de la '))->ancestor()->sibling()->wife(), 229 Relationship::dynamic(fn (int $n) => $compoundgreat($n - 1, 'grand-', 'oncle', 'de l’', 'du '))->ancestor()->brother(), 230 Relationship::dynamic(fn (int $n) => $compoundgreat($n - 1, 'grand-', 'oncle par alliance', 'de l’', 'du '))->ancestor()->sibling()->husband(), 231 Relationship::dynamic(fn (int $n) => $compoundgreat($n - 1, 'petite-', 'nièce', 'de la ', 'de la '))->sibling()->descendant()->female(), 232 Relationship::dynamic(fn (int $n) => $compoundgreat($n - 1, 'petite-', 'nièce par alliance', 'de la ', 'de la '))->married()->spouse()->sibling()->descendant()->female(), 233 Relationship::dynamic(fn (int $n) => $compoundgreat($n - 1, 'petit-', 'neveu', 'du ', 'du '))->sibling()->descendant()->male(), 234 Relationship::dynamic(fn (int $n) => $compoundgreat($n - 1, 'petit-', 'neveu par alliance', 'du ', 'du '))->married()->spouse()->sibling()->descendant()->male(), 235 // Cousins (based on canon law) 236 Relationship::dynamic(fn (int $n) => $symmetricCousin($n, 'F'))->symmetricCousin()->female(), 237 Relationship::dynamic(fn (int $n) => $symmetricCousin($n, 'M'))->symmetricCousin()->male(), 238 Relationship::dynamic(fn (int $up, int $down) => $asymmetricCousin($up, $down, 'F'))->cousin()->female(), 239 Relationship::dynamic(fn (int $up, int $down) => $asymmetricCousin($up, $down, 'M'))->cousin()->male(), 240 241 ]; 242 } 243} 244