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 { useState } from "react";
import {
defaultTextOptions as opts,
VerbTable,
} from "@lingdocs/pashto-inflector";
import {
makeBlockWPronouns,
} from "./explorer-helpers";
import { import {
reducer, reducer,
} from "./explorer-reducer"; } from "./explorer-reducer";
import { import {
PredicateSelector, PredicateSelector,
SubjectSelector,
} from "./explorer-selectors"; } from "./explorer-selectors";
import { import {
ExplorerState, ExplorerState,
@ -19,7 +13,9 @@ import {
import { import {
defaultUnisexNoun, defaultUnisexNoun,
defaultAdjective, defaultAdjective,
defaultNoun,
} from "./explorer-inputs"; } from "./explorer-inputs";
import EquativeDisplay from "./EquativeDisplay";
// TODO: Plural nouns like shoode // TODO: Plural nouns like shoode
@ -28,7 +24,15 @@ const defaultState: ExplorerState = {
adjective: defaultAdjective, adjective: defaultAdjective,
unisexNoun: defaultUnisexNoun, unisexNoun: defaultUnisexNoun,
}, },
subjectsSelected: {
noun: defaultNoun,
info: {
plural: false,
gender: "masc",
},
},
predicateType: "adjective", predicateType: "adjective",
subjectType: "pronouns",
}; };
function EquativeExplorer() { function EquativeExplorer() {
@ -38,16 +42,11 @@ function EquativeExplorer() {
unsafeSetState(newState); unsafeSetState(newState);
} }
return <> return <>
<div className="d-flex flex-row"> <div className="d-flex flex-row justify-content-between">
<PredicateSelector <SubjectSelector state={state} dispatch={dispatch} />
state={state} <PredicateSelector state={state} dispatch={dispatch} />
dispatch={dispatch}
/>
</div> </div>
<VerbTable <EquativeDisplay state={state} />
textOptions={opts}
block={makeBlockWPronouns(state.predicatesSelected[state.predicateType])}
/>
</>; </>;
} }

View File

