nouns in explorer working!

This commit is contained in:
lingdocs 2021-10-19 20:07:32 -04:00
parent ad31f2b966
commit b5a5c2c9a8
11 changed files with 285 additions and 53 deletions

View File

@ -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 <VerbTable
textOptions={opts}
block={makeBlockWPronouns(state.predicatesSelected[state.predicateType])}
/>
}
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<Noun>,
plural: state.subjectsSelected.info.plural,
};
const eq = assembleEquativeOutput(
equativeMachine(nounInput, state.predicatesSelected[state.predicateType])
);
if ("short" in eq) return <div>length options not supported yet</div>;
return <div>
<VerbTable textOptions={opts} block={eq} />
</div>;
}
export default EquativeDisplay;

View File

@ -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 <>
<div className="d-flex flex-row">
<PredicateSelector
state={state}
dispatch={dispatch}
/>
<div className="d-flex flex-row justify-content-between">
<SubjectSelector state={state} dispatch={dispatch} />
<PredicateSelector state={state} dispatch={dispatch} />
</div>
<VerbTable
textOptions={opts}
block={makeBlockWPronouns(state.predicatesSelected[state.predicateType])}
/>
<EquativeDisplay state={state} />
</>;
}

View File

@ -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<T extends (Adjective | Noun)>(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})`;
}

View File

@ -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;

View File

@ -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,
},
},
};
}

View File

@ -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 <div className="form-group">
return <div className="form-group ml-2">
<label htmlFor="predicate-select"><strong>Predicate:</strong></label>
<div className="form-check">
<input
@ -40,6 +48,7 @@ export function PredicateSelector({ state, dispatch }: {
value="unisexNoun"
checked={state.predicateType === "unisexNoun"}
onChange={onTypeSelect}
disabled={state.subjectType !== "pronouns"}
/>
<label className="form-check-label" htmlFor="unisexNounsPredicateRadio">
Unisex Nouns
@ -56,4 +65,75 @@ export function PredicateSelector({ state, dispatch }: {
))}
</select>
</div>;
}
export function SubjectSelector({ state, dispatch }: {
state: ExplorerState,
dispatch: (action: ExplorerReducerAction) => void,
}) {
function onTypeSelect(e: React.ChangeEvent<HTMLInputElement>) {
const t = e.target.value as SubjectType;
dispatch({ type: "setSubjectType", payload: t });
}
function onSubjectSelect(e: React.ChangeEvent<HTMLSelectElement>) {
const ts = parseInt(e.target.value);
dispatch({ type: "setSubject", payload: ts });
}
const pluralNounSelected = (
state.subjectType === "noun" && isPluralEntry(state.subjectsSelected.noun)
)
return <div className="form-group mr-2">
<label htmlFor="predicate-select"><strong>Subject:</strong></label>
<div className="form-check">
<input
className="form-check-input"
type="radio"
name="pronounsSubjectRadio"
id="pronounsSubjectRadio"
value="pronouns"
checked={state.subjectType === "pronouns"}
onChange={onTypeSelect}
/>
<label className="form-check-label" htmlFor="adjectivesPredicateRadio">
Pronouns
</label>
</div>
<div className="form-check mb-2">
<input
className="form-check-input"
type="radio"
name="nounsSubjectRadio"
id="nounsSubjectRadio"
value="noun"
checked={state.subjectType === "noun"}
onChange={onTypeSelect}
/>
<label className="form-check-label" htmlFor="unisexNounsPredicateRadio">
Nouns
</label>
</div>
{state.subjectType !== "pronouns" &&
<>
<select
className="form-control mb-3"
id="subject-select"
value={state.subjectsSelected[state.subjectType].ts}
onChange={onSubjectSelect}
>
{inputs[state.subjectType].map(e => (
<option key={e.ts+"s"} value={e.ts}>{makeOptionLabel(e)}</option>
))}
</select>
<ButtonSelect
small
options={[
...!pluralNounSelected ? [{ label: "Singular", value: "singular" }] : [],
{ label: "Plural", value: "plural" },
]}
value={(state.subjectsSelected.info.plural || pluralNounSelected) ? "plural" : "singular"}
handleChange={(p) => dispatch({ type: "setSubjectPlural", payload: p === "plural" ? true : false })}
/>
</>
}
</div>;
}

View File

@ -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,
};

View File

@ -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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
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<Noun>,
plural: false,
gender: "fem",
},

View File

@ -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<Noun>,
plural: boolean,
} | {
entry: PluralEntry<Noun>,
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<T.PsString[]> {
export function assembleEquativeOutput(o: EquativeMachineOutput): T.SingleOrLengthOpts<T.ArrayOneOrMore<T.PsString>> {
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<T.PsString>,
short: assembleEquativeOutput({ ...o, equative: o.equative.short }) as T.ArrayOneOrMore<T.PsString>,
}
}
// 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<T.PsString>;
}
// 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),
);

View File

@ -134,6 +134,14 @@ export function isPattern6FemNoun(e: FemNoun): e is Pattern6FemNoun<FemNoun> {
return e.p.slice(-1) === "ي";
}
export function isPluralEntry<U extends Noun>(e: U): e is PluralEntry<U> {
return e.c.includes("pl.");
}
export function isSingularEntry<U extends Noun>(e: U): e is SingularEntry<U> {
return !isPluralEntry(e);
}
export function isArrayOneOrMore<U>(a: U[]): a is T.ArrayOneOrMore<U> {
return a.length > 0;
}

3
src/types.d.ts vendored
View File

@ -32,6 +32,9 @@ type Verb = {
complement?: import("@lingdocs/pashto-inflector").Types.DictionaryEntry,
};
type SingularEntry<T extends Noun> = T & { __brand7: "a singular noun - as opposed to an always plural noun" };
type PluralEntry<T extends Noun> = T & { __brand7: "a noun that is always plural" };
type RawWord = T.DictionaryEntry | {
entry: T.DictionaryEntry,
complement?: T.DictionaryEntry,