refactor with more abstraction
This commit is contained in:
parent
502031b054
commit
46fd6e66e8
|
@ -14,6 +14,7 @@ import {
|
||||||
hasShwaEnding,
|
hasShwaEnding,
|
||||||
mapPsString,
|
mapPsString,
|
||||||
endsWith,
|
endsWith,
|
||||||
|
psStringFromEntry,
|
||||||
} from "./p-text-helpers";
|
} from "./p-text-helpers";
|
||||||
import { removeDuplicates } from "./phrase-building/vp-tools";
|
import { removeDuplicates } from "./phrase-building/vp-tools";
|
||||||
import {
|
import {
|
||||||
|
@ -25,6 +26,16 @@ import {
|
||||||
isNounEntry,
|
isNounEntry,
|
||||||
isNumberEntry,
|
isNumberEntry,
|
||||||
} from "./type-predicates";
|
} from "./type-predicates";
|
||||||
|
import { semigroupPsString } from "../dist/lib/src/fp-ps";
|
||||||
|
|
||||||
|
const concatPs = semigroupPsString.concat;
|
||||||
|
|
||||||
|
const o = { p: "و", f: "o" };
|
||||||
|
const ó = { p: "و", f: "ó" };
|
||||||
|
const a = { p: "ه", f: "a" };
|
||||||
|
const á = { p: "ه", f: "á" };
|
||||||
|
const e = { p: "ې", f: "e" };
|
||||||
|
const é = { p: "ې", f: "é" };
|
||||||
|
|
||||||
type Plurals =
|
type Plurals =
|
||||||
| {
|
| {
|
||||||
|
@ -33,11 +44,11 @@ type Plurals =
|
||||||
}
|
}
|
||||||
| undefined;
|
| undefined;
|
||||||
|
|
||||||
const endingInSingleARegex = /[^a]'?’?[aá]'?’?$/;
|
// const endingInSingleARegex = /[^a]'?’?[aá]'?’?$/;
|
||||||
const endingInHayOrAynRegex = /[^ا][هع]$/;
|
// const endingInHayOrAynRegex = /[^ا][هع]$/;
|
||||||
|
|
||||||
export function getInfsAndVocative(
|
export function getInfsAndVocative(
|
||||||
entry: T.DictionaryEntryNoFVars,
|
entryR: T.DictionaryEntryNoFVars,
|
||||||
plurals: Plurals
|
plurals: Plurals
|
||||||
):
|
):
|
||||||
| {
|
| {
|
||||||
|
@ -45,51 +56,51 @@ export function getInfsAndVocative(
|
||||||
vocative?: T.PluralInflections;
|
vocative?: T.PluralInflections;
|
||||||
}
|
}
|
||||||
| false {
|
| false {
|
||||||
if (!isInflectableEntry(entry)) {
|
if (!isInflectableEntry(entryR)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const e: T.InflectableEntry = entry as T.InflectableEntry;
|
const entry: T.InflectableEntry = entryR as T.InflectableEntry;
|
||||||
const pattern = getInflectionPattern(e);
|
const pattern = getInflectionPattern(entry);
|
||||||
if (
|
if (
|
||||||
pattern === 0 &&
|
pattern === 0 &&
|
||||||
isFemNounEntry(e) &&
|
isFemNounEntry(entry) &&
|
||||||
isAnimNounEntry(e) &&
|
isAnimNounEntry(entry) &&
|
||||||
endsInConsonant(e)
|
endsInConsonant(entry)
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
vocative: vocFemAnimException({
|
vocative: vocFemAnimException({
|
||||||
e,
|
entry,
|
||||||
plurals: genderPlural("fem", plurals),
|
plurals: genderPlural("fem", plurals),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const gender: T.Gender | "unisex" =
|
const gender: T.Gender | "unisex" =
|
||||||
isAdjOrUnisexNounEntry(e) || isNumberEntry(e)
|
isAdjOrUnisexNounEntry(entry) || isNumberEntry(entry)
|
||||||
? "unisex"
|
? "unisex"
|
||||||
: isMascNounEntry(e)
|
: isMascNounEntry(entry)
|
||||||
? "masc"
|
? "masc"
|
||||||
: "fem";
|
: "fem";
|
||||||
if (pattern === 0) {
|
if (pattern === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (pattern === 6) {
|
if (pattern === 6) {
|
||||||
return pattern6({ e, plurals: genderPlural("fem", plurals) });
|
return pattern6({ entry, plurals: genderPlural("fem", plurals) });
|
||||||
}
|
}
|
||||||
const funcs = patternFuncs[pattern];
|
const funcs = patternFuncs[pattern];
|
||||||
const masc =
|
const masc =
|
||||||
gender === "unisex" || gender === "masc"
|
gender === "unisex" || gender === "masc"
|
||||||
? funcs.masc({ e, plurals: genderPlural("masc", plurals) })
|
? funcs.masc({ entry, plurals: genderPlural("masc", plurals) })
|
||||||
: undefined;
|
: undefined;
|
||||||
const fem =
|
const fem =
|
||||||
gender === "unisex" || gender === "fem"
|
gender === "unisex" || gender === "fem"
|
||||||
? funcs.fem({ e, plurals: genderPlural("fem", plurals) })
|
? funcs.fem({ entry, plurals: genderPlural("fem", plurals) })
|
||||||
: undefined;
|
: undefined;
|
||||||
return aggregateInfsAndVoc(masc, fem);
|
return aggregateInfsAndVoc(masc, fem);
|
||||||
}
|
}
|
||||||
|
|
||||||
type PatternInput = {
|
type PatternInput = {
|
||||||
e: T.DictionaryEntryNoFVars | T.NounEntry | T.InflectableEntry;
|
entry: T.DictionaryEntryNoFVars | T.NounEntry | T.InflectableEntry;
|
||||||
plurals: T.PsString[];
|
plurals: T.PsString[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,45 +118,45 @@ const patternFuncs: Record<
|
||||||
fem: vocPattern1Fem,
|
fem: vocPattern1Fem,
|
||||||
},
|
},
|
||||||
2: {
|
2: {
|
||||||
masc: vocPattern2Masc,
|
masc: pattern2Masc,
|
||||||
fem: vocPattern2Fem,
|
fem: pattern2Fem,
|
||||||
},
|
},
|
||||||
3: {
|
3: {
|
||||||
masc: vocPattern3Masc,
|
masc: pattern3Masc,
|
||||||
fem: vocPattern3Fem,
|
fem: pattern3Fem,
|
||||||
},
|
},
|
||||||
4: {
|
4: {
|
||||||
masc: vocPattern4Masc,
|
masc: pattern4Masc,
|
||||||
fem: vocPattern4Fem,
|
fem: pattern4Fem,
|
||||||
},
|
},
|
||||||
5: {
|
5: {
|
||||||
masc: vocPattern5Masc,
|
masc: vocPattern5Masc,
|
||||||
fem: vocPattern5Fem,
|
fem: pattern5Fem,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function addPlurals(
|
function addPlurals(
|
||||||
e: T.ArrayOneOrMore<T.PsString>,
|
x: T.ArrayOneOrMore<T.PsString>,
|
||||||
plurals: T.PsString[]
|
plurals: T.PsString[]
|
||||||
): T.ArrayOneOrMore<T.PsString> {
|
): T.ArrayOneOrMore<T.PsString> {
|
||||||
if (!plurals) {
|
if (!plurals) {
|
||||||
return e;
|
return x;
|
||||||
}
|
}
|
||||||
return removeDuplicates([...e, ...plurals]) as T.ArrayOneOrMore<T.PsString>;
|
return removeDuplicates([...x, ...plurals]) as T.ArrayOneOrMore<T.PsString>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pattern6({ e, plurals }: PatternInput): {
|
function pattern6({ entry, plurals }: PatternInput): {
|
||||||
inflections: T.Inflections;
|
inflections: T.Inflections;
|
||||||
vocative: T.PluralInflections;
|
vocative: T.PluralInflections;
|
||||||
} {
|
} {
|
||||||
const base = removeAccents({ p: e.p.slice(0, -1), f: e.f.slice(0, -2) });
|
const base = removeAccents({
|
||||||
|
p: entry.p.slice(0, -1),
|
||||||
|
f: entry.f.slice(0, -2),
|
||||||
|
});
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: e.p, f: e.f }],
|
[psStringFromEntry(entry)],
|
||||||
[{ p: `${base.p}ۍ`, f: `${base.f}úy` }],
|
[concatPs(base, { p: "ۍ", f: "úy" })],
|
||||||
[
|
[concatPs(base, { p: "یو", f: "úyo" }), concatPs(base, ó)],
|
||||||
{ p: `${base.p}یو`, f: `${base.f}úyo` },
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}ó` },
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections: {
|
inflections: {
|
||||||
|
@ -158,83 +169,88 @@ function pattern6({ e, plurals }: PatternInput): {
|
||||||
}
|
}
|
||||||
|
|
||||||
function vocFemAnimException({
|
function vocFemAnimException({
|
||||||
e,
|
entry,
|
||||||
plurals,
|
plurals,
|
||||||
}: PatternInput): T.PluralInflections {
|
}: PatternInput): T.PluralInflections {
|
||||||
if (!e.ppp || !e.ppf) {
|
if (!entry.ppp || !entry.ppf) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"plural missing for feminine animate exception noun " + e.p
|
"plural missing for feminine animate exception noun " + entry.p
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO: HANDLE BETTER WITH PLURALS!
|
// TODO: HANDLE BETTER WITH PLURALS!
|
||||||
const plurBase = mapPsString(
|
const plurBase = mapPsString(
|
||||||
(x) => x.slice(0, -1),
|
(x) => x.slice(0, -1),
|
||||||
makePsString(e.ppp, e.ppf)
|
makePsString(entry.ppp, entry.ppf)
|
||||||
);
|
);
|
||||||
const base =
|
const base =
|
||||||
countSyllables(e) === 1 ? accentOnNFromEnd(e, 0) : makePsString(e.p, e.f);
|
countSyllables(entry) === 1
|
||||||
|
? accentOnNFromEnd(entry, 0)
|
||||||
|
: psStringFromEntry(entry);
|
||||||
return {
|
return {
|
||||||
fem: [
|
fem: [[concatPs(base, e)], addPlurals([concatPs(plurBase, o)], plurals)],
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}e` }],
|
|
||||||
addPlurals([{ p: `${plurBase.p}و`, f: `${plurBase.f}o` }], plurals),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function vocPattern1Masc({ e, plurals }: PatternInput): InflectionsAndVocative {
|
function vocPattern1Masc({
|
||||||
if (isNounEntry(e) && endsInTob(e)) {
|
entry,
|
||||||
const base = mapPsString((x) => x.slice(0, -3), e);
|
plurals,
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
}: PatternInput): InflectionsAndVocative {
|
||||||
{ p: `${base.p}تبو`, f: `${base.f}tábo` },
|
const plain = psStringFromEntry(entry);
|
||||||
|
if (isNounEntry(entry) && endsInTob(entry)) {
|
||||||
|
const base = mapPsString((x) => x.slice(0, -3), entry);
|
||||||
|
const inflections: T.InflectionSet = [
|
||||||
|
[plain],
|
||||||
|
[concatPs(base, { p: "تابه", f: "taabú" })],
|
||||||
|
[concatPs(base, { p: "تبو", f: "tábo" })],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections: [
|
inflections,
|
||||||
[{ p: e.p, f: e.f }],
|
vocative: [[concatPs(plain, a)], addPlurals(inflections[2], plurals)],
|
||||||
[{ p: `${base.p}تابه`, f: `${base.f}taabú` }],
|
|
||||||
second,
|
|
||||||
],
|
|
||||||
vocative: [[{ p: `${e.p}ه`, f: `${e.f}a` }], addPlurals(second, plurals)],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const shwaEnding = hasShwaEnding(e);
|
const shwaEnding = hasShwaEnding(entry);
|
||||||
const base = mapGen(
|
const base = mapGen(
|
||||||
(ps) => (countSyllables(e) === 1 ? accentOnNFromEnd(ps, 0) : ps),
|
(ps) => (countSyllables(entry) === 1 ? accentOnNFromEnd(ps, 0) : ps),
|
||||||
mapPsString((x: string): string => (shwaEnding ? x.slice(0, -1) : x), e)
|
mapPsString((x: string): string => (shwaEnding ? x.slice(0, -1) : x), entry)
|
||||||
);
|
);
|
||||||
if (shwaEnding && e.f.endsWith("ú")) {
|
if (shwaEnding && entry.f.endsWith("ú")) {
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
const inflections: T.InflectionSet = [
|
||||||
{ p: `${base.p}و`, f: `${base.f}ó` },
|
[plain],
|
||||||
|
[plain],
|
||||||
|
[concatPs(base, ó)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections: [[{ p: e.p, f: e.f }], [{ p: e.p, f: e.f }], second],
|
inflections,
|
||||||
vocative: [
|
vocative: [[concatPs(base, á)], addPlurals(inflections[2], plurals)],
|
||||||
[{ p: `${base.p}ه`, f: `${base.f}á` }],
|
|
||||||
addPlurals(second, plurals),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// TODO: shouldn't this be accent-sensitive?
|
// TODO: shouldn't this be accent-sensitive?
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
const inflections: T.InflectionSet = [[plain], [plain], [concatPs(base, o)]];
|
||||||
{ p: `${base.p}و`, f: `${base.f}o` },
|
|
||||||
];
|
|
||||||
return {
|
return {
|
||||||
inflections: [[{ p: e.p, f: e.f }], [{ p: e.p, f: e.f }], second],
|
inflections,
|
||||||
vocative: [
|
vocative: [
|
||||||
[{ p: `${base.p}ه`, f: `${base.f}a` }],
|
[concatPs(base, { p: "ه", f: "a" })],
|
||||||
addPlurals(second, plurals),
|
addPlurals(inflections[2], plurals),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this is HUGELY repetitive refactor this!
|
// TODO this is HUGELY repetitive refactor this!
|
||||||
function vocPattern1Fem({ e, plurals }: PatternInput): InflectionsAndVocative {
|
function vocPattern1Fem({
|
||||||
const shwaEnding = hasShwaEnding(e);
|
entry,
|
||||||
const hasFemEnding = endsWith([{ p: "ه", f: "a" }], e) || shwaEnding;
|
plurals,
|
||||||
|
}: PatternInput): InflectionsAndVocative {
|
||||||
|
const shwaEnding = hasShwaEnding(entry);
|
||||||
|
const hasFemEnding = endsWith([{ p: "ه", f: "a" }], entry) || shwaEnding;
|
||||||
|
const endAccented = accentIsOnEnd(entry);
|
||||||
const base = mapGen(
|
const base = mapGen(
|
||||||
(ps) => (countSyllables(e) === 1 ? accentOnNFromEnd(ps, 0) : ps),
|
(ps) =>
|
||||||
|
countSyllables(entry) === 1 && !endAccented
|
||||||
|
? accentOnNFromEnd(ps, 0)
|
||||||
|
: ps,
|
||||||
hasFemEnding
|
hasFemEnding
|
||||||
? mapPsString((x) => x.slice(0, -1), e)
|
? mapPsString((x) => x.slice(0, -1), entry)
|
||||||
: makePsString(e.p, e.f)
|
: psStringFromEntry(entry)
|
||||||
);
|
);
|
||||||
if (
|
if (
|
||||||
endsWith(
|
endsWith(
|
||||||
|
@ -242,291 +258,268 @@ function vocPattern1Fem({ e, plurals }: PatternInput): InflectionsAndVocative {
|
||||||
{ p: "ع", f: "a" },
|
{ p: "ع", f: "a" },
|
||||||
{ p: "ع", f: "a'" },
|
{ p: "ع", f: "a'" },
|
||||||
],
|
],
|
||||||
e
|
entry
|
||||||
) &&
|
) &&
|
||||||
!["ا", "ی", "ې"].includes(e.p.at(-2) || "")
|
!["ا", "ی", "ې"].includes(e.p.at(-2) || "")
|
||||||
) {
|
) {
|
||||||
const base = applyPsString(
|
const base2 = applyPsString(
|
||||||
{
|
{
|
||||||
f: (f) => f.slice(0, f.endsWith("'") ? -2 : -1),
|
f: (f) => f.slice(0, f.endsWith("'") ? -2 : -1),
|
||||||
},
|
},
|
||||||
e
|
entry
|
||||||
);
|
);
|
||||||
if (accentIsOnEnd(e)) {
|
if (endAccented) {
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}ó` },
|
|
||||||
];
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: e.p, f: e.f }],
|
[psStringFromEntry(entry)],
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}é` }],
|
[concatPs(base2, é)],
|
||||||
second,
|
[concatPs(base2, ó)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [inflections[1], addPlurals(second, plurals)],
|
vocative: [inflections[1], addPlurals(inflections[2], plurals)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}o` },
|
|
||||||
];
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: e.p, f: e.f }],
|
[psStringFromEntry(entry)],
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}e` }],
|
[concatPs(base2, e)],
|
||||||
second,
|
[concatPs(base2, o)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [inflections[1], addPlurals(second, plurals)],
|
vocative: [inflections[1], addPlurals(inflections[2], plurals)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
endsWith([{ p: "ح", f: "a" }], e) &&
|
endsWith([{ p: "ح", f: "a" }], entry) &&
|
||||||
!["ا", "ی", "ې"].includes(e.p.at(-2) || "")
|
!["ا", "ی", "ې"].includes(entry.p.at(-2) || "")
|
||||||
) {
|
) {
|
||||||
const base = applyPsString(
|
const base = applyPsString(
|
||||||
{
|
{
|
||||||
f: (f) => f.slice(0, -1),
|
f: (f) => f.slice(0, -1),
|
||||||
},
|
},
|
||||||
e
|
entry
|
||||||
);
|
);
|
||||||
if (accentIsOnEnd(e)) {
|
if (accentIsOnEnd(entry)) {
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}ó` },
|
|
||||||
];
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: e.p, f: e.f }],
|
[psStringFromEntry(entry)],
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}é` }],
|
[concatPs(base, é)],
|
||||||
second,
|
[concatPs(base, ó)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [inflections[1], addPlurals(second, plurals)],
|
vocative: [inflections[1], addPlurals(inflections[2], plurals)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}o` },
|
|
||||||
];
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: e.p, f: e.f }],
|
[psStringFromEntry(entry)],
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}e` }],
|
[concatPs(base, e)],
|
||||||
second,
|
[concatPs(base, o)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [inflections[1], addPlurals(second, plurals)],
|
vocative: [inflections[1], addPlurals(inflections[2], plurals)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (hasFemEnding && accentIsOnEnd(e)) {
|
if (hasFemEnding && accentIsOnEnd(entry)) {
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}ó` },
|
|
||||||
];
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: `${base.p}ه`, f: `${base.f}á` }],
|
[concatPs(base, á)],
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}é` }],
|
[concatPs(base, é)],
|
||||||
second,
|
[concatPs(base, ó)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [inflections[1], addPlurals(second, plurals)],
|
vocative: [inflections[1], addPlurals(inflections[2], plurals)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (isFemNounEntry(e) && endsInConsonant(e)) {
|
if (isFemNounEntry(entry) && endsInConsonant(entry)) {
|
||||||
const baseForInf = countSyllables(e) === 1 ? accentOnNFromEnd(e, 0) : e;
|
const baseForInf =
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
countSyllables(entry) === 1 ? accentOnNFromEnd(entry, 0) : e;
|
||||||
{ p: `${baseForInf.p}و`, f: `${baseForInf.f}o` },
|
|
||||||
];
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: e.p, f: e.f }],
|
[psStringFromEntry(entry)],
|
||||||
[{ p: `${baseForInf.p}ې`, f: `${baseForInf.f}e` }],
|
[concatPs(baseForInf, e)],
|
||||||
second,
|
[concatPs(baseForInf, o)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [inflections[1], addPlurals(second, plurals)],
|
vocative: [inflections[1], addPlurals(inflections[2], plurals)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}o` },
|
|
||||||
];
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: `${base.p}ه`, f: `${base.f}a` }],
|
[concatPs(base, a)],
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}e` }],
|
[concatPs(base, e)],
|
||||||
second,
|
[concatPs(base, o)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [inflections[1], addPlurals(second, plurals)],
|
vocative: [inflections[1], addPlurals(inflections[2], plurals)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function vocPattern2Masc({ e, plurals }: PatternInput): InflectionsAndVocative {
|
function pattern2Masc({
|
||||||
const base = makePsString(e.p.slice(0, -1), e.f.slice(0, -2));
|
entry,
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
plurals,
|
||||||
{ p: `${base.p}یو`, f: `${base.f}iyo` },
|
}: PatternInput): InflectionsAndVocative {
|
||||||
{ p: `${base.p}و`, f: `${base.f}o` },
|
const base = makePsString(entry.p.slice(0, -1), entry.f.slice(0, -2));
|
||||||
|
const inflections: T.InflectionSet = [
|
||||||
|
[psStringFromEntry(entry)],
|
||||||
|
[concatPs(base, { p: "ي", f: "ee" })],
|
||||||
|
[concatPs(base, { p: "یو", f: "iyo" }), concatPs(base, { p: "و", f: "o" })],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections: [
|
inflections,
|
||||||
[{ p: e.p, f: e.f }],
|
|
||||||
[{ p: `${base.p}ي`, f: `${base.f}ee` }],
|
|
||||||
second,
|
|
||||||
],
|
|
||||||
vocative: [
|
vocative: [
|
||||||
[{ p: `${base.p}یه`, f: `${base.f}iya` }],
|
[concatPs(base, { p: "یه", f: "iya" })],
|
||||||
addPlurals(second, plurals),
|
addPlurals(inflections[2], plurals),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function vocPattern2Fem({ e, plurals }: PatternInput): InflectionsAndVocative {
|
function pattern2Fem({ entry, plurals }: PatternInput): InflectionsAndVocative {
|
||||||
const base = makePsString(
|
const base = makePsString(
|
||||||
e.p.slice(0, -1),
|
entry.p.slice(0, -1),
|
||||||
e.f.slice(0, e.f.endsWith("ay") ? -2 : -1)
|
entry.f.slice(0, entry.f.endsWith("ay") ? -2 : -1)
|
||||||
);
|
);
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}یو`, f: `${base.f}iyo` },
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}o` },
|
|
||||||
];
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}e` }],
|
[concatPs(base, e)],
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}e` }],
|
[concatPs(base, e)],
|
||||||
second,
|
[concatPs(base, { p: "یو", f: "iyo" }), concatPs(base, o)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [inflections[0], addPlurals(second, plurals)],
|
vocative: [inflections[1], addPlurals(inflections[2], plurals)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function vocPattern3Masc({ e, plurals }: PatternInput): InflectionsAndVocative {
|
function pattern3Masc({
|
||||||
|
entry,
|
||||||
|
plurals,
|
||||||
|
}: PatternInput): InflectionsAndVocative {
|
||||||
const base = makePsString(
|
const base = makePsString(
|
||||||
e.p.slice(0, -1),
|
entry.p.slice(0, -1),
|
||||||
// shouldn't be accents here but remove just to be sure
|
// shouldn't be accents here but remove just to be sure
|
||||||
removeAccents(e.f.slice(0, -2))
|
removeAccents(entry.f.slice(0, -2))
|
||||||
);
|
);
|
||||||
const baseSyls = countSyllables(base);
|
const baseSyls = countSyllables(base);
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}یو`, f: `${base.f}úyo` },
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}${baseSyls ? "ó" : "o"}` },
|
|
||||||
];
|
|
||||||
return {
|
|
||||||
inflections: [
|
|
||||||
[{ p: e.p, f: e.f }],
|
|
||||||
[{ p: `${base.p}ي`, f: `${base.f}${baseSyls ? "ée" : "ee"}` }],
|
|
||||||
second,
|
|
||||||
],
|
|
||||||
vocative: [
|
|
||||||
[{ p: `${base.p}یه`, f: `${base.f}úya` }],
|
|
||||||
addPlurals(second, plurals),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function vocPattern3Fem({ e, plurals }: PatternInput): InflectionsAndVocative {
|
|
||||||
const base = makePsString(
|
|
||||||
e.p.slice(0, -1),
|
|
||||||
// shouldn't be accents here but remove just to be sure
|
|
||||||
removeAccents(e.f.slice(0, -2))
|
|
||||||
);
|
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}یو`, f: `${base.f}úyo` },
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}ó` },
|
|
||||||
];
|
|
||||||
const plain: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}ۍ`, f: `${base.f}úy` },
|
|
||||||
];
|
|
||||||
return {
|
|
||||||
inflections: [plain, plain, second],
|
|
||||||
vocative: [plain, addPlurals(second, plurals)],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function vocPattern4Masc({ e, plurals }: PatternInput): InflectionsAndVocative {
|
|
||||||
const base = countSyllables(e) === 1 ? accentOnNFromEnd(e, 0) : e;
|
|
||||||
const firstInf = accentOnNFromEnd(
|
|
||||||
makePsString(e.infap || "", e.infaf || ""),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
const secondBase = makePsString(e.infbp || "", e.infbf || "");
|
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${secondBase.p}و`, f: `${secondBase.f}ó` },
|
|
||||||
];
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: e.p, f: e.f }],
|
[psStringFromEntry(entry)],
|
||||||
[firstInf],
|
[concatPs(base, { p: `ي`, f: baseSyls ? "ée" : "ee" })],
|
||||||
second,
|
[
|
||||||
|
concatPs(base, { p: "یو", f: "úyo" }),
|
||||||
|
concatPs(base, { p: "و", f: baseSyls ? "ó" : "o" }),
|
||||||
|
],
|
||||||
];
|
];
|
||||||
if (endsInConsonant(e)) {
|
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [
|
vocative: [
|
||||||
[{ p: `${base.p}ه`, f: `${base.f}a` }],
|
[concatPs(base, { p: "یه", f: "úya" })],
|
||||||
addPlurals(second, plurals),
|
addPlurals(inflections[2], plurals),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function pattern3Fem({ entry, plurals }: PatternInput): InflectionsAndVocative {
|
||||||
|
const base = makePsString(
|
||||||
|
entry.p.slice(0, -1),
|
||||||
|
// shouldn't be accents here but remove just to be sure
|
||||||
|
removeAccents(entry.f.slice(0, -2))
|
||||||
|
);
|
||||||
|
const baseSyls = countSyllables(base);
|
||||||
|
const plain: T.ArrayOneOrMore<T.PsString> = [
|
||||||
|
concatPs(base, { p: "ۍ", f: "úy" }),
|
||||||
|
];
|
||||||
|
const inflections: T.InflectionSet = [
|
||||||
|
plain,
|
||||||
|
plain,
|
||||||
|
[concatPs(base, { p: "یو", f: "úyo" }), concatPs(base, baseSyls ? ó : o)],
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
inflections,
|
||||||
|
vocative: [plain, addPlurals(inflections[2], plurals)],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function pattern4Masc({
|
||||||
|
entry,
|
||||||
|
plurals,
|
||||||
|
}: PatternInput): InflectionsAndVocative {
|
||||||
|
const base = countSyllables(entry) === 1 ? accentOnNFromEnd(entry, 0) : entry;
|
||||||
|
const firstInf = accentOnNFromEnd(
|
||||||
|
makePsString(entry.infap || "", entry.infaf || ""),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
const secondBase = makePsString(entry.infbp || "", entry.infbf || "");
|
||||||
|
const inflections: T.InflectionSet = [
|
||||||
|
[psStringFromEntry(entry)],
|
||||||
|
[firstInf],
|
||||||
|
[concatPs(secondBase, ó)],
|
||||||
|
];
|
||||||
|
if (endsInConsonant(entry)) {
|
||||||
|
return {
|
||||||
|
inflections,
|
||||||
|
vocative: [[concatPs(base, a)], addPlurals(inflections[2], plurals)],
|
||||||
|
};
|
||||||
|
}
|
||||||
// TODO: is this even possible?
|
// TODO: is this even possible?
|
||||||
if (hasShwaEnding(e)) {
|
if (hasShwaEnding(entry)) {
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [
|
vocative: [
|
||||||
[{ p: `${base.p.slice(0, -1)}ه`, f: `${base.f.slice(0, -1)}á` }],
|
[
|
||||||
addPlurals(second, plurals),
|
concatPs(
|
||||||
|
mapPsString((x) => x.slice(0, -1), base),
|
||||||
|
á
|
||||||
|
),
|
||||||
|
],
|
||||||
|
addPlurals(inflections[2], plurals),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// exception for مېلمه, کوربه
|
// exception for مېلمه, کوربه
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [[{ p: e.p, f: e.f }], second],
|
vocative: [[psStringFromEntry(entry)], inflections[2]],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function vocPattern4Fem({ e, plurals }: PatternInput): InflectionsAndVocative {
|
function pattern4Fem({ entry }: PatternInput): InflectionsAndVocative {
|
||||||
const base = makePsString(e.infbp || "", e.infbf || "");
|
const base = makePsString(entry.infbp || "", entry.infbf || "");
|
||||||
const second = addPlurals([{ p: `${base.p}و`, f: `${base.f}ó` }], plurals);
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: `${base.p}ه`, f: `${base.f}á` }],
|
[concatPs(base, á)],
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}é` }],
|
[concatPs(base, é)],
|
||||||
second,
|
[concatPs(base, ó)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [inflections[1], second],
|
vocative: [inflections[1], inflections[2]],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function vocPattern5Masc({ e, plurals }: PatternInput): InflectionsAndVocative {
|
function vocPattern5Masc({
|
||||||
const base = makePsString(e.infbp || "", e.infbf || "");
|
entry,
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
plurals,
|
||||||
{ p: `${base.p}و`, f: `${base.f}o` },
|
}: PatternInput): InflectionsAndVocative {
|
||||||
];
|
const base = makePsString(entry.infbp || "", entry.infbf || "");
|
||||||
return {
|
|
||||||
inflections: [
|
|
||||||
[{ p: e.p, f: e.f }],
|
|
||||||
[{ p: `${base.p}ه`, f: `${base.f}u` }],
|
|
||||||
second,
|
|
||||||
],
|
|
||||||
vocative: [
|
|
||||||
[{ p: `${base.p}ه`, f: `${base.f}a` }],
|
|
||||||
addPlurals(second, plurals),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function vocPattern5Fem({ e, plurals }: PatternInput): InflectionsAndVocative {
|
|
||||||
const base = makePsString(e.infbp || "", e.infbf || "");
|
|
||||||
const second: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
{ p: `${base.p}و`, f: `${base.f}o` },
|
|
||||||
];
|
|
||||||
const inflections: T.InflectionSet = [
|
const inflections: T.InflectionSet = [
|
||||||
[{ p: `${base.p}ه`, f: `${base.f}a` }],
|
[psStringFromEntry(entry)],
|
||||||
[{ p: `${base.p}ې`, f: `${base.f}e` }],
|
[concatPs(base, { p: "ه", f: "u" })],
|
||||||
second,
|
[concatPs(base, o)],
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
inflections,
|
inflections,
|
||||||
vocative: [inflections[1], addPlurals(second, plurals)],
|
vocative: [[concatPs(base, a)], addPlurals(inflections[2], plurals)],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function pattern5Fem({ entry, plurals }: PatternInput): InflectionsAndVocative {
|
||||||
|
const base = makePsString(entry.infbp || "", entry.infbf || "");
|
||||||
|
const inflections: T.InflectionSet = [
|
||||||
|
[concatPs(base, a)],
|
||||||
|
[concatPs(base, e)],
|
||||||
|
[concatPs(base, o)],
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
inflections,
|
||||||
|
vocative: [inflections[1], addPlurals(inflections[2], plurals)],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,320 @@
|
||||||
|
import {
|
||||||
|
concatPsString,
|
||||||
|
endsInConsonant,
|
||||||
|
endsInAaOrOo,
|
||||||
|
addOEnding,
|
||||||
|
splitPsByVarients,
|
||||||
|
removeEndTick,
|
||||||
|
endsWith,
|
||||||
|
hasShwaEnding,
|
||||||
|
} from "./p-text-helpers";
|
||||||
|
import { makePsString } from "./accent-and-ps-utils";
|
||||||
|
import {
|
||||||
|
accentOnNFromEnd,
|
||||||
|
countSyllables,
|
||||||
|
removeAccents,
|
||||||
|
} from "./accent-helpers";
|
||||||
|
import * as T from "../../types";
|
||||||
|
|
||||||
|
function makePashtoPlural(
|
||||||
|
word: T.DictionaryEntryNoFVars
|
||||||
|
): T.PluralInflections | undefined {
|
||||||
|
if (!(word.ppp && word.ppf)) return undefined;
|
||||||
|
const base = splitPsByVarients(makePsString(word.ppp, word.ppf));
|
||||||
|
function getBaseAndO(): T.PluralInflectionSet {
|
||||||
|
return [base, base.flatMap(addOEnding) as T.ArrayOneOrMore<T.PsString>];
|
||||||
|
}
|
||||||
|
if (word.c?.includes("n. m.")) {
|
||||||
|
return { masc: getBaseAndO() };
|
||||||
|
}
|
||||||
|
if (word.c?.includes("n. f.")) {
|
||||||
|
return { fem: getBaseAndO() };
|
||||||
|
}
|
||||||
|
// TODO: handle masculine and unisex
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeBundledPlural(
|
||||||
|
word: T.DictionaryEntryNoFVars
|
||||||
|
): T.PluralInflections | undefined {
|
||||||
|
if (!endsInConsonant(word) || !word.c?.includes("n.")) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const w = makePsString(word.p, word.f);
|
||||||
|
const base = countSyllables(w) === 1 ? accentOnNFromEnd(w, 0) : w;
|
||||||
|
return {
|
||||||
|
masc: [
|
||||||
|
[concatPsString(base, { p: "ه", f: "a" })],
|
||||||
|
[concatPsString(base, { p: "و", f: "o" })],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeArabicPlural(
|
||||||
|
word: T.DictionaryEntryNoFVars
|
||||||
|
): T.PluralInflections | undefined {
|
||||||
|
if (!(word.apf && word.app)) return undefined;
|
||||||
|
const w = makePsString(word.app, word.apf);
|
||||||
|
const plural = splitPsByVarients(w);
|
||||||
|
const end = removeAccents(removeEndTick(word.apf).slice(-1));
|
||||||
|
// again typescript being dumb and not letting me use a typed key here
|
||||||
|
const value = [
|
||||||
|
plural,
|
||||||
|
plural.flatMap(addOEnding) as T.ArrayOneOrMore<T.PsString>,
|
||||||
|
] as T.PluralInflectionSet;
|
||||||
|
// feminine words that have arabic plurals stay feminine with the plural - ie مرجع - مراجع
|
||||||
|
// but masculine words that appear feminine in the plural aren't femening with the Arabic plural - ie. نبي - انبیا
|
||||||
|
if (["i", "e", "a"].includes(end) && word.c?.includes("n. f.")) {
|
||||||
|
return { fem: value };
|
||||||
|
}
|
||||||
|
return { masc: value };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makePlural(
|
||||||
|
w: T.DictionaryEntryNoFVars
|
||||||
|
):
|
||||||
|
| { plural: T.PluralInflections; bundledPlural?: T.PluralInflections }
|
||||||
|
| { arabicPlural: T.PluralInflections; bundledPlural?: T.PluralInflections }
|
||||||
|
| undefined {
|
||||||
|
function addSecondInf(
|
||||||
|
plur: T.ArrayOneOrMore<T.PsString> | T.PsString
|
||||||
|
): T.PluralInflectionSet {
|
||||||
|
if (!Array.isArray(plur)) {
|
||||||
|
return addSecondInf([plur]);
|
||||||
|
}
|
||||||
|
return [plur, plur.flatMap(addOEnding) as T.ArrayOneOrMore<T.PsString>];
|
||||||
|
}
|
||||||
|
if (w.c && w.c.includes("pl.")) {
|
||||||
|
const plural = addSecondInf(makePsString(w.p, w.f));
|
||||||
|
// Typescript being dumb and not letting me do a typed variable for the key
|
||||||
|
// could try refactoring with an updated TypeScript dependency
|
||||||
|
if (w.c.includes("n. m.")) return { plural: { masc: plural } };
|
||||||
|
if (w.c.includes("n. f.")) return { plural: { fem: plural } };
|
||||||
|
}
|
||||||
|
// exception for mUláa
|
||||||
|
if (w.f === "mUláa" || w.f === "mUlaa") {
|
||||||
|
return {
|
||||||
|
plural: {
|
||||||
|
masc: [
|
||||||
|
[
|
||||||
|
{ p: "ملایان", f: "mUlaayáan" },
|
||||||
|
{ p: "ملاګان", f: "mUlaagáan" },
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ p: "ملایانو", f: "mUlaayáano" },
|
||||||
|
{ p: "ملاګانو", f: "mUlaagáano" },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const arabicPlural = makeArabicPlural(w);
|
||||||
|
const pashtoPlural = makePashtoPlural(w);
|
||||||
|
const bundledPlural = makeBundledPlural(w);
|
||||||
|
function addMascPluralSuffix(
|
||||||
|
animate?: boolean,
|
||||||
|
shortSquish?: boolean
|
||||||
|
): T.PluralInflectionSet {
|
||||||
|
if (shortSquish && (w.infap === undefined || w.infaf === undefined)) {
|
||||||
|
throw new Error(`no irregular inflection info for ${w.p} - ${w.ts}`);
|
||||||
|
}
|
||||||
|
const b = removeAccents(
|
||||||
|
shortSquish
|
||||||
|
? makePsString(
|
||||||
|
(w.infap as string).slice(0, -1),
|
||||||
|
(w.infaf as string).slice(0, -1)
|
||||||
|
)
|
||||||
|
: w
|
||||||
|
);
|
||||||
|
const base = hasShwaEnding(b)
|
||||||
|
? makePsString(b.p.slice(0, -1), b.f.slice(0, -1))
|
||||||
|
: b;
|
||||||
|
return addSecondInf(
|
||||||
|
concatPsString(
|
||||||
|
base,
|
||||||
|
animate && !shortSquish
|
||||||
|
? { p: "ان", f: "áan" }
|
||||||
|
: { p: "ونه", f: "óona" }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function addAnimUnisexPluralSuffix(): T.UnisexSet<T.PluralInflectionSet> {
|
||||||
|
const base = removeAccents(w);
|
||||||
|
return {
|
||||||
|
masc: addMascPluralSuffix(true),
|
||||||
|
fem: addSecondInf(concatPsString(base, { p: "انې", f: "áane" })),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function addEePluralSuffix(gender: T.Gender): T.PluralInflectionSet {
|
||||||
|
const b = removeAccents(w);
|
||||||
|
const base = {
|
||||||
|
p: b.p.slice(0, -1),
|
||||||
|
f: b.f.slice(0, -2),
|
||||||
|
};
|
||||||
|
const firstInf: T.ArrayOneOrMore<T.PsString> = [
|
||||||
|
concatPsString(
|
||||||
|
base,
|
||||||
|
{ p: "یان", f: "iyáan" },
|
||||||
|
gender === "fem" ? { p: "ې", f: "e" } : ""
|
||||||
|
),
|
||||||
|
];
|
||||||
|
return [
|
||||||
|
firstInf,
|
||||||
|
firstInf.flatMap(addOEnding),
|
||||||
|
// firstInf.map(addOEnding),
|
||||||
|
] as T.PluralInflectionSet;
|
||||||
|
}
|
||||||
|
function addAnimN3UnisexPluralSuffix(): T.UnisexSet<T.PluralInflectionSet> {
|
||||||
|
const b = removeAccents(w);
|
||||||
|
const base = {
|
||||||
|
p: b.p.slice(0, -1),
|
||||||
|
f: b.f.slice(0, -2),
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
masc: [
|
||||||
|
[concatPsString(base, { p: "یان", f: "iyáan" })],
|
||||||
|
[concatPsString(base, { p: "یانو", f: "iyáano" })],
|
||||||
|
// TODO: or use addSecondInf method above?
|
||||||
|
],
|
||||||
|
fem: [
|
||||||
|
[concatPsString(base, { p: "یانې", f: "iyáane" })],
|
||||||
|
[concatPsString(base, { p: "یانو", f: "iyáano" })],
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function addLongVowelSuffix(gender: "masc" | "fem"): T.PluralInflectionSet {
|
||||||
|
if (pashtoPlural) {
|
||||||
|
}
|
||||||
|
const base = removeEndTick(makePsString(w.p, w.f));
|
||||||
|
const baseWOutAccents = removeAccents(base);
|
||||||
|
const space =
|
||||||
|
w.p.slice(-1) === "ع" || w.p.slice(-1) === "ه" ? { p: " ", f: " " } : "";
|
||||||
|
if (gender === "fem") {
|
||||||
|
return addSecondInf([
|
||||||
|
concatPsString(base, space, { p: "وې", f: "we" }),
|
||||||
|
concatPsString(baseWOutAccents, space, { p: "ګانې", f: "gáane" }),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
return addSecondInf([
|
||||||
|
concatPsString(baseWOutAccents, space, { p: "ګان", f: "gáan" }),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: This should be possible for words like پلویان but not for words like ترورزامن 🤔
|
||||||
|
// function addFemToPashtoPlural(i: T.PluralInflections): T.UnisexSet<T.PluralInflectionSet> {
|
||||||
|
// if ("fem" in i && "masc" in i) return i;
|
||||||
|
// if (!("masc" in i)) throw new Error("bad pashto plural doesn't even have masculine");
|
||||||
|
// if (endsInConsonant(i.masc[0][0])) {
|
||||||
|
// return {
|
||||||
|
// ...i,
|
||||||
|
// fem: [
|
||||||
|
// i.masc[0].map((x) => concatPsString(x, { p: "ې", f: "e" })) as T.ArrayOneOrMore<T.PsString>,
|
||||||
|
// i.masc[0].map((x) => concatPsString(x, { p: "و", f: "o" })) as T.ArrayOneOrMore<T.PsString>,
|
||||||
|
// ],
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// return {
|
||||||
|
// ...i,
|
||||||
|
// fem: i.masc,
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
const shortSquish = !!w.infap && !w.infap.includes("ا");
|
||||||
|
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 (pashtoPlural) {
|
||||||
|
return {
|
||||||
|
plural: pashtoPlural,
|
||||||
|
arabicPlural,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (type === "unisex noun") {
|
||||||
|
// doesn't need to be labelled anim - because it's only with animate nouns that you get the unisex - I THINK
|
||||||
|
if (endsInConsonant(w) && !w.infap) {
|
||||||
|
return {
|
||||||
|
arabicPlural,
|
||||||
|
bundledPlural,
|
||||||
|
plural: addAnimUnisexPluralSuffix(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (shortSquish && !anim) {
|
||||||
|
return {
|
||||||
|
arabicPlural,
|
||||||
|
plural: { masc: addMascPluralSuffix(anim, shortSquish) },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (endsWith([{ p: "ی", f: "áy" }, { p: "ي" }], w, true)) {
|
||||||
|
return { arabicPlural, plural: addAnimN3UnisexPluralSuffix() };
|
||||||
|
}
|
||||||
|
// usually shortSquish nouns would never have arabicPlurals -- so we don't have to worry about catching
|
||||||
|
// arabic plurals for the animat ones, right?
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
type === "masc noun" &&
|
||||||
|
(shortSquish || ((endsInConsonant(w) || hasShwaEnding(w)) && !w.infap)) &&
|
||||||
|
w.p.slice(-3) !== "توب"
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
arabicPlural,
|
||||||
|
bundledPlural,
|
||||||
|
plural: {
|
||||||
|
masc: addMascPluralSuffix(anim, shortSquish),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (type === "masc noun" && endsWith({ p: "ی", f: "áy" }, w, true) && anim) {
|
||||||
|
const { masc } = addAnimN3UnisexPluralSuffix();
|
||||||
|
return {
|
||||||
|
arabicPlural,
|
||||||
|
plural: {
|
||||||
|
masc,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (type === "masc noun" && endsWith({ p: "ي" }, w)) {
|
||||||
|
const masc = addEePluralSuffix("masc");
|
||||||
|
return {
|
||||||
|
arabicPlural,
|
||||||
|
plural: { masc },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// TODO: What about endings in long ee / animate at inanimate
|
||||||
|
if (type === "masc noun" && endsInAaOrOo(w) && !w.infap) {
|
||||||
|
return {
|
||||||
|
arabicPlural,
|
||||||
|
plural: {
|
||||||
|
masc: addLongVowelSuffix("masc"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// TODO: What about endings in long ee / animate at inanimate
|
||||||
|
if (type === "fem noun" && endsInAaOrOo(w) && !w.infap) {
|
||||||
|
return {
|
||||||
|
arabicPlural,
|
||||||
|
plural: {
|
||||||
|
fem: addLongVowelSuffix("fem"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
type === "fem noun" &&
|
||||||
|
(endsWith({ p: "ي" }, w) || (endsWith({ p: "ۍ" }, w) && anim))
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
arabicPlural,
|
||||||
|
plural: {
|
||||||
|
fem: addEePluralSuffix("fem"),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (arabicPlural) {
|
||||||
|
return { arabicPlural, plural: pashtoPlural, bundledPlural };
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
|
@ -2114,7 +2114,8 @@ const others: T.DictionaryEntry[] = [
|
||||||
|
|
||||||
adjectives.forEach((word) => {
|
adjectives.forEach((word) => {
|
||||||
test(`${word.in.p} should inflect properly`, () => {
|
test(`${word.in.p} should inflect properly`, () => {
|
||||||
expect(inflectWord(word.in)).toEqual(word.out);
|
const out = inflectWord(word.in);
|
||||||
|
expect(out).toEqual(word.out);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,25 +10,14 @@ import {
|
||||||
concatInflections,
|
concatInflections,
|
||||||
splitDoubleWord,
|
splitDoubleWord,
|
||||||
ensureUnisexInflections,
|
ensureUnisexInflections,
|
||||||
concatPsString,
|
|
||||||
endsInConsonant,
|
|
||||||
endsInAaOrOo,
|
|
||||||
addOEnding,
|
|
||||||
splitPsByVarients,
|
|
||||||
removeEndTick,
|
|
||||||
endsWith,
|
|
||||||
concatPlurals,
|
concatPlurals,
|
||||||
hasShwaEnding,
|
|
||||||
} from "./p-text-helpers";
|
} from "./p-text-helpers";
|
||||||
import { makePsString, removeFVarients } from "./accent-and-ps-utils";
|
import { makePsString, removeFVarients } from "./accent-and-ps-utils";
|
||||||
import {
|
import { removeAccents } from "./accent-helpers";
|
||||||
accentOnNFromEnd,
|
|
||||||
countSyllables,
|
|
||||||
removeAccents,
|
|
||||||
} from "./accent-helpers";
|
|
||||||
import * as T from "../../types";
|
import * as T from "../../types";
|
||||||
import { getInfsAndVocative } from "./inflections-and-vocative";
|
import { getInfsAndVocative } from "./inflections-and-vocative";
|
||||||
import { fmapSingleOrLengthOpts } from "./fp-ps";
|
import { fmapSingleOrLengthOpts } from "./fp-ps";
|
||||||
|
import { makePlural } from "./nouns-plural";
|
||||||
|
|
||||||
export function inflectWord(word: T.DictionaryEntry): T.InflectorOutput {
|
export function inflectWord(word: T.DictionaryEntry): T.InflectorOutput {
|
||||||
// If it's a noun/adj, inflect accordingly
|
// If it's a noun/adj, inflect accordingly
|
||||||
|
@ -131,309 +120,6 @@ export function inflectRegularShwaEndingUnisex(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function makePashtoPlural(
|
|
||||||
word: T.DictionaryEntryNoFVars
|
|
||||||
): T.PluralInflections | undefined {
|
|
||||||
if (!(word.ppp && word.ppf)) return undefined;
|
|
||||||
const base = splitPsByVarients(makePsString(word.ppp, word.ppf));
|
|
||||||
function getBaseAndO(): T.PluralInflectionSet {
|
|
||||||
return [base, base.flatMap(addOEnding) as T.ArrayOneOrMore<T.PsString>];
|
|
||||||
}
|
|
||||||
if (word.c?.includes("n. m.")) {
|
|
||||||
return { masc: getBaseAndO() };
|
|
||||||
}
|
|
||||||
if (word.c?.includes("n. f.")) {
|
|
||||||
return { fem: getBaseAndO() };
|
|
||||||
}
|
|
||||||
// TODO: handle masculine and unisex
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeBundledPlural(
|
|
||||||
word: T.DictionaryEntryNoFVars
|
|
||||||
): T.PluralInflections | undefined {
|
|
||||||
if (!endsInConsonant(word) || !word.c?.includes("n.")) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const w = makePsString(word.p, word.f);
|
|
||||||
const base = countSyllables(w) === 1 ? accentOnNFromEnd(w, 0) : w;
|
|
||||||
return {
|
|
||||||
masc: [
|
|
||||||
[concatPsString(base, { p: "ه", f: "a" })],
|
|
||||||
[concatPsString(base, { p: "و", f: "o" })],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeArabicPlural(
|
|
||||||
word: T.DictionaryEntryNoFVars
|
|
||||||
): T.PluralInflections | undefined {
|
|
||||||
if (!(word.apf && word.app)) return undefined;
|
|
||||||
const w = makePsString(word.app, word.apf);
|
|
||||||
const plural = splitPsByVarients(w);
|
|
||||||
const end = removeAccents(removeEndTick(word.apf).slice(-1));
|
|
||||||
// again typescript being dumb and not letting me use a typed key here
|
|
||||||
const value = [
|
|
||||||
plural,
|
|
||||||
plural.flatMap(addOEnding) as T.ArrayOneOrMore<T.PsString>,
|
|
||||||
] as T.PluralInflectionSet;
|
|
||||||
// feminine words that have arabic plurals stay feminine with the plural - ie مرجع - مراجع
|
|
||||||
// but masculine words that appear feminine in the plural aren't femening with the Arabic plural - ie. نبي - انبیا
|
|
||||||
if (["i", "e", "a"].includes(end) && word.c?.includes("n. f.")) {
|
|
||||||
return { fem: value };
|
|
||||||
}
|
|
||||||
return { masc: value };
|
|
||||||
}
|
|
||||||
|
|
||||||
function makePlural(
|
|
||||||
w: T.DictionaryEntryNoFVars
|
|
||||||
):
|
|
||||||
| { plural: T.PluralInflections; bundledPlural?: T.PluralInflections }
|
|
||||||
| { arabicPlural: T.PluralInflections; bundledPlural?: T.PluralInflections }
|
|
||||||
| undefined {
|
|
||||||
function addSecondInf(
|
|
||||||
plur: T.ArrayOneOrMore<T.PsString> | T.PsString
|
|
||||||
): T.PluralInflectionSet {
|
|
||||||
if (!Array.isArray(plur)) {
|
|
||||||
return addSecondInf([plur]);
|
|
||||||
}
|
|
||||||
return [plur, plur.flatMap(addOEnding) as T.ArrayOneOrMore<T.PsString>];
|
|
||||||
}
|
|
||||||
if (w.c && w.c.includes("pl.")) {
|
|
||||||
const plural = addSecondInf(makePsString(w.p, w.f));
|
|
||||||
// Typescript being dumb and not letting me do a typed variable for the key
|
|
||||||
// could try refactoring with an updated TypeScript dependency
|
|
||||||
if (w.c.includes("n. m.")) return { plural: { masc: plural } };
|
|
||||||
if (w.c.includes("n. f.")) return { plural: { fem: plural } };
|
|
||||||
}
|
|
||||||
// exception for mUláa
|
|
||||||
if (w.f === "mUláa" || w.f === "mUlaa") {
|
|
||||||
return {
|
|
||||||
plural: {
|
|
||||||
masc: [
|
|
||||||
[
|
|
||||||
{ p: "ملایان", f: "mUlaayáan" },
|
|
||||||
{ p: "ملاګان", f: "mUlaagáan" },
|
|
||||||
],
|
|
||||||
[
|
|
||||||
{ p: "ملایانو", f: "mUlaayáano" },
|
|
||||||
{ p: "ملاګانو", f: "mUlaagáano" },
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const arabicPlural = makeArabicPlural(w);
|
|
||||||
const pashtoPlural = makePashtoPlural(w);
|
|
||||||
const bundledPlural = makeBundledPlural(w);
|
|
||||||
function addMascPluralSuffix(
|
|
||||||
animate?: boolean,
|
|
||||||
shortSquish?: boolean
|
|
||||||
): T.PluralInflectionSet {
|
|
||||||
if (shortSquish && (w.infap === undefined || w.infaf === undefined)) {
|
|
||||||
throw new Error(`no irregular inflection info for ${w.p} - ${w.ts}`);
|
|
||||||
}
|
|
||||||
const b = removeAccents(
|
|
||||||
shortSquish
|
|
||||||
? makePsString(
|
|
||||||
(w.infap as string).slice(0, -1),
|
|
||||||
(w.infaf as string).slice(0, -1)
|
|
||||||
)
|
|
||||||
: w
|
|
||||||
);
|
|
||||||
const base = hasShwaEnding(b)
|
|
||||||
? makePsString(b.p.slice(0, -1), b.f.slice(0, -1))
|
|
||||||
: b;
|
|
||||||
return addSecondInf(
|
|
||||||
concatPsString(
|
|
||||||
base,
|
|
||||||
animate && !shortSquish
|
|
||||||
? { p: "ان", f: "áan" }
|
|
||||||
: { p: "ونه", f: "óona" }
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
function addAnimUnisexPluralSuffix(): T.UnisexSet<T.PluralInflectionSet> {
|
|
||||||
const base = removeAccents(w);
|
|
||||||
return {
|
|
||||||
masc: addMascPluralSuffix(true),
|
|
||||||
fem: addSecondInf(concatPsString(base, { p: "انې", f: "áane" })),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function addEePluralSuffix(gender: T.Gender): T.PluralInflectionSet {
|
|
||||||
const b = removeAccents(w);
|
|
||||||
const base = {
|
|
||||||
p: b.p.slice(0, -1),
|
|
||||||
f: b.f.slice(0, -2),
|
|
||||||
};
|
|
||||||
const firstInf: T.ArrayOneOrMore<T.PsString> = [
|
|
||||||
concatPsString(
|
|
||||||
base,
|
|
||||||
{ p: "یان", f: "iyáan" },
|
|
||||||
gender === "fem" ? { p: "ې", f: "e" } : ""
|
|
||||||
),
|
|
||||||
];
|
|
||||||
return [
|
|
||||||
firstInf,
|
|
||||||
firstInf.flatMap(addOEnding),
|
|
||||||
// firstInf.map(addOEnding),
|
|
||||||
] as T.PluralInflectionSet;
|
|
||||||
}
|
|
||||||
function addAnimN3UnisexPluralSuffix(): T.UnisexSet<T.PluralInflectionSet> {
|
|
||||||
const b = removeAccents(w);
|
|
||||||
const base = {
|
|
||||||
p: b.p.slice(0, -1),
|
|
||||||
f: b.f.slice(0, -2),
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
masc: [
|
|
||||||
[concatPsString(base, { p: "یان", f: "iyáan" })],
|
|
||||||
[concatPsString(base, { p: "یانو", f: "iyáano" })],
|
|
||||||
// TODO: or use addSecondInf method above?
|
|
||||||
],
|
|
||||||
fem: [
|
|
||||||
[concatPsString(base, { p: "یانې", f: "iyáane" })],
|
|
||||||
[concatPsString(base, { p: "یانو", f: "iyáano" })],
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function addLongVowelSuffix(gender: "masc" | "fem"): T.PluralInflectionSet {
|
|
||||||
if (pashtoPlural) {
|
|
||||||
}
|
|
||||||
const base = removeEndTick(makePsString(w.p, w.f));
|
|
||||||
const baseWOutAccents = removeAccents(base);
|
|
||||||
const space =
|
|
||||||
w.p.slice(-1) === "ع" || w.p.slice(-1) === "ه" ? { p: " ", f: " " } : "";
|
|
||||||
if (gender === "fem") {
|
|
||||||
return addSecondInf([
|
|
||||||
concatPsString(base, space, { p: "وې", f: "we" }),
|
|
||||||
concatPsString(baseWOutAccents, space, { p: "ګانې", f: "gáane" }),
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
return addSecondInf([
|
|
||||||
concatPsString(baseWOutAccents, space, { p: "ګان", f: "gáan" }),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO: This should be possible for words like پلویان but not for words like ترورزامن 🤔
|
|
||||||
// function addFemToPashtoPlural(i: T.PluralInflections): T.UnisexSet<T.PluralInflectionSet> {
|
|
||||||
// if ("fem" in i && "masc" in i) return i;
|
|
||||||
// if (!("masc" in i)) throw new Error("bad pashto plural doesn't even have masculine");
|
|
||||||
// if (endsInConsonant(i.masc[0][0])) {
|
|
||||||
// return {
|
|
||||||
// ...i,
|
|
||||||
// fem: [
|
|
||||||
// i.masc[0].map((x) => concatPsString(x, { p: "ې", f: "e" })) as T.ArrayOneOrMore<T.PsString>,
|
|
||||||
// i.masc[0].map((x) => concatPsString(x, { p: "و", f: "o" })) as T.ArrayOneOrMore<T.PsString>,
|
|
||||||
// ],
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// return {
|
|
||||||
// ...i,
|
|
||||||
// fem: i.masc,
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
const shortSquish = !!w.infap && !w.infap.includes("ا");
|
|
||||||
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 (pashtoPlural) {
|
|
||||||
return {
|
|
||||||
plural: pashtoPlural,
|
|
||||||
arabicPlural,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (type === "unisex noun") {
|
|
||||||
// doesn't need to be labelled anim - because it's only with animate nouns that you get the unisex - I THINK
|
|
||||||
if (endsInConsonant(w) && !w.infap) {
|
|
||||||
return {
|
|
||||||
arabicPlural,
|
|
||||||
bundledPlural,
|
|
||||||
plural: addAnimUnisexPluralSuffix(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (shortSquish && !anim) {
|
|
||||||
return {
|
|
||||||
arabicPlural,
|
|
||||||
plural: { masc: addMascPluralSuffix(anim, shortSquish) },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (endsWith([{ p: "ی", f: "áy" }, { p: "ي" }], w, true)) {
|
|
||||||
return { arabicPlural, plural: addAnimN3UnisexPluralSuffix() };
|
|
||||||
}
|
|
||||||
// usually shortSquish nouns would never have arabicPlurals -- so we don't have to worry about catching
|
|
||||||
// arabic plurals for the animat ones, right?
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
type === "masc noun" &&
|
|
||||||
(shortSquish || ((endsInConsonant(w) || hasShwaEnding(w)) && !w.infap)) &&
|
|
||||||
w.p.slice(-3) !== "توب"
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
arabicPlural,
|
|
||||||
bundledPlural,
|
|
||||||
plural: {
|
|
||||||
masc: addMascPluralSuffix(anim, shortSquish),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (type === "masc noun" && endsWith({ p: "ی", f: "áy" }, w, true) && anim) {
|
|
||||||
const { masc } = addAnimN3UnisexPluralSuffix();
|
|
||||||
return {
|
|
||||||
arabicPlural,
|
|
||||||
plural: {
|
|
||||||
masc,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (type === "masc noun" && endsWith({ p: "ي" }, w)) {
|
|
||||||
const masc = addEePluralSuffix("masc");
|
|
||||||
return {
|
|
||||||
arabicPlural,
|
|
||||||
plural: { masc },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// TODO: What about endings in long ee / animate at inanimate
|
|
||||||
if (type === "masc noun" && endsInAaOrOo(w) && !w.infap) {
|
|
||||||
return {
|
|
||||||
arabicPlural,
|
|
||||||
plural: {
|
|
||||||
masc: addLongVowelSuffix("masc"),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// TODO: What about endings in long ee / animate at inanimate
|
|
||||||
if (type === "fem noun" && endsInAaOrOo(w) && !w.infap) {
|
|
||||||
return {
|
|
||||||
arabicPlural,
|
|
||||||
plural: {
|
|
||||||
fem: addLongVowelSuffix("fem"),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
type === "fem noun" &&
|
|
||||||
(endsWith({ p: "ي" }, w) || (endsWith({ p: "ۍ" }, w) && anim))
|
|
||||||
) {
|
|
||||||
return {
|
|
||||||
arabicPlural,
|
|
||||||
plural: {
|
|
||||||
fem: addEePluralSuffix("fem"),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (arabicPlural) {
|
|
||||||
return { arabicPlural, plural: pashtoPlural, bundledPlural };
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function inflectYay(
|
export function inflectYay(
|
||||||
ps: T.SingleOrLengthOpts<T.PsString>
|
ps: T.SingleOrLengthOpts<T.PsString>
|
||||||
): T.SingleOrLengthOpts<T.UnisexInflections> {
|
): T.SingleOrLengthOpts<T.UnisexInflections> {
|
||||||
|
|
Loading…
Reference in New Issue