now working with dynamic compounds and OSV

This commit is contained in:
lingdocs 2022-03-28 11:08:08 +05:00
parent 4f79456115
commit 693aecdd70
13 changed files with 156 additions and 82 deletions

View File

@ -1,11 +1,13 @@
import Select from "react-select"; import Select from "react-select";
import { import {
makeNounSelection,
makeVerbSelectOption, makeVerbSelectOption,
zIndexProps, zIndexProps,
} from "./np-picker/picker-tools"; } from "./np-picker/picker-tools";
import { import {
Types as T, Types as T,
ButtonSelect, ButtonSelect,
getVerbInfo,
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
const tenseOptions: { label: string, value: VerbTense }[] = [{ const tenseOptions: { label: string, value: VerbTense }[] = [{
@ -29,42 +31,54 @@ const tenseOptions: { label: string, value: VerbTense }[] = [{
}]; }];
function makeVerbSelection(verb: VerbEntry, oldVerbSelection?: VerbSelection): VerbSelection { function makeVerbSelection(verb: VerbEntry, oldVerbSelection?: VerbSelection): VerbSelection {
const info = getVerbInfo(verb.entry, verb.complement);
function getTransObjFromOldVerbSelection() { function getTransObjFromOldVerbSelection() {
if (!oldVerbSelection || oldVerbSelection.object === "none" || typeof oldVerbSelection.object === "number") return undefined; if (
!oldVerbSelection ||
oldVerbSelection.object === "none" ||
typeof oldVerbSelection.object === "number" ||
oldVerbSelection.isCompound === "dynamic" ||
(oldVerbSelection.object?.type === "noun" && oldVerbSelection.object.dynamicComplement)
) return undefined;
return oldVerbSelection.object; return oldVerbSelection.object;
} }
// TODO: more complex types and unchangeable dynamic compound objects const transitivity: T.Transitivity = "grammaticallyTransitive" in info
// TODO: use proper type predicates ? "grammatically transitive"
const transitivity: "intransitive" | "transitive" | "grammaticallyTransitive" = verb.entry.c?.includes("intrans.") : info.transitivity;
? "intransitive" const object = (transitivity === "grammatically transitive")
: verb.entry.c?.includes("v. gramm. trans.")
? "grammaticallyTransitive"
: "transitive";
const object = (transitivity === "grammaticallyTransitive")
? T.Person.ThirdPlurMale ? T.Person.ThirdPlurMale
: transitivity === "transitive" : info.type === "dynamic compound"
? makeNounSelection(info.objComplement.entry as NounEntry, true)
: (transitivity === "transitive")
? getTransObjFromOldVerbSelection() ? getTransObjFromOldVerbSelection()
: "none"; : "none";
// TODO: better here based on selection of which type const isCompound = "stative" in info
const isCompound = verb.entry.c?.includes("stat. comp.")
? "stative" ? "stative"
: verb.entry.c?.includes("dyn. comp.") : info.type === "dynamic compound"
? "dynamic" ? "dynamic"
: false; : false;
const dynAuxVerb: VerbEntry | undefined = isCompound !== "dynamic"
? undefined
: info.type === "dynamic compound"
? { entry: info.auxVerb } as VerbEntry
: "dynamic" in info
? { entry: info.dynamic.auxVerb } as VerbEntry
: undefined;
return { return {
type: "verb", type: "verb",
verb, verb: verb,
dynAuxVerb,
tense: oldVerbSelection ? oldVerbSelection.tense : "present", tense: oldVerbSelection ? oldVerbSelection.tense : "present",
object, object,
transitivity, transitivity,
isCompound, isCompound,
negative: oldVerbSelection ? oldVerbSelection.negative : false, negative: oldVerbSelection ? oldVerbSelection.negative : false,
...verb.entry.c?.includes("v. trans./gramm. trans") ? { ...("grammaticallyTransitive" in info) ? {
changeTransitivity: function (t) { changeTransitivity: function (t) {
return { return {
...this, ...this,
transitivity: t, transitivity: t,
object: t === "grammaticallyTransitive" ? T.Person.ThirdPlurMale : undefined, object: t === "grammatically transitive" ? T.Person.ThirdPlurMale : undefined,
}; };
}, },
} : {}, } : {},
@ -97,10 +111,10 @@ function VerbPicker({ onChange, verb, verbs }: { verbs: VerbEntry[], verb: VerbS
}); });
} }
} }
function notInstransitive(t: "transitive" | "intransitive" | "grammaticallyTransitive"): "transitive" | "grammaticallyTransitive" { function notInstransitive(t: "transitive" | "intransitive" | "grammatically transitive"): "transitive" | "grammatically transitive" {
return t === "intransitive" ? "transitive" : t; return t === "intransitive" ? "transitive" : t;
} }
function handleChangeTransitivity(t: "transitive" | "grammaticallyTransitive") { function handleChangeTransitivity(t: "transitive" | "grammatically transitive") {
if (verb && verb.changeTransitivity) { if (verb && verb.changeTransitivity) {
onChange(verb.changeTransitivity(t)); onChange(verb.changeTransitivity(t));
} }
@ -150,7 +164,7 @@ function VerbPicker({ onChange, verb, verbs }: { verbs: VerbEntry[], verb: VerbS
small small
options={[{ options={[{
label: "gramm. trans.", label: "gramm. trans.",
value: "grammaticallyTransitive", value: "grammatically transitive",
}, { }, {
label: "trans.", label: "trans.",
value: "transitive", value: "transitive",

View File

@ -6,9 +6,10 @@ import {
} from "./picker-tools"; } from "./picker-tools";
import { import {
ButtonSelect, ButtonSelect,
InlinePs,
defaultTextOptions as opts,
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
function NPNounPicker({ onChange, noun, nouns }: { nouns: NounEntry[], noun: NounSelection | undefined, onChange: (p: NounSelection) => void }) { function NPNounPicker({ onChange, noun, nouns }: { nouns: NounEntry[], noun: NounSelection | undefined, onChange: (p: NounSelection) => void }) {
const options = nouns.sort((a, b) => (a.p.localeCompare(b.p, "af-PS"))).map(makeSelectOption) const options = nouns.sort((a, b) => (a.p.localeCompare(b.p, "af-PS"))).map(makeSelectOption)
function onEntrySelect({ value }: { label: string, value: string }) { function onEntrySelect({ value }: { label: string, value: string }) {
@ -20,7 +21,7 @@ function NPNounPicker({ onChange, noun, nouns }: { nouns: NounEntry[], noun: Nou
onChange(makeNounSelection(entry)); onChange(makeNounSelection(entry));
} }
return <div style={{ maxWidth: "225px", minWidth: "125px" }}> return <div style={{ maxWidth: "225px", minWidth: "125px" }}>
<Select {!(noun && noun.dynamicComplement) ? <Select
value={noun && noun.entry.ts.toString()} value={noun && noun.entry.ts.toString()}
// @ts-ignore // @ts-ignore
onChange={onEntrySelect} onChange={onEntrySelect}
@ -32,7 +33,17 @@ function NPNounPicker({ onChange, noun, nouns }: { nouns: NounEntry[], noun: Nou
placeholder={noun ? options.find(o => o.value === (noun.entry).ts.toString())?.label : "Select Noun..."} placeholder={noun ? options.find(o => o.value === (noun.entry).ts.toString())?.label : "Select Noun..."}
{...zIndexProps} {...zIndexProps}
/> /> : <div>
{noun && <div>
<div className="mb-2">Included in Dyn. Compound:</div>
<div className="mb-3 text-center">
<InlinePs opts={opts}>
{{ p: noun.entry.p, f: noun.entry.f }}
</InlinePs>
<div className="text-muted">{noun.entry.e}</div>
</div>
</div>}
</div>}
{noun && <div className="my-2 d-flex flex-row justify-content-around align-items-center"> {noun && <div className="my-2 d-flex flex-row justify-content-around align-items-center">
<div> <div>
{noun.changeGender ? <ButtonSelect {noun.changeGender ? <ButtonSelect

View File

@ -4,16 +4,24 @@ import ParticiplePicker from "./NPParticiplePicker";
// import { getEnglishPronoun } from "../../lib/english-pronoun-tools"; // import { getEnglishPronoun } from "../../lib/english-pronoun-tools";
// import { ButtonSelect } from "@lingdocs/pashto-inflector"; // import { ButtonSelect } from "@lingdocs/pashto-inflector";
import { randomPerson } from "../../lib/np-tools"; import { randomPerson } from "../../lib/np-tools";
import { useState } from "react"; import { useState, useEffect } from "react";
import { nouns, verbs } from "../../words/words"; import { nouns, verbs } from "../../words/words";
// import { capitalizeFirstLetter } from "../../lib/text-tools"; // import { capitalizeFirstLetter } from "../../lib/text-tools";
const npTypes: NPType[] = ["pronoun", "noun", "participle"]; const npTypes: NPType[] = ["pronoun", "noun", "participle"];
function NPPicker({ np, onChange, counterPart, asObject }: { onChange: (nps: NPSelection | undefined) => void, np: NPSelection | undefined, counterPart: NPSelection | VerbObject | undefined, asObject?: boolean }) { function NPPicker({ np, onChange, counterPart, asObject }: {
// eslint-disable-next-line onChange: (nps: NPSelection | undefined) => void,
np: NPSelection | undefined,
counterPart: NPSelection | VerbObject | undefined,
asObject?: boolean,
}) {
const [npType, setNpType] = useState<NPType | undefined>(np ? np.type : undefined); const [npType, setNpType] = useState<NPType | undefined>(np ? np.type : undefined);
useEffect(() => {
setNpType(np ? np.type : undefined);
}, [np]);
function handleClear() { function handleClear() {
if (np && np.type === "noun" && np.dynamicComplement) return;
setNpType(undefined); setNpType(undefined);
onChange(undefined); onChange(undefined);
} }
@ -32,8 +40,9 @@ function NPPicker({ np, onChange, counterPart, asObject }: { onChange: (nps: NPS
setNpType(ntp); setNpType(ntp);
} }
} }
const isDynamicComplement = np && np.type === "noun" && np.dynamicComplement;
return <div> return <div>
{!npType ? <div className="text-center mt-3"> {!npType && <div className="text-center mt-3">
{npTypes.map((npt) => <div className="mb-2"> {npTypes.map((npt) => <div className="mb-2">
<button <button
key={npt} key={npt}
@ -44,19 +53,16 @@ function NPPicker({ np, onChange, counterPart, asObject }: { onChange: (nps: NPS
{npt} {npt}
</button> </button>
</div>)} </div>)}
</div> </div>}
: <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>} {(npType && !isDynamicComplement) && <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>}
{np ? {(npType === "pronoun" && np?.type === "pronoun")
((np.type === "pronoun"
? <PronounPicker asObject={asObject} pronoun={np} onChange={onChange} /> ? <PronounPicker asObject={asObject} pronoun={np} onChange={onChange} />
: np.type === "noun" : npType === "noun"
? <NounPicker nouns={nouns} noun={np} onChange={onChange} /> ? <NounPicker nouns={nouns} noun={(np && np.type === "noun") ? np : undefined} onChange={onChange} />
: <ParticiplePicker verbs={verbs} participle={np} onChange={onChange} />)) : npType === "participle"
: (npType === "noun") ? <ParticiplePicker verbs={verbs} participle={(np && np.type === "participle") ? np : undefined} onChange={onChange} />
? <NounPicker nouns={nouns} noun={np} onChange={onChange} /> : null
: (npType === "participle") }
? <ParticiplePicker verbs={verbs} participle={np} onChange={onChange} />
: null}
</div>; </div>;
} }

View File

@ -45,13 +45,14 @@ export function makeSelectOption(e: VerbEntry | NounEntry | AdjectiveEntry | Loc
}; };
} }
export function makeNounSelection(entry: NounEntry): NounSelection { export function makeNounSelection(entry: NounEntry, dynamicComplement?: true): NounSelection {
const number = isPluralNounEntry(entry) ? "plural" : "singular"; const number = isPluralNounEntry(entry) ? "plural" : "singular";
return { return {
type: "noun", type: "noun",
entry, entry,
gender: isMascNounEntry(entry) ? "masc" : "fem", gender: isMascNounEntry(entry) ? "masc" : "fem",
number, number,
dynamicComplement,
...isUnisexNounEntry(entry) ? { ...isUnisexNounEntry(entry) ? {
changeGender: function(gender: T.Gender): NounSelection { changeGender: function(gender: T.Gender): NounSelection {
return { return {

View File

@ -85,7 +85,7 @@ function AbbreviationFormSelector({ form, onChange, adjustable }: {
} }
} }
// TODO: limit display of shrinking options based on the verb type // TODO: limit display of shrinking options based on the verb type
return <div className="my-3"> return <div className="mb-3">
{/* <div className="text-center text-small mb-2">Abbreviation Options</div> */} {/* <div className="text-center text-small mb-2">Abbreviation Options</div> */}
<ButtonSelect <ButtonSelect
// @ts-ignore // @ts-ignore

View File

@ -3,12 +3,17 @@ import NPPicker from "../np-picker/NPPicker";
function ObjectDisplay({ object, onChange, counterPart }: { function ObjectDisplay({ object, onChange, counterPart }: {
object: Exclude<VerbObject, "none">, object: Exclude<VerbObject, "none">,
onChange: (o: NPSelection | undefined) => void, onChange: (o: NPSelection | undefined) => void,
counterPart: NPSelection | undefined }, counterPart: NPSelection | undefined ,
) { }) {
return <div> return <div>
{(typeof object === "number") {(typeof object === "number")
? <div className="text-muted">Unspoken 3rd Pers. Masc. Plur.</div> ? <div className="text-muted">Unspoken 3rd Pers. Masc. Plur.</div>
: <NPPicker asObject np={object} counterPart={counterPart} onChange={onChange} />} : <NPPicker
asObject
np={object}
counterPart={counterPart}
onChange={onChange}
/>}
</div>; </div>;
} }

View File

@ -27,7 +27,6 @@ export function PhraseBuilder() {
function handleObjectChange(object: NPSelection | undefined) { function handleObjectChange(object: NPSelection | undefined) {
if (!verb) return; if (!verb) return;
if ((verb.object === "none") || (typeof verb.object === "number")) return; if ((verb.object === "none") || (typeof verb.object === "number")) return;
console.log("handling object change and checking", object);
// check for pronoun conflict // check for pronoun conflict
if (hasPronounConflict(subject, object)) { if (hasPronounConflict(subject, object)) {
alert("That combination of pronouns is not allowed"); alert("That combination of pronouns is not allowed");
@ -36,6 +35,7 @@ export function PhraseBuilder() {
setVerb({ ...verb, object }); setVerb({ ...verb, object });
} }
function handleSubjObjSwap() { function handleSubjObjSwap() {
if (verb?.isCompound === "dynamic") return;
const output = switchSubjObj({ subject, verb }); const output = switchSubjObj({ subject, verb });
setSubject(output.subject); setSubject(output.subject);
setVerb(output.verb); setVerb(output.verb);
@ -47,7 +47,8 @@ export function PhraseBuilder() {
<div>{kingEmoji} = <abbr title="controls the verb conjugation, can be removed">king</abbr> of phrase</div> <div>{kingEmoji} = <abbr title="controls the verb conjugation, can be removed">king</abbr> of phrase</div>
<div>{servantEmoji} = <abbr title="can be shrunken into a mini-pronoun">servant</abbr> of phrase</div> <div>{servantEmoji} = <abbr title="can be shrunken into a mini-pronoun">servant</abbr> of phrase</div>
</div> </div>
{verb && (typeof verb.object === "object") && <div className="d-flex flex-row justify-content-around flex-wrap mb-2"> {(verb && (typeof verb.object === "object") && (verb.isCompound !== "dynamic")) &&
<div className="d-flex flex-row justify-content-around flex-wrap mb-2">
<button onClick={handleSubjObjSwap} className="btn btn-sm btn-light"> <button onClick={handleSubjObjSwap} className="btn btn-sm btn-light">
<i className="fas fa-exchange-alt mr-2" /> subj/obj <i className="fas fa-exchange-alt mr-2" /> subj/obj
</button> </button>
@ -64,7 +65,11 @@ export function PhraseBuilder() {
</div> </div>
{verb && (verb.object !== "none") && <div className="mb-2"> {verb && (verb.object !== "none") && <div className="mb-2">
<div className="h4">Object {showRole(VPRendered, "object")}</div> <div className="h4">Object {showRole(VPRendered, "object")}</div>
<ObjectDisplay object={verb.object} counterPart={subject} onChange={handleObjectChange} /> <ObjectDisplay
object={verb.object}
counterPart={subject}
onChange={handleObjectChange}
/>
</div>} </div>}
<div className="mb-2"> <div className="mb-2">
<div className="h4">Verb</div> <div className="h4">Verb</div>

View File

@ -8,10 +8,25 @@ import {
import AbbreviationFormSelector from "./AbbreviationFormSelector"; import AbbreviationFormSelector from "./AbbreviationFormSelector";
import { isPastTense } from "../../lib/phrase-building/vp-tools"; import { isPastTense } from "../../lib/phrase-building/vp-tools";
// TODO: Issue when picking dynamic compound and then going back with the object dissappearing
function VPDisplay({ VP }: { VP: VPSelection }) { function VPDisplay({ VP }: { VP: VPSelection }) {
const [form, setForm] = useState<FormVersion>({ removeKing: false, shrinkServant: false }); const [form, setForm] = useState<FormVersion>({ removeKing: false, shrinkServant: false });
const result = compileVP(renderVP(VP), form); const [OSV, setOSV] = useState<boolean>(false);
const result = compileVP(renderVP(VP), { ...form, OSV });
return <div className="text-center mt-2"> return <div className="text-center mt-2">
<div className="form-check mb-2">
<input
className="form-check-input"
type="checkbox"
checked={OSV}
id="OSVCheckbox"
onChange={e => setOSV(e.target.checked)}
/>
<label className="form-check-label text-muted" htmlFor="OSVCheckbox">
Include O S V
</label>
</div>
<AbbreviationFormSelector <AbbreviationFormSelector
adjustable={whatsAdjustable(VP)} adjustable={whatsAdjustable(VP)}
form={form} form={form}
@ -37,7 +52,10 @@ function VPDisplay({ VP }: { VP: VPSelection }) {
} }
function whatsAdjustable(VP: VPSelection): "both" | "king" | "servant" { function whatsAdjustable(VP: VPSelection): "both" | "king" | "servant" {
return VP.verb.transitivity === "transitive" // TODO: intransitive dynamic compounds?
return (VP.verb.isCompound === "dynamic" && VP.verb.transitivity === "transitive")
? (isPastTense(VP.verb.tense) ? "servant" : "king")
: VP.verb.transitivity === "transitive"
? "both" ? "both"
: VP.verb.transitivity === "intransitive" : VP.verb.transitivity === "intransitive"
? "king" ? "king"

View File

@ -9,9 +9,10 @@ import { removeBa } from "./vp-tools";
// TODO: make it an option to include O S V order ? // TODO: make it an option to include O S V order ?
// TODO: tu ba laaR nu she hyphens all messed up // TODO: tu ba laaR nu she hyphens all messed up
export function compileVP(VP: VPRendered, form: FormVersion): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] }; type Form = FormVersion & { OSV?: boolean };
export function compileVP(VP: VPRendered, form: FormVersion, combineLengths: true): { ps: T.PsString[], e?: string [] }; export function compileVP(VP: VPRendered, form: Form): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] };
export function compileVP(VP: VPRendered, form: FormVersion, combineLengths?: true): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] } { export function compileVP(VP: VPRendered, form: Form, combineLengths: true): { ps: T.PsString[], e?: string [] };
export function compileVP(VP: VPRendered, form: Form, combineLengths?: true): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] } {
const verb = VP.verb.ps; const verb = VP.verb.ps;
const { kids, NPs } = getSegmentsAndKids(VP, form); const { kids, NPs } = getSegmentsAndKids(VP, form);
const psResult = compilePs({ const psResult = compilePs({
@ -65,24 +66,33 @@ function compilePs({ NPs, kids, verb: { head, rest }, isCompound, negative }: Co
)); ));
} }
function getSegmentsAndKids(VP: VPRendered, form: FormVersion): { kids: Segment[], NPs: Segment[][] } { function getSegmentsAndKids(VP: VPRendered, form: Form): { kids: Segment[], NPs: Segment[][] } {
const main = { const SO = {
subject: VP.subject.ps, subject: VP.subject.ps,
object: typeof VP.object === "object" ? VP.object.ps : undefined, object: typeof VP.object === "object" ? VP.object.ps : undefined,
} }
// TODO: simplify all this logic const removeKing = form.removeKing && !(VP.isCompound === "dynamic" && VP.isPast);
const { removeKing, shrinkServant } = form; const shrinkServant = form.shrinkServant && !(VP.isCompound === "dynamic" && !VP.isPast);
const shrinkCanditate = (shrinkServant && VP.servant)
? VP[VP.servant] const toShrink = (() => {
if (!shrinkServant) return undefined;
if (!VP.servant) return undefined;
const servant = VP[VP.servant];
if (typeof servant !== "object") return undefined;
return servant;
})();
function getSegment(t: "subject" | "object"): Segment | undefined {
const word = (VP.servant === t)
? (!shrinkServant ? SO[t] : undefined)
: (VP.king === t)
? (!removeKing ? SO[t] : undefined)
: undefined; : undefined;
const toShrink = (!shrinkCanditate || typeof shrinkCanditate !== "object") if (!word) return undefined;
? undefined return makeSegment(word);
: shrinkCanditate; }
const king = main[VP.king]; const subject = getSegment("subject");
const showSubject = (VP.king === "subject" && !removeKing && king) || (VP.servant === "subject" && !shrinkServant); const object = getSegment("object");
const showObject = (
(king && VP.king === "object" && !removeKing) || (VP.servant === "object" && !shrinkServant)
);
return { return {
kids: [ kids: [
...VP.verb.hasBa ...VP.verb.hasBa
@ -92,17 +102,14 @@ function getSegmentsAndKids(VP: VPRendered, form: FormVersion): { kids: Segment[
], ],
NPs: [ NPs: [
[ [
...showSubject ? [makeSegment(main.subject)] : [], ...subject ? [subject] : [],
...(showObject && main.object) ? [makeSegment(main.object)] : [], ...object ? [object] : [],
], ],
// TODO: make this an option to also include O S V order ?? // TODO: make this an option to also include O S V order ??
// also show O S V if both are showing // also show O S V if both are showing
...(main.object && showObject && showSubject) ? [[ ...(subject && object && form.OSV) ? [[object, subject]] : [],
makeSegment(main.object),
makeSegment(main.subject),
]] : [],
], ],
} };
} }
function putKidsInKidsSection(segments: Segment[], kids: Segment[]): Segment[] { function putKidsInKidsSection(segments: Segment[], kids: Segment[]): Segment[] {

View File

@ -52,15 +52,15 @@ export function renderVP(VP: VPSelection): VPRendered {
verb: renderVerbSelection(VP.verb, kingPerson, objectPerson), verb: renderVerbSelection(VP.verb, kingPerson, objectPerson),
englishBase: renderEnglishVPBase({ englishBase: renderEnglishVPBase({
subjectPerson, subjectPerson,
object: VP.object, object: VP.verb.isCompound === "dynamic" ? "none" : VP.object,
vs: VP.verb, vs: VP.verb,
}), }),
}; };
} }
function renderNPSelection(NP: NPSelection, inflected: boolean, inflectEnglish: boolean, role: "subject"): Rendered<NPSelection> export function renderNPSelection(NP: NPSelection, inflected: boolean, inflectEnglish: boolean, role: "subject"): Rendered<NPSelection>
function renderNPSelection(NP: NPSelection | ObjectNP, inflected: boolean, inflectEnglish: boolean, role: "object"): Rendered<NPSelection> | T.Person.ThirdPlurMale | "none"; export function renderNPSelection(NP: NPSelection | ObjectNP, inflected: boolean, inflectEnglish: boolean, role: "object"): Rendered<NPSelection> | T.Person.ThirdPlurMale | "none";
function renderNPSelection(NP: NPSelection | ObjectNP, inflected: boolean, inflectEnglish: boolean, role: "subject" | "object"): Rendered<NPSelection> | T.Person.ThirdPlurMale | "none" { export function renderNPSelection(NP: NPSelection | ObjectNP, inflected: boolean, inflectEnglish: boolean, role: "subject" | "object"): Rendered<NPSelection> | T.Person.ThirdPlurMale | "none" {
if (typeof NP !== "object") { if (typeof NP !== "object") {
if (role !== "object") { if (role !== "object") {
throw new Error("ObjectNP only allowed for objects"); throw new Error("ObjectNP only allowed for objects");
@ -125,7 +125,8 @@ function renderParticipleSelection(p: ParticipleSelection, inflected: boolean):
} }
function renderVerbSelection(vs: VerbSelection, person: T.Person, objectPerson: T.Person | undefined): VerbRendered { function renderVerbSelection(vs: VerbSelection, person: T.Person, objectPerson: T.Person | undefined): VerbRendered {
const conjugations = conjugateVerb(vs.verb.entry, vs.verb.complement); const v = vs.dynAuxVerb || vs.verb;
const conjugations = conjugateVerb(v.entry, v.complement);
// TODO: error handle this? // TODO: error handle this?
const conj = "grammaticallyTransitive" in conjugations const conj = "grammaticallyTransitive" in conjugations
// if there's an option for grammatically transitive or transitive // if there's an option for grammatically transitive or transitive

View File

@ -31,11 +31,12 @@ type VerbTense = "present" | "subjunctive" | "perfectiveFuture" | "imperfectiveF
type VerbSelection = { type VerbSelection = {
type: "verb", type: "verb",
verb: VerbEntry, verb: VerbEntry,
dynAuxVerb?: VerbEntry,
tense: VerbTense, tense: VerbTense,
object: VerbObject, // TODO: should have a locked in (but number changeable noun) here for dynamic compounds object: VerbObject, // TODO: should have a locked in (but number changeable noun) here for dynamic compounds
transitivity: "transitive" | "intransitive" | "grammaticallyTransitive", transitivity: import("@lingdocs/pashto-inflector").Types.Transitivity,
isCompound: "stative" | "dynamic" | false, isCompound: "stative" | "dynamic" | false,
changeTransitivity?: (t: "transitive" | "grammaticallyTransitive") => VerbSelection, changeTransitivity?: (t: "transitive" | "grammatically transitive") => VerbSelection,
// TODO: changeStativeDynamic // TODO: changeStativeDynamic
// TODO: add in aspect element here?? // TODO: add in aspect element here??
negative: boolean, negative: boolean,
@ -73,6 +74,7 @@ type NounSelection = {
entry: NounEntry, entry: NounEntry,
gender: import("@lingdocs/pashto-inflector").Types.Gender, gender: import("@lingdocs/pashto-inflector").Types.Gender,
number: NounNumber, number: NounNumber,
dynamicComplement?: boolean,
// TODO: Implement // TODO: Implement
// adjectives: [], // adjectives: [],
// TODO: Implement // TODO: Implement

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,4 @@
module.exports = [
{ ts: 1527812732, e: "to work" }, // کار کول
{ ts: 1527812939, e: "to run" }, // منډې وهل
];