getting going with stative compounds - spacing

ee
is still a bit rough
This commit is contained in:
lingdocs 2022-03-27 16:39:40 +05:00
parent 299aa0ca68
commit 6b8842c9b1
10 changed files with 88 additions and 92 deletions

View File

@ -5,7 +5,7 @@
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^5.15.4", "@fortawesome/fontawesome-free": "^5.15.4",
"@lingdocs/lingdocs-main": "^0.2.0", "@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/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0", "@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10", "@testing-library/user-event": "^12.1.10",

View File

@ -34,7 +34,8 @@ function makeVerbSelection(verb: VerbEntry, oldVerbSelection?: VerbSelection): V
return oldVerbSelection.object; return oldVerbSelection.object;
} }
// TODO: more complex types and unchangeable dynamic compound objects // 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" ? "intransitive"
: verb.entry.c?.includes("v. gramm. trans.") : verb.entry.c?.includes("v. gramm. trans.")
? "grammaticallyTransitive" ? "grammaticallyTransitive"
@ -44,12 +45,19 @@ function makeVerbSelection(verb: VerbEntry, oldVerbSelection?: VerbSelection): V
: transitivity === "transitive" : transitivity === "transitive"
? getTransObjFromOldVerbSelection() ? getTransObjFromOldVerbSelection()
: "none"; : "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 { return {
type: "verb", type: "verb",
verb, verb,
tense: oldVerbSelection ? oldVerbSelection.tense : "present", tense: oldVerbSelection ? oldVerbSelection.tense : "present",
object, object,
transitivity, transitivity,
isCompound,
negative: oldVerbSelection ? oldVerbSelection.negative : false, negative: oldVerbSelection ? oldVerbSelection.negative : false,
...verb.entry.c?.includes("v. trans./gramm. trans") ? { ...verb.entry.c?.includes("v. trans./gramm. trans") ? {
changeTransitivity: function (t) { changeTransitivity: function (t) {

View File

@ -13,59 +13,14 @@ const kingEmoji = "👑";
const servantEmoji = "🙇‍♂️"; const servantEmoji = "🙇‍♂️";
const verbs = verbsRaw; 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 // TODO: error handling on error with rendering etc
export function PhraseBuilder() { export function PhraseBuilder() {
const [subject, setSubject] = useState<NPSelection | undefined>(undefined); const [subject, setSubject] = useState<NPSelection | undefined>(undefined);
const [verb, setVerb] = useState<VerbSelection | undefined>(undefined); const [verb, setVerb] = useState<VerbSelection | undefined>(undefined);
function handleSubjectChange(subject: NPSelection | undefined) { function handleSubjectChange(subject: NPSelection | undefined) {
// check for pronoun conflict if (hasPronounConflict(subject, verb?.object)) {
const objPronoun = (typeof verb?.object === "object" && verb.object.type === "pronoun")
? verb.object.person
: undefined;
if (subject?.type === "pronoun" && objPronoun && isInvalidSubjObjCombo(subject.person, objPronoun)) {
alert("That combination of pronouns is not allowed"); alert("That combination of pronouns is not allowed");
return; return;
// let newP = 0;
// do {
// newP = randomPerson();
// } while (isInvalidSubjObjCombo(newP, object.person));
// return setSubject({ ...incoming, person: newP });
} }
setSubject(subject); setSubject(subject);
} }
@ -73,19 +28,11 @@ export function PhraseBuilder() {
if (!verb) return; if (!verb) return;
if ((verb.object === "none") || (typeof verb.object === "number")) return; if ((verb.object === "none") || (typeof verb.object === "number")) return;
// check for pronoun conflict // 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"); alert("That combination of pronouns is not allowed");
return; return;
// let newP = 0;
// do {
// newP = randomPerson();
// } while (isInvalidSubjObjCombo(newP, object.person));
// return setSubject({ ...incoming, person: newP });
} }
setVerb({ setVerb({ ...verb, object });
...verb,
object,
});
} }
function handleSubjObjSwap() { function handleSubjObjSwap() {
const output = switchSubjObj({ subject, verb }); const output = switchSubjObj({ subject, verb });
@ -130,3 +77,44 @@ export function PhraseBuilder() {
} }
export default 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,
}
};
}

View File

