kinship: implement g-rule

Allow arbitrary depth

Signed-off-by: Arc676/Alessandro Vinciguerra <alesvinciguerra@gmail.com>
This commit is contained in:
Arc676/Alessandro Vinciguerra committed 2026-11-01 12:06:21 +01:00
1 parent 24e7ea1994
commit 568db606da
2 files changed
+49 -14

No files matched your search

+47 -14
View File
@@ -29,6 +29,15 @@ function times(n) {
}
}
function grule(n) {
switch (n - 1) {
case 1:
return "Grand"
default:
return `Great-${"great-".repeat(n - 3)}grand`
}
}
export default function nameEn(path) {
const { ups, downs, hasSpouse, sex } = kinshipFacts(path)
@@ -45,21 +54,45 @@ export default function nameEn(path) {
let label
if (downs === 0 && ups > 0) {
if (ups === 1) label = g(sex, 'Father', 'Mother', 'Parent')
else if (ups === 2) label = g(sex, 'Grandfather', 'Grandmother', 'Grandparent')
else if (ups === 3) label = g(sex, 'Great-grandfather', 'Great-grandmother', 'Great-grandparent')
else label = `Ancestor, ${ups} generations up`
switch (ups) {
case 1:
label = g(sex, 'Father', 'Mother', 'Parent')
break;
default:
label = `${grule(ups)}${g(sex, 'father', 'mother', 'parent')}`
break;
}
} else if (ups === 0 && downs > 0) {
if (downs === 1) label = g(sex, 'Son', 'Daughter', 'Child')
else if (downs === 2) label = g(sex, 'Grandson', 'Granddaughter', 'Grandchild')
else if (downs === 3) label = g(sex, 'Great-grandson', 'Great-granddaughter', 'Great-grandchild')
else label = `Descendant, ${downs} generations down`
} else if (ups === 1 && downs === 1) label = g(sex, 'Brother', 'Sister', 'Sibling')
else if (ups === 2 && downs === 1) label = g(sex, 'Uncle', 'Aunt', 'Uncle/Aunt')
else if (ups === 3 && downs === 1) label = g(sex, 'Great-uncle', 'Great-aunt', 'Great-uncle/aunt')
else if (ups === 1 && downs === 2) label = g(sex, 'Nephew', 'Niece', 'Nibling')
else if (ups === 1 && downs === 3) label = g(sex, 'Grandnephew', 'Grandniece', 'Grandnibling')
else if (ups >= 2 && downs >= 2) {
switch (downs) {
case 1:
label = g(sex, 'Son', 'Daughter', 'Child')
break;
default:
label = `${grule(downs)}${g(sex, 'son', 'daughter', 'child')}`
break;
}
} else if (downs == 1) {
switch (ups) {
case 1:
label = g(sex, 'Brother', 'Sister', 'Sibling')
break;
case 2:
label = g(sex, 'Uncle', 'Aunt', 'Uncle/Aunt')
break;
default:
label = `${grule(ups - 1)}${g(sex, 'uncle', 'aunt', 'uncle/aunt')}`
break;
}
} else if (ups === 1) {
switch (downs) {
case 2:
label = g(sex, 'Nephew', 'Niece', 'Nibling')
break;
default:
label = `${grule(downs - 1)}${g(sex, 'nephew', 'niece', 'nibling')}`
break;
}
} else if (ups >= 2 && downs >= 2) {
const degree = Math.min(ups, downs) - 1
const removed = Math.abs(ups - downs)
if (removed === 0) label = `${ordinal(degree)} cousin`
@@ -56,6 +56,8 @@ describe('nommage français', () => {
describe('nommage anglais', () => {
it('genre le mot quand le sexe est connu', () => {
expect(bothEn(['up'])).toEqual(['Father', 'Mother', 'Parent'])
expect(bothEn(['up', 'up'])).toEqual(['Grandfather', 'Grandmother', 'Grandparent'])
expect(bothEn(['up', 'up', 'up', 'up'])).toEqual(['Great-great-grandfather', 'Great-great-grandmother', 'Great-great-grandparent'])
expect(bothEn(['down', 'down'])).toEqual(['Grandson', 'Granddaughter', 'Grandchild'])
expect(bothEn(['sibling'])).toEqual(['Brother', 'Sister', 'Sibling'])
expect(bothEn(['up', 'sibling'])).toEqual(['Uncle', 'Aunt', 'Uncle/Aunt'])