getting going with stative compounds - spacing
ee is still a bit rough
This commit is contained in:
parent
299aa0ca68
commit
6b8842c9b1
|
@ -5,7 +5,7 @@
|
|||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@lingdocs/lingdocs-main": "^0.2.0",
|
||||
"@lingdocs/pashto-inflector": "^1.5.5",
|
||||
"@lingdocs/pashto-inflector": "^1.5.7",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
|
|
|
@ -34,7 +34,8 @@ function makeVerbSelection(verb: VerbEntry, oldVerbSelection?: VerbSelection): V
|
|||
return oldVerbSelection.object;
|
||||
}
|
||||
// TODO: more complex types and unchangeable dynamic compound objects
|
||||
const transitivity: "intransitive" | "transitive" | "grammaticallyTransitive" = verb.entry.c?.includes("v. intrans.")
|
||||
// TODO: use proper type predicates
|
||||
const transitivity: "intransitive" | "transitive" | "grammaticallyTransitive" = verb.entry.c?.includes("intrans.")
|
||||
? "intransitive"
|
||||
: verb.entry.c?.includes("v. gramm. trans.")
|
||||
? "grammaticallyTransitive"
|
||||
|
@ -44,12 +45,19 @@ function makeVerbSelection(verb: VerbEntry, oldVerbSelection?: VerbSelection): V
|
|||
: transitivity === "transitive"
|
||||
? getTransObjFromOldVerbSelection()
|
||||
: "none";
|
||||
// TODO: better here based on selection of which type
|
||||
const isCompound = verb.entry.c?.includes("stat. comp.")
|
||||
? "stative"
|
||||
: verb.entry.c?.includes("dyn. comp.")
|
||||
? "dynamic"
|
||||
: false;
|
||||
return {
|
||||
type: "verb",
|
||||
verb,
|
||||
tense: oldVerbSelection ? oldVerbSelection.tense : "present",
|
||||
object,
|
||||
transitivity,
|
||||
isCompound,
|
||||
negative: oldVerbSelection ? oldVerbSelection.negative : false,
|
||||
...verb.entry.c?.includes("v. trans./gramm. trans") ? {
|
||||
changeTransitivity: function (t) {
|
||||
|
|
|
@ -13,59 +13,14 @@ const kingEmoji = "👑";
|
|||
const servantEmoji = "🙇♂️";
|
||||
const verbs = verbsRaw;
|
||||
|
||||
function verbPhraseComplete({ subject, verb }: { subject: NPSelection | undefined, verb: VerbSelection | undefined }): VPSelection | undefined {
|
||||
if (!subject) return undefined;
|
||||
if (!verb) return undefined;
|
||||
if (verb.object === undefined) return undefined;
|
||||
return {
|
||||
type: "VPSelection",
|
||||
subject,
|
||||
object: verb.object,
|
||||
verb,
|
||||
};
|
||||
}
|
||||
|
||||
function showRole(VP: VPRendered | undefined, member: "subject" | "object") {
|
||||
return VP
|
||||
? <span className="ml-2">
|
||||
{(VP.king === member ? kingEmoji : VP.servant === member ? servantEmoji : "")}
|
||||
</span>
|
||||
: "";
|
||||
}
|
||||
|
||||
type soClump = { subject: NPSelection | undefined, verb: VerbSelection | undefined };
|
||||
function switchSubjObj({ subject, verb }: soClump): soClump {
|
||||
if (!subject|| !verb || !verb.object || !(typeof verb.object === "object")) {
|
||||
return { subject, verb };
|
||||
}
|
||||
return {
|
||||
subject: verb.object,
|
||||
verb: {
|
||||
...verb,
|
||||
object: subject,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: BIG ISSUE, IF YOU OPEN THE OBJECT PRONOUN BOX AND IT CONFLICTS WITH THE SUBJECT
|
||||
// IT CAN SAY THE COMBO IS NOT ALLOWED AND SHOW SOMETHING BLANK
|
||||
// TODO: error handling on error with rendering etc
|
||||
export function PhraseBuilder() {
|
||||
const [subject, setSubject] = useState<NPSelection | undefined>(undefined);
|
||||
const [verb, setVerb] = useState<VerbSelection | undefined>(undefined);
|
||||
function handleSubjectChange(subject: NPSelection | undefined) {
|
||||
// check for pronoun conflict
|
||||
const objPronoun = (typeof verb?.object === "object" && verb.object.type === "pronoun")
|
||||
? verb.object.person
|
||||
: undefined;
|
||||
if (subject?.type === "pronoun" && objPronoun && isInvalidSubjObjCombo(subject.person, objPronoun)) {
|
||||
if (hasPronounConflict(subject, verb?.object)) {
|
||||
alert("That combination of pronouns is not allowed");
|
||||
return;
|
||||
// let newP = 0;
|
||||
// do {
|
||||
// newP = randomPerson();
|
||||
// } while (isInvalidSubjObjCombo(newP, object.person));
|
||||
// return setSubject({ ...incoming, person: newP });
|
||||
}
|
||||
setSubject(subject);
|
||||
}
|
||||
|
@ -73,19 +28,11 @@ export function PhraseBuilder() {
|
|||
if (!verb) return;
|
||||
if ((verb.object === "none") || (typeof verb.object === "number")) return;
|
||||
// check for pronoun conflict
|
||||
if (object?.type === "pronoun" && subject?.type === "pronoun" && isInvalidSubjObjCombo(object.person, subject.person)) {
|
||||
if (hasPronounConflict(subject, verb.object)) {
|
||||
alert("That combination of pronouns is not allowed");
|
||||
return;
|
||||
// let newP = 0;
|
||||
// do {
|
||||
// newP = randomPerson();
|
||||
// } while (isInvalidSubjObjCombo(newP, object.person));
|
||||
// return setSubject({ ...incoming, person: newP });
|
||||
}
|
||||
setVerb({
|
||||
...verb,
|
||||
object,
|
||||
});
|
||||
setVerb({ ...verb, object });
|
||||
}
|
||||
function handleSubjObjSwap() {
|
||||
const output = switchSubjObj({ subject, verb });
|
||||
|
@ -130,3 +77,44 @@ export function PhraseBuilder() {
|
|||
}
|
||||
|
||||
export default PhraseBuilder;
|
||||
|
||||
function hasPronounConflict(subject: NPSelection | undefined, object: undefined | VerbObject): boolean {
|
||||
const subjPronoun = (subject && subject.type === "pronoun") ? subject : undefined;
|
||||
const objPronoun = (object && typeof object === "object" && object.type === "pronoun") ? object : undefined;
|
||||
if (!subjPronoun || !objPronoun) return false;
|
||||
return isInvalidSubjObjCombo(subjPronoun.person, objPronoun.person);
|
||||
}
|
||||
|
||||
function verbPhraseComplete({ subject, verb }: { subject: NPSelection | undefined, verb: VerbSelection | undefined }): VPSelection | undefined {
|
||||
if (!subject) return undefined;
|
||||
if (!verb) return undefined;
|
||||
if (verb.object === undefined) return undefined;
|
||||
return {
|
||||
type: "VPSelection",
|
||||
subject,
|
||||
object: verb.object,
|
||||
verb,
|
||||
};
|
||||
}
|
||||
|
||||
function showRole(VP: VPRendered | undefined, member: "subject" | "object") {
|
||||
return VP
|
||||
? <span className="ml-2">
|
||||
{(VP.king === member ? kingEmoji : VP.servant === member ? servantEmoji : "")}
|
||||
</span>
|
||||
: "";
|
||||
}
|
||||
|
||||
type SOClump = { subject: NPSelection | undefined, verb: VerbSelection | undefined };
|
||||
function switchSubjObj({ subject, verb }: SOClump): SOClump {
|
||||
if (!subject|| !verb || !verb.object || !(typeof verb.object === "object")) {
|
||||
return { subject, verb };
|
||||
}
|
||||
return {
|
||||
subject: verb.object,
|
||||
verb: {
|
||||
...verb,
|
||||
object: subject,
|
||||
}
|
||||
};
|
||||
}
|
|
@ -8,18 +8,8 @@ import {
|
|||
import AbbreviationFormSelector from "./AbbreviationFormSelector";
|
||||
import { isPastTense } from "../../lib/phrase-building/vp-tools";
|
||||
|
||||
// function buttonClass(active: boolean, side: "l" | "r") {
|
||||
// return classNames(
|
||||
// "btn btn-sm btn-outline-secondary",
|
||||
// { active },
|
||||
// { "mr-1": side === "l" },
|
||||
// { "ml-1": side === "r" },
|
||||
// );
|
||||
// }
|
||||
|
||||
function VPDisplay({ VP }: { VP: VPSelection }) {
|
||||
const [form, setForm] = useState<FormVersion>({ removeKing: false, shrinkServant: false });
|
||||
// TODO: Possibly put the servant shrinking in here after the render
|
||||
const result = compileVP(renderVP(VP), form);
|
||||
return <div className="text-center mt-2">
|
||||
<AbbreviationFormSelector
|
||||
|
@ -27,18 +17,6 @@ function VPDisplay({ VP }: { VP: VPSelection }) {
|
|||
form={form}
|
||||
onChange={setForm}
|
||||
/>
|
||||
{/* <button
|
||||
onClick={toggleForm("removeKing")}
|
||||
className={buttonClass(form.removeKing, "l")}
|
||||
>
|
||||
🚫 King
|
||||
</button>
|
||||
{servantShrinkable && <button
|
||||
onClick={toggleForm("shrinkServant")}
|
||||
className={buttonClass(form.shrinkServant, "r")}
|
||||
>
|
||||
👶 Servant
|
||||
</button>} */}
|
||||
{"long" in result.ps ?
|
||||
<div>
|
||||
{/* <div className="h6">Long Verb:</div> */}
|
||||
|
|
|
@ -19,6 +19,7 @@ export function compileVP(VP: VPRendered, form: FormVersion, combineLengths?: tr
|
|||
kids,
|
||||
verb,
|
||||
negative: VP.verb.negative,
|
||||
isCompound: VP.isCompound,
|
||||
});
|
||||
return {
|
||||
ps: combineLengths ? flattenLengths(psResult) : psResult,
|
||||
|
@ -33,19 +34,20 @@ type CompilePsInput = {
|
|||
head: T.PsString | undefined,
|
||||
rest: T.SingleOrLengthOpts<T.PsString[]>,
|
||||
},
|
||||
isCompound: "stative" | "dynamic" | false,
|
||||
negative: boolean,
|
||||
}
|
||||
function compilePs({ NPs, kids, verb: { head, rest }, negative }: CompilePsInput): T.SingleOrLengthOpts<T.PsString[]> {
|
||||
function compilePs({ NPs, kids, verb: { head, rest }, isCompound, negative }: CompilePsInput): T.SingleOrLengthOpts<T.PsString[]> {
|
||||
if ("long" in rest) {
|
||||
return {
|
||||
long: compilePs({ NPs, verb: { head, rest: rest.long }, negative, kids }) as T.PsString[],
|
||||
short: compilePs({ NPs, verb: { head, rest: rest.short }, negative, kids }) as T.PsString[],
|
||||
long: compilePs({ NPs, verb: { head, rest: rest.long }, negative, isCompound, kids }) as T.PsString[],
|
||||
short: compilePs({ NPs, verb: { head, rest: rest.short }, negative, isCompound, kids }) as T.PsString[],
|
||||
...rest.mini ? {
|
||||
mini: compilePs({ NPs, verb: { head, rest: rest.mini }, negative, kids }) as T.PsString[],
|
||||
mini: compilePs({ NPs, verb: { head, rest: rest.mini }, negative, isCompound, kids }) as T.PsString[],
|
||||
} : {},
|
||||
};
|
||||
}
|
||||
const verbWNegativeVersions = arrangeVerbWNegative(head, rest, negative);
|
||||
const verbWNegativeVersions = arrangeVerbWNegative(head, rest, negative, isCompound);
|
||||
|
||||
// put together all the different possible permutations based on:
|
||||
// a. potential different versions of where the nu goes
|
||||
|
@ -116,7 +118,7 @@ function putKidsInKidsSection(segments: Segment[], kids: Segment[]): Segment[] {
|
|||
];
|
||||
}
|
||||
|
||||
function arrangeVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[], negative: boolean): Segment[][] {
|
||||
function arrangeVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[], negative: boolean, isCompound: "stative" | "dynamic" | false): Segment[][] {
|
||||
const rest = makeSegment(restRaw.map(removeBa), ["isVerbRest"]);
|
||||
const headSegment: Segment | undefined = !head
|
||||
? head
|
||||
|
@ -148,7 +150,7 @@ function arrangeVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[
|
|||
],
|
||||
// verbs that have a perfective prefix that is not و or وا can put the
|
||||
// nu *before* the prefix as well // TODO: also وي prefixes?
|
||||
...!headSegment.isOoOrWaaHead ? [[
|
||||
...(!headSegment.isOoOrWaaHead && !isCompound) ? [[
|
||||
makeSegment(nu, ["isNu"]),
|
||||
headSegment.adjust({ ps: removeAccents }),
|
||||
rest.adjust({ ps: removeAccents }),
|
||||
|
@ -168,10 +170,19 @@ function addSpacesBetweenSegments(segments: Segment[]): (Segment | " " | "" | T.
|
|||
const next = segments[i+1];
|
||||
o.push(current);
|
||||
if (!next) break;
|
||||
if ((next.isKidBetweenHeadAndRest || next.isNu) || (next.isVerbRest && current.isKidBetweenHeadAndRest)) {
|
||||
if (
|
||||
// stative compound part
|
||||
!current.ps[0].p.endsWith(" ")
|
||||
&&
|
||||
(
|
||||
(next.isKidBetweenHeadAndRest || next.isNu)
|
||||
||
|
||||
(next.isVerbRest && current.isKidBetweenHeadAndRest)
|
||||
)
|
||||
) {
|
||||
o.push({
|
||||
f: "-",
|
||||
p: ((current.isVerbHead && next.isMiniPronoun)
|
||||
p: ((current.isVerbHead && (next.isMiniPronoun || next.isNu))
|
||||
|| (current.isOoOrWaaHead && (next.isBa || next.isNu))) ? "" : " ", // or if its waa head
|
||||
});
|
||||
} else if (current.isVerbHead && next.isVerbRest) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
concatPsString,
|
||||
removeAccents,
|
||||
getPersonNumber,
|
||||
hasBaParticle,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import {
|
||||
psStringFromEntry,
|
||||
|
@ -20,7 +21,6 @@ import {
|
|||
isPastTense,
|
||||
} from "./vp-tools";
|
||||
import { isPattern4Entry } from "../type-predicates";
|
||||
import { hasBaParticle } from "@lingdocs/pashto-inflector/dist/lib/p-text-helpers";
|
||||
|
||||
// TODO: ISSUE GETTING SPLIT HEAD NOT MATCHING WITH FUTURE VERBS
|
||||
|
||||
|
@ -46,6 +46,7 @@ export function renderVP(VP: VPSelection): VPRendered {
|
|||
servant,
|
||||
isPast,
|
||||
isTransitive,
|
||||
isCompound: VP.verb.isCompound,
|
||||
subject: renderNPSelection(VP.subject, inflectSubject, false, "subject"),
|
||||
object: renderNPSelection(VP.object, inflectObject, true, "object"),
|
||||
verb: renderVerbSelection(VP.verb, kingPerson, objectPerson),
|
||||
|
|
|
@ -19,6 +19,7 @@ type VPRendered = {
|
|||
servant: "subject" | "object" | undefined,
|
||||
isPast: boolean,
|
||||
isTransitive: boolean,
|
||||
isCompound: "stative" | "dynamic" | false,
|
||||
subject: Rendered<NPSelection>,
|
||||
object: Rendered<NPSelection> | ObjectNP,
|
||||
verb: VerbRendered,
|
||||
|
@ -33,6 +34,7 @@ type VerbSelection = {
|
|||
tense: VerbTense,
|
||||
object: VerbObject, // TODO: should have a locked in (but number changeable noun) here for dynamic compounds
|
||||
transitivity: "transitive" | "intransitive" | "grammaticallyTransitive",
|
||||
isCompound: "stative" | "dynamic" | false,
|
||||
changeTransitivity?: (t: "transitive" | "grammaticallyTransitive") => VerbSelection,
|
||||
// TODO: changeStativeDynamic
|
||||
// TODO: add in aspect element here??
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,4 @@
|
|||
module.exports = [
|
||||
{ ts: 1581906176268, e: "to be cooked" }, // پخېدل
|
||||
{ ts: 1591033069786, e: "to get tired" }, // ستړی کېدل
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = [
|
||||
{ ts: 1527815444, e: "to learn" }, // زده کول
|
||||
{ ts: 1571859113828, e: "to cook" }, // پخول
|
||||
]
|
Loading…
Reference in New Issue