getting going on plural-suffixes

This commit is contained in:
lingdocs 2021-09-07 15:49:57 +04:00
parent a4eddf82d2
commit 47551aa7dd
7 changed files with 571 additions and 318 deletions

View File

@ -21,6 +21,7 @@ import {
psStringEquals, psStringEquals,
removeRetroflexR, removeRetroflexR,
splitDoubleWord, splitDoubleWord,
endsInConsonant,
} from "./p-text-helpers"; } from "./p-text-helpers";
import * as T from "../types"; import * as T from "../types";
import { import {
@ -1003,10 +1004,34 @@ test("psStringEquals", () => {
expect( expect(
psStringEquals({ p: "بور", f: "bor" }, { p: "تور", f: "tor" }) psStringEquals({ p: "بور", f: "bor" }, { p: "تور", f: "tor" })
).toBe(false); ).toBe(false);
expect(
psStringEquals({ p: "ملګری", f: "malgúrey" }, { p: "ملګری", f: "malgurey" })
).toBe(false);
expect(
psStringEquals({ p: "ملګری", f: "malgúrey" }, { p: "ملګری", f: "malgurey" }, true)
).toBe(true);
}); });
test("removeRetroflexR", () => { test("removeRetroflexR", () => {
expect( expect(
removeRetroflexR({ p: "وکړ", f: "óokR" }), removeRetroflexR({ p: "وکړ", f: "óokR" }),
).toEqual({ p: "وک", f: "óok" }); ).toEqual({ p: "وک", f: "óok" });
}); });
test("endsInAConsonant", () => {
const does: T.PsString[] = [
{ p: "پښتون", f: "puxtoon" },
{ p: "کور", f: "kor" },
{ p: "ګناه", f: "gUnaah" },
{ p: "زوی", f: "zooy" },
{ p: "ځای", f: "dzaay" },
];
const doesnt: T.PsString[] = [
{ p: "بابا", f: "baabaa" },
{ p: "قاضي", f: "qaazee" },
{ p: "ګناه", f: "gunaa" },
{ p: "اطلاع", f: "itlaa" },
];
does.forEach((x) => expect(endsInConsonant(x)).toBe(true));
doesnt.forEach((x) => expect(endsInConsonant(x)).toBe(false));
})

View File