@ -8,18 +8,8 @@ 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";
// 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 }) { function VPDisplay({ VP }: { VP: VPSelection }) {
const [form, setForm] = useState<FormVersion>({ removeKing: false, shrinkServant: false }); 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); const result = compileVP(renderVP(VP), form);
return <div className="text-center mt-2"> return <div className="text-center mt-2">
<AbbreviationFormSelector <AbbreviationFormSelector
@ -27,18 +17,6 @@ function VPDisplay({ VP }: { VP: VPSelection }) {
form={form} form={form}
onChange={setForm} 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 ? {"long" in result.ps ?
<div> <div>
{/* <div className="h6">Long Verb:</div> */} {/* <div className="h6">Long Verb:</div> */}

View File

@ -19,6 +19,7 @@ export function compileVP(VP: VPRendered, form: FormVersion, combineLengths?: tr
kids, kids,
verb, verb,
negative: VP.verb.negative, negative: VP.verb.negative,
isCompound: VP.isCompound,
}); });
return { return {
ps: combineLengths ? flattenLengths(psResult) : psResult, ps: combineLengths ? flattenLengths(psResult) : psResult,
@ -33,19 +34,20 @@ type CompilePsInput = {
head: T.PsString | undefined, head: T.PsString | undefined,
rest: T.SingleOrLengthOpts<T.PsString[]>, rest: T.SingleOrLengthOpts<T.PsString[]>,
}, },
isCompound: "stative" | "dynamic" | false,
negative: boolean, 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) { if ("long" in rest) {
return { return {
long: compilePs({ NPs, verb: { head, rest: rest.long }, 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, kids }) as T.PsString[], short: compilePs({ NPs, verb: { head, rest: rest.short }, negative, isCompound, kids }) as T.PsString[],
...rest.mini ? { ...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: // put together all the different possible permutations based on:
// a. potential different versions of where the nu goes // 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 rest = makeSegment(restRaw.map(removeBa), ["isVerbRest"]);
const headSegment: Segment | undefined = !head const headSegment: Segment | undefined = !head
? 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 // verbs that have a perfective prefix that is not و or وا can put the
// nu *before* the prefix as well // TODO: also وي prefixes? // nu *before* the prefix as well // TODO: also وي prefixes?
...!headSegment.isOoOrWaaHead ? [[ ...(!headSegment.isOoOrWaaHead && !isCompound) ? [[
makeSegment(nu, ["isNu"]), makeSegment(nu, ["isNu"]),
headSegment.adjust({ ps: removeAccents }), headSegment.adjust({ ps: removeAccents }),
rest.adjust({ ps: removeAccents }), rest.adjust({ ps: removeAccents }),
@ -168,10 +170,19 @@ function addSpacesBetweenSegments(segments: Segment[]): (Segment | " " | "" | T.
const next = segments[i+1]; const next = segments[i+1];
o.push(current); o.push(current);
if (!next) break; 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({ o.push({
f: "-", f: "-",
p: ((current.isVerbHead && next.isMiniPronoun) p: ((current.isVerbHead && (next.isMiniPronoun || next.isNu))
|| (current.isOoOrWaaHead && (next.isBa || next.isNu))) ? "" : " ", // or if its waa head || (current.isOoOrWaaHead && (next.isBa || next.isNu))) ? "" : " ", // or if its waa head
}); });
} else if (current.isVerbHead && next.isVerbRest) { } else if (current.isVerbHead && next.isVerbRest) {

View File

@ -9,6 +9,7 @@ import {
concatPsString, concatPsString,
removeAccents, removeAccents,
getPersonNumber, getPersonNumber,
hasBaParticle,
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
import { import {
psStringFromEntry, psStringFromEntry,
@ -20,7 +21,6 @@ import {
isPastTense, isPastTense,
} from "./vp-tools"; } from "./vp-tools";
import { isPattern4Entry } from "../type-predicates"; 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 // TODO: ISSUE GETTING SPLIT HEAD NOT MATCHING WITH FUTURE VERBS
@ -46,6 +46,7 @@ export function renderVP(VP: VPSelection): VPRendered {
servant, servant,
isPast, isPast,
isTransitive, isTransitive,
isCompound: VP.verb.isCompound,
subject: renderNPSelection(VP.subject, inflectSubject, false, "subject"), subject: renderNPSelection(VP.subject, inflectSubject, false, "subject"),
object: renderNPSelection(VP.object, inflectObject, true, "object"), object: renderNPSelection(VP.object, inflectObject, true, "object"),
verb: renderVerbSelection(VP.verb, kingPerson, objectPerson), verb: renderVerbSelection(VP.verb, kingPerson, objectPerson),

View File

@ -19,6 +19,7 @@ type VPRendered = {
servant: "subject" | "object" | undefined, servant: "subject" | "object" | undefined,
isPast: boolean, isPast: boolean,
isTransitive: boolean, isTransitive: boolean,
isCompound: "stative" | "dynamic" | false,
subject: Rendered<NPSelection>, subject: Rendered<NPSelection>,
object: Rendered<NPSelection> | ObjectNP, object: Rendered<NPSelection> | ObjectNP,
verb: VerbRendered, verb: VerbRendered,
@ -33,6 +34,7 @@ type VerbSelection = {
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: "transitive" | "intransitive" | "grammaticallyTransitive",
isCompound: "stative" | "dynamic" | false,
changeTransitivity?: (t: "transitive" | "grammaticallyTransitive") => VerbSelection, changeTransitivity?: (t: "transitive" | "grammaticallyTransitive") => VerbSelection,
// TODO: changeStativeDynamic // TODO: changeStativeDynamic
// TODO: add in aspect element here?? // TODO: add in aspect element here??

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,4 @@
module.exports = [
{ ts: 1581906176268, e: "to be cooked" }, // پخېدل
{ ts: 1591033069786, e: "to get tired" }, // ستړی کېدل
]

View File

@ -0,0 +1,4 @@
module.exports = [
{ ts: 1527815444, e: "to learn" }, // زده کول
{ ts: 1571859113828, e: "to cook" }, // پخول
]