@ -8,9 +8,7 @@ import {
assembleEquativeOutput, assembleEquativeOutput,
} from "../../lib/equative-machine"; } from "../../lib/equative-machine";
export function sort(arr: Adjective[]): Adjective[]; export function sort<T extends (Adjective | Noun)>(arr: T[]): T[] {
export function sort(arr: UnisexNoun[]): UnisexNoun[];
export function sort(arr: (Adjective | UnisexNoun)[]): (Adjective | UnisexNoun)[] {
return arr.sort((a, b) => a.p.localeCompare(b.p)); 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 { export function makeOptionLabel(e: T.DictionaryEntry): string {
const eng = getEnglishWord(e); 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})`; return `${e.p} - ${removeFVarients(e.f)} (${english})`;
} }

View File

@ -5,13 +5,16 @@ import {
import { sort } from "./explorer-helpers"; import { sort } from "./explorer-helpers";
const unisexNouns = nouns.filter(x => isUnisexNoun(x)) as UnisexNoun[]; const unisexNouns = nouns.filter(x => isUnisexNoun(x)) as UnisexNoun[];
const nonUnisexNouns = nouns.filter(x => !isUnisexNoun(x)) as (MascNoun | FemNoun)[];
const inputs = { const inputs = {
adjective: sort(adjectives), adjective: sort(adjectives),
unisexNoun: sort(unisexNouns), unisexNoun: sort(unisexNouns),
noun: sort(nonUnisexNouns),
}; };
export const defaultAdjective = inputs.adjective.find(ps => ps.p === "ستړی") || inputs.adjective[0]; 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 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; 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 { return {
...state, ...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 { makeOptionLabel } from "./explorer-helpers";
import inputs from "./explorer-inputs"; 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 }: { export function PredicateSelector({ state, dispatch }: {
state: ExplorerState, state: ExplorerState,
@ -15,7 +23,7 @@ export function PredicateSelector({ state, dispatch }: {
const ts = parseInt(e.target.value); const ts = parseInt(e.target.value);
dispatch({ type: "setPredicate", payload: ts }); 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> <label htmlFor="predicate-select"><strong>Predicate:</strong></label>
<div className="form-check"> <div className="form-check">
<input <input
@ -40,6 +48,7 @@ export function PredicateSelector({ state, dispatch }: {
value="unisexNoun" value="unisexNoun"
checked={state.predicateType === "unisexNoun"} checked={state.predicateType === "unisexNoun"}
onChange={onTypeSelect} onChange={onTypeSelect}
disabled={state.subjectType !== "pronouns"}
/> />
<label className="form-check-label" htmlFor="unisexNounsPredicateRadio"> <label className="form-check-label" htmlFor="unisexNounsPredicateRadio">
Unisex Nouns Unisex Nouns
@ -57,3 +66,74 @@ export function PredicateSelector({ state, dispatch }: {
</select> </select>
</div>; </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 PredicateType = keyof PredicatesSelected;
export type SubjectType = "noun" | "pronouns";
export type ExplorerState = { export type ExplorerState = {
subjectType: SubjectType,
subjectsSelected: SubjectSelected,
predicateType: PredicateType, predicateType: PredicateType,
predicatesSelected: PredicatesSelected, predicatesSelected: PredicatesSelected,
}; };
@ -8,9 +13,22 @@ type PredicatesSelected = {
adjective: Adjective, adjective: Adjective,
unisexNoun: UnisexNoun, unisexNoun: UnisexNoun,
}; };
type SubjectSelected = {
noun: Noun,
info: {
plural: boolean,
gender: T.Gender,
},
};
export type ExplorerReducerAction = { export type ExplorerReducerAction = {
type: "setPredicateType", payload: PredicateType, type: "setPredicateType", payload: PredicateType,
} | { } | {
type: "setPredicate", payload: number, 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 ✔ // Person | Participle ✔
// Noun | Noun ✔ // Noun | Noun ✔
// Noun | Adjective ✔ // Noun | Adjective ✔
// Plural Noun | Adjective ✔
// Noun | Participle ✔ // Noun | Participle ✔
// Noun | Specified Unisex Noun ✔ // Noun | Specified Unisex Noun ✔
// Specified Unisex Noun | Noun ✔ // Specified Unisex Noun | Noun ✔
@ -146,7 +147,7 @@ const abilities: {
{ {
in: { in: {
subject: { 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, 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, 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: { in: {
subject: { 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, 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, 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: { in: {
subject: { 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, 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, 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: { in: {
subject: { 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, 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, 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: { in: {
subject: { 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, plural: true,
}, },
predicate: {"ts":1527812798,"i":5595,"p":"خفه","f":"khufa","g":"khufa","e":"sad, upset, angry; choked, suffocated","c":"adj."} as Adjective, 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", label: "SUBJECT: Participle PREDICATE: Adjective",
tests: [ tests: [
@ -276,11 +310,11 @@ const abilities: {
{ {
in: { in: {
subject: { 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, plural: false,
}, },
predicate: { 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, plural: false,
}, },
}, },
@ -298,7 +332,7 @@ const abilities: {
{ {
in: { in: {
subject: { 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, 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, 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: { 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, 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: { 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, plural: false,
}, },
}, },
@ -352,11 +386,11 @@ const abilities: {
{ {
in: { in: {
subject: { 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, plural: true,
}, },
predicate: { 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, plural: false,
gender: "fem", gender: "fem",
}, },
@ -375,7 +409,7 @@ const abilities: {
{ {
in: { in: {
subject: { 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, plural: true,
gender: "fem", gender: "fem",
}, },
@ -398,12 +432,12 @@ const abilities: {
{ {
in: { in: {
subject: { 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, plural: false,
gender: "fem", gender: "fem",
}, },
predicate: { 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, plural: true,
}, },
}, },
@ -421,7 +455,7 @@ const abilities: {
{ {
in: { in: {
subject: { 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, plural: false,
gender: "fem", gender: "fem",
}, },
@ -442,7 +476,7 @@ const abilities: {
in: { 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, 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: { 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, plural: false,
gender: "fem", gender: "fem",
}, },

View File

@ -14,7 +14,7 @@ import {
concatPsString, concatPsString,
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
import { import {
isArrayOneOrMore, isArrayOneOrMore, isPluralEntry,
} from "./type-predicates"; } from "./type-predicates";
export type EquativeMachineOutput = { export type EquativeMachineOutput = {
@ -24,8 +24,11 @@ export type EquativeMachineOutput = {
}; };
export type NounInput = { export type NounInput = {
entry: T.DictionaryEntry, entry: SingularEntry<Noun>,
plural: boolean, plural: boolean,
} | {
entry: PluralEntry<Noun>,
plural: true,
}; };
export type ParticipleInput = T.DictionaryEntry & { __brand: "a participle" }; 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 predPerson = getInputPerson(pred, "predicate") || subjPerson;
const subject = makeEntity(sub); const subject = makeEntity(sub);
const predicate = makeEntity(pred, subjPerson); const predicate = makeEntity(pred, subjPerson);
const equative = makeEquative(subjPerson, predPerson, isParticipleInput(sub)); const equative = makeEquative(subjPerson, predPerson, sub);
return { return {
subject, subject,
predicate, 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) { if ("long" in o.equative) {
return { return {
long: assembleEquativeOutput({ ...o, equative: o.equative.long }) as T.PsString[], long: assembleEquativeOutput({ ...o, equative: o.equative.long }) as T.ArrayOneOrMore<T.PsString>,
short: assembleEquativeOutput({ ...o, equative: o.equative.short }) as T.PsString[], short: assembleEquativeOutput({ ...o, equative: o.equative.short }) as T.ArrayOneOrMore<T.PsString>,
} }
} }
// get all possible combinations of subject, predicate, and equative // 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}`; 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 // 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"}`); 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 // 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( return addEnglish(
// english agrees with subject grammarUnits.englishEquative.present[eeRow][eeCol],
grammarUnits.englishEquative.present[sRow][sCol],
// pashto agrees with predicate (if possible) // pashto agrees with predicate (if possible)
getPersonFromVerbForm(grammarUnits.equativeEndings.present, pred), 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) === "ي"; 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> { export function isArrayOneOrMore<U>(a: U[]): a is T.ArrayOneOrMore<U> {
return a.length > 0; 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, 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 | { type RawWord = T.DictionaryEntry | {
entry: T.DictionaryEntry, entry: T.DictionaryEntry,
complement?: T.DictionaryEntry, complement?: T.DictionaryEntry,