215 lines
7.1 KiB
TypeScript
215 lines
7.1 KiB
TypeScript
/**
|
|
* 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];
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
// 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]);
|
|
// }
|