towards new verb explorer form
This commit is contained in:
parent
0467080343
commit
9f9236ba9b
|
@ -5,7 +5,7 @@
|
|||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@lingdocs/lingdocs-main": "^0.2.0",
|
||||
"@lingdocs/pashto-inflector": "^1.6.8",
|
||||
"@lingdocs/pashto-inflector": "^1.6.9",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
|
|
|
@ -1,73 +1,12 @@
|
|||
import Select from "react-select";
|
||||
import {
|
||||
makeNounSelection,
|
||||
zIndexProps,
|
||||
} from "./np-picker/picker-tools";
|
||||
import {
|
||||
Types as T,
|
||||
ButtonSelect,
|
||||
getVerbInfo,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import { isPerfectTense } from "../lib/phrase-building/vp-tools";
|
||||
import {
|
||||
makeVerbSelection,
|
||||
} from "./phrase-builder/verb-selection";
|
||||
import EntrySelect from "./EntrySelect";
|
||||
// import { useState } from "react";
|
||||
|
||||
const tenseOptions: { label: string | JSX.Element, value: VerbTense }[] = [{
|
||||
label: <div><i className="fas fa-video mr-2" />present</div>,
|
||||
value: "presentVerb",
|
||||
}, {
|
||||
label: <div><i className="fas fa-camera mr-2" />subjunctive</div>,
|
||||
value: "subjunctiveVerb",
|
||||
}, {
|
||||
label: <div><i className="fas fa-video mr-2" />imperf. future</div>,
|
||||
value: "imperfectiveFuture",
|
||||
}, {
|
||||
label: <div><i className="fas fa-camera mr-2" />perf. future</div>,
|
||||
value: "perfectiveFuture",
|
||||
}, {
|
||||
label: <div><i className="fas fa-video mr-2" />continuous past</div>,
|
||||
value: "imperfectivePast",
|
||||
}, {
|
||||
label: <div><i className="fas fa-camera mr-2" />simple past</div>,
|
||||
value: "perfectivePast",
|
||||
}, {
|
||||
label: <div><i className="fas fa-video mr-2" />habitual cont. past.</div>,
|
||||
value: "habitualImperfectivePast",
|
||||
}, {
|
||||
label: <div><i className="fas fa-camera mr-2" />habitual simp. past.</div>,
|
||||
value: "habitualPerfectivePast",
|
||||
}];
|
||||
|
||||
const perfectTenseOptions: { label: string | JSX.Element, value: PerfectTense }[] = [{
|
||||
label: "Present Perfect",
|
||||
value: "present perfect",
|
||||
}, {
|
||||
label: "Habitual Perfect",
|
||||
value: "habitual perfect",
|
||||
}, {
|
||||
label: "Subjunctive Perfect",
|
||||
value: "subjunctive perfect",
|
||||
}, {
|
||||
label: "Future Perfect",
|
||||
value: "future perfect",
|
||||
}, {
|
||||
label: "Past Perfect",
|
||||
value: "past perfect",
|
||||
}, {
|
||||
label: `"Would Be" Perfect`,
|
||||
value: "wouldBe perfect",
|
||||
}, {
|
||||
label: "Past Subjunctive Perfect",
|
||||
value: "pastSubjunctive perfect",
|
||||
}];
|
||||
|
||||
// type Filters = {
|
||||
// stative: boolean,
|
||||
// dynamic: boolean,
|
||||
// transitive: boolean,
|
||||
// intransitive: boolean,
|
||||
// grammaticallyTransitive: boolean,
|
||||
// }
|
||||
// TODO: dark on past tense selecitons
|
||||
|
||||
function VerbPicker({ onChange, subject, changeSubject, verb, verbs }: {
|
||||
verbs: VerbEntry[],
|
||||
|
@ -90,65 +29,6 @@ function VerbPicker({ onChange, subject, changeSubject, verb, verbs }: {
|
|||
}
|
||||
onChange(makeVerbSelection(v, changeSubject, verb));
|
||||
}
|
||||
function onTenseSelect(o: { value: VerbTense | PerfectTense } | null) {
|
||||
const value = o?.value ? o.value : undefined;
|
||||
if (verb && value) {
|
||||
if (isPerfectTense(value)) {
|
||||
onChange({
|
||||
...verb,
|
||||
tense: value,
|
||||
tenseCategory: "perfect",
|
||||
});
|
||||
} else {
|
||||
onChange({
|
||||
...verb,
|
||||
tense: value,
|
||||
tenseCategory: verb.tenseCategory === "perfect" ? "basic" : verb.tenseCategory,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function moveTense(dir: "forward" | "back") {
|
||||
if (!verb) return;
|
||||
return () => {
|
||||
const tenses = verb.tenseCategory === "perfect" ? perfectTenseOptions : tenseOptions;
|
||||
const currIndex = tenses.findIndex(tn => tn.value === verb.tense)
|
||||
if (currIndex === -1) {
|
||||
console.error("error moving tense", dir);
|
||||
return;
|
||||
}
|
||||
const newIndex = dir === "forward"
|
||||
? ((currIndex + 1) % tenses.length)
|
||||
: (currIndex === 0 ? (tenses.length - 1) : (currIndex - 1))
|
||||
const newTense = tenses[newIndex];
|
||||
onTenseSelect(newTense);
|
||||
};
|
||||
}
|
||||
function onPosNegSelect(value: string) {
|
||||
if (verb) {
|
||||
onChange({
|
||||
...verb,
|
||||
negative: value === "true",
|
||||
});
|
||||
}
|
||||
}
|
||||
function onTenseCategorySelect(value: "basic" | "modal" | "perfect") {
|
||||
if (verb) {
|
||||
if (value === "perfect") {
|
||||
onChange({
|
||||
...verb,
|
||||
tenseCategory: value,
|
||||
tense: isPerfectTense(verb.tense) ? verb.tense : "present perfect",
|
||||
});
|
||||
} else {
|
||||
onChange({
|
||||
...verb,
|
||||
tenseCategory: value,
|
||||
tense: isPerfectTense(verb.tense) ? "presentVerb" : verb.tense,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function onVoiceSelect(value: "active" | "passive") {
|
||||
if (verb && verb.changeVoice) {
|
||||
if (value === "passive" && (typeof verb.object === "object")) {
|
||||
|
@ -173,8 +53,8 @@ function VerbPicker({ onChange, subject, changeSubject, verb, verbs }: {
|
|||
onChange(verb.changeStatDyn(c));
|
||||
}
|
||||
}
|
||||
const tOptions = (verb?.tenseCategory === "perfect") ? perfectTenseOptions : tenseOptions;
|
||||
return <div style={{ maxWidth: "225px", minWidth: "175px" }}>
|
||||
return <div className="mb-3">
|
||||
<div style={{ maxWidth: "300px", margin: "0 auto" }}>
|
||||
<div>Verb:</div>
|
||||
<EntrySelect
|
||||
entries={verbs}
|
||||
|
@ -183,19 +63,9 @@ function VerbPicker({ onChange, subject, changeSubject, verb, verbs }: {
|
|||
name="Verb"
|
||||
isVerbSelect
|
||||
/>
|
||||
{/* <Select
|
||||
value={verb && verb.verb.entry.ts.toString()}
|
||||
// @ts-ignore
|
||||
onChange={onEntrySelect}
|
||||
className="mb-2"
|
||||
// @ts-ignore
|
||||
options={options}
|
||||
isSearchable
|
||||
// // @ts-ignore
|
||||
placeholder={verb ? options.find(o => o.value === (verb.verb.entry).ts.toString())?.label : "Select Verb..."}
|
||||
{...zIndexProps}
|
||||
/> */}
|
||||
{verb && verb.changeTransitivity && <div className="text-center mt-3">
|
||||
</div>
|
||||
<div className="d-flex flex-row justify-content-around flex-wrap" style={{ maxWidth: "400px", margin: "0 auto" }}>
|
||||
{verb && verb.changeTransitivity && <div className="text-center my-2">
|
||||
<ButtonSelect
|
||||
small
|
||||
options={[{
|
||||
|
@ -209,24 +79,7 @@ function VerbPicker({ onChange, subject, changeSubject, verb, verbs }: {
|
|||
handleChange={handleChangeTransitivity}
|
||||
/>
|
||||
</div>}
|
||||
{verb && <div className="col text-center my-3">
|
||||
<ButtonSelect
|
||||
small
|
||||
value={verb.tenseCategory}
|
||||
options={[{
|
||||
label: "Basic",
|
||||
value: "basic",
|
||||
}, {
|
||||
label: "Perfect",
|
||||
value: "perfect",
|
||||
}, {
|
||||
label: "Modal",
|
||||
value: "modal",
|
||||
}]}
|
||||
handleChange={onTenseCategorySelect}
|
||||
/>
|
||||
</div>}
|
||||
{verb && verb.changeVoice && <div className="col text-center my-3">
|
||||
{verb && verb.changeVoice && <div className="text-center my-2">
|
||||
<ButtonSelect
|
||||
small
|
||||
value={verb.voice}
|
||||
|
@ -240,17 +93,7 @@ function VerbPicker({ onChange, subject, changeSubject, verb, verbs }: {
|
|||
handleChange={onVoiceSelect}
|
||||
/>
|
||||
</div>}
|
||||
<div>Tense:</div>
|
||||
<Select
|
||||
isSearchable={false}
|
||||
// for some reason can't use tOptions with find here;
|
||||
value={verb && ([...tenseOptions, ...perfectTenseOptions].find(o => o.value === verb.tense))}
|
||||
onChange={onTenseSelect}
|
||||
className="mb-2"
|
||||
options={tOptions}
|
||||
{...zIndexProps}
|
||||
/>
|
||||
{verb && verb.changeStatDyn && <div className="text-center">
|
||||
{verb && verb.changeStatDyn && <div className="text-center my-2">
|
||||
<ButtonSelect
|
||||
small
|
||||
options={[{
|
||||
|
@ -264,127 +107,9 @@ function VerbPicker({ onChange, subject, changeSubject, verb, verbs }: {
|
|||
handleChange={handleChangeStatDyn}
|
||||
/>
|
||||
</div>}
|
||||
{verb && <div className="d-flex flex-row justify-content-between align-items-center my-3" style={{ width: "100%" }}>
|
||||
<div onClick={moveTense("back")} className="clickable">
|
||||
<i className="fas fa-chevron-left" />
|
||||
</div>
|
||||
<ButtonSelect
|
||||
small
|
||||
value={verb.negative.toString()}
|
||||
options={[{
|
||||
label: "Pos.",
|
||||
value: "false",
|
||||
}, {
|
||||
label: "Neg.",
|
||||
value: "true",
|
||||
}]}
|
||||
handleChange={onPosNegSelect}
|
||||
/>
|
||||
<div onClick={moveTense("forward")} className="clickable">
|
||||
<i className="fas fa-chevron-right" />
|
||||
</div>
|
||||
</div>}
|
||||
</div>;
|
||||
}
|
||||
|
||||
function makeVerbSelection(verb: VerbEntry, changeSubject: (s: NPSelection | undefined) => void, oldVerbSelection?: VerbSelection): VerbSelection {
|
||||
const info = getVerbInfo(verb.entry, verb.complement);
|
||||
function getTransObjFromOldVerbSelection() {
|
||||
if (
|
||||
!oldVerbSelection ||
|
||||
oldVerbSelection.object === "none" ||
|
||||
typeof oldVerbSelection.object === "number" ||
|
||||
oldVerbSelection.isCompound === "dynamic" ||
|
||||
(oldVerbSelection.object?.type === "noun" && oldVerbSelection.object.dynamicComplement)
|
||||
) return undefined;
|
||||
return oldVerbSelection.object;
|
||||
}
|
||||
const transitivity: T.Transitivity = "grammaticallyTransitive" in info
|
||||
? "transitive"
|
||||
: info.transitivity;
|
||||
const object = (transitivity === "grammatically transitive")
|
||||
? T.Person.ThirdPlurMale
|
||||
: (info.type === "dynamic compound" && oldVerbSelection?.voice !== "passive")
|
||||
? makeNounSelection(info.objComplement.entry as NounEntry, true)
|
||||
: (transitivity === "transitive" && oldVerbSelection?.voice !== "passive")
|
||||
? getTransObjFromOldVerbSelection()
|
||||
: "none";
|
||||
if (oldVerbSelection?.voice === "passive" && info.type === "dynamic compound") {
|
||||
changeSubject(makeNounSelection(info.objComplement.entry as NounEntry, true));
|
||||
}
|
||||
const isCompound = ("stative" in info || info.type === "stative compound")
|
||||
? "stative"
|
||||
: info.type === "dynamic compound"
|
||||
? "dynamic"
|
||||
: false;
|
||||
// TODO: here and below in the changeStatDyn function ... allow for entries with complement
|
||||
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;
|
||||
const tenseSelection = ((): { tenseCategory: "perfect", tense: PerfectTense } | {
|
||||
tenseCategory: "basic" | "modal",
|
||||
tense: VerbTense,
|
||||
} => {
|
||||
if (!oldVerbSelection) {
|
||||
return { tense: "presentVerb", tenseCategory: "basic" };
|
||||
}
|
||||
if (oldVerbSelection.tenseCategory === "modal") {
|
||||
return { tenseCategory: "modal", tense: isPerfectTense(oldVerbSelection.tense) ? "presentVerb" : oldVerbSelection.tense };
|
||||
}
|
||||
if (oldVerbSelection.tenseCategory === "basic") {
|
||||
return { tenseCategory: "basic", tense: isPerfectTense(oldVerbSelection.tense) ? "presentVerb" : oldVerbSelection.tense };
|
||||
}
|
||||
return { tenseCategory: "perfect", tense: isPerfectTense(oldVerbSelection.tense) ? oldVerbSelection.tense : "present perfect" };
|
||||
})();
|
||||
return {
|
||||
type: "verb",
|
||||
verb: verb,
|
||||
dynAuxVerb,
|
||||
...tenseSelection,
|
||||
object,
|
||||
transitivity,
|
||||
isCompound,
|
||||
voice: transitivity === "transitive"
|
||||
? (oldVerbSelection?.voice || "active")
|
||||
: "active",
|
||||
negative: oldVerbSelection ? oldVerbSelection.negative : false,
|
||||
...("grammaticallyTransitive" in info) ? {
|
||||
changeTransitivity: function(t) {
|
||||
return {
|
||||
...this,
|
||||
transitivity: t,
|
||||
object: t === "grammatically transitive" ? T.Person.ThirdPlurMale : undefined,
|
||||
};
|
||||
},
|
||||
} : {},
|
||||
...("stative" in info) ? {
|
||||
changeStatDyn: function(c) {
|
||||
return {
|
||||
...this,
|
||||
isCompound: c,
|
||||
object: c === "dynamic"
|
||||
? makeNounSelection(info.dynamic.objComplement.entry as NounEntry, true)
|
||||
: undefined,
|
||||
dynAuxVerb: c === "dynamic"
|
||||
? { entry: info.dynamic.auxVerb } as VerbEntry
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
} : {},
|
||||
...(transitivity === "transitive") ? {
|
||||
changeVoice: function(v, s) {
|
||||
return {
|
||||
...this,
|
||||
voice: v,
|
||||
object: v === "active" ? s : "none",
|
||||
};
|
||||
},
|
||||
} : {},
|
||||
};
|
||||
}
|
||||
|
||||
export default VerbPicker;
|
|
@ -0,0 +1,177 @@
|
|||
import Select from "react-select";
|
||||
import {
|
||||
zIndexProps,
|
||||
} from "./np-picker/picker-tools";
|
||||
import {
|
||||
ButtonSelect,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import { isPerfectTense } from "../lib/phrase-building/vp-tools";
|
||||
|
||||
const tenseOptions: { label: string | JSX.Element, value: VerbTense }[] = [{
|
||||
label: <div><i className="fas fa-video mr-2" />present</div>,
|
||||
value: "presentVerb",
|
||||
}, {
|
||||
label: <div><i className="fas fa-camera mr-2" />subjunctive</div>,
|
||||
value: "subjunctiveVerb",
|
||||
}, {
|
||||
label: <div><i className="fas fa-video mr-2" />imperf. future</div>,
|
||||
value: "imperfectiveFuture",
|
||||
}, {
|
||||
label: <div><i className="fas fa-camera mr-2" />perf. future</div>,
|
||||
value: "perfectiveFuture",
|
||||
}, {
|
||||
label: <div><i className="fas fa-video mr-2" />continuous past</div>,
|
||||
value: "imperfectivePast",
|
||||
}, {
|
||||
label: <div><i className="fas fa-camera mr-2" />simple past</div>,
|
||||
value: "perfectivePast",
|
||||
}, {
|
||||
label: <div><i className="fas fa-video mr-2" />habitual cont. past.</div>,
|
||||
value: "habitualImperfectivePast",
|
||||
}, {
|
||||
label: <div><i className="fas fa-camera mr-2" />habitual simp. past.</div>,
|
||||
value: "habitualPerfectivePast",
|
||||
}];
|
||||
|
||||
const perfectTenseOptions: { label: string | JSX.Element, value: PerfectTense }[] = [{
|
||||
label: "Present Perfect",
|
||||
value: "present perfect",
|
||||
}, {
|
||||
label: "Habitual Perfect",
|
||||
value: "habitual perfect",
|
||||
}, {
|
||||
label: "Subjunctive Perfect",
|
||||
value: "subjunctive perfect",
|
||||
}, {
|
||||
label: "Future Perfect",
|
||||
value: "future perfect",
|
||||
}, {
|
||||
label: "Past Perfect",
|
||||
value: "past perfect",
|
||||
}, {
|
||||
label: `"Would Be" Perfect`,
|
||||
value: "wouldBe perfect",
|
||||
}, {
|
||||
label: "Past Subjunctive Perfect",
|
||||
value: "pastSubjunctive perfect",
|
||||
}];
|
||||
|
||||
function VerbPickerBelow({ onChange, verb }: {
|
||||
verbs: VerbEntry[],
|
||||
verb: VerbSelection | undefined,
|
||||
onChange: (p: VerbSelection | undefined) => void,
|
||||
}) {
|
||||
function onTenseSelect(o: { value: VerbTense | PerfectTense } | null) {
|
||||
const value = o?.value ? o.value : undefined;
|
||||
if (verb && value) {
|
||||
if (isPerfectTense(value)) {
|
||||
onChange({
|
||||
...verb,
|
||||
tense: value,
|
||||
tenseCategory: "perfect",
|
||||
});
|
||||
} else {
|
||||
onChange({
|
||||
...verb,
|
||||
tense: value,
|
||||
tenseCategory: verb.tenseCategory === "perfect" ? "basic" : verb.tenseCategory,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function moveTense(dir: "forward" | "back") {
|
||||
if (!verb) return;
|
||||
return () => {
|
||||
const tenses = verb.tenseCategory === "perfect" ? perfectTenseOptions : tenseOptions;
|
||||
const currIndex = tenses.findIndex(tn => tn.value === verb.tense)
|
||||
if (currIndex === -1) {
|
||||
console.error("error moving tense", dir);
|
||||
return;
|
||||
}
|
||||
const newIndex = dir === "forward"
|
||||
? ((currIndex + 1) % tenses.length)
|
||||
: (currIndex === 0 ? (tenses.length - 1) : (currIndex - 1))
|
||||
const newTense = tenses[newIndex];
|
||||
onTenseSelect(newTense);
|
||||
};
|
||||
}
|
||||
function onPosNegSelect(value: string) {
|
||||
if (verb) {
|
||||
onChange({
|
||||
...verb,
|
||||
negative: value === "true",
|
||||
});
|
||||
}
|
||||
}
|
||||
function onTenseCategorySelect(value: "basic" | "modal" | "perfect") {
|
||||
if (verb) {
|
||||
if (value === "perfect") {
|
||||
onChange({
|
||||
...verb,
|
||||
tenseCategory: value,
|
||||
tense: isPerfectTense(verb.tense) ? verb.tense : "present perfect",
|
||||
});
|
||||
} else {
|
||||
onChange({
|
||||
...verb,
|
||||
tenseCategory: value,
|
||||
tense: isPerfectTense(verb.tense) ? "presentVerb" : verb.tense,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
const tOptions = (verb?.tenseCategory === "perfect") ? perfectTenseOptions : tenseOptions;
|
||||
return <div className="mb-4 mt-3">
|
||||
{verb && <div className="col text-center mb-2">
|
||||
<ButtonSelect
|
||||
small
|
||||
value={verb.tenseCategory}
|
||||
options={[{
|
||||
label: "Basic",
|
||||
value: "basic",
|
||||
}, {
|
||||
label: "Perfect",
|
||||
value: "perfect",
|
||||
}, {
|
||||
label: "Modal",
|
||||
value: "modal",
|
||||
}]}
|
||||
handleChange={onTenseCategorySelect}
|
||||
/>
|
||||
</div>}
|
||||
<div style={{ maxWidth: "300px", margin: "0 auto" }}>
|
||||
<div>Tense:</div>
|
||||
<Select
|
||||
isSearchable={false}
|
||||
// for some reason can't use tOptions with find here;
|
||||
value={verb && ([...tenseOptions, ...perfectTenseOptions].find(o => o.value === verb.tense))}
|
||||
onChange={onTenseSelect}
|
||||
className="mb-2"
|
||||
options={tOptions}
|
||||
{...zIndexProps}
|
||||
/>
|
||||
{verb && <div className="d-flex flex-row justify-content-between align-items-center my-3" style={{ width: "100%" }}>
|
||||
<div onClick={moveTense("back")} className="clickable">
|
||||
<i className="fas fa-chevron-left" />
|
||||
</div>
|
||||
<ButtonSelect
|
||||
small
|
||||
value={verb.negative.toString()}
|
||||
options={[{
|
||||
label: "Pos.",
|
||||
value: "false",
|
||||
}, {
|
||||
label: "Neg.",
|
||||
value: "true",
|
||||
}]}
|
||||
handleChange={onPosNegSelect}
|
||||
/>
|
||||
<div onClick={moveTense("forward")} className="clickable">
|
||||
<i className="fas fa-chevron-right" />
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
export default VerbPickerBelow;
|
|
@ -1,6 +1,7 @@
|
|||
import { useState } from "react";
|
||||
import NPPicker from "../np-picker/NPPicker";
|
||||
import VerbPicker from "../VerbPicker";
|
||||
import VerbPickerBelow from "../VerbPickerBelow";
|
||||
import VPDisplay from "./VPDisplay";
|
||||
import { verbs } from "../../words/words";
|
||||
import { renderVP } from "../../lib/phrase-building";
|
||||
|
@ -47,12 +48,19 @@ export function PhraseBuilder() {
|
|||
<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>
|
||||
<VerbPicker
|
||||
verbs={verbs}
|
||||
verb={verb}
|
||||
subject={subject}
|
||||
changeSubject={(s) => handleSubjectChange(s, true)}
|
||||
onChange={setVerb}
|
||||
/>
|
||||
{(verb && (typeof verb.object === "object") && (verb.isCompound !== "dynamic")) &&
|
||||
<div className="d-flex flex-row justify-content-around flex-wrap mb-2">
|
||||
<div className="d-flex flex-row justify-content-around flex-wrap mt-4">
|
||||
<button onClick={handleSubjObjSwap} className="btn btn-sm btn-light">
|
||||
<i className="fas fa-exchange-alt mr-2" /> subj/obj
|
||||
</button>
|
||||
<div>{` `}</div>
|
||||
{/* <div>{` `}</div> */}
|
||||
</div>}
|
||||
<div className="d-flex flex-row justify-content-around flex-wrap">
|
||||
<div className="my-2">
|
||||
|
@ -74,17 +82,12 @@ export function PhraseBuilder() {
|
|||
onChange={handleObjectChange}
|
||||
/>}
|
||||
</div>}
|
||||
<div className="my-2">
|
||||
<div className="h4">Verb</div>
|
||||
<VerbPicker
|
||||
</div>
|
||||
<VerbPickerBelow
|
||||
verbs={verbs}
|
||||
verb={verb}
|
||||
subject={subject}
|
||||
changeSubject={(s) => handleSubjectChange(s, true)}
|
||||
onChange={setVerb}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{verbPhrase && <div>
|
||||
<VPDisplay VP={verbPhrase} />
|
||||
</div>}
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
import {
|
||||
makeNounSelection,
|
||||
} from "../np-picker/picker-tools";
|
||||
import {
|
||||
getVerbInfo,
|
||||
Types as T,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import { isPerfectTense } from "../../lib/phrase-building/vp-tools";
|
||||
|
||||
export function makeVerbSelection(verb: VerbEntry, changeSubject: (s: NPSelection | undefined) => void, oldVerbSelection?: VerbSelection): VerbSelection {
|
||||
const info = getVerbInfo(verb.entry, verb.complement);
|
||||
function getTransObjFromOldVerbSelection() {
|
||||
if (
|
||||
!oldVerbSelection ||
|
||||
oldVerbSelection.object === "none" ||
|
||||
typeof oldVerbSelection.object === "number" ||
|
||||
oldVerbSelection.isCompound === "dynamic" ||
|
||||
(oldVerbSelection.object?.type === "noun" && oldVerbSelection.object.dynamicComplement)
|
||||
) return undefined;
|
||||
return oldVerbSelection.object;
|
||||
}
|
||||
const transitivity: T.Transitivity = "grammaticallyTransitive" in info
|
||||
? "transitive"
|
||||
: info.transitivity;
|
||||
const object = (transitivity === "grammatically transitive")
|
||||
? T.Person.ThirdPlurMale
|
||||
: (info.type === "dynamic compound" && oldVerbSelection?.voice !== "passive")
|
||||
? makeNounSelection(info.objComplement.entry as NounEntry, true)
|
||||
: (transitivity === "transitive" && oldVerbSelection?.voice !== "passive")
|
||||
? getTransObjFromOldVerbSelection()
|
||||
: "none";
|
||||
if (oldVerbSelection?.voice === "passive" && info.type === "dynamic compound") {
|
||||
changeSubject(makeNounSelection(info.objComplement.entry as NounEntry, true));
|
||||
}
|
||||
const isCompound = ("stative" in info || info.type === "stative compound")
|
||||
? "stative"
|
||||
: info.type === "dynamic compound"
|
||||
? "dynamic"
|
||||
: false;
|
||||
// TODO: here and below in the changeStatDyn function ... allow for entries with complement
|
||||
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;
|
||||
const tenseSelection = ((): { tenseCategory: "perfect", tense: PerfectTense } | {
|
||||
tenseCategory: "basic" | "modal",
|
||||
tense: VerbTense,
|
||||
} => {
|
||||
if (!oldVerbSelection) {
|
||||
return { tense: "presentVerb", tenseCategory: "basic" };
|
||||
}
|
||||
if (oldVerbSelection.tenseCategory === "modal") {
|
||||
return { tenseCategory: "modal", tense: isPerfectTense(oldVerbSelection.tense) ? "presentVerb" : oldVerbSelection.tense };
|
||||
}
|
||||
if (oldVerbSelection.tenseCategory === "basic") {
|
||||
return { tenseCategory: "basic", tense: isPerfectTense(oldVerbSelection.tense) ? "presentVerb" : oldVerbSelection.tense };
|
||||
}
|
||||
return { tenseCategory: "perfect", tense: isPerfectTense(oldVerbSelection.tense) ? oldVerbSelection.tense : "present perfect" };
|
||||
})();
|
||||
return {
|
||||
type: "verb",
|
||||
verb: verb,
|
||||
dynAuxVerb,
|
||||
...tenseSelection,
|
||||
object,
|
||||
transitivity,
|
||||
isCompound,
|
||||
voice: transitivity === "transitive"
|
||||
? (oldVerbSelection?.voice || "active")
|
||||
: "active",
|
||||
negative: oldVerbSelection ? oldVerbSelection.negative : false,
|
||||
...("grammaticallyTransitive" in info) ? {
|
||||
changeTransitivity: function(t) {
|
||||
return {
|
||||
...this,
|
||||
transitivity: t,
|
||||
object: t === "grammatically transitive" ? T.Person.ThirdPlurMale : undefined,
|
||||
};
|
||||
},
|
||||
} : {},
|
||||
...("stative" in info) ? {
|
||||
changeStatDyn: function(c) {
|
||||
return {
|
||||
...this,
|
||||
isCompound: c,
|
||||
object: c === "dynamic"
|
||||
? makeNounSelection(info.dynamic.objComplement.entry as NounEntry, true)
|
||||
: undefined,
|
||||
dynAuxVerb: c === "dynamic"
|
||||
? { entry: info.dynamic.auxVerb } as VerbEntry
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
} : {},
|
||||
...(transitivity === "transitive") ? {
|
||||
changeVoice: function(v, s) {
|
||||
return {
|
||||
...this,
|
||||
voice: v,
|
||||
object: v === "active" ? s : "none",
|
||||
};
|
||||
},
|
||||
} : {},
|
||||
};
|
||||
}
|
|
@ -1684,10 +1684,10 @@
|
|||
pbf "^3.2.1"
|
||||
rambda "^6.7.0"
|
||||
|
||||
"@lingdocs/pashto-inflector@^1.6.8":
|
||||
version "1.6.8"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.6.8.tgz#adc94c84c49cc067e26fb3066fae2a13b9d25d03"
|
||||
integrity sha512-BGzMP0URWm6fEGdUUX653oImSMEkn11S/3vxeQILrQDCUNjGpNPQlORF27OlzCs8+n9lDBMDQHVjfhBlAZFN4w==
|
||||
"@lingdocs/pashto-inflector@^1.6.9":
|
||||
version "1.6.9"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.6.9.tgz#cd66b8afe1c55ce609ba25952984cd5c329355ac"
|
||||
integrity sha512-ipssrtenaDr9k/VFz6WAxZ/spVb62IFgxczSVsd8Zc/fdIqzy9UKV4R4efJhBp2d7h5QadqBkfEk81PUZu48UQ==
|
||||
dependencies:
|
||||
classnames "^2.2.6"
|
||||
pbf "^3.2.1"
|
||||
|
|
Loading…
Reference in New Issue