@@ -207,7 +195,7 @@ export function VPExplorer(props: {
@@ -237,13 +225,6 @@ export function VPExplorer(props: {
export default VPExplorer;
-function hasPronounConflict(subject: T.NPSelection | undefined, object: undefined | T.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 getShareUrl(vps: T.VPSelectionState): string {
const stringJSON = JSON.stringify(vps);
const encoded = LZString.compressToEncodedURIComponent(stringJSON);
diff --git a/src/components/vp-explorer/VerbPicker.tsx b/src/components/vp-explorer/VerbPicker.tsx
index 15cd1f9..cbc92df 100644
--- a/src/components/vp-explorer/VerbPicker.tsx
+++ b/src/components/vp-explorer/VerbPicker.tsx
@@ -5,13 +5,15 @@ import { getVerbInfo } from "../../lib/verb-info";
import Hider from "../Hider";
import useStickyState from "../../lib/useStickyState";
import CompoundDisplay from "./CompoundDisplay";
-import { changeStatDyn, changeTransitivity, changeVoice } from "./verb-selection";
+import {
+ VpsReducerAction
+} from "./vps-reducer";
// TODO: dark on past tense selecitons
function VerbPicker(props: {
vps: T.VPSelectionState,
- onChange: (p: T.VPSelectionState) => void,
+ onChange: (a: VpsReducerAction) => void,
opts: T.TextOptions,
handleLinkClick: ((ts: number) => void) | "none",
}) {
@@ -28,42 +30,25 @@ function VerbPicker(props: {
return
ERROR: Verb version should be select first
;
}
function onVoiceSelect(value: "active" | "passive") {
- if (props.vps.verb && props.vps.verb.canChangeVoice) {
- if (value === "passive" && props.vps.verb.tenseCategory === "imperative") {
- return;
- }
- if (value === "passive" && (typeof props.vps.verb.object === "object")) {
- props.onChange({
- ...props.vps,
- subject: props.vps.verb.object,
- verb: changeVoice(props.vps.verb, value, props.vps.verb.object),
- });
- } else {
- props.onChange({
- ...props.vps,
- verb: changeVoice(props.vps.verb, value, value === "active" ? props.vps.subject : undefined),
- });
- }
- }
+ props.onChange({
+ type: "set voice",
+ payload: value,
+ });
}
function notInstransitive(t: "transitive" | "intransitive" | "grammatically transitive"): "transitive" | "grammatically transitive" {
return t === "intransitive" ? "transitive" : t;
}
- function handleChangeTransitivity(t: "transitive" | "grammatically transitive") {
- if (props.vps.verb && props.vps.verb.canChangeTransitivity) {
- props.onChange({
- ...props.vps,
- verb: changeTransitivity(props.vps.verb, t),
- });
- }
+ function handleChangeTransitivity(payload: "transitive" | "grammatically transitive") {
+ props.onChange({
+ type: "set transitivity",
+ payload,
+ });
}
- function handleChangeStatDyn(c: "stative" | "dynamic") {
- if (props.vps.verb && props.vps.verb.canChangeStatDyn) {
- props.onChange({
- ...props.vps,
- verb: changeStatDyn(props.vps.verb, c),
- });
- }
+ function handleChangeStatDyn(payload: "stative" | "dynamic") {
+ props.onChange({
+ type: "set statDyn",
+ payload,
+ });
}
return
{info && , e?: string[] };
-export function compileEP(EP: T.EPRendered, form: T.FormVersion, combineLengths: true): { ps: T.PsString[], e?: string[] };
-export function compileEP(EP: T.EPRendered, form: T.FormVersion, combineLengths?: true): { ps: T.SingleOrLengthOpts, e?: string[] } {
- const { kids, NPs } = getSegmentsAndKids(EP, form);
+export function compileEP(EP: T.EPRendered): { ps: T.SingleOrLengthOpts, e?: string[] };
+export function compileEP(EP: T.EPRendered, combineLengths: true): { ps: T.PsString[], e?: string[] };
+export function compileEP(EP: T.EPRendered, combineLengths?: true): { ps: T.SingleOrLengthOpts, e?: string[] } {
+ const { kids, NPs } = getSegmentsAndKids(EP);
const equative = EP.equative.ps;
const psResult = compilePs({
NPs,
@@ -35,15 +35,9 @@ export function compileEP(EP: T.EPRendered, form: T.FormVersion, combineLengths?
};
}
-function getSegmentsAndKids(EP: T.EPRendered, form: Omit): { kids: Segment[], NPs: Segment[] } {
- function ifNotRemoved(s: Segment, role: "subject" | "predicate"): Segment[] {
- if (form.removeKing && EP.king === role) {
- return [];
- }
- return [s];
- }
- const possToShrink = findPossesiveToShrink(EP);
- const shrunkenPossAllowed = !(form.removeKing && possToShrink?.role === "king");
+function getSegmentsAndKids(EP: T.EPRendered): { kids: Segment[], NPs: Segment[] } {
+ const possToShrink = findPossesiveToShrinkInEP(EP);
+ const shrunkenPossAllowed = !((possToShrink?.from === "subject") && EP.omitSubject);
const possUid = shrunkenPossAllowed ? EP.shrunkenPossesive : undefined;
const subject = makeSegment(getPashtoFromRendered(EP.subject, possUid, false));
const predicate = makeSegment(getPashtoFromRendered(EP.predicate, possUid, false));
@@ -53,12 +47,12 @@ function getSegmentsAndKids(EP: T.EPRendered, form: Omit | undefined {
- const uid = VP.shrunkenPossesive;
- function findPossesiveInNP(NP: T.Rendered | T.ObjectNP | undefined): T.Rendered | undefined {
- if (NP === undefined) return undefined;
- if (typeof NP !== "object") return undefined;
- if (!NP.possesor) return undefined;
- if (NP.possesor.uid === uid) {
- return NP.possesor.np;
- }
- return findPossesiveInNP(NP.possesor.np);
+function findPossesiveInNP(NP: T.Rendered | T.ObjectNP | undefined, uid: number): T.Rendered | undefined {
+ if (NP === undefined) return undefined;
+ if (typeof NP !== "object") return undefined;
+ if (!NP.possesor) return undefined;
+ if (NP.possesor.uid === uid) {
+ return NP.possesor.np;
}
+ return findPossesiveInNP(NP.possesor.np, uid);
+}
+
+export function findPossesiveToShrinkInEP(EP: T.EPRendered): {
+ np: T.Rendered,
+ from: "subject" | "predicate",
+} | undefined {
+ const uid = EP.shrunkenPossesive;
if (uid === undefined) return undefined;
- const objPred: T.Rendered | undefined = ("object" in VP)
- ? (typeof VP.object === "object" ? VP.object : undefined)
- : (VP.predicate.type === "noun" || VP.predicate.type === "participle" || VP.predicate.type === "pronoun")
- // typescript is dumb here;
- ? VP.predicate as T.Rendered
+ const inSubject = findPossesiveInNP(EP.subject, uid);
+ if (inSubject) {
+ return {
+ np: inSubject,
+ from: "subject",
+ };
+ }
+ if (EP.predicate.type === "adjective" || EP.predicate.type === "loc. adv.") {
+ return undefined;
+
+ }
+ // ts being stupid
+ const predicate = EP.predicate as T.Rendered;
+ const inPredicate = findPossesiveInNP(predicate, uid);
+ if (inPredicate) {
+ return {
+ np: inPredicate,
+ from: "predicate",
+ };
+ }
+ return undefined;
+}
+
+export function findPossesiveToShrinkInVP(VP: T.VPRendered): T.Rendered | undefined {
+ const uid = VP.shrunkenPossesive;
+ if (uid === undefined) return undefined;
+ const obj: T.Rendered | undefined = ("object" in VP && typeof VP.object === "object")
+ ? VP.object
: undefined;
return (
- findPossesiveInNP(VP.subject)
+ findPossesiveInNP(VP.subject, uid)
||
- findPossesiveInNP(objPred)
+ findPossesiveInNP(obj, uid)
);
}
diff --git a/src/lib/phrase-building/compile-vp.ts b/src/lib/phrase-building/compile-vp.ts
index a03d72a..79985cb 100644
--- a/src/lib/phrase-building/compile-vp.ts
+++ b/src/lib/phrase-building/compile-vp.ts
@@ -22,7 +22,7 @@ import { isImperativeTense, isModalTense, isPerfectTense } from "../type-predica
import { getEnglishFromRendered, getPashtoFromRendered } from "./np-tools";
import {
orderKidsSection,
- findPossesiveToShrink,
+ findPossesiveToShrinkInVP,
shrinkNP,
} from "./compile-tools";
@@ -93,7 +93,7 @@ function getSegmentsAndKids(VP: T.VPRendered, form: Form): { kids: Segment[], NP
return servant;
})();
const shrunkenServant = toShrinkServant ? shrinkNP(toShrinkServant) : undefined;
- const possToShrink = findPossesiveToShrink(VP);
+ const possToShrink = findPossesiveToShrinkInVP(VP);
const shrunkenPossesive = possToShrink ? shrinkNP(possToShrink) : undefined;
const shrunkenPossAllowed = possToShrink && shrunkenPossesive && (
!shrunkenServant || !psStringEquals(shrunkenPossesive.ps[0], shrunkenServant.ps[0])
diff --git a/src/lib/phrase-building/render-ep.ts b/src/lib/phrase-building/render-ep.ts
index 3949c09..ef80394 100644
--- a/src/lib/phrase-building/render-ep.ts
+++ b/src/lib/phrase-building/render-ep.ts
@@ -33,7 +33,7 @@ export function renderEP(EP: T.EPSelectionComplete): T.EPRendered {
equative: renderEquative(EP.equative, kingPerson),
englishBase: equativeBuilders[EP.equative.tense](kingPerson, EP.equative.negative),
shrunkenPossesive: EP.shrunkenPossesive,
- form: EP.form,
+ omitSubject: EP.omitSubject,
};
}
diff --git a/src/lib/useStickyState.ts b/src/lib/useStickyState.ts
index 3c0e2da..a31e8aa 100644
--- a/src/lib/useStickyState.ts
+++ b/src/lib/useStickyState.ts
@@ -1,5 +1,7 @@
import { useEffect, useState } from "react";
+type SaveableData = string | number | object | boolean | undefined | null
+
/**
* replacement from the React useState hook that will persist the state in local storage
*
@@ -8,7 +10,7 @@ import { useEffect, useState } from "react";
* @param key a key for saving the state in locolStorage
* @returns
*/
-export default function useStickyState(defaultValue: T | ((old: T | undefined) => T), key: string): [
+export default function useStickyState(defaultValue: T | ((old: T | undefined) => T), key: string): [
value: T,
setValue: React.Dispatch>,
] {
@@ -42,3 +44,17 @@ export default function useStickyState(
+ reducer: (state: T, dispatch: A) => T,
+ defaultValue: T | ((old: T | undefined) => T),
+ key: string,
+): [T, (action: A) => void] {
+ const [state, unsafeSetState] = useStickyState(defaultValue, key);
+ function adjustState(action: A) {
+ unsafeSetState(oldState => {
+ return reducer(oldState, action);
+ });
+ }
+ return [state, adjustState];
+}
diff --git a/src/types.ts b/src/types.ts
index b0f5518..e7c81b1 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -667,7 +667,7 @@ export type EPSelectionState = {
},
equative: EquativeSelection,
shrunkenPossesive: undefined | number,
- form: FormVersion,
+ omitSubject: boolean,
};
export type EPSelectionComplete = Omit & {
@@ -679,7 +679,7 @@ export type EPSelectionComplete = Omit,
- predicate: Rendered,
+ predicate: Rendered | Rendered,
equative: EquativeRendered,
englishBase?: string[],
shrunkenPossesive: undefined | number,
- form: FormVersion,
+ omitSubject: boolean,
}
export type EntryFeeder = {