Skip to content

Commit

Permalink
Merge pull request #3 from alexharri/full-names
Browse files Browse the repository at this point in the history
Support full names
  • Loading branch information
alexharri authored Nov 13, 2022
2 parents 31d5451 + 0e887f3 commit b075984
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 10 deletions.
48 changes: 48 additions & 0 deletions lib/beygla.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,52 @@ describe("applyCase", () => {
expect(out).toEqual(expected);
}
});

it("applies a case to a full name", () => {
const sourceName = "Gunnar Sigurberg Brjánsson";

const out = applyCase("þgf", sourceName);

expect(out).toEqual("Gunnari Sigurbergi Brjánssyni");
});

it("strips whitespace in full names", () => {
const sourceName = " \n Hildigerður Oddný\tPatreksdóttir \n\n";

const out = applyCase("þf", sourceName);

expect(out).toEqual("Hildigerði Oddnýju Patreksdóttur");
});

it("applies a case to a first and middle name", () => {
const sourceName = "Þorleifur Sigþór";

const out = applyCase("ef", sourceName);

expect(out).toEqual("Þorleifs Sigþórs");
});

it("applies a case only the last name", () => {
const sourceName = "Ríkharðsdóttir";

const out = applyCase("ef", sourceName);

expect(out).toEqual("Ríkharðsdóttur");
});

it("applies a case to the first and last name", () => {
const sourceName = "Magnús Herleifsson";

const out = applyCase("þgf", sourceName);

expect(out).toEqual("Magnúsi Herleifssyni");
});

it("applies a case to only 'son' or 'dóttir'", () => {
const son = applyCase("þgf", "son");
const dottir = applyCase("þgf", "dóttir");

expect(son).toEqual("syni");
expect(dottir).toEqual("dóttur");
});
});
57 changes: 47 additions & 10 deletions lib/beygla.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,66 @@ function declineName(name: string, declension: string, caseStr: Case): string {
return root + appendices[caseIndex];
}

const namesThatEndWithSon = ["Samson", "Jason"];

function applyCaseToName(caseStr: Case, name: string) {
let postfix: [string, string] | null = null;

for (const [ending, declension] of [
["son", "2;on,on,yni,onar"],
["dóttir", "2;ir,ur,ur,ur"],
]) {
if (!name.endsWith(ending)) continue;
if (namesThatEndWithSon.indexOf(name) !== -1) continue;
postfix = [ending, declension];
name = name.split(ending)[0];
}

if (!postfix) {
const declension = extractDeclension(trie, name);
if (declension) name = declineName(name, declension, caseStr);
} else {
name += declineName(postfix[0], postfix[1], caseStr);
}

return name;
}

/**
* This function can applies one of the following cases to a source name
* provided in the nominative case (nefnifall).
* Applies a case to a source name provided in the nominative
* case (nefnifall).
*
* @example
* ```tsx
* applyCase("ef", "Jóhann");
* //=> "Jóhannesar"
*
* applyCase("þgf", "Helga Fríða Smáradóttir");
* //=> "Helgu Fríðu Smáradóttur"
* ```
*
* The name provided must be an Icelandic name in the nominative case
* (nefnifall). Otherwise, an unexpected output is likely.
*
* The supported cases are:
*
* - Nominative `nom` (nefnifall `nf` in Icelandic)
* - Accusative `acc` (þolfall `þf` in Icelandic)
* - Dative `dat` (þágufall `þgf` in Icelandic)
* - Genitive `gen` (eignarfall `ef` in Icelandic)
*
* Note that superfluous whitespace is not retained:
*
* @example
* ```tsx
* applyCase("ef", "Jóhann");
* //=> "Jóhannesar"
* applyCase("þf", " \n Hildigerður Oddný\tPatreksdóttir \n\n");
* //=> "Hildigerði Oddnýju Patreksdóttur"
* ```
*
* The name provided must be an Icelandic name in the nominative case
* (nefnifall) or an unexpected output is likely.
*
* @param name - An Icelandic name in the nominative case (nefnifall)
* @param caseStr - The case to apply to the name to, e.g. `þf`
*/
export function applyCase(caseStr: Case, name: string): string {
const declension = extractDeclension(trie, name);
if (!declension) return name;
return declineName(name, declension, caseStr);
const names = name.split(/\s+/).filter(Boolean);
return names.map((name) => applyCaseToName(caseStr, name)).join(" ");
}

0 comments on commit b075984

Please sign in to comment.