now working with dynamic compounds and OSV
This commit is contained in:
parent
4f79456115
commit
693aecdd70
|
@ -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",
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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[] {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = [
|
||||||
|
{ ts: 1527812732, e: "to work" }, // کار کول
|
||||||
|
{ ts: 1527812939, e: "to run" }, // منډې وهل
|
||||||
|
];
|
Loading…
Reference in New Issue