Parenté : demi-frère et quasi-frère (#218)

Un enfant du conjoint d'un parent était nommé « Brother-in-law » en anglais,
et un enfant d'un seul parent en commun « Brother ». Le nommage lit
maintenant la suite des pas : up,down = demi (Half-brother, Demi-frère),
up,spouse,down = Stepbrother en anglais ; le français garde Beau-frère,
usage courant pour le quasi-frère.

Closes #218

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
IliesAllaliandClaude Opus 5.5 committed 2026-11-09 11:44:40 +01:00
1 parent 92e3c74673
commit 3fefb4542e
4 files changed
+23 -2

No files matched your search

+3 -1
View File
@@ -1,4 +1,4 @@
import { kinshipFacts } from './facts.js'
import { isHalfSibling, isStepSibling, kinshipFacts } from './facts.js'
// Mot genré quand le sexe de la personne nommée est connu, forme neutre ou double sinon
const g = (sex, male, female, neutral) => (sex === 'male' ? male : sex === 'female' ? female : neutral)
@@ -25,6 +25,8 @@ export default function nameEn(path) {
// « Partner » reste neutre au lieu de supposer un mariage
if (hasSpouse && ups === 0 && downs === 0) return 'Partner'
if (isHalfSibling(path)) return g(sex, 'Half-brother', 'Half-sister', 'Half-sibling')
if (isStepSibling(path)) return g(sex, 'Stepbrother', 'Stepsister', 'Stepsibling')
if (hasSpouse) {
// L'anglais distingue l'ordre : le parent du conjoint (in-law) n'est pas le conjoint du parent (step)
+8
View File
@@ -23,3 +23,11 @@ export function kinshipFacts(path) {
const target = path.steps[path.steps.length - 1]?.person
return { ups, downs, hasSpouse, sex: normalizeSex(target?.sex) }
}
// Suite des pas d'un chemin, pour reconnaître les liens que le compte des générations confond (#218)
export const movesOf = (path) => path.steps.map((step) => step.move).join(',')
// Demi-frère ou demi-sœur : un seul parent en commun. Deux enfants du même couple passent par 'sibling'
// (le chemin le plus court) ; deux enfants d'un même parent avec deux conjoints passent par ce parent.
export const isHalfSibling = (path) => movesOf(path) === 'up,down'
// Quasi-frère ou quasi-sœur : l'enfant du conjoint d'un parent
export const isStepSibling = (path) => movesOf(path) === 'up,spouse,down'
+3 -1
View File
@@ -1,4 +1,4 @@
import { kinshipFacts } from './facts.js'
import { isHalfSibling, kinshipFacts } from './facts.js'
// Mot genré quand le sexe de la personne nommée est connu, forme double sinon
const g = (sex, male, female, both) => (sex === 'male' ? male : sex === 'female' ? female : both)
@@ -7,10 +7,12 @@ export default function nameFr(path) {
const { ups, downs, hasSpouse, sex } = kinshipFacts(path)
if (hasSpouse && ups === 0 && downs === 0) return g(sex, 'Conjoint', 'Conjointe', 'Conjoint(e)')
if (isHalfSibling(path)) return g(sex, 'Demi-frère', 'Demi-sœur', 'Demi-frère/sœur')
if (hasSpouse) {
if (ups === 1 && downs === 0) return g(sex, 'Beau-père', 'Belle-mère', 'Beau-parent')
if (ups === 0 && downs === 1) return g(sex, 'Beau-fils', 'Belle-fille', 'Bel-enfant')
// Le français dit aussi beau-frère pour l'enfant du conjoint d'un parent (quasi-frère, peu employé)
if (ups === 1 && downs === 1) return g(sex, 'Beau-frère', 'Belle-sœur', 'Beau-frère/sœur')
}
@@ -39,6 +39,12 @@ describe('nommage français', () => {
expect(both(['spouse', 'up', 'sibling'])).toEqual(['Oncle par alliance', 'Tante par alliance', 'Oncle/Tante par alliance'])
})
it('demi-frère par un seul parent, beau-frère par le conjoint d’un parent (#218)', () => {
expect(both(['up', 'down'])).toEqual(['Demi-frère', 'Demi-sœur', 'Demi-frère/sœur'])
expect(both(['up', 'spouse', 'down'])).toEqual(['Beau-frère', 'Belle-sœur', 'Beau-frère/sœur'])
expect(both(['sibling', 'spouse'])).toEqual(['Beau-frère', 'Belle-sœur', 'Beau-frère/sœur'])
})
it('« Autre » prend les formes neutres ou doubles, comme non précisé', () => {
const autre = (moves, lang) => nameKinship(path(moves, 'other'), lang)
expect(['up', 'down', 'sibling', 'spouse'].map((m) => autre([m], 'fr'))).toEqual(['Parent', 'Enfant', 'Frère/Sœur', 'Conjoint(e)'])
@@ -67,6 +73,9 @@ describe('nommage anglais', () => {
expect(bothEn(['spouse', 'down'])).toEqual(['Stepson', 'Stepdaughter', 'Stepchild'])
expect(bothEn(['down', 'spouse'])).toEqual(['Son-in-law', 'Daughter-in-law', 'Child-in-law'])
expect(bothEn(['spouse', 'sibling'])).toEqual(['Brother-in-law', 'Sister-in-law', 'Brother/sister-in-law'])
expect(bothEn(['sibling', 'spouse'])).toEqual(['Brother-in-law', 'Sister-in-law', 'Brother/sister-in-law'])
expect(bothEn(['up', 'spouse', 'down'])).toEqual(['Stepbrother', 'Stepsister', 'Stepsibling'])
expect(bothEn(['up', 'down'])).toEqual(['Half-brother', 'Half-sister', 'Half-sibling'])
expect(bothEn(['spouse'])).toEqual(['Partner', 'Partner', 'Partner'])
expect(bothEn(['up', 'sibling', 'down'])).toEqual(['First cousin', 'First cousin', 'First cousin'])
expect(bothEn(['up', 'up', 'sibling', 'down', 'down'])).toEqual(['Second cousin', 'Second cousin', 'Second cousin'])