add inflection on NPPronounPicker
This commit is contained in:
parent
2a6a4a9918
commit
5259305822
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@lingdocs/pashto-inflector",
|
"name": "@lingdocs/pashto-inflector",
|
||||||
"version": "2.1.8",
|
"version": "2.1.9",
|
||||||
"author": "lingdocs.com",
|
"author": "lingdocs.com",
|
||||||
"description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations",
|
"description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations",
|
||||||
"homepage": "https://verbs.lingdocs.com",
|
"homepage": "https://verbs.lingdocs.com",
|
||||||
|
|
|
@ -18,7 +18,7 @@ function NPPicker(props: {
|
||||||
onChange: (nps: T.NPSelection | undefined) => void,
|
onChange: (nps: T.NPSelection | undefined) => void,
|
||||||
np: T.NPSelection | undefined,
|
np: T.NPSelection | undefined,
|
||||||
counterPart: T.NPSelection | T.VerbObject | undefined,
|
counterPart: T.NPSelection | T.VerbObject | undefined,
|
||||||
asObject?: boolean,
|
role: "subject" | "object" | "ergative",
|
||||||
opts: T.TextOptions,
|
opts: T.TextOptions,
|
||||||
cantClear?: boolean,
|
cantClear?: boolean,
|
||||||
is2ndPersonPicker?: boolean,
|
is2ndPersonPicker?: boolean,
|
||||||
|
@ -90,7 +90,7 @@ function NPPicker(props: {
|
||||||
</div>}
|
</div>}
|
||||||
{(npType === "pronoun" && props.np?.type === "pronoun")
|
{(npType === "pronoun" && props.np?.type === "pronoun")
|
||||||
? <PronounPicker
|
? <PronounPicker
|
||||||
asObject={props.asObject}
|
role={props.role}
|
||||||
pronoun={props.np}
|
pronoun={props.np}
|
||||||
onChange={props.onChange}
|
onChange={props.onChange}
|
||||||
is2ndPersonPicker={props.is2ndPersonPicker}
|
is2ndPersonPicker={props.is2ndPersonPicker}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import ButtonSelect from "../ButtonSelect";
|
||||||
import useStickyState from "../../lib/useStickyState";
|
import useStickyState from "../../lib/useStickyState";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import {
|
import {
|
||||||
isSecondPerson, isThirdPerson,
|
isSecondPerson,
|
||||||
} from "../../lib/phrase-building/vp-tools";
|
} from "../../lib/phrase-building/vp-tools";
|
||||||
|
|
||||||
const gColors = {
|
const gColors = {
|
||||||
|
@ -11,13 +11,14 @@ const gColors = {
|
||||||
fem: "pink",
|
fem: "pink",
|
||||||
};
|
};
|
||||||
|
|
||||||
const labels = (asObject: boolean) => ({
|
// TODO: better logic on this
|
||||||
persons: [
|
const labels = (role: "subject" | "object" | "ergative") => ({
|
||||||
["1st", "1st pl."],
|
// persons: [
|
||||||
["2nd", "2nd pl."],
|
// ["1st", "1st pl."],
|
||||||
["3rd", "3rd pl."],
|
// ["2nd", "2nd pl."],
|
||||||
],
|
// ["3rd", "3rd pl."],
|
||||||
e: asObject ? [
|
// ],
|
||||||
|
e: role === "object" ? [
|
||||||
["me", "us"],
|
["me", "us"],
|
||||||
["you", "you pl."],
|
["you", "you pl."],
|
||||||
[{ masc: "him/it", fem: "her/it"}, "them"],
|
[{ masc: "him/it", fem: "her/it"}, "them"],
|
||||||
|
@ -26,7 +27,7 @@ const labels = (asObject: boolean) => ({
|
||||||
["You", "You pl."],
|
["You", "You pl."],
|
||||||
[{ masc: "He/It", fem: "She/It"}, "They"],
|
[{ masc: "He/It", fem: "She/It"}, "They"],
|
||||||
],
|
],
|
||||||
p: {
|
p: role === "subject" ? {
|
||||||
far: [
|
far: [
|
||||||
["زه", "مونږ"],
|
["زه", "مونږ"],
|
||||||
["ته", "تاسو"],
|
["ته", "تاسو"],
|
||||||
|
@ -37,6 +38,28 @@ const labels = (asObject: boolean) => ({
|
||||||
["ته", "تاسو"],
|
["ته", "تاسو"],
|
||||||
[{ masc: "دی", fem: "دا" }, "دوي"],
|
[{ masc: "دی", fem: "دا" }, "دوي"],
|
||||||
],
|
],
|
||||||
|
} : role === "object" ? {
|
||||||
|
far: [
|
||||||
|
["زه", "مونږ"],
|
||||||
|
["ته", "تاسو"],
|
||||||
|
[{ masc: "هغهٔ", fem: "هغې" }, "هغوي"],
|
||||||
|
],
|
||||||
|
near: [
|
||||||
|
["زه", "مونږ"],
|
||||||
|
["ته", "تاسو"],
|
||||||
|
[{ masc: "دهٔ", fem: "دې" }, "دوي"],
|
||||||
|
],
|
||||||
|
} : {
|
||||||
|
far: [
|
||||||
|
["ما", "مونږ"],
|
||||||
|
["تا", "تاسو"],
|
||||||
|
[{ masc: "هغهٔ", fem: "هغې" }, "هغوي"],
|
||||||
|
],
|
||||||
|
near: [
|
||||||
|
["ما", "مونږ"],
|
||||||
|
["تا", "تاسو"],
|
||||||
|
[{ masc: "دهٔ", fem: "دې" }, "دوي"],
|
||||||
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -56,10 +79,10 @@ function pickerStateToPerson(s: PickerState): T.Person {
|
||||||
+ (6 * s.col);
|
+ (6 * s.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
function NPPronounPicker({ onChange, pronoun, asObject, clearButton, opts, is2ndPersonPicker }: {
|
function NPPronounPicker({ onChange, pronoun, role, clearButton, opts, is2ndPersonPicker }: {
|
||||||
pronoun: T.PronounSelection,
|
pronoun: T.PronounSelection,
|
||||||
onChange: (p: T.PronounSelection) => void,
|
onChange: (p: T.PronounSelection) => void,
|
||||||
asObject?: boolean,
|
role: "object" | "subject" | "ergative",
|
||||||
clearButton?: JSX.Element,
|
clearButton?: JSX.Element,
|
||||||
opts: T.TextOptions,
|
opts: T.TextOptions,
|
||||||
is2ndPersonPicker?: boolean,
|
is2ndPersonPicker?: boolean,
|
||||||
|
@ -67,7 +90,7 @@ function NPPronounPicker({ onChange, pronoun, asObject, clearButton, opts, is2nd
|
||||||
if (is2ndPersonPicker && !isSecondPerson(pronoun.person)) {
|
if (is2ndPersonPicker && !isSecondPerson(pronoun.person)) {
|
||||||
throw new Error("can't use 2ndPerson NPProunounPicker without a pronoun");
|
throw new Error("can't use 2ndPerson NPProunounPicker without a pronoun");
|
||||||
}
|
}
|
||||||
const [display, setDisplay] = useStickyState<"persons" | "p" | "e">("e", "prounoun-picker-display");
|
const [display, setDisplay] = useStickyState<"p" | "e">("e", "prounoun-picker-display2");
|
||||||
const p = personToPickerState(pronoun.person);
|
const p = personToPickerState(pronoun.person);
|
||||||
function handleClick(row: number, col: number) {
|
function handleClick(row: number, col: number) {
|
||||||
const person = pickerStateToPerson({ ...p, row, col });
|
const person = pickerStateToPerson({ ...p, row, col });
|
||||||
|
@ -90,21 +113,19 @@ function NPPronounPicker({ onChange, pronoun, asObject, clearButton, opts, is2nd
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function handleDisplayChange() {
|
function handleDisplayChange() {
|
||||||
const newPerson = display === "persons"
|
const newPerson = display === "p"
|
||||||
? "p"
|
|
||||||
: display === "p"
|
|
||||||
? "e"
|
? "e"
|
||||||
: "persons";
|
: "p";
|
||||||
setDisplay(newPerson);
|
setDisplay(newPerson);
|
||||||
}
|
}
|
||||||
const prs = labels(!!asObject)[display];
|
const prs = labels(role)[display];
|
||||||
const pSpecA = "near" in prs ? prs[pronoun.distance] : prs;
|
const pSpecA = "near" in prs ? prs[pronoun.distance] : prs;
|
||||||
const pSpec = is2ndPersonPicker
|
const pSpec = is2ndPersonPicker
|
||||||
? [pSpecA[1]]
|
? [pSpecA[1]]
|
||||||
: pSpecA;
|
: pSpecA;
|
||||||
return <div style={{ maxWidth: "145px", padding: 0 }}>
|
return <div style={{ maxWidth: "145px", padding: 0 }}>
|
||||||
<div className="d-flex flex-row justify-content-between mb-2">
|
<div className="d-flex flex-row justify-content-between mb-2">
|
||||||
{isThirdPerson(pronoun.person) ? <ButtonSelect
|
<ButtonSelect
|
||||||
xSmall
|
xSmall
|
||||||
options={[
|
options={[
|
||||||
{ label: "Far", value: "far" },
|
{ label: "Far", value: "far" },
|
||||||
|
@ -112,9 +133,9 @@ function NPPronounPicker({ onChange, pronoun, asObject, clearButton, opts, is2nd
|
||||||
]}
|
]}
|
||||||
value={pronoun.distance}
|
value={pronoun.distance}
|
||||||
handleChange={(g) => handlePronounTypeChange(g as "far" | "near")}
|
handleChange={(g) => handlePronounTypeChange(g as "far" | "near")}
|
||||||
/> : <div>{` `}</div>}
|
/>
|
||||||
<button className="btn btn-sm btn-outline-secondary" onClick={handleDisplayChange}>
|
<button className="btn btn-sm btn-outline-secondary" onClick={handleDisplayChange}>
|
||||||
{display === "persons" ? "#" : display === "p" ? "PS" : "EN"}
|
{display === "p" ? "PS" : display === "e" ? "PS" : "EN"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<table className="table table-bordered table-sm" style={{ textAlign: "center", minWidth: "100px", tableLayout: "fixed" }}>
|
<table className="table table-bordered table-sm" style={{ textAlign: "center", minWidth: "100px", tableLayout: "fixed" }}>
|
||||||
|
@ -125,6 +146,7 @@ function NPPronounPicker({ onChange, pronoun, asObject, clearButton, opts, is2nd
|
||||||
const active = is2ndPersonPicker
|
const active = is2ndPersonPicker
|
||||||
? (p.col === j)
|
? (p.col === j)
|
||||||
: (p.row === i && p.col === j);
|
: (p.row === i && p.col === j);
|
||||||
|
const content = typeof r === "string" ? r : r[p.gender];
|
||||||
return <td
|
return <td
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleClick(is2ndPersonPicker ? 1 : i, j);
|
handleClick(is2ndPersonPicker ? 1 : i, j);
|
||||||
|
@ -136,7 +158,7 @@ function NPPronounPicker({ onChange, pronoun, asObject, clearButton, opts, is2nd
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="my-1">
|
<div className="my-1">
|
||||||
{typeof r === "string" ? r : r[p.gender]}
|
{content}
|
||||||
</div>
|
</div>
|
||||||
</td>;
|
</td>;
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -224,11 +224,12 @@ function TensePicker(props: ({
|
||||||
: verbTenseOptions;
|
: verbTenseOptions;
|
||||||
const showImperativeOption = ("vps" in props && props.vps.verb.voice === "active")
|
const showImperativeOption = ("vps" in props && props.vps.verb.voice === "active")
|
||||||
|| ("vpsComplete" in props && props.vpsComplete.verb.voice !== "active");
|
|| ("vpsComplete" in props && props.vpsComplete.verb.voice !== "active");
|
||||||
|
const canHaveFormula = "vps" in props && props.vps.verb.voice === "active";
|
||||||
return <div>
|
return <div>
|
||||||
<div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
|
<div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
|
||||||
<div className="d-flex flex-row justify-content-between align-items-center">
|
<div className="d-flex flex-row justify-content-between align-items-center">
|
||||||
<div className="h5">Tense:</div>
|
<div className="h5">Tense:</div>
|
||||||
{"vps" in props && <div className="clickable mb-2 small" onClick={() => setShowFormula(x => !x)}>
|
{canHaveFormula && <div className="clickable mb-2 small" onClick={() => setShowFormula(x => !x)}>
|
||||||
🧪 {!showFormula ? "Show" : "Hide"} Formula
|
🧪 {!showFormula ? "Show" : "Hide"} Formula
|
||||||
</div>}
|
</div>}
|
||||||
</div>
|
</div>
|
||||||
|
@ -305,7 +306,7 @@ function TensePicker(props: ({
|
||||||
<i className="fas fa-chevron-right" />
|
<i className="fas fa-chevron-right" />
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
{("vps" in props && showFormula) && (() => {
|
{(canHaveFormula && showFormula) && (() => {
|
||||||
// TODO: Be able to show modal formulas too
|
// TODO: Be able to show modal formulas too
|
||||||
const curr = (props.vps.verb.tenseCategory === "imperative" && props.vps.verb.negative)
|
const curr = (props.vps.verb.tenseCategory === "imperative" && props.vps.verb.negative)
|
||||||
? imperativeTenseOptions.find(x => x.value === "imperfectiveImperative")
|
? imperativeTenseOptions.find(x => x.value === "imperfectiveImperative")
|
||||||
|
|
|
@ -63,8 +63,9 @@ export function VPExplorer(props: {
|
||||||
"verbExplorerMode",
|
"verbExplorerMode",
|
||||||
);
|
);
|
||||||
const [showingExplanation, setShowingExplanation] = useState<{ role: "servant" | "king", item: "subject" | "object" } | false>(false);
|
const [showingExplanation, setShowingExplanation] = useState<{ role: "servant" | "king", item: "subject" | "object" } | false>(false);
|
||||||
|
const isPast = isPastTense(vps.verb.tenseCategory === "perfect" ? vps.verb.perfectTense : vps.verb.verbTense);
|
||||||
const roles = getKingAndServant(
|
const roles = getKingAndServant(
|
||||||
isPastTense(vps.verb.tenseCategory === "perfect" ? vps.verb.perfectTense : vps.verb.verbTense),
|
isPast,
|
||||||
vps.verb.transitivity !== "intransitive",
|
vps.verb.transitivity !== "intransitive",
|
||||||
);
|
);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -158,6 +159,10 @@ export function VPExplorer(props: {
|
||||||
nouns: props.nouns,
|
nouns: props.nouns,
|
||||||
verbs: props.verbs,
|
verbs: props.verbs,
|
||||||
}}
|
}}
|
||||||
|
role={(isPast && vps.verb.transitivity !== "intransitive")
|
||||||
|
? "ergative"
|
||||||
|
: "subject"
|
||||||
|
}
|
||||||
is2ndPersonPicker={vps.verb.tenseCategory === "imperative"}
|
is2ndPersonPicker={vps.verb.tenseCategory === "imperative"}
|
||||||
np={vps.subject}
|
np={vps.subject}
|
||||||
counterPart={vps.verb ? vps.verb.object : undefined}
|
counterPart={vps.verb ? vps.verb.object : undefined}
|
||||||
|
@ -181,7 +186,7 @@ export function VPExplorer(props: {
|
||||||
nouns: props.nouns,
|
nouns: props.nouns,
|
||||||
verbs: props.verbs,
|
verbs: props.verbs,
|
||||||
}}
|
}}
|
||||||
asObject
|
role="object"
|
||||||
np={vps.verb.object}
|
np={vps.verb.object}
|
||||||
counterPart={vps.subject}
|
counterPart={vps.subject}
|
||||||
onChange={handleObjectChange}
|
onChange={handleObjectChange}
|
||||||
|
|
Loading…
Reference in New Issue