/** * 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; export function noPersInfs(s: T.FullForm): T.SingleOrLengthOpts; export function noPersInfs(s: T.OptionalPersonInflections> | T.FullForm ): T.SingleOrLengthOpts | T.LengthOptions { if ("mascSing" in s) { // this path shouldn't be used, just for type safety return s.mascSing; } return s; } export function pickPersInf(s: T.OptionalPersonInflections, persInf: T.PersonInflectionsField): T { if ("mascSing" in s) { return s[persInf]; } return s; } // export function pickPersInf( // s: T.OptionalPersonInflections>, // persInf: T.PersonInflectionsField, // ): T.LengthOptions; // export function pickPersInf( // s: T.FullForm, // persInf: T.PersonInflectionsField, // ): T.SingleOrLengthOpts; // export function pickPersInf( // s: T.FullForm, // persInf: T.PersonInflectionsField, // ): T.SingleOrLengthOpts; // export function pickPersInf( // s: T.SplitInfo, // persInf: T.PersonInflectionsField, // ): T.SingleOrLengthOpts<[T.PsString, T.PsString]>; // export function pickPersInf( // s: T.OptionalPersonInflections> | T.FullForm | T.FullForm | T.SplitInfo, // persInf: T.PersonInflectionsField, // ): T.SingleOrLengthOpts | T.LengthOptions | T.SingleOrLengthOpts | 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.SingleOrLengthOpts, person: T.Person, ): T.SingleOrLengthOpts { 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): 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, person: T.Person): T.SentenceForm { if ("long" in form) { return { long: getPersonFromVerbForm(form.long, person) as T.ArrayOneOrMore, short: getPersonFromVerbForm(form.short, person) as T.ArrayOneOrMore, ...form.mini ? { mini: getPersonFromVerbForm(form.mini, person) as T.ArrayOneOrMore, } : {}, }; } 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; } /** * 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 */ export function parseEc(ec: string): T.EnglishVerbConjugationEc { function isVowel(s: string): boolean { return ["a", "e", "i", "o", "u"].includes(s); } function makeRegularConjugations(s: string): T.EnglishVerbConjugationEc { if (s === "get") { return ["get","gets","getting","got","gotten"]; } if (s === "become") { return ["become","becomes","becoming","became","become"]; } if (s === "make") { return ["make","makes","making","made","made"]; } if (s === "have") { return ["have","has","having","had","had"]; } if (s === "be") { return ["am","is","being","was","been"]; } 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`]; } if (s.slice(-2) === "ss") { return [`${s}`, `${s}es`, `${s}ing`, `${s}ed`, `${s}ed`]; } 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()); 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]); } // 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]); // }