xref: /webtrees/app/Module/LanguageFrench.php (revision e873f434551745f888937263ff89e80db3b0f785)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2023 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 array 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 array ASYMMETRIC_COUSINS = [
47        1 => [
48            'F' => ['down', 'petite-cousine', 'de la '],
49            'M' => ['down', 'petit-cousin', 'du '],
50            'U' => ['down', 'petit-cousin', 'du ']
51        ],
52        -1 => [
53            'F' => ['up', 'grand-cousine', 'de la '],
54            'M' => ['up', 'grand-cousin', 'du '],
55            'U' => ['up', 'grand-cousin', '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 ouverts à 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ères/sœurs jumeaux, 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 jumelle` 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é traduite:
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 variantes sur
86     *   `frère aîné`/`frère cadet` ou `frère plus âgé`/`frère plus jeune`
87     * - Lorsqu'il est nécessaire d'aller au-delà d'un `arrière-`{substantif} (par exemple, pour décrire le case de
88     *   l'enfant d'un arrière-petit-enfant), la forme `{substantif} au Ne degré` est choisie, avec pour convention
89     *   N = 1 pour le niveau du substantif racine, on utilisera donc par exemple:
90     *      - `petit-enfant` (= petit-enfant au 1er degré)
91     *      - `arrière-petit-enfant` (= petit-enfant au 2e degré)
92     *      - `petit-enfant au 3e degré` et ainsi de suite pour les degrés supérieurs
93     * - Un exception à la règle précédente sont les grand-parents au 3e degré, qui ont la description de `trisaïeux`.
94     * - Pour les cousins, c'est la description selon le droit canon qui a été choisie (principalement car elle donne
95     *   une meilleure visibilité de la distance à l'ancêtre commun que la description en droit civil), donc:
96     *      - l'enfant d'un oncle/tante est un `cousin germain`/`cousine germaine` (= cousins au 1er degré)
97     *      - les enfants de cousins germains sont des `cousins issus de germain` (= cousins au 2e degré)
98     *      - pour les enfants des cousins issus de germains, et ainsi de suite, la relation est décrite suivant le
99     *      nombre de degré séparant les cousins de l'ancêtre commun:
100     *      - en cas de symétrie des chemins, ils sont dits `cousins au N-ème degré`
101     *      - en cas d'asymétrie des chemins, ils sont dit  `cousins du N-ème au M-ème degré`
102     *      - de plus, les notions de `grand-cousin` et `petit-cousin` ont été implémentées comme suit:
103     *          - un `(arrière-)grand-cousin` est l'enfant d'un `(arrière-)grand-oncle`/`grand-tante`
104     *              (= cousin du 1er au N-ème degré)
105     *          - un `(arrière-)petit-cousin` est un `(arrière-)petit-neveu`/`petite-nièce` d'un parent
106     *              (= cousin du Ner au 1er degré)
107     *
108     * @return array<Relationship>
109     */
110    public function relationships(): array
111    {
112        // Construct the genitive form in French
113        $genitive = static fn (string $s, string $genitive_link): array => [$s, '%s ' . $genitive_link . $s];
114
115        // Functions to coumpound the name that can be indefinitely repeated
116        $degree = static fn (int $n, string $suffix, string $genitive_link): array =>
117                $genitive($suffix . ' au ' . $n . '<sup>e</sup> degré', $genitive_link);
118
119        $great = static fn (int $n, string $suffix, string $genitive_link): array =>
120                $n <= 1 ? $genitive('arrière-' . $suffix, 'de l’') : $degree($n + 1, $suffix, $genitive_link);
121
122        $firstCompound = static fn (int $n, string $suffix, string $genitive_link): array =>
123                $n <= 1 ? $genitive($suffix, $genitive_link) : $great($n - 1, $suffix, $genitive_link);
124
125        $compound =
126            static fn (int $n, string $first_level, string $suffix, string $genitive_none, string $genitive_first): array =>
127                $n <= 1 ? $genitive($suffix, $genitive_none) : $firstCompound($n - 1, $first_level . $suffix, $genitive_first);
128
129        // Functions to translate cousins' degree of relationship
130        $symmetricCousin = static fn (int $n, string $sex): array => self::SYMMETRIC_COUSINS[$n][$sex] ?? $genitive(
131            $sex === 'F' ? 'cousine au ' . $n . '<sup>e</sup> degré' : 'cousin au ' . $n . '<sup>e</sup> degré',
132            $sex === 'F' ? 'de la ' : 'du '
133        );
134
135        $cousin =
136            static function (int $up, int $down, string $sex) use ($symmetricCousin, $firstCompound, $genitive): array {
137                if ($up === $down) {
138                    return $symmetricCousin($up, $sex);
139                }
140                $fixed = self::ASYMMETRIC_COUSINS[$up][$sex] ?? self::ASYMMETRIC_COUSINS[-$down][$sex] ?? null;
141                if ($fixed !== null) {
142                    $fixed[0] = $fixed[0] === 'up' ? $up - 1 : $down - 1;
143                    return $firstCompound(...$fixed);
144                }
145                return $genitive(
146                    $sex === 'F' ?
147                        'cousine du ' . $down . '<sup>e</sup> au ' . $up . '<sup>e</sup> degré' :
148                        'cousin du ' . $down . '<sup>e</sup> au ' . $up . '<sup>e</sup> degré',
149                    $sex === 'F' ? 'de la ' : 'du '
150                );
151            };
152
153        return [
154            // Adopted
155            Relationship::fixed('mère adoptive', '%s de la mère adoptive')->adoptive()->mother(),
156            Relationship::fixed('père adoptif', '%s du père adoptif')->adoptive()->father(),
157            Relationship::fixed('parent adoptif', '%s du parent adoptif')->adoptive()->parent(),
158            Relationship::fixed('sœur adoptive', '%s de la sœur adoptive')->adoptive()->sister(),
159            Relationship::fixed('frère adoptif', '%s du frère adoptif')->adoptive()->brother(),
160            Relationship::fixed('frère/sœur adoptif', '%s du frère/sœur adoptif')->adoptive()->sibling(),
161            Relationship::fixed('fille adoptive', '%s de la fille adoptive')->adopted()->daughter(),
162            Relationship::fixed('fils adoptif', '%s du fils adoptif')->adopted()->son(),
163            Relationship::fixed('enfant adoptif', '%s de l’enfant adoptif')->adopted()->child(),
164            Relationship::fixed('sœur adoptive', '%s de la sœur adoptive')->adopted()->sister(),
165            Relationship::fixed('frère adoptif', '%s du frère adoptif')->adopted()->brother(),
166            Relationship::fixed('frère/sœur adoptif', '%s du frère/sœur adoptif')->adopted()->sibling(),
167            // Fostered
168            Relationship::fixed('mère d’accueil', '%s de la mère d’acceuil')->fostering()->mother(),
169            Relationship::fixed('père d’accueil', '%s du père d’acceuil')->fostering()->father(),
170            Relationship::fixed('parent d’accueil', '%s du parent d’acceuil')->fostering()->parent(),
171            Relationship::fixed('sœur d’accueil', '%s de la sœur d’accueil')->fostering()->sister(),
172            Relationship::fixed('frère d’accueil', '%s du frère d’accueil')->fostering()->brother(),
173            Relationship::fixed('frère/sœur d’accueil', '%s du frère/sœur d’accueil')->fostering()->sibling(),
174            Relationship::fixed('fille accueillie', '%s de la fille accueillie')->fostered()->daughter(),
175            Relationship::fixed('fils accueilli', '%s du fils accueilli')->fostered()->son(),
176            Relationship::fixed('enfant accueilli', '%s de l’enfant accueilli')->fostered()->child(),
177            Relationship::fixed('sœur accueillie', '%s de la sœur accueillie')->fostered()->sister(),
178            Relationship::fixed('frère accueilli', '%s du frère accueilli')->fostered()->brother(),
179            Relationship::fixed('frère/sœur accueilli', '%s du frère/sœur accueilli')->fostered()->sibling(),
180            // Parents
181            Relationship::fixed('mère', '%s de la mère')->mother(),
182            Relationship::fixed('père', '%s du père')->father(),
183            Relationship::fixed('parent', '%s du parent')->parent(),
184            // Children
185            Relationship::fixed('fille', '%s de la fille')->daughter(),
186            Relationship::fixed('fils', '%s du fils')->son(),
187            Relationship::fixed('enfant', '%s de l’enfant')->child(),
188            // Siblings
189            Relationship::fixed('sœur jumelle', '%s de la sœur jumelle')->twin()->sister(),
190            Relationship::fixed('frère jumeau', '%s du frère jumeau')->twin()->brother(),
191            Relationship::fixed('jumeau', '%s du jumeau')->twin()->sibling(),
192            Relationship::fixed('grande sœur', '%s de la grande sœur')->older()->sister(),
193            Relationship::fixed('grand frère', '%s du grand frère')->older()->brother(),
194            Relationship::fixed('grand frère/sœur', '%s du grand frère/sœur')->older()->sibling(),
195            Relationship::fixed('petite sœur', '%s de la petite sœur')->younger()->sister(),
196            Relationship::fixed('petit frère', '%s du petit-frère')->younger()->brother(),
197            Relationship::fixed('petit frère/sœur', '%s du petit frère/sœur')->younger()->sibling(),
198            Relationship::fixed('sœur', '%s de la sœur')->sister(),
199            Relationship::fixed('frère', '%s du frère')->brother(),
200            Relationship::fixed('frère/sœur', '%s du frère/sœur')->sibling(),
201            // Half-family
202            Relationship::fixed('demi-sœur', '%s de la demi-sœur')->parent()->daughter(),
203            Relationship::fixed('demi-frère', '%s du demi-frère')->parent()->son(),
204            Relationship::fixed('demi-frère/sœur', '%s du demi-frère/sœur')->parent()->child(),
205            // Stepfamily
206            Relationship::fixed('belle-mère', '%s de la belle-mère')->parent()->wife(),
207            Relationship::fixed('beau-père', '%s du beau-père')->parent()->husband(),
208            Relationship::fixed('beau-parent', '%s du beau-parent')->parent()->married()->spouse(),
209            Relationship::fixed('belle-fille', '%s de la belle-fille')->married()->spouse()->daughter(),
210            Relationship::fixed('beau-fils', '%s du beau-fils')->married()->spouse()->son(),
211            Relationship::fixed('beau-fils/fille', '%s du beau-fils/fille')->married()->spouse()->child(),
212            Relationship::fixed('quasi-sœur', '%s de la quasi-sœur')->parent()->spouse()->daughter(),
213            Relationship::fixed('quasi-frère', '%s du quasi-frère')->parent()->spouse()->son(),
214            Relationship::fixed('quasi-frère/sœur', '%s du quasi-frère/sœur')->parent()->spouse()->child(),
215            // Partners
216            Relationship::fixed('ex-épouse', '%s de l’ex-épouse')->divorced()->partner()->female(),
217            Relationship::fixed('ex-époux', '%s de l’ex-époux')->divorced()->partner()->male(),
218            Relationship::fixed('ex-époux', '%s de l’ex-époux')->divorced()->partner(),
219            Relationship::fixed('ex-conjointe', '%s de l’ex-conjoint')->divorced()->partner()->female(),
220            Relationship::fixed('ex-conjoint', '%s de l’ex-conjoint')->divorced()->partner()->male(),
221            Relationship::fixed('ex-conjoint', '%s de l’ex-conjoint')->divorced()->partner(),
222            Relationship::fixed('fiancée', '%s de la fiancée')->engaged()->partner()->female(),
223            Relationship::fixed('fiancé', '%s du fiancé')->engaged()->partner()->male(),
224            Relationship::fixed('épouse', '%s de l’épouse')->wife(),
225            Relationship::fixed('époux', '%s de l’époux')->husband(),
226            Relationship::fixed('époux', '%s de l’époux')->spouse(),
227            Relationship::fixed('conjointe', '%s du conjoint')->partner()->female(),
228            Relationship::fixed('conjoint', '%s du conjoint')->partner()->male(),
229            Relationship::fixed('conjoint', '%s du conjoint')->partner(),
230            // In-laws
231            Relationship::fixed('belle-mère', '%s de la belle-mère')->married()->spouse()->mother(),
232            Relationship::fixed('beau-père', '%s du beau-père')->married()->spouse()->father(),
233            Relationship::fixed('beau-parent', '%s du beau-parent')->married()->spouse()->parent(),
234            Relationship::fixed('bru', '%s de la bru')->child()->wife(),
235            Relationship::fixed('gendre', '%s du gendre')->child()->husband(),
236            Relationship::fixed('belle-sœur', '%s de la belle-sœur')->spouse()->sister(),
237            Relationship::fixed('beau-frère', '%s du beau-frère')->spouse()->brother(),
238            Relationship::fixed('beau-frère/belle-sœur', '%s du beau-frère/belle-sœur')->spouse()->sibling(),
239            Relationship::fixed('belle-sœur', '%s de la belle-sœur')->sibling()->wife(),
240            Relationship::fixed('beau-frère', '%s du beau-frère')->sibling()->husband(),
241            Relationship::fixed('beau-frère/belle-sœur', '%s du beau-frère/belle-sœur')->sibling()->spouse(),
242            // Grandparents and above
243            //"Trisaïeux" are an exception to the dynamic rule
244            Relationship::fixed('trisaïeule maternelle', '%s de la trisaïeule maternelle')->mother()->parent()->parent()->mother(),
245            Relationship::fixed('trisaïeul maternel', '%s du trisaïeul maternel')->mother()->parent()->parent()->father(),
246            Relationship::fixed('trisaïeule paternelle', '%s de la trisaïeule paternelle')->father()->parent()->parent()->mother(),
247            Relationship::fixed('trisaïeul paternel', '%s du trisaïeul paternel')->father()->parent()->parent()->father(),
248            Relationship::fixed('trisaïeule', '%s de la trisaïeule')->parent()->parent()->parent()->mother(),
249            Relationship::fixed('trisaïeul', '%s du trisaïeul')->parent()->parent()->parent()->father(),
250            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'grand-mère maternelle', 'de la '))->mother()->ancestor()->female(),
251            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'grand-père maternel', 'du '))->mother()->ancestor()->male(),
252            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'grand-parent maternel', 'du '))->mother()->ancestor(),
253            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'grand-mère paternelle', 'de la '))->father()->ancestor()->female(),
254            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'grand-père paternel', 'du '))->father()->ancestor()->male(),
255            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'grand-parent paternel', 'du '))->father()->ancestor(),
256            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'grand-mère', 'de la '))->parent()->ancestor()->female(),
257            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'grand-père', 'du '))->parent()->ancestor()->male(),
258            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'grand-parent', 'du '))->parent()->ancestor(),
259            // Grandchildren and below
260            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'petite-fille', 'de la '))->child()->descendant()->female(),
261            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'petit-fils', 'du '))->child()->descendant()->male(),
262            Relationship::dynamic(static fn (int $n) => $firstCompound($n, 'petit-enfant', 'du '))->child()->descendant(),
263            // Collateral relatives
264            Relationship::dynamic(static fn (int $n) => $compound($n, 'grand-', 'tante', 'de la ', 'de la '))->ancestor()->sister(),
265            Relationship::dynamic(static fn (int $n) => $compound($n, 'grand-', 'tante par alliance', 'de la ', 'de la '))->ancestor()->sibling()->wife(),
266            Relationship::dynamic(static fn (int $n) => $compound($n, 'grand-', 'oncle', 'de l’', 'du '))->ancestor()->brother(),
267            Relationship::dynamic(static fn (int $n) => $compound($n, 'grand-', 'oncle par alliance', 'de l’', 'du '))->ancestor()->sibling()->husband(),
268            Relationship::dynamic(static fn (int $n) => $compound($n, 'petite-', 'nièce', 'de la ', 'de la '))->sibling()->descendant()->female(),
269            Relationship::dynamic(static fn (int $n) => $compound($n, 'petite-', 'nièce par alliance', 'de la ', 'de la '))->married()->spouse()->sibling()->descendant()->female(),
270            Relationship::dynamic(static fn (int $n) => $compound($n, 'petit-', 'neveu', 'du ', 'du '))->sibling()->descendant()->male(),
271            Relationship::dynamic(static fn (int $n) => $compound($n, 'petit-', 'neveu par alliance', 'du ', 'du '))->married()->spouse()->sibling()->descendant()->male(),
272            // Cousins (based on canon law)
273            Relationship::dynamic(static fn (int $up, int $down) => $cousin($up, $down, 'F'))->cousin()->female(),
274            Relationship::dynamic(static fn (int $up, int $down) => $cousin($up, $down, 'M'))->cousin()->male(),
275
276        ];
277    }
278}
279