@ -15,6 +15,9 @@ import {
getPersonInflectionsKey, getPersonInflectionsKey,
} from "./misc-helpers"; } from "./misc-helpers";
import * as T from "../types"; import * as T from "../types";
import { removeAccents } from "./accent-helpers";
import { pashtoConsonants, phoneticsConsonants } from "./pashto-consonants";
import { simplifyPhonetics } from "./simplify-phonetics";
// export function concatPsStringWithVars(...items: Array<T.PsString | " " | "">): T.PsString[] { // export function concatPsStringWithVars(...items: Array<T.PsString | " " | "">): T.PsString[] {
@ -90,7 +93,7 @@ export function concatPsString(...items: Array<T.PsString | T.LengthOptions<T.Ps
* @param w * @param w
* @returns * @returns
*/ */
export function splitDoubleWord(w: T.DictionaryEntry): [T.DictionaryEntry, T.DictionaryEntry] { export function splitDoubleWord(w: T.DictionaryEntryNoFVars): [T.DictionaryEntryNoFVars, T.DictionaryEntryNoFVars] {
const pSplit = w.p.split(" "); const pSplit = w.p.split(" ");
const fSplit = w.f.split(" "); const fSplit = w.f.split(" ");
const c = w.c?.replace(" doub.", ""); const c = w.c?.replace(" doub.", "");
@ -176,25 +179,25 @@ export function ensureBaAt(ps: T.FullForm<T.PsString>, pos: number): T.FullForm<
return baInserted; return baInserted;
} }
/** export function removeFVarients(x: T.DictionaryEntry): T.DictionaryEntryNoFVars;
* Returns the first phonetics value in a comma-seperated list export function removeFVarients(x: T.PsString): T.PsStringNoFVars;
* export function removeFVarients(x: string): T.FStringNoFVars;
* @param f - a phonetics string export function removeFVarients(x: string | T.PsString | T.DictionaryEntry): T.FStringNoFVars | T.PsStringNoFVars | T.DictionaryEntryNoFVars {
*/ if (typeof x === "string") {
export function firstPhonetics(f: string): string { return x.split(",")[0] as T.FStringNoFVars;
return f.split(",")[0]; }
} if ("ts" in x) {
return {
/** ...x,
* returs a PsString or DictionaryEntry ensuring only one phonetics variation f: removeFVarients(x.f),
* __brand: "name for a dictionary entry with all the phonetics variations removed",
* @param ps } as T.DictionaryEntryNoFVars;
*/ }
export function removeFVariants(ps: T.PsString): T.PsString {
return { return {
...ps, ...x,
f: firstPhonetics(ps.f), f: removeFVarients(x.f),
}; __brand: "name for a ps string with all the phonetics variations removed",
} as T.PsStringNoFVars;
} }
/** /**
@ -514,13 +517,6 @@ export function yulEndingInfinitive(s: T.PsString): boolean {
return ((pEnding === "یل") && (["yul", "yúl"].includes(fEnding))); return ((pEnding === "یل") && (["yul", "yúl"].includes(fEnding)));
} }
export function psStringFromEntry(entry: T.DictionaryEntry): T.PsString {
return makePsString(
entry.p,
firstPhonetics(entry.f),
);
}
export function allOnePersonInflection(block: T.ImperativeForm, person: T.Person): T.SingleOrLengthOpts<T.ImperativeBlock>; export function allOnePersonInflection(block: T.ImperativeForm, person: T.Person): T.SingleOrLengthOpts<T.ImperativeBlock>;
export function allOnePersonInflection(block: T.VerbForm, person: T.Person): T.SingleOrLengthOpts<T.VerbBlock>; export function allOnePersonInflection(block: T.VerbForm, person: T.Person): T.SingleOrLengthOpts<T.VerbBlock>;
export function allOnePersonInflection(block: T.SingleOrLengthOpts<T.UnisexInflections>, person: T.Person): T.SingleOrLengthOpts<T.UnisexInflections>; export function allOnePersonInflection(block: T.SingleOrLengthOpts<T.UnisexInflections>, person: T.Person): T.SingleOrLengthOpts<T.UnisexInflections>;
@ -617,8 +613,9 @@ export function complementInflects(inf: T.UnisexInflections): boolean {
// ); // );
} }
export function psStringEquals(ps1: T.PsString, ps2: T.PsString): boolean { export function psStringEquals(ps1: T.PsString, ps2: T.PsString, ignoreAccents?: boolean): boolean {
return (ps1.p === ps2.p) && (ps1.f === ps2.f); const [p1, p2] = ignoreAccents ? [removeAccents(ps1), removeAccents(ps2)] : [ps1, ps2];
return (p1.p === p2.p) && (p1.f === p2.f);
} }
export function removeRetroflexR(ps: T.PsString): T.PsString { export function removeRetroflexR(ps: T.PsString): T.PsString {
@ -754,33 +751,76 @@ export function ensureShortWurShwaShift(ps: T.PsString): T.PsString {
return ps; return ps;
} }
export function ensureUnisexInflections(infs: T.Inflections | false, w: T.DictionaryEntry): T.UnisexInflections { export function ensureUnisexInflections(infs: T.InflectorOutput, w: T.DictionaryEntryNoFVars): {
const ps = { p: w.p, f: firstPhonetics(w.f) }; inflections: T.UnisexInflections,
if (infs === false) { plural?: T.PluralInflections,
} {
const ps = { p: w.p, f: w.f };
if (infs === false || infs.inflections === undefined) {
return { return {
masc: [ inflections: {
[ps], masc: [
[ps], [ps],
[ps], [ps],
], [ps],
fem: [ ],
[ps], fem: [
[ps], [ps],
[ps], [ps],
], [ps],
],
},
}; };
} }
if (!("fem" in infs)) { if (!("fem" in infs.inflections)) {
return { return {
...infs, inflections: {
fem: [[ps], [ps], [ps]], ...infs.inflections,
fem: [[ps], [ps], [ps]],
}
}; };
} }
if (!("masc" in infs)) { if (!("masc" in infs.inflections)) {
return { return {
...infs, inflections: {
masc: [[ps], [ps], [ps]], ...infs.inflections,
masc: [[ps], [ps], [ps]],
},
}; };
} }
return infs; // for some dumb reason have to do this for type safety
return {
inflections: infs.inflections,
};
}
export function endsInAaOrOo(w: T.PsString): boolean {
const fEnd = simplifyPhonetics(w.f).slice(-2);
const pEnd = w.p.slice(-1);
return (
pEnd === "و" && fEnd.endsWith("o")
||
pEnd === "ا" && fEnd === "aa"
);
}
export function endsInConsonant(w: T.PsString): boolean {
// TODO: Add reporting back that the plural ending will need a space?
function endsInLongDipthong(w: T.PsString): boolean {
function isLongDipthong(end: T.PsString): boolean {
return (psStringEquals(end, { p: "ای", f: "aay" }, true) || psStringEquals(end, { p: "وی", f: "ooy" }, true));
}
const end = makePsString(
w.p.slice(-2),
w.f.slice(-3),
);
return isLongDipthong(end);
}
if (endsInLongDipthong(w)) return true;
// const pCons = pashtoConsonants.includes(w.p.slice(-1));
const fCons = phoneticsConsonants.includes(simplifyPhonetics(w.f).slice(-1));
return fCons;
} }

View File

@ -7,3 +7,6 @@
*/ */
export const pashtoConsonants = ["ب", "پ", "ت", "ټ", "ث", "ج", "چ", "ح", "خ", "څ", "ځ", "د", "ډ", "ذ", "ر", "ړ", "ز", "ژ", "ږ", "س", "ش", "ښ", "ص", "ض", "ط", "ظ", "غ", "ف", "ق", "ک", "ګ", "گ", "ل", "ل", "م", "ن", "ڼ"]; export const pashtoConsonants = ["ب", "پ", "ت", "ټ", "ث", "ج", "چ", "ح", "خ", "څ", "ځ", "د", "ډ", "ذ", "ر", "ړ", "ز", "ژ", "ږ", "س", "ش", "ښ", "ص", "ض", "ط", "ظ", "غ", "ف", "ق", "ک", "ګ", "گ", "ل", "ل", "م", "ن", "ڼ"];
export const phoneticsConsonants = [
"b", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "w", "z",
];

View File

@ -16,7 +16,7 @@ import * as T from "../types";
const adjectives: Array<{ const adjectives: Array<{
in: T.DictionaryEntry, in: T.DictionaryEntry,
out: T.Inflections | false, out: T.InflectorOutput,
}> = [ }> = [
// irregular adj. // irregular adj.
{ {
@ -34,16 +34,18 @@ const adjectives: Array<{
infbf: "zaR", infbf: "zaR",
}, },
out: { out: {
masc: [ inflections:{
[{p: "زوړ", f: "zoR"}], masc: [
[{p: "زاړه", f: "zaaRu"}], [{p: "زوړ", f: "zoR"}],
[{p: "زړو", f: "zaRo"}], [{p: "زاړه", f: "zaaRu"}],
], [{p: "زړو", f: "zaRo"}],
fem: [ ],
[{p: "زړه", f: "zaRa"}], fem: [
[{p: "زړې", f: "zaRe"}], [{p: "زړه", f: "zaRa"}],
[{p: "زړو", f: "zaRo"}], [{p: "زړې", f: "zaRe"}],
], [{p: "زړو", f: "zaRo"}],
],
},
}, },
}, },
// regular adjective ending in ی // regular adjective ending in ی
@ -58,16 +60,18 @@ const adjectives: Array<{
i: 6564, i: 6564,
}, },
out: { out: {
masc: [ inflections: {
[{p: "ستړی", f: "stúRey"}], masc: [
[{p: "ستړي", f: "stúRee"}], [{p: "ستړی", f: "stúRey"}],
[{p: "ستړیو", f: "stúRiyo"}, {p: "ستړو", f: "stúRo"}], [{p: "ستړي", f: "stúRee"}],
], [{p: "ستړیو", f: "stúRiyo"}, {p: "ستړو", f: "stúRo"}],
fem: [ ],
[{p: "ستړې", f: "stúRe"}], fem: [
[{p: "ستړې", f: "stúRe"}], [{p: "ستړې", f: "stúRe"}],
[{p: "ستړو", f: "stúRo"}], [{p: "ستړې", f: "stúRe"}],
], [{p: "ستړو", f: "stúRo"}],
],
}
}, },
}, },
// regular adjective ending in ی with stress on the end // regular adjective ending in ی with stress on the end
@ -82,16 +86,18 @@ const adjectives: Array<{
i: 12026, i: 12026,
}, },
out: { out: {
masc: [ inflections: {
[{p: "وروستی", f: "wroostéy"}], masc: [
[{p: "وروستي", f: "wroostée"}], [{p: "وروستی", f: "wroostéy"}],
[{p: "وروستیو", f: "wroostiyo"}, {p: "وروستو", f: "wroostó"}], [{p: "وروستي", f: "wroostée"}],
], [{p: "وروستیو", f: "wroostiyo"}, {p: "وروستو", f: "wroostó"}],
fem: [ ],
[{p: "وروستۍ", f: "wroostúy"}], fem: [
[{p: "وروستۍ", f: "wroostúy"}], [{p: "وروستۍ", f: "wroostúy"}],
[{p: "وروستیو", f: "wroostúyo"}, {p: "وروستو", f: "wroostó"}], [{p: "وروستۍ", f: "wroostúy"}],
], [{p: "وروستیو", f: "wroostúyo"}, {p: "وروستو", f: "wroostó"}],
],
}
}, },
}, },
// regular adjective ending in a consonant // regular adjective ending in a consonant
@ -106,16 +112,18 @@ const adjectives: Array<{
i: 6502, i: 6502,
}, },
out: { out: {
masc: [ inflections: {
[{p: "سپک", f: "spuk"}], masc: [
[{p: "سپک", f: "spuk"}], [{p: "سپک", f: "spuk"}],
[{p: "سپکو", f: "spuko"}], [{p: "سپک", f: "spuk"}],
], [{p: "سپکو", f: "spuko"}],
fem: [ ],
[{p: "سپکه", f: "spuka"}], fem: [
[{p: "سپکې", f: "spuke"}], [{p: "سپکه", f: "spuka"}],
[{p: "سپکو", f: "spuko"}], [{p: "سپکې", f: "spuke"}],
], [{p: "سپکو", f: "spuko"}],
],
},
}, },
}, },
{ {
@ -129,16 +137,18 @@ const adjectives: Array<{
i: 9945, i: 9945,
}, },
out: { out: {
masc: [ inflections: {
[{p: "لوی", f: "looy"}], masc: [
[{p: "لوی", f: "looy"}], [{p: "لوی", f: "looy"}],
[{p: "لویو", f: "looyo"}], [{p: "لوی", f: "looy"}],
], [{p: "لویو", f: "looyo"}],
fem: [ ],
[{p: "لویه", f: "looya"}], fem: [
[{p: "لویې", f: "looye"}], [{p: "لویه", f: "looya"}],
[{p: "لویو", f: "looyo"}], [{p: "لویې", f: "looye"}],
], [{p: "لویو", f: "looyo"}],
],
},
}, },
}, },
{ {
@ -152,16 +162,18 @@ const adjectives: Array<{
i: 2430, i: 2430,
}, },
out: { out: {
masc: [ inflections: {
[{p: "پوه", f: "poh"}], masc: [
[{p: "پوه", f: "poh"}], [{p: "پوه", f: "poh"}],
[{p: "پوهو", f: "poho"}], [{p: "پوه", f: "poh"}],
], [{p: "پوهو", f: "poho"}],
fem: [ ],
[{p: "پوهه", f: "poha"}], fem: [
[{p: "پوهې", f: "pohe"}], [{p: "پوهه", f: "poha"}],
[{p: "پوهو", f: "poho"}], [{p: "پوهې", f: "pohe"}],
], [{p: "پوهو", f: "poho"}],
],
},
}, },
}, },
// adjective ending in u // adjective ending in u
@ -176,16 +188,18 @@ const adjectives: Array<{
i: 1, i: 1,
}, },
out: { out: {
masc: [ inflections: {
[{p: "ویده", f: "weedú"}], masc: [
[{p: "ویده", f: "weedú"}], [{p: "ویده", f: "weedú"}],
[{p: "ویدو", f: "weedó"}], [{p: "ویده", f: "weedú"}],
], [{p: "ویدو", f: "weedó"}],
fem: [ ],
[{p: "ویده", f: "weedá"}], fem: [
[{p: "ویدې", f: "weedé"}], [{p: "ویده", f: "weedá"}],
[{p: "ویدو", f: "weedó"}], [{p: "ویدې", f: "weedé"}],
], [{p: "ویدو", f: "weedó"}],
],
},
}, },
}, },
// adjective non-inflecting // adjective non-inflecting
@ -225,23 +239,25 @@ const adjectives: Array<{
i: 1, i: 1,
}, },
out: { out: {
masc: [ inflections: {
[{ p: "ګډ وډ", f: "guD wuD" }], masc: [
[{ p: "ګډ وډ", f: "guD wuD" }], [{ p: "ګډ وډ", f: "guD wuD" }],
[{ p: "ګډو وډو", f: "guDo wuDo" }], [{ p: "ګډ وډ", f: "guD wuD" }],
], [{ p: "ګډو وډو", f: "guDo wuDo" }],
fem: [ ],
[{ p: "ګډه وډه", f: "guDa wuDa" }], fem: [
[{ p: "ګډې وډې", f: "guDe wuDe" }], [{ p: "ګډه وډه", f: "guDa wuDa" }],
[{ p: "ګډو وډو", f: "guDo wuDo" }], [{ p: "ګډې وډې", f: "guDe wuDe" }],
], [{ p: "ګډو وډو", f: "guDo wuDo" }],
} ],
} },
},
},
]; ];
const nouns: Array<{ const nouns: Array<{
in: T.DictionaryEntry, in: T.DictionaryEntry,
out: T.Inflections | false, out: T.InflectorOutput,
}> = [ }> = [
// ## UNISEX // ## UNISEX
// Unisex noun irregular // Unisex noun irregular
@ -260,16 +276,18 @@ const nouns: Array<{
infbf: "melman", infbf: "melman",
}, },
out: { out: {
masc: [ inflections: {
[{p: "مېلمه", f: "melmá"}], masc: [
[{p: "مېلمانه", f: "melmaanu"}], [{p: "مېلمه", f: "melmá"}],
[{p: "مېلمنو", f: "melmano"}], [{p: "مېلمانه", f: "melmaanu"}],
], [{p: "مېلمنو", f: "melmano"}],
fem: [ ],
[{p: "مېلمنه", f: "melmana"}], fem: [
[{p: "مېلمنې", f: "melmane"}], [{p: "مېلمنه", f: "melmana"}],
[{p: "مېلمنو", f: "melmano"}], [{p: "مېلمنې", f: "melmane"}],
], [{p: "مېلمنو", f: "melmano"}],
],
},
}, },
}, },
// Unisex noun ending with ی // Unisex noun ending with ی
@ -284,16 +302,18 @@ const nouns: Array<{
i: 10943, i: 10943,
}, },
out: { out: {
masc: [ inflections: {
[{p: "ملګری", f: "malgúrey"}], masc: [
[{p: "ملګري", f: "malgúree"}], [{p: "ملګری", f: "malgúrey"}],
[{p: "ملګریو", f: "malgúriyo"}, {p: "ملګرو", f: "malgúro"}], [{p: "ملګري", f: "malgúree"}],
], [{p: "ملګریو", f: "malgúriyo"}, {p: "ملګرو", f: "malgúro"}],
fem: [ ],
[{p: "ملګرې", f: "malgúre"}], fem: [
[{p: "ملګرې", f: "malgúre"}], [{p: "ملګرې", f: "malgúre"}],
[{p: "ملګرو", f: "malgúro"}], [{p: "ملګرې", f: "malgúre"}],
], [{p: "ملګرو", f: "malgúro"}],
],
},
}, },
}, },
// Unisex noun ending on ی with emphasis on the end // Unisex noun ending on ی with emphasis on the end
@ -308,16 +328,24 @@ const nouns: Array<{
i: 2900, i: 2900,
}, },
out: { out: {
masc: [ inflections: {
[{p: "ترورزی", f: "trorzéy"}], masc: [
[{p: "ترورزي", f: "trorzée"}], [{p: "ترورزی", f: "trorzéy"}],
[{p: "ترورزیو", f: "trorziyo"}, {p: "ترورزو", f: "trorzó"}], [{p: "ترورزي", f: "trorzée"}],
], [{p: "ترورزیو", f: "trorziyo"}, {p: "ترورزو", f: "trorzó"}],
fem: [ ],
[{p: "ترورزۍ", f: "trorzúy"}], fem: [
[{p: "ترورزۍ", f: "trorzúy"}], [{p: "ترورزۍ", f: "trorzúy"}],
[{p: "ترورزیو", f: "trorzúyo"}, {p: "ترورزو", f: "trorzó"}], [{p: "ترورزۍ", f: "trorzúy"}],
], [{p: "ترورزیو", f: "trorzúyo"}, {p: "ترورزو", f: "trorzó"}],
],
},
// plural: {
// masc: [
// [{ p: "ترورزامن", f: "trorzaamun" }],
// [{ p: "ترورزامنو", f: "trorzaamuno" }],
// ],
// },
}, },
}, },
// Unisex noun ending with a consanant // Unisex noun ending with a consanant
@ -328,20 +356,32 @@ const nouns: Array<{
f: "churg", f: "churg",
g: "", g: "",
e: "rooster, cock; chicken, poultry", e: "rooster, cock; chicken, poultry",
c: "n. m. unisex", c: "n. m. unisex anim.",
i: 4101, i: 4101,
}, },
out: { out: {
masc: [ inflections: {
[{p: "چرګ", f: "churg"}], masc: [
[{p: "چرګ", f: "churg"}], [{p: "چرګ", f: "churg"}],
[{p: "چرګو", f: "churgo"}], [{p: "چرګ", f: "churg"}],
], [{p: "چرګو", f: "churgo"}],
fem: [ ],
[{p: "چرګه", f: "churga"}], fem: [
[{p: "چرګې", f: "churge"}], [{p: "چرګه", f: "churga"}],
[{p: "چرګو", f: "churgo"}], [{p: "چرګې", f: "churge"}],
], [{p: "چرګو", f: "churgo"}],
],
},
plural: {
masc: [
[{p: "چرګان", f: "churgáan"}],
[{p: "چرګانو", f: "churgáano"}],
],
fem: [
[{p: "چرګانې", f: "churgáane"}],
[{p: "چرګانو", f: "churgáano"}],
],
},
}, },
}, },
// ## MASCULINE // ## MASCULINE
@ -357,11 +397,13 @@ const nouns: Array<{
i: 6750, i: 6750,
}, },
out: { out: {
masc: [ inflections: {
[{p: "سړی", f: "saRey"}], masc: [
[{p: "سړي", f: "saRee"}], [{p: "سړی", f: "saRey"}],
[{p: "سړیو", f: "saRiyo"}, {p: "سړو", f: "saRo"}], [{p: "سړي", f: "saRee"}],
], [{p: "سړیو", f: "saRiyo"}, {p: "سړو", f: "saRo"}],
],
}
}, },
}, },
// Masculine regular ending in ی with emphasis on end // Masculine regular ending in ی with emphasis on end
@ -376,11 +418,13 @@ const nouns: Array<{
i: 2931, i: 2931,
}, },
out: { out: {
masc: [ inflections: {
[{p: "ترېلی", f: "treléy"}], masc: [
[{p: "ترېلي", f: "trelée"}], [{p: "ترېلی", f: "treléy"}],
[{p: "ترېلیو", f: "treliyo"}, {p: "ترېلو", f: "trelo"}], [{p: "ترېلي", f: "trelée"}],
], [{p: "ترېلیو", f: "treliyo"}, {p: "ترېلو", f: "trelo"}],
],
},
}, },
}, },
// Masculine ending in tob // Masculine ending in tob
@ -395,11 +439,13 @@ const nouns: Array<{
c: "n. m.", c: "n. m.",
}, },
out: { out: {
masc: [ inflections: {
[{p: "مشرتوب", f: "mushurtob"}], masc: [
[{p: "مشرتابه", f: "mushurtaabu"}], [{p: "مشرتوب", f: "mushurtob"}],
[{p: "مشرتبو", f: "mushurtabo"}], [{p: "مشرتابه", f: "mushurtaabu"}],
], [{p: "مشرتبو", f: "mushurtabo"}],
],
},
}, },
}, },
// Masculine irregular // Masculine irregular
@ -418,11 +464,19 @@ const nouns: Array<{
infbf: "lamandz", infbf: "lamandz",
}, },
out: { out: {
masc: [ inflections: {
[{p: "لمونځ", f: "lamoondz"}], masc: [
[{p: "لمانځه", f: "lamaandzu"}], [{p: "لمونځ", f: "lamoondz"}],
[{p: "لمنځو", f: "lamandzo"}], [{p: "لمانځه", f: "lamaandzu"}],
], [{p: "لمنځو", f: "lamandzo"}],
],
},
// plural: {
// masc: [
// [{ p: "لمونځونه", f: "lamoondzóona" }],
// [{ p: "لمونځونو", f: "lamoondzóono" }],
// ],
// },
}, },
}, },
// Masculine non-inflecting // Masculine non-inflecting
@ -436,7 +490,14 @@ const nouns: Array<{
c: "n. m.", c: "n. m.",
i: 8640, i: 8640,
}, },
out: false, out: {
plural: {
masc: [
[{ p: "کتابونه", f: "kitaabóona" }],
[{ p: "کتابونو", f: "kitaabóono" }],
],
},
},
}, },
// ## FEMININE // ## FEMININE
// Feminine regular ending in ه // Feminine regular ending in ه
@ -451,11 +512,13 @@ const nouns: Array<{
i: 7444, i: 7444,
}, },
out: { out: {
fem: [ inflections: {
[{p: "ښځه", f: "xudza"}], fem: [
[{p: "ښځې", f: "xudze"}], [{p: "ښځه", f: "xudza"}],
[{p: "ښځو", f: "xudzo"}], [{p: "ښځې", f: "xudze"}],
], [{p: "ښځو", f: "xudzo"}],
],
},
}, },
}, },
{ {
@ -469,11 +532,13 @@ const nouns: Array<{
i: 365, i: 365,
}, },
out: { out: {
fem: [ inflections: {
[{p: "اره", f: "ará"}], fem: [
[{p: "ارې", f: "are"}], [{p: "اره", f: "ará"}],
[{p: "ارو", f: "aro"}], [{p: "ارې", f: "are"}],
], [{p: "ارو", f: "aro"}],
],
},
}, },
}, },
// Feminine regular ending in ع - a' // Feminine regular ending in ع - a'
@ -490,11 +555,13 @@ const nouns: Array<{
apf: "maraají", apf: "maraají",
}, },
out: { out: {
fem: [ inflections: {
[{p: "مرجع", f: "marja'"}], fem: [
[{p: "مرجعې", f: "marje"}], [{p: "مرجع", f: "marja'"}],
[{p: "مرجعو", f: "marjo"}], [{p: "مرجعې", f: "marje"}],
], [{p: "مرجعو", f: "marjo"}],
],
},
}, },
}, },
{ {
@ -510,11 +577,13 @@ const nouns: Array<{
apf: "manaabí", apf: "manaabí",
}, },
out: { out: {
fem: [ inflections: {
[{p: "منبع", f: "manbá"}], fem: [
[{p: "منبعې", f: "manbe"}], [{p: "منبع", f: "manbá"}],
[{p: "منبعو", f: "manbo"}], [{p: "منبعې", f: "manbe"}],
], [{p: "منبعو", f: "manbo"}],
],
},
}, },
}, },
// Feminine regular ending in ح - a // Feminine regular ending in ح - a
@ -529,11 +598,13 @@ const nouns: Array<{
i: 5813, i: 5813,
}, },
out: { out: {
fem: [ inflections: {
[{p: "ذبح", f: "zabha"}], fem: [
[{p: "ذبحې", f: "zabhe"}], [{p: "ذبح", f: "zabha"}],
[{p: "ذبحو", f: "zabho"}], [{p: "ذبحې", f: "zabhe"}],
], [{p: "ذبحو", f: "zabho"}],
],
},
}, },
}, },
// Feminine inanimate regular with missing ه // Feminine inanimate regular with missing ه
@ -548,14 +619,17 @@ const nouns: Array<{
i: 9593, i: 9593,
}, },
out: { out: {
fem: [ inflections: {
[{p: "لار", f: "laar"}], fem: [
[{p: "لارې", f: "laare"}], [{p: "لار", f: "laar"}],
[{p: "لارو", f: "laaro"}], [{p: "لارې", f: "laare"}],
], [{p: "لارو", f: "laaro"}],
],
},
}, },
}, },
// Feminine animate ending in a consonant // Feminine animate ending in a consonant
// TODO: ALLOW FOR MULTIPLE PLURAL POSSIBILITIES میندې, میېنې etc.
{ {
in: { in: {
ts: 1527812928, ts: 1527812928,
@ -564,9 +638,18 @@ const nouns: Array<{
g: "", g: "",
e: "mother, mom", e: "mother, mom",
c: "n. f. anim.", c: "n. f. anim.",
ppp: "میندې",
ppf: "meynde",
i: 11113, i: 11113,
}, },
out: false, out: {
plural: {
fem: [
[{ p: "میندې", f: "meynde" }],
[{ p: "میندو", f: "meyndo" }],
],
},
},
}, },
// Feminine regular inanimate ending in ي // Feminine regular inanimate ending in ي
{ {
@ -580,11 +663,13 @@ const nouns: Array<{
i: 5503, i: 5503,
}, },
out: { out: {
fem: [ inflections: {
[{p: "دوستي", f: "dostee"}], fem: [
[{p: "دوستۍ", f: "dostuy"}], [{p: "دوستي", f: "dostee"}],
[{p: "دوستیو", f: "dostuyo"}], [{p: "دوستۍ", f: "dostuy"}],
], [{p: "دوستیو", f: "dostuyo"}],
],
},
}, },
}, },
// Feminine regular ending in ۍ // Feminine regular ending in ۍ
@ -599,11 +684,13 @@ const nouns: Array<{
i: 8718, i: 8718,
}, },
out: { out: {
fem: [ inflections: {
[{p: "کرسۍ", f: "kUrsuy"}], fem: [
[{p: "کرسۍ", f: "kUrsuy"}], [{p: "کرسۍ", f: "kUrsuy"}],
[{p: "کرسیو", f: "kUrsuyo"}, { p: "کرسو", f: "kUrso"}], [{p: "کرسۍ", f: "kUrsuy"}],
], [{p: "کرسیو", f: "kUrsuyo"}, { p: "کرسو", f: "kUrso"}],
],
},
}, },
}, },
// Feminine regular ending in ا // Feminine regular ending in ا
@ -611,18 +698,19 @@ const nouns: Array<{
in: { in: {
ts: 1527812456, ts: 1527812456,
p: "اړتیا", p: "اړتیا",
f: "aRtiyaa, aRtyaa", f: "aRtiyáa, aRtyáa",
g: "", g: "",
e: "need, necessity", e: "need, necessity",
c: "n. f.", c: "n. f.",
i: 376, i: 376,
}, },
out: { out: {
fem: [ plural: {
[{p: "اړتیا", f: "aRtiyaa"}], fem: [
[{p: "اړتیاوې", f: "aRtiyaawe"}], [{p: "اړتیاوې", f: "aRtiyáawe"}, { p: "اړتیاګانې", f:"aRtiyaagáane"}],
[{p: "اړتیاوو", f: "aRtiyaawo"}], [{p: "اړتیاوو", f: "aRtiyáawo"}, { p: "اړتیاګانو", f:"aRtiyaagáano"}],
], ],
},
}, },
}, },
// Feminine regular ending in اع // Feminine regular ending in اع
@ -636,13 +724,15 @@ const nouns: Array<{
c: "n. f.", c: "n. f.",
i: 12205, i: 12205,
}, },
out: { out: false,
fem: [ // out: {
[{p: "وداع", f: "widáa'"}], // plural: {
[{p: "وداعوې", f: "widáawe"}], // fem: [
[{p: "وداعوو", f: "widáawo"}], // [{p: "وداع وې", f: "widáawe"}, {p: "وداع ګانې", f: "widaagáane"}],
], // [{p: "وداع وو", f: "widáawo"}, {p: "وداع ګانو", f: "widaagáano"}],
}, // ],
// },
// },
}, },
// Word with no inflections // Word with no inflections
{ {
@ -658,6 +748,7 @@ const nouns: Array<{
}, },
out: false, out: false,
}, },
// TODO: WORDS THAT ARE ALREADY PLURAL!
]; ];
const others: T.DictionaryEntry[] = [ const others: T.DictionaryEntry[] = [

View File

@ -12,6 +12,10 @@ import {
splitDoubleWord, splitDoubleWord,
ensureUnisexInflections, ensureUnisexInflections,
makePsString, makePsString,
removeFVarients,
concatPsString,
endsInConsonant,
endsInAaOrOo,
} from "./p-text-helpers"; } from "./p-text-helpers";
import { import {
removeAccents, removeAccents,
@ -20,95 +24,102 @@ import * as T from "../types";
const endingInSingleARegex = /[^a]'??[aá]'??$/; const endingInSingleARegex = /[^a]'??[aá]'??$/;
const endingInHeyOrAynRegex = /[^ا][هع]$/; const endingInHeyOrAynRegex = /[^ا][هع]$/;
const endingInAlefRegex = /اع?$/; // const endingInAlefRegex = /اع?$/;
export function inflectWord(word: T.DictionaryEntry): T.Inflections | false { export function inflectWord(word: T.DictionaryEntry): T.InflectorOutput {
// If it's a noun/adj, inflect accordingly // If it's a noun/adj, inflect accordingly
// TODO: What about n. f. / adj. that end in ي ?? // TODO: What about n. f. / adj. that end in ي ??
if (word.noInf) { const w = removeFVarients(word);
if (w.noInf) {
return false; return false;
} }
if (word.c?.includes("doub.")) { if (w.c?.includes("doub.")) {
const words = splitDoubleWord(word); const words = splitDoubleWord(w);
const inflected = words.map((word) => ensureUnisexInflections(inflectWord(word), word)); const inflected = words.map((x) => ensureUnisexInflections(inflectWord(x), x));
return concatInflections( return {
inflected[0], inflections: concatInflections(
inflected[1], inflected[0].inflections,
) as T.UnisexInflections; inflected[1].inflections,
) as T.UnisexInflections,
};
} }
if (word.c && (word.c.includes("adj.") || word.c.includes("unisex"))) { if (w.c && (w.c.includes("adj.") || w.c.includes("unisex"))) {
return handleUnisexWord(word); return handleUnisexWord(w);
} }
if (word.c && (word.c.includes("n. m."))) { if (w.c && (w.c.includes("n. m."))) {
return handleMascNoun(word); return handleMascNoun(w);
} }
if (word.c && (word.c.includes("n. f."))) { if (w.c && (w.c.includes("n. f."))) {
return handleFemNoun(word); return handleFemNoun(w);
} }
// It's not a noun/adj // It's not a noun/adj
return false; return false;
} }
// LEVEL 2 FUNCTIONS // LEVEL 2 FUNCTIONS
function handleUnisexWord(word: T.DictionaryEntry): T.Inflections | false { function handleUnisexWord(word: T.DictionaryEntryNoFVars): T.InflectorOutput {
// Get first of comma seperated phonetics entries
const f = word.f.split(",")[0].trim();
// Get last letter of Pashto and last two letters of phonetics // Get last letter of Pashto and last two letters of phonetics
// TODO: !!! Handle weird endings / symbols ' etc. // TODO: !!! Handle weird endings / symbols ' etc.
const pEnd = word.p.slice(-1); const pEnd = word.p.slice(-1);
const plural = makePlural(word);
if (word.infap && word.infaf && word.infbp && word.infbf) { if (word.infap && word.infaf && word.infbp && word.infbf) {
return inflectIrregularUnisex(word.p, f, [ return {
{p: word.infap, f: word.infaf}, inflections: inflectIrregularUnisex(word.p, word.f, [
{p: word.infbp, f: word.infbf}, {p: word.infap, f: word.infaf},
]); {p: word.infbp, f: word.infbf},
]),
plural,
};
} }
if (pEnd === "ی" && f.slice(-2) === "ey") { if (pEnd === "ی" && word.f.slice(-2) === "ey") {
return inflectRegularYeyUnisex(word.p, f); return { inflections: inflectRegularYeyUnisex(word.p, word.f), plural };
} }
if (pEnd === "ه" && word.g.slice(-1) === "u") { if (pEnd === "ه" && word.g.slice(-1) === "u") {
return inflectRegularShwaEndingUnisex(word.p, f); return { inflections: inflectRegularShwaEndingUnisex(word.p, word.f), plural };
} }
if (pEnd === "ی" && f.slice(-2) === "éy") { if (pEnd === "ی" && word.f.slice(-2) === "éy") {
return inflectEmphasizedYeyUnisex(word.p, f); return { inflections: inflectEmphasizedYeyUnisex(word.p, word.f), plural };
} }
if ( if (
pashtoConsonants.includes(pEnd) || pashtoConsonants.includes(pEnd) ||
word.p.slice(-2) === "وی" || word.p.slice(-2) === "وی" ||
word.p.slice(-2) === "ای" || word.p.slice(-2) === "ای" ||
(word.p.slice(-1) === "ه" && f.slice(-1) === "h") (word.p.slice(-1) === "ه" && word.f.slice(-1) === "h")
) { ) {
return inflectConsonantEndingUnisex(word.p, f); return { inflections: inflectConsonantEndingUnisex(word.p, word.f), plural };
} }
return false; return false;
} }
function handleMascNoun(word: T.DictionaryEntry): T.Inflections | false { function handleMascNoun(w: T.DictionaryEntryNoFVars): T.InflectorOutput {
// Get first of comma seperated phonetics entries
const f = word.f.split(",")[0].trim();
// Get last letter of Pashto and last two letters of phonetics // Get last letter of Pashto and last two letters of phonetics
// TODO: !!! Handle weird endings / symbols ' etc. // TODO: !!! Handle weird endings / symbols ' etc.
const pEnd = word.p.slice(-1); const plural = makePlural(w);
const fEnd = f.slice(-2); const pEnd = w.p.slice(-1);
if (word.infap && word.infaf && word.infbp && word.infbf) { const fEnd = w.f.slice(-2);
return inflectIrregularMasc(word.p, f, [ if (w.infap && w.infaf && w.infbp && w.infbf) {
{p: word.infap, f: word.infaf}, return {
{p: word.infbp, f: word.infbf}, inflections: inflectIrregularMasc(w.p, w.f, [
]); {p: w.infap, f: w.infaf},
{p: w.infbp, f: w.infbf},
]),
plural,
};
} }
const isTobEnding = (word.p.slice(-3) === "توب" && ["tób", "tob"].includes(f.slice(-3)) && word.p.length > 3); const isTobEnding = (w.p.slice(-3) === "توب" && ["tób", "tob"].includes(w.f.slice(-3)) && w.p.length > 3);
if (isTobEnding) { if (isTobEnding) {
return inflectTobMasc(word.p, f); return { inflections: inflectTobMasc(w.p, w.f), plural };
} }
if (pEnd === "ی" && fEnd === "ey") { if (pEnd === "ی" && fEnd === "ey") {
return inflectRegularYeyMasc(word.p, f); return { inflections: inflectRegularYeyMasc(w.p, w.f), plural };
} }
if (pEnd === "ی" && fEnd === "éy") { if (pEnd === "ی" && fEnd === "éy") {
return inflectRegularEmphasizedYeyMasc(word.p, f); return { inflections: inflectRegularEmphasizedYeyMasc(w.p, w.f), plural };
} }
return false; return plural ? { plural } : false
} }
function handleFemNoun(word: T.DictionaryEntry): T.Inflections | false { function handleFemNoun(word: T.DictionaryEntryNoFVars): T.InflectorOutput {
// Get first of comma seperated phonetics entries // Get first of comma seperated phonetics entries
const f = word.f.split(",")[0].trim(); const f = word.f.split(",")[0].trim();
/* istanbul ignore next */ // will always have word.c at this point /* istanbul ignore next */ // will always have word.c at this point
@ -116,25 +127,27 @@ function handleFemNoun(word: T.DictionaryEntry): T.Inflections | false {
const animate = c.includes("anim."); const animate = c.includes("anim.");
const pEnd = word.p.slice(-1); const pEnd = word.p.slice(-1);
const plural = makePlural(word);
if (endingInHeyOrAynRegex.test(word.p) && endingInSingleARegex.test(f)) { if (endingInHeyOrAynRegex.test(word.p) && endingInSingleARegex.test(f)) {
return inflectRegularAFem(word.p, f); return { inflections: inflectRegularAFem(word.p, f), plural };
} }
if (word.p.slice(-1) === "ح" && endingInSingleARegex.test(f)) { if (word.p.slice(-1) === "ح" && endingInSingleARegex.test(f)) {
return inflectRegularAWithHimPEnding(word.p, f); return { inflections: inflectRegularAWithHimPEnding(word.p, f), plural };
} }
if (pashtoConsonants.includes(pEnd) && !animate) { if (pashtoConsonants.includes(pEnd) && !animate) {
return inflectRegularInanMissingAFem(word.p, f); return { inflections: inflectRegularInanMissingAFem(word.p, f), plural };
} }
if (pEnd === "ي" && (!animate)) { if (pEnd === "ي" && (!animate)) {
return inflectRegularInanEeFem(word.p, f); return { inflections: inflectRegularInanEeFem(word.p, f), plural };
} }
if (pEnd === "ۍ") { if (pEnd === "ۍ") {
return inflectRegularUyFem(word.p, f); return { inflections: inflectRegularUyFem(word.p, f), plural };
} }
if (endingInAlefRegex.test(word.p)) { // if (endingInAlefRegex.test(word.p)) {
return inflectRegularAaFem(word.p, f); // return { inflections: inflectRegularAaFem(word.p, f) };
} // }
return false; return plural ? { plural } : false;
} }
// LEVEL 3 FUNCTIONS // LEVEL 3 FUNCTIONS
@ -341,13 +354,77 @@ function inflectRegularUyFem(p: string, f: string): T.Inflections {
}; };
} }
function inflectRegularAaFem(p: string, f: string): T.Inflections { function makePashtoPlural(word: T.DictionaryEntryNoFVars): T.PluralInflections | undefined {
const baseF = ["'", ""].includes(f.slice(-1)) ? f.slice(0, -1) : f; if (!(word.ppp && word.ppf)) return undefined;
return { const base = makePsString(word.ppp, word.ppf);
fem: [ // TODO: Add male Pashto plural
[{p, f}], if (word.c?.includes("n. f.")) {
[{p: `${p}وې`, f: `${baseF}we`}], return {
[{p: `${p}وو`, f: `${baseF}wo`}], fem: [
], [base],
}; // todo: function to add و ending automatically
[concatPsString(
makePsString(base.p.slice(0, -1), base.f.slice(0, -1)),
{ p: "و", f: "o" },
)],
],
}
}
// TODO: handle masculine and unisex
return undefined;
}
function makePlural(w: T.DictionaryEntryNoFVars): T.PluralInflections | undefined {
// TODO: Include the Pashto plural thing here
const pashtoPlural = makePashtoPlural(w);
if (pashtoPlural) return pashtoPlural;
function addMascPluralSuffix(animate?: boolean): T.PluralInflectionSet {
const base = removeAccents(w);
return [
[concatPsString(base, animate ? { p: "ان", f: "áan" } : { p: "ونه", f: "óona" })],
[concatPsString(base, animate ? { p: "انو", f: "áano" } : { p: "ونو", f: "óono" })],
];
}
function addAnimUnisexPluralSuffix(): T.UnisexSet<T.PluralInflectionSet> {
const base = removeAccents(w);
return {
masc: addMascPluralSuffix(true),
fem: [
[concatPsString(base, { p: "انې", f: "áane" })],
[concatPsString(base, { p: "انو", f: "áano" })],
],
};
}
function addFemLongVowelSuffix(): T.PluralInflectionSet {
const base = makePsString(w.p, w.f);
const baseWOutAccents = removeAccents(base);
return [
[concatPsString(base, { p: "وې", f: "we" }), concatPsString(baseWOutAccents, { p: "ګانې", f: "gáane" })],
[concatPsString(base, { p: "وو", f: "wo" }), concatPsString(baseWOutAccents, { p: "ګانو", f: "gáano" })],
];
}
const anim = w.c?.includes("anim.");
const type = (w.c?.includes("unisex"))
? "unisex noun"
: (w.c?.includes("n. m."))
? "masc noun"
: (w.c?.includes("n. f."))
? "fem noun"
: "other";
if (type === "unisex noun" && endsInConsonant(w) && (!w.infap) && anim) {
return addAnimUnisexPluralSuffix();
}
if (type === "masc noun" && endsInConsonant(w) && (!w.infap) && (w.p.slice(-3) !== "توب")) {
return {
masc: addMascPluralSuffix(anim),
};
}
// TODO: What about endings in long ee / animate at inanimate
if (type === "fem noun" && endsInAaOrOo(w) && (!w.infap)) {
return {
fem: addFemLongVowelSuffix(),
};
}
return undefined;
} }

View File

@ -121,7 +121,7 @@ export function getVerbInfo(
return getGenerativeStativeCompoundVerbInfo(entry, complement as T.DictionaryEntry); return getGenerativeStativeCompoundVerbInfo(entry, complement as T.DictionaryEntry);
} }
} }
const comp = complement ? ensureUnisexInflections(complement) : undefined; const comp = complement ? ensureUnisexInf(complement) : undefined;
const root = getVerbRoots(entry, transitivity, comp); const root = getVerbRoots(entry, transitivity, comp);
const stem = getVerbStems(entry, root, transitivity, comp); const stem = getVerbStems(entry, root, transitivity, comp);
const infinitive = "mascSing" in root.imperfective ? root.imperfective.mascSing.long : root.imperfective.long; const infinitive = "mascSing" in root.imperfective ? root.imperfective.mascSing.long : root.imperfective.long;
@ -877,7 +877,7 @@ function addOoPrefix(
}; };
} }
function ensureUnisexInflections(complement: T.DictionaryEntry): T.UnisexInflections { function ensureUnisexInf(complement: T.DictionaryEntry): T.UnisexInflections {
const inflected = inflectWord(complement); const inflected = inflectWord(complement);
const isUnisex = inflected && (("masc" in inflected) && ("fem" in inflected)); const isUnisex = inflected && (("masc" in inflected) && ("fem" in inflected));
if (isUnisex) { if (isUnisex) {

View File

@ -114,6 +114,10 @@ export type DictionaryEntry = {
ep?: string; ep?: string;
} }
export type DictionaryEntryNoFVars = DictionaryEntry & { __brand: "name for a dictionary entry with all the phonetics variations removed" };
export type PsStringNoFVars = PsString & { __brand: "name for a ps string with all the phonetics variations removed" };
export type FStringNoFVars = string & { __brand: "name for a phonetics string with all the phonetics variations removed" };
export type DictionaryEntryTextField = "p" | "f" | "e" | "c" | "infap" | "infaf" | "infbp" | "infbf" | "app" | "apf" | "ppp" | "ppf" | "psp" | "psf" | "ssp" | "ssf" | "prp" | "prf" | "pprtp" | "pprtf" | "tppp" | "tppf" | "ec" | "ep"; export type DictionaryEntryTextField = "p" | "f" | "e" | "c" | "infap" | "infaf" | "infbp" | "infbf" | "app" | "apf" | "ppp" | "ppf" | "psp" | "psf" | "ssp" | "ssf" | "prp" | "prf" | "pprtp" | "pprtf" | "tppp" | "tppf" | "ec" | "ep";
export type DictionaryEntryBooleanField = "noInf" | "shortIntrans" | "noOo" | "sepOo" | "diacExcept"; export type DictionaryEntryBooleanField = "noInf" | "shortIntrans" | "noOo" | "sepOo" | "diacExcept";
export type DictionaryEntryNumberField = "ts" | "i" | "l" | "separationAtP" | "separationAtF"; export type DictionaryEntryNumberField = "ts" | "i" | "l" | "separationAtP" | "separationAtF";
@ -334,12 +338,25 @@ export type PerfectContent = {
// Plain, 1st, and 2nd Inflection // Plain, 1st, and 2nd Inflection
export type InflectionSet = ArrayFixed<ArrayOneOrMore<PsString>, 3>; export type InflectionSet = ArrayFixed<ArrayOneOrMore<PsString>, 3>;
// Plural and Second Inflection
export type PluralInflectionSet = ArrayFixed<ArrayOneOrMore<PsString>, 2>
export type Gender = "masc" | "fem"; export type Gender = "masc" | "fem";
export type UnisexInflections = Record<Gender, InflectionSet>; export type UnisexSet<T> = Record<Gender, T>;
export type GenderedSet<T> = UnisexSet<T> | Omit<UnisexSet<T>, "fem"> | Omit<UnisexSet<T>, "masc">;
export type UnisexInflections = UnisexSet<InflectionSet>;
export type Inflections = UnisexInflections export type Inflections = GenderedSet<InflectionSet>;
| Omit<UnisexInflections, "fem"> | Omit<UnisexInflections, "masc">;
export type PluralInflections = GenderedSet<PluralInflectionSet>;
export type InflectorOutput = {
plural: PluralInflections,
inflections?: Inflections,
} | {
inflections: Inflections,
} | false;
export type PersonLine = [ export type PersonLine = [
/** singular form of person */ /** singular form of person */