pashto-inflector/src/lib/misc-helpers.ts

249 lines
8.4 KiB
TypeScript
Raw Normal View History

2021-03-09 12:39:13 +00:00
/**
* Copyright (c) 2021 lingdocs.com
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import * as T from "../types";
// just for type safety
export function noPersInfs(s: T.OptionalPersonInflections<T.LengthOptions<T.PsString>>): T.LengthOptions<T.PsString>;
export function noPersInfs(s: T.FullForm<T.PsString>): T.SingleOrLengthOpts<T.PsString>;
export function noPersInfs(s:
T.OptionalPersonInflections<T.LengthOptions<T.PsString>> | T.FullForm<T.PsString>
): T.SingleOrLengthOpts<T.PsString> | T.LengthOptions<T.PsString> {
if ("mascSing" in s) {
// this path shouldn't be used, just for type safety
return s.mascSing;
}
return s;
}
export function pickPersInf<T>(s: T.OptionalPersonInflections<T>, persInf: T.PersonInflectionsField): T {
if ("mascSing" in s) {
return s[persInf];
}
return s;
}
// export function pickPersInf(
// s: T.OptionalPersonInflections<T.LengthOptions<T.PsString>>,
// persInf: T.PersonInflectionsField,
// ): T.LengthOptions<T.PsString>;
// export function pickPersInf(
// s: T.FullForm<T.PsString>,
// persInf: T.PersonInflectionsField,
// ): T.SingleOrLengthOpts<T.PsString>;
// export function pickPersInf(
// s: T.FullForm<T.VerbBlock>,
// persInf: T.PersonInflectionsField,
// ): T.SingleOrLengthOpts<T.VerbBlock>;
// export function pickPersInf(
// s: T.SplitInfo,
// persInf: T.PersonInflectionsField,
// ): T.SingleOrLengthOpts<[T.PsString, T.PsString]>;
// export function pickPersInf(
// s: T.OptionalPersonInflections<T.LengthOptions<T.PsString>> | T.FullForm<T.PsString> | T.FullForm<T.VerbBlock> | T.SplitInfo,
// persInf: T.PersonInflectionsField,
// ): T.SingleOrLengthOpts<T.PsString> | T.LengthOptions<T.PsString> | T.SingleOrLengthOpts<T.VerbBlock> | T.SingleOrLengthOpts<[T.PsString, T.PsString]> {
// if ("mascSing" in s) {
// return s[persInf];
// }
// return s;
// }
export function hasPersInfs(info: T.NonComboVerbInfo): boolean {
return (
"mascSing" in info.root.perfective ||
"mascSing" in info.stem.perfective ||
"mascSing" in info.participle.present ||
"mascSing" in info.participle.past
);
}
export function chooseParticipleInflection(
pPartInfs: T.SingleOrLengthOpts<T.UnisexInflections> | T.SingleOrLengthOpts<T.PsString>,
person: T.Person,
): T.SingleOrLengthOpts<T.PsString> {
if ("long" in pPartInfs) {
return {
short: chooseParticipleInflection(pPartInfs.short, person) as T.PsString,
long: chooseParticipleInflection(pPartInfs.long, person) as T.PsString,
};
}
if ("masc" in pPartInfs) {
const gender = personGender(person);
const infNum = personIsPlural(person) ? 1 : 0;
return pPartInfs[gender][infNum][0];
}
return pPartInfs; // already just one thing
}
export function getPersonNumber(gender: "masc" | "fem", number: "singular" | "plural"): T.Person {
const base = gender === "masc" ? 4 : 5;
return base + (number === "singular" ? 0 : 6);
}
export function getPersonInflectionsKey(person: T.Person): T.PersonInflectionsField {
return `${personGender(person)}${personIsPlural(person) ? "Plur" : "Sing"}` as T.PersonInflectionsField;
}
export function spaceInForm(form: T.FullForm<T.PsString>): boolean {
if ("mascSing" in form) {
return spaceInForm(form.mascSing);
}
if ("long" in form) {
return spaceInForm(form.long);
}
return form.p.includes(" ");
}
export function getPersonFromVerbForm(form: T.SingleOrLengthOpts<T.VerbBlock>, person: T.Person): T.SentenceForm {
if ("long" in form) {
return {
long: getPersonFromVerbForm(form.long, person) as T.ArrayOneOrMore<T.PsString>,
short: getPersonFromVerbForm(form.short, person) as T.ArrayOneOrMore<T.PsString>,
...form.mini ? {
mini: getPersonFromVerbForm(form.mini, person) as T.ArrayOneOrMore<T.PsString>,
} : {},
};
}
const [row, col] = getBlockRowCol(person);
return form[row][col];
}
export function getBlockRowCol(person: T.Person): [0 | 1 | 2 | 3 | 4 | 5, 0 | 1] {
const plural = personIsPlural(person)
const row = (plural ? (person - 6) : person) as 0 | 1 | 2 | 3 | 4 | 5;
const col = plural ? 1 : 0;
return [row, col];
}
export function getAuxTransitivity(trans: T.Transitivity): "transitive" | "intransitive" {
return trans === "intransitive" ? "intransitive" : "transitive";
}
export function personGender(person: T.Person): "masc" | "fem" {
return person % 2 === 0 ? "masc" : "fem";
}
export function personIsPlural(person: T.Person): boolean {
return person > 5;
}
export function getEnglishPersonInfo(person: T.Person): string {
const p = [0,1,6,7].includes(person)
? "1st pers"
: [2,3,8,9].includes(person)
? "2nd pers"
: "3rd pers";
const a = personIsPlural(person) ? "plur" : "sing";
const g = personGender(person);
return `${p}. ${a}. ${g}.`;
}
export function randomNumber(minInclusive: number, maxExclusive: number): number {
return Math.floor(Math.random() * (maxExclusive - minInclusive) + minInclusive);
}
/**
* Sees if a possiblePerson (for subject/object) is possible, given the other person
*
* @param possiblePerson
* @param existingPerson
*/
export function personIsAllowed(possiblePerson: T.Person, existingPerson: T.Person): boolean {
const isFirstPerson = (p: T.Person) => [0, 1, 6, 7].includes(p);
const isSecondPerson = (p: T.Person) => [2, 3, 8, 9].includes(p);
// can't have both subject and object be 1st person
if (isFirstPerson(possiblePerson) && isFirstPerson(existingPerson)) {
return false;
}
// can't have both subject and object be 2nd person
if (isSecondPerson(possiblePerson) && isSecondPerson(existingPerson)) {
return false;
}
// otherwise it's ok
return true;
}
/**
* Picks a random person while assuring that the other person is not in conflict
*
* @param other
*/
export function randomPerson(other: T.Person): T.Person {
let newPerson: T.Person;
do {
newPerson = randomNumber(0, 12);
} while(!personIsAllowed(newPerson, other));
return newPerson;
}
export function incrementPerson(p: T.Person): T.Person {
return (p + 1) % 12;
}
export function isSentenceForm(f: any): boolean {
if ("long" in f) {
return isSentenceForm(f.long);
}
return Array.isArray(f) && "p" in f[0];
}
2021-03-10 16:51:40 +00:00
export function isNounAdjOrVerb(entry: T.DictionaryEntry): "nounAdj" | "verb" | false {
if (!entry.c) {
return false;
}
if (entry.c.includes("adj.") || entry.c.includes("n. m.") || entry.c.includes("n. f.")) {
return "nounAdj";
}
if (entry.c.slice(0, 3) === "v. ") {
return "verb";
}
return false;
}
/**
* takes the ec field from a dictionary entry and produces an array of an EnglishVerbConjugation
* for use with the conjugations display for showing English translation sentences of various verb
* forms and conjugations
*
* @param ec
* @returns
*/
2021-07-05 08:21:57 +00:00
export function parseEc(ec: string): T.EnglishVerbConjugationEc {
2021-07-05 15:39:20 +00:00
function isVowel(s: string): boolean {
return ["a", "e", "i", "o", "u"].includes(s);
}
2021-07-05 08:21:57 +00:00
function makeRegularConjugations(s: string): T.EnglishVerbConjugationEc {
2021-07-05 15:39:20 +00:00
if ((s.slice(-1) === "y") && !isVowel(s.slice(-2)[0])) {
const b = s.slice(0, -1);
return [`${s}`, `${b}ies`, `${s}ing`, `${b}ied`, `${b}ied`];
}
2021-07-07 11:27:04 +00:00
if (s.slice(-2) === "ie" && !isVowel(s.slice(-3)[0])) {
const b = s.slice(0, -2);
return [`${s}`, `${s}s`, `${b}ying`, `${s}d`, `${s}d`];
}
const b = (s.slice(-1) === "e")
? s.slice(0, -1)
: s;
return [`${s}`, `${s}s`, `${b}ing`, `${b}ed`, `${b}ed`];
}
const items = ec.split(",").map(x => x.trim());
2021-07-07 11:27:04 +00:00
return (items.length === 4)
? [items[0], items[1], items[2], items[3], items[3]]
: (items.length === 5)
? [items[0], items[1], items[2], items[3], items[4]]
: makeRegularConjugations(items[0]);
}
2021-03-09 12:39:13 +00:00
// not being used
// export function isImperativeBlock(f: any): boolean {
// function isPersonLine(g: any): boolean {
// return Array.isArray(g) && Array.isArray(g[0]) && "p" in g[0][0];
// }
// return Array.isArray(f) && f.length === 2 && isPersonLine(f[0]);
// }