From b5a5c2c9a808f6e366b2ad7ceab3ed90b95ba8e7 Mon Sep 17 00:00:00 2001 From: lingdocs <71590811+lingdocs@users.noreply.github.com> Date: Tue, 19 Oct 2021 20:07:32 -0400 Subject: [PATCH] nouns in explorer working! --- .../equative-explorer/EquativeDisplay.tsx | 45 ++++++++++ .../equative-explorer/EquativeExplorer.tsx | 31 ++++--- .../equative-explorer/explorer-helpers.ts | 12 ++- .../equative-explorer/explorer-inputs.ts | 3 + .../equative-explorer/explorer-reducer.ts | 37 +++++++- .../equative-explorer/explorer-selectors.tsx | 86 ++++++++++++++++++- .../equative-explorer/explorer-types.ts | 18 ++++ src/lib/equative-machine.test.ts | 66 ++++++++++---- src/lib/equative-machine.ts | 29 ++++--- src/lib/type-predicates.ts | 8 ++ src/types.d.ts | 3 + 11 files changed, 285 insertions(+), 53 deletions(-) create mode 100644 src/components/equative-explorer/EquativeDisplay.tsx diff --git a/src/components/equative-explorer/EquativeDisplay.tsx b/src/components/equative-explorer/EquativeDisplay.tsx new file mode 100644 index 0000000..fec3a4f --- /dev/null +++ b/src/components/equative-explorer/EquativeDisplay.tsx @@ -0,0 +1,45 @@ +import { + VerbTable, + defaultTextOptions as opts, +} from "@lingdocs/pashto-inflector"; +import { + ExplorerState, +} from "./explorer-types"; +import { + makeBlockWPronouns, +} from "./explorer-helpers"; +import { + equativeMachine, + assembleEquativeOutput, + NounInput, +} from "../../lib/equative-machine"; +import { isPluralEntry, isSingularEntry } from "../../lib/type-predicates"; + +function EquativeDisplay({ state }: { state: ExplorerState }) { + if (state.subjectType === "pronouns") { + return + } + const entry = state.subjectsSelected[state.subjectType]; + const nounInput: NounInput = isSingularEntry(entry) ? { + entry, + plural: state.subjectsSelected.info.plural, + } : isPluralEntry(entry) ? { + entry, + plural: true, + } : { + entry: entry as SingularEntry, + plural: state.subjectsSelected.info.plural, + }; + const eq = assembleEquativeOutput( + equativeMachine(nounInput, state.predicatesSelected[state.predicateType]) + ); + if ("short" in eq) return
length options not supported yet
; + return
+ +
; +} + +export default EquativeDisplay; \ No newline at end of file diff --git a/src/components/equative-explorer/EquativeExplorer.tsx b/src/components/equative-explorer/EquativeExplorer.tsx index effb38e..53b881f 100644 --- a/src/components/equative-explorer/EquativeExplorer.tsx +++ b/src/components/equative-explorer/EquativeExplorer.tsx @@ -1,16 +1,10 @@ import { useState } from "react"; -import { - defaultTextOptions as opts, - VerbTable, -} from "@lingdocs/pashto-inflector"; -import { - makeBlockWPronouns, -} from "./explorer-helpers"; import { reducer, } from "./explorer-reducer"; import { PredicateSelector, + SubjectSelector, } from "./explorer-selectors"; import { ExplorerState, @@ -19,7 +13,9 @@ import { import { defaultUnisexNoun, defaultAdjective, + defaultNoun, } from "./explorer-inputs"; +import EquativeDisplay from "./EquativeDisplay"; // TODO: Plural nouns like shoode @@ -28,7 +24,15 @@ const defaultState: ExplorerState = { adjective: defaultAdjective, unisexNoun: defaultUnisexNoun, }, + subjectsSelected: { + noun: defaultNoun, + info: { + plural: false, + gender: "masc", + }, + }, predicateType: "adjective", + subjectType: "pronouns", }; function EquativeExplorer() { @@ -38,16 +42,11 @@ function EquativeExplorer() { unsafeSetState(newState); } return <> -
- +
+ +
- + ; } diff --git a/src/components/equative-explorer/explorer-helpers.ts b/src/components/equative-explorer/explorer-helpers.ts index abf2808..5ab7022 100644 --- a/src/components/equative-explorer/explorer-helpers.ts +++ b/src/components/equative-explorer/explorer-helpers.ts @@ -8,9 +8,7 @@ import { assembleEquativeOutput, } from "../../lib/equative-machine"; -export function sort(arr: Adjective[]): Adjective[]; -export function sort(arr: UnisexNoun[]): UnisexNoun[]; -export function sort(arr: (Adjective | UnisexNoun)[]): (Adjective | UnisexNoun)[] { +export function sort(arr: T[]): T[] { return arr.sort((a, b) => a.p.localeCompare(b.p)); } @@ -31,6 +29,12 @@ export function makeBlockWPronouns(e: Adjective | UnisexNoun): T.VerbBlock { export function makeOptionLabel(e: T.DictionaryEntry): string { const eng = getEnglishWord(e); - const english = typeof eng === "string" ? eng : eng?.singular; + const english = typeof eng === "string" + ? eng + : !eng + ? "" + : ("singular" in eng && eng.singular !== undefined) + ? eng.singular + : eng.plural; return `${e.p} - ${removeFVarients(e.f)} (${english})`; } \ No newline at end of file diff --git a/src/components/equative-explorer/explorer-inputs.ts b/src/components/equative-explorer/explorer-inputs.ts index b3355e1..232f881 100644 --- a/src/components/equative-explorer/explorer-inputs.ts +++ b/src/components/equative-explorer/explorer-inputs.ts @@ -5,13 +5,16 @@ import { import { sort } from "./explorer-helpers"; const unisexNouns = nouns.filter(x => isUnisexNoun(x)) as UnisexNoun[]; +const nonUnisexNouns = nouns.filter(x => !isUnisexNoun(x)) as (MascNoun | FemNoun)[]; const inputs = { adjective: sort(adjectives), unisexNoun: sort(unisexNouns), + noun: sort(nonUnisexNouns), }; export const defaultAdjective = inputs.adjective.find(ps => ps.p === "ستړی") || inputs.adjective[0]; export const defaultUnisexNoun = inputs.unisexNoun.find(ps => ps.p === "پښتون") || inputs.unisexNoun[0]; +export const defaultNoun = inputs.noun.find(ps => ps.p === "کتاب") || inputs.noun[0]; export default inputs; \ No newline at end of file diff --git a/src/components/equative-explorer/explorer-reducer.ts b/src/components/equative-explorer/explorer-reducer.ts index d7f30b0..c6a8229 100644 --- a/src/components/equative-explorer/explorer-reducer.ts +++ b/src/components/equative-explorer/explorer-reducer.ts @@ -13,10 +13,41 @@ export function reducer(state: ExplorerState, action: ExplorerReducerAction): Ex }, }; } - // if (action.type === "setPredicateType") { + if (action.type === "setPredicateType") { + const predicateType = action.payload; return { ...state, - predicateType: action.payload, + predicateType: (predicateType === "unisexNoun" && state.subjectType === "noun") ? "adjective" : predicateType, }; - // } + } + if (action.type === "setSubjectType") { + const subjectType = action.payload; + return { + ...state, + predicateType: state.predicateType === "unisexNoun" ? "adjective" : state.predicateType, + subjectType, + }; + } + if (action.type === "setSubject") { + if (state.subjectType === "pronouns") return state; + const pile = inputs[state.subjectType]; + const subject = (pile.find(p => p.ts === action.payload) || pile[0]); + return { + ...state, + subjectsSelected: { + ...state.subjectsSelected, + [state.subjectType]: subject, + }, + }; + } + return { + ...state, + subjectsSelected: { + ...state.subjectsSelected, + info: { + ...state.subjectsSelected.info, + plural: action.payload, + }, + }, + }; } \ No newline at end of file diff --git a/src/components/equative-explorer/explorer-selectors.tsx b/src/components/equative-explorer/explorer-selectors.tsx index 75bc4ae..93e56e1 100644 --- a/src/components/equative-explorer/explorer-selectors.tsx +++ b/src/components/equative-explorer/explorer-selectors.tsx @@ -1,7 +1,15 @@ -import { ExplorerState, PredicateType } from "./explorer-types"; import { makeOptionLabel } from "./explorer-helpers"; import inputs from "./explorer-inputs"; -import { ExplorerReducerAction } from "./explorer-types"; +import { + ExplorerReducerAction, + ExplorerState, + PredicateType, + SubjectType, +} from "./explorer-types"; +import { + ButtonSelect, +} from "@lingdocs/pashto-inflector"; +import { isPluralEntry } from "../../lib/type-predicates"; export function PredicateSelector({ state, dispatch }: { state: ExplorerState, @@ -15,7 +23,7 @@ export function PredicateSelector({ state, dispatch }: { const ts = parseInt(e.target.value); dispatch({ type: "setPredicate", payload: ts }); } - return
+ return
; +} + +export function SubjectSelector({ state, dispatch }: { + state: ExplorerState, + dispatch: (action: ExplorerReducerAction) => void, +}) { + function onTypeSelect(e: React.ChangeEvent) { + const t = e.target.value as SubjectType; + dispatch({ type: "setSubjectType", payload: t }); + } + function onSubjectSelect(e: React.ChangeEvent) { + const ts = parseInt(e.target.value); + dispatch({ type: "setSubject", payload: ts }); + } + const pluralNounSelected = ( + state.subjectType === "noun" && isPluralEntry(state.subjectsSelected.noun) + ) + return
+ +
+ + +
+
+ + +
+ {state.subjectType !== "pronouns" && + <> + + dispatch({ type: "setSubjectPlural", payload: p === "plural" ? true : false })} + /> + + } +
; } \ No newline at end of file diff --git a/src/components/equative-explorer/explorer-types.ts b/src/components/equative-explorer/explorer-types.ts index 58188e5..31fd7a9 100644 --- a/src/components/equative-explorer/explorer-types.ts +++ b/src/components/equative-explorer/explorer-types.ts @@ -1,6 +1,11 @@ +import { Types as T } from "@lingdocs/pashto-inflector"; + export type PredicateType = keyof PredicatesSelected; +export type SubjectType = "noun" | "pronouns"; export type ExplorerState = { + subjectType: SubjectType, + subjectsSelected: SubjectSelected, predicateType: PredicateType, predicatesSelected: PredicatesSelected, }; @@ -8,9 +13,22 @@ type PredicatesSelected = { adjective: Adjective, unisexNoun: UnisexNoun, }; +type SubjectSelected = { + noun: Noun, + info: { + plural: boolean, + gender: T.Gender, + }, +}; export type ExplorerReducerAction = { type: "setPredicateType", payload: PredicateType, } | { type: "setPredicate", payload: number, +} | { + type: "setSubjectType", payload: SubjectType, +} | { + type: "setSubject", payload: number, +} | { + type: "setSubjectPlural", payload: boolean, }; \ No newline at end of file diff --git a/src/lib/equative-machine.test.ts b/src/lib/equative-machine.test.ts index 14dcfe8..94bd8bf 100644 --- a/src/lib/equative-machine.test.ts +++ b/src/lib/equative-machine.test.ts @@ -26,6 +26,7 @@ import { // Person | Participle ✔ // Noun | Noun ✔ // Noun | Adjective ✔ +// Plural Noun | Adjective ✔ // Noun | Participle ✔ // Noun | Specified Unisex Noun ✔ // Specified Unisex Noun | Noun ✔ @@ -146,7 +147,7 @@ const abilities: { { in: { subject: { - entry: { "ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m." }, + entry: { "ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m." } as SingularEntry, plural: false, }, predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective, @@ -160,7 +161,7 @@ const abilities: { { in: { subject: { - entry: { "ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m." }, + entry: { "ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m." } as SingularEntry, plural: true, }, predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective, @@ -174,7 +175,7 @@ const abilities: { { in: { subject: { - entry: {"ts":1527812797,"i":8542,"p":"ښځه","f":"xúdza","g":"xudza","e":"woman, wife","c":"n. f. anim.","ec":"woman","ep":"women"}, + entry: {"ts":1527812797,"i":8542,"p":"ښځه","f":"xúdza","g":"xudza","e":"woman, wife","c":"n. f. anim.","ec":"woman","ep":"women"} as SingularEntry, plural: false, }, predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective, @@ -188,7 +189,7 @@ const abilities: { { in: { subject: { - entry: {"ts":1527812797,"i":8542,"p":"ښځه","f":"xúdza","g":"xudza","e":"woman, wife","c":"n. f. anim.","ec":"woman","ep":"women"}, + entry: {"ts":1527812797,"i":8542,"p":"ښځه","f":"xúdza","g":"xudza","e":"woman, wife","c":"n. f. anim.","ec":"woman","ep":"women"} as SingularEntry, plural: true, }, predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective, @@ -203,7 +204,7 @@ const abilities: { { in: { subject: { - entry: {"ts":1527812797,"i":8542,"p":"ښځه","f":"xúdza","g":"xudza","e":"woman, wife","c":"n. f. anim.","ec":"woman","ep":"women"}, + entry: {"ts":1527812797,"i":8542,"p":"ښځه","f":"xúdza","g":"xudza","e":"woman, wife","c":"n. f. anim.","ec":"woman","ep":"women"} as SingularEntry, plural: true, }, predicate: {"ts":1527812798,"i":5595,"p":"خفه","f":"khufa","g":"khufa","e":"sad, upset, angry; choked, suffocated","c":"adj."} as Adjective, @@ -216,6 +217,39 @@ const abilities: { }, ], }, + { + label: "SUBJECT: Plural Noun Predicate: Adjective", + tests: [ + { + in: { + subject: { + entry: {"ts":1527815008,"i":8433,"p":"شودې","f":"shoodé","g":"shoode","e":"milk","c":"n. f. pl."} as PluralEntry, + plural: true, + }, + predicate: {"ts":1527812796,"i":8578,"p":"ښه","f":"xu","g":"xu","e":"good","c":"adj."} as Adjective, + }, + out: { + subject: [{ p: "شودې", f: "shoodé", e: "(The) milk" }], + predicate: [{ p: "ښې", f: "xe", e: "good" }], + equative: [{ p: "دي", f: "dee", e: "is" }], + }, + }, + { + in: { + subject: { + entry: {"ts":1527817330,"i":9204,"p":"غنم","f":"ghanúm","g":"ghanum","e":"wheat","c":"n. m. pl."} as PluralEntry, + plural: true, + }, + predicate: {"ts":1527815451,"i":7192,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective, + }, + out: { + subject: [{ p: "غنم", f: "ghanúm", e: "(The) wheat" }], + predicate: [{ p: "زاړه", f: "zaaRu", e: "old" }], + equative: [{ p: "دي", f: "dee", e: "is" }], + }, + }, + ], + }, { label: "SUBJECT: Participle PREDICATE: Adjective", tests: [ @@ -276,11 +310,11 @@ const abilities: { { in: { subject: { - entry: {"ts":1527813477,"i":5790,"p":"خوشحالي","f":"khosh`haalee","g":"khoshhaalee","e":"happiness, joy","c":"n. f."}, + entry: {"ts":1527813477,"i":5790,"p":"خوشحالي","f":"khosh`haalee","g":"khoshhaalee","e":"happiness, joy","c":"n. f."} as SingularEntry, plural: false, }, predicate: { - entry: {"ts":1527812788,"i":5729,"p":"خوراک","f":"khoráak, khwaráak","g":"khoraak,khwaraak","e":"food","c":"n. m."}, + entry: {"ts":1527812788,"i":5729,"p":"خوراک","f":"khoráak, khwaráak","g":"khoraak,khwaraak","e":"food","c":"n. m."} as SingularEntry, plural: false, }, }, @@ -298,7 +332,7 @@ const abilities: { { in: { subject: { - entry: {"ts":1527822878,"i":14157,"p":"وروروالی","f":"wrorwaaley","g":"wrorwaaley","e":"brotherhood, comradery, tight and good friendship","c":"n. m."}, + entry: {"ts":1527822878,"i":14157,"p":"وروروالی","f":"wrorwaaley","g":"wrorwaaley","e":"brotherhood, comradery, tight and good friendship","c":"n. m."} as SingularEntry, plural: false, }, predicate: {"ts":1527816064,"i":7097,"p":"زغمل","f":"zghamul","g":"zghamul","e":"to endure, bear, tolerate, take on, digest","c":"v. trans.","tppp":"زغامه","tppf":"zghaamu","ec":"endure"} as ParticipleInput, @@ -318,7 +352,7 @@ const abilities: { in: { subject: {"ts":1527812856,"i":11521,"p":"لیکل","f":"leekul","g":"leekul","e":"to write","c":"v. trans.","ec":"write,writes,writing,wrote,wrote"} as ParticipleInput, predicate: { - entry: {"ts":1527813477,"i":5790,"p":"خوشحالي","f":"khosh`haalee","g":"khoshhaalee","e":"happiness, joy","c":"n. f."}, + entry: {"ts":1527813477,"i":5790,"p":"خوشحالي","f":"khosh`haalee","g":"khoshhaalee","e":"happiness, joy","c":"n. f."} as SingularEntry, plural: false, }, }, @@ -352,11 +386,11 @@ const abilities: { { in: { subject: { - entry: {"ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."}, + entry: {"ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."} as SingularEntry, plural: true, }, predicate: { - entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"}, + entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"} as SingularEntry, plural: false, gender: "fem", }, @@ -375,7 +409,7 @@ const abilities: { { in: { subject: { - entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"}, + entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"} as SingularEntry, plural: true, gender: "fem", }, @@ -398,12 +432,12 @@ const abilities: { { in: { subject: { - entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"}, + entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"} as SingularEntry, plural: false, gender: "fem", }, predicate: { - entry: {"ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."}, + entry: {"ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."} as SingularEntry, plural: true, }, }, @@ -421,7 +455,7 @@ const abilities: { { in: { subject: { - entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"}, + entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"} as SingularEntry, plural: false, gender: "fem", }, @@ -442,7 +476,7 @@ const abilities: { in: { subject: {"ts":1527812856,"i":11521,"p":"لیکل","f":"leekul","g":"leekul","e":"to write","c":"v. trans.","ec":"write,writes,writing,wrote,wrote"} as ParticipleInput, predicate: { - entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"}, + entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"} as SingularEntry, plural: false, gender: "fem", }, diff --git a/src/lib/equative-machine.ts b/src/lib/equative-machine.ts index bd45fdd..8c552c2 100644 --- a/src/lib/equative-machine.ts +++ b/src/lib/equative-machine.ts @@ -14,7 +14,7 @@ import { concatPsString, } from "@lingdocs/pashto-inflector"; import { - isArrayOneOrMore, + isArrayOneOrMore, isPluralEntry, } from "./type-predicates"; export type EquativeMachineOutput = { @@ -24,8 +24,11 @@ export type EquativeMachineOutput = { }; export type NounInput = { - entry: T.DictionaryEntry, + entry: SingularEntry, plural: boolean, +} | { + entry: PluralEntry, + plural: true, }; export type ParticipleInput = T.DictionaryEntry & { __brand: "a participle" }; @@ -44,7 +47,7 @@ export function equativeMachine(sub: SubjectInput, pred: PredicateInput): Equati const predPerson = getInputPerson(pred, "predicate") || subjPerson; const subject = makeEntity(sub); const predicate = makeEntity(pred, subjPerson); - const equative = makeEquative(subjPerson, predPerson, isParticipleInput(sub)); + const equative = makeEquative(subjPerson, predPerson, sub); return { subject, predicate, @@ -52,11 +55,11 @@ export function equativeMachine(sub: SubjectInput, pred: PredicateInput): Equati }; } -export function assembleEquativeOutput(o: EquativeMachineOutput): T.SingleOrLengthOpts { +export function assembleEquativeOutput(o: EquativeMachineOutput): T.SingleOrLengthOpts> { if ("long" in o.equative) { return { - long: assembleEquativeOutput({ ...o, equative: o.equative.long }) as T.PsString[], - short: assembleEquativeOutput({ ...o, equative: o.equative.short }) as T.PsString[], + long: assembleEquativeOutput({ ...o, equative: o.equative.long }) as T.ArrayOneOrMore, + short: assembleEquativeOutput({ ...o, equative: o.equative.short }) as T.ArrayOneOrMore, } } // get all possible combinations of subject, predicate, and equative @@ -71,7 +74,7 @@ export function assembleEquativeOutput(o: EquativeMachineOutput): T.SingleOrLeng )) )); const e = `${o.subject[0].e} ${o.equative[0].e} ${o.predicate[0].e}`; - return ps.map(x => ({ ...x, e })); + return ps.map(x => ({ ...x, e })) as T.ArrayOneOrMore; } // LEVEL 2 FUNCTIONS @@ -117,12 +120,16 @@ function makeEntity(e: EntityInput, subjPerson?: T.Person): T.PsString[] { throw new Error(`invalid entity in ${subjPerson ? "predicate" : "subject"}`); } -function makeEquative(subj: T.Person, pred: T.Person, subjIsParticipleInput: boolean): T.SentenceForm { +function makeEquative(subj: T.Person, pred: T.Person, subjectInput: SubjectInput): T.SentenceForm { + const isPluralNoun = isNounInput(subjectInput) && isPluralEntry(subjectInput.entry); // The subject's person information, for the English equative - const [sRow, sCol] = getVerbBlockPosFromPerson(subjIsParticipleInput ? T.Person.ThirdSingMale : subj); + const [eeRow, eeCol] = getVerbBlockPosFromPerson( + (isParticipleInput(subjectInput) || isPluralNoun) + ? T.Person.ThirdSingMale + : subj + ); return addEnglish( - // english agrees with subject - grammarUnits.englishEquative.present[sRow][sCol], + grammarUnits.englishEquative.present[eeRow][eeCol], // pashto agrees with predicate (if possible) getPersonFromVerbForm(grammarUnits.equativeEndings.present, pred), ); diff --git a/src/lib/type-predicates.ts b/src/lib/type-predicates.ts index c1a7d8b..9e56254 100644 --- a/src/lib/type-predicates.ts +++ b/src/lib/type-predicates.ts @@ -134,6 +134,14 @@ export function isPattern6FemNoun(e: FemNoun): e is Pattern6FemNoun { return e.p.slice(-1) === "ي"; } +export function isPluralEntry(e: U): e is PluralEntry { + return e.c.includes("pl."); +} + +export function isSingularEntry(e: U): e is SingularEntry { + return !isPluralEntry(e); +} + export function isArrayOneOrMore(a: U[]): a is T.ArrayOneOrMore { return a.length > 0; } diff --git a/src/types.d.ts b/src/types.d.ts index 9dffdba..f5fbd8f 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -32,6 +32,9 @@ type Verb = { complement?: import("@lingdocs/pashto-inflector").Types.DictionaryEntry, }; +type SingularEntry = T & { __brand7: "a singular noun - as opposed to an always plural noun" }; +type PluralEntry = T & { __brand7: "a noun that is always plural" }; + type RawWord = T.DictionaryEntry | { entry: T.DictionaryEntry, complement?: T.DictionaryEntry,