better
This commit is contained in:
parent
8f1e283216
commit
d24c6d8aba
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@lingdocs/pashto-inflector",
|
"name": "@lingdocs/pashto-inflector",
|
||||||
"version": "3.2.8",
|
"version": "3.2.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",
|
||||||
|
|
|
@ -3,7 +3,7 @@ import classNames from "classnames";
|
||||||
import {
|
import {
|
||||||
getEnglishFromRendered,
|
getEnglishFromRendered,
|
||||||
} from "../../lib/phrase-building/np-tools";
|
} from "../../lib/phrase-building/np-tools";
|
||||||
import { getEnglishPersonInfo } from "../../library";
|
import { getEnglishPersonInfo, getEnglishParticipleInflection } from "../../lib/misc-helpers";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { getLength } from "../../lib/p-text-helpers";
|
import { getLength } from "../../lib/p-text-helpers";
|
||||||
import { roleIcon } from "../vp-explorer/VPExplorerExplanationModal";
|
import { roleIcon } from "../vp-explorer/VPExplorerExplanationModal";
|
||||||
|
@ -101,8 +101,11 @@ function VerbSBlock({ opts, v, script }: {
|
||||||
<Border>
|
<Border>
|
||||||
{getLength(v.ps, length)[0][script]}
|
{getLength(v.ps, length)[0][script]}
|
||||||
</Border>
|
</Border>
|
||||||
<div>{v.type === "perfectParticipleBlock" ? "Past Partic." : "Verb"}</div>
|
<div>{v.type === "perfectParticipleBlock" ? "Past Partic." : "Verb"} aa</div>
|
||||||
<EnglishBelow>{getEnglishPersonInfo(v.person, "short")}</EnglishBelow>
|
<EnglishBelow>{((v.type === "perfectParticipleBlock" ? "Past Partic." : "Verb")
|
||||||
|
? getEnglishParticipleInflection
|
||||||
|
: getEnglishPersonInfo
|
||||||
|
)(v.person, "short")}</EnglishBelow>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ function NPPicker(props: {
|
||||||
entryFeeder: T.EntryFeeder,
|
entryFeeder: T.EntryFeeder,
|
||||||
phraseIsComplete: boolean,
|
phraseIsComplete: boolean,
|
||||||
isShrunk?: boolean,
|
isShrunk?: boolean,
|
||||||
|
isRemoved?: boolean,
|
||||||
}) {
|
}) {
|
||||||
if (props.is2ndPersonPicker && ((props.np?.selection.type !== "pronoun") || !isSecondPerson(props.np.selection.person))) {
|
if (props.is2ndPersonPicker && ((props.np?.selection.type !== "pronoun") || !isSecondPerson(props.np.selection.person))) {
|
||||||
throw new Error("can't use 2ndPerson NPPicker without a pronoun");
|
throw new Error("can't use 2ndPerson NPPicker without a pronoun");
|
||||||
|
@ -106,7 +107,9 @@ function NPPicker(props: {
|
||||||
? <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>
|
? <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>
|
||||||
: <div></div>;
|
: <div></div>;
|
||||||
const possesiveLabel = props.np?.selection.type === "participle" ? "Subj/Obj" : "Possesor";
|
const possesiveLabel = props.np?.selection.type === "participle" ? "Subj/Obj" : "Possesor";
|
||||||
return <>
|
return <div style={{
|
||||||
|
opacity: props.isRemoved ? 0.6 : 1,
|
||||||
|
}}>
|
||||||
<div className="d-flex flex-row justify-content-between">
|
<div className="d-flex flex-row justify-content-between">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -119,79 +122,79 @@ function NPPicker(props: {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ minWidth: "9rem" }}>
|
<div style={{ minWidth: "9rem" }}>
|
||||||
{!npType && <div className="text-center">
|
{!npType && <div className="text-center">
|
||||||
<div className="h6 mr-3">
|
<div className="h6 mr-3">
|
||||||
Choose NP
|
Choose NP
|
||||||
|
</div>
|
||||||
|
{npTypes.map((npt) => <div key={npt} className="mb-2">
|
||||||
|
<button
|
||||||
|
key={npt}
|
||||||
|
type="button"
|
||||||
|
className="mr-2 btn btn-sm btn-outline-secondary"
|
||||||
|
onClick={() => handleNPTypeChange(npt)}
|
||||||
|
>
|
||||||
|
{npt}
|
||||||
|
</button>
|
||||||
|
</div>)}
|
||||||
|
</div>}
|
||||||
|
{(props.np && props.np.selection.type !== "pronoun" && (props.np.selection.possesor || addingPoss)) && <div className="mb-3" style={{
|
||||||
|
paddingLeft: "0.65rem",
|
||||||
|
borderLeft: "2px solid grey",
|
||||||
|
background: (props.np.selection.possesor?.shrunken && !props.isShrunk) ? shrunkenBackground : "inherit",
|
||||||
|
}}>
|
||||||
|
<div className="d-flex flex-row text-muted mb-2">
|
||||||
|
<div>{possesiveLabel}:</div>
|
||||||
|
{(props.np.selection.possesor && !props.isShrunk && props.phraseIsComplete) && <div className="clickable ml-3 mr-2" onClick={handleToggleShrunken}>
|
||||||
|
{!props.np.selection.possesor.shrunken ? "🪄" : "👶"}
|
||||||
|
</div>}
|
||||||
|
<div className="clickable ml-2" onClick={() => {
|
||||||
|
setAddingPoss(false);
|
||||||
|
handlePossesiveChange(undefined);
|
||||||
|
}}>
|
||||||
|
<i className="fas fa-trash" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{npTypes.map((npt) => <div key={npt} className="mb-2">
|
<NPPicker
|
||||||
<button
|
phraseIsComplete={props.phraseIsComplete}
|
||||||
key={npt}
|
onChange={handlePossesiveChange}
|
||||||
type="button"
|
counterPart={undefined}
|
||||||
className="mr-2 btn btn-sm btn-outline-secondary"
|
cantClear
|
||||||
onClick={() => handleNPTypeChange(npt)}
|
np={props.np.selection.possesor ? props.np.selection.possesor.np : undefined}
|
||||||
>
|
role="possesor"
|
||||||
{npt}
|
opts={props.opts}
|
||||||
</button>
|
entryFeeder={props.entryFeeder}
|
||||||
</div>)}
|
/>
|
||||||
</div>}
|
</div>}
|
||||||
{(props.np && props.np.selection.type !== "pronoun" && (props.np.selection.possesor || addingPoss)) && <div className="mb-3" style={{
|
{(npType === "noun" || npType === "participle") && props.np && !addingPoss && <div>
|
||||||
paddingLeft: "0.65rem",
|
<span className="clickable text-muted" onClick={() => setAddingPoss(true)}>+ {possesiveLabel}</span>
|
||||||
borderLeft: "2px solid grey",
|
</div>}
|
||||||
background: (props.np.selection.possesor?.shrunken && !props.isShrunk) ? shrunkenBackground : "inherit",
|
{(npType === "pronoun" && props.np?.selection.type === "pronoun")
|
||||||
}}>
|
? <PronounPicker
|
||||||
<div className="d-flex flex-row text-muted mb-2">
|
role={props.role}
|
||||||
<div>{possesiveLabel}:</div>
|
pronoun={props.np.selection}
|
||||||
{(props.np.selection.possesor && !props.isShrunk && props.phraseIsComplete) && <div className="clickable ml-3 mr-2" onClick={handleToggleShrunken}>
|
onChange={(p) => onChange({ type: "NP", selection: p })}
|
||||||
{!props.np.selection.possesor.shrunken ? "🪄" : "👶"}
|
is2ndPersonPicker={props.is2ndPersonPicker}
|
||||||
</div>}
|
opts={props.opts}
|
||||||
<div className="clickable ml-2" onClick={() => {
|
/>
|
||||||
setAddingPoss(false);
|
: npType === "noun"
|
||||||
handlePossesiveChange(undefined);
|
? <NounPicker
|
||||||
}}>
|
phraseIsComplete={props.phraseIsComplete}
|
||||||
<i className="fas fa-trash" />
|
entryFeeder={props.entryFeeder}
|
||||||
</div>
|
noun={(props.np && props.np.selection.type === "noun") ? props.np.selection : undefined}
|
||||||
</div>
|
onChange={(s) => onChange(s ? { type: "NP", selection: s } : undefined)}
|
||||||
<NPPicker
|
opts={props.opts}
|
||||||
phraseIsComplete={props.phraseIsComplete}
|
/>
|
||||||
onChange={handlePossesiveChange}
|
: npType === "participle"
|
||||||
counterPart={undefined}
|
? <ParticiplePicker
|
||||||
cantClear
|
entryFeeder={props.entryFeeder.verbs}
|
||||||
np={props.np.selection.possesor ? props.np.selection.possesor.np : undefined}
|
participle={(props.np && props.np.selection.type === "participle") ? props.np.selection : undefined}
|
||||||
role="possesor"
|
onChange={(s) => onChange(s ? { type: "NP", selection: s } : undefined)}
|
||||||
opts={props.opts}
|
opts={props.opts}
|
||||||
entryFeeder={props.entryFeeder}
|
/>
|
||||||
/>
|
: null
|
||||||
</div>}
|
}
|
||||||
{(npType === "noun" || npType === "participle") && props.np && !addingPoss && <div>
|
</div>
|
||||||
<span className="clickable text-muted" onClick={() => setAddingPoss(true)}>+ {possesiveLabel}</span>
|
</div>;
|
||||||
</div>}
|
|
||||||
{(npType === "pronoun" && props.np?.selection.type === "pronoun")
|
|
||||||
? <PronounPicker
|
|
||||||
role={props.role}
|
|
||||||
pronoun={props.np.selection}
|
|
||||||
onChange={(p) => onChange({ type: "NP", selection: p })}
|
|
||||||
is2ndPersonPicker={props.is2ndPersonPicker}
|
|
||||||
opts={props.opts}
|
|
||||||
/>
|
|
||||||
: npType === "noun"
|
|
||||||
? <NounPicker
|
|
||||||
phraseIsComplete={props.phraseIsComplete}
|
|
||||||
entryFeeder={props.entryFeeder}
|
|
||||||
noun={(props.np && props.np.selection.type === "noun") ? props.np.selection : undefined}
|
|
||||||
onChange={(s) => onChange(s ? { type: "NP", selection: s } : undefined)}
|
|
||||||
opts={props.opts}
|
|
||||||
/>
|
|
||||||
: npType === "participle"
|
|
||||||
? <ParticiplePicker
|
|
||||||
entryFeeder={props.entryFeeder.verbs}
|
|
||||||
participle={(props.np && props.np.selection.type === "participle") ? props.np.selection : undefined}
|
|
||||||
onChange={(s) => onChange(s ? { type: "NP", selection: s } : undefined)}
|
|
||||||
opts={props.opts}
|
|
||||||
/>
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureSingleShrink(old: T.NPSelection | undefined, s: T.NPSelection | undefined): T.NPSelection | undefined {
|
function ensureSingleShrink(old: T.NPSelection | undefined, s: T.NPSelection | undefined): T.NPSelection | undefined {
|
||||||
|
|
|
@ -95,9 +95,16 @@ function VPPicker({ opts, vps, onChange, entryFeeder }: {
|
||||||
? <NPPicker
|
? <NPPicker
|
||||||
phraseIsComplete={phraseIsComplete}
|
phraseIsComplete={phraseIsComplete}
|
||||||
heading={roles.king === "subject"
|
heading={roles.king === "subject"
|
||||||
? <div className="h5 text-center" onClick={() => setShowingExplanation({ role: "king", item: "subject" })}>Subject {roleIcon.king}</div>
|
? <div className="h5 text-center">
|
||||||
|
Subj. <span onClick={() => setShowingExplanation({ role: "king", item: "subject" })}>{roleIcon.king}</span>
|
||||||
|
{(rendered && rendered.whatsAdjustable !== "servant") &&
|
||||||
|
<span onClick={() => adjustVps({ type: "toggle king remove" })} className="mx-2 clickable">
|
||||||
|
{!VPS?.form.removeKing ? "🚫" : "🙈"}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
: <div className="h5 text-center">
|
: <div className="h5 text-center">
|
||||||
Subject
|
Subj.
|
||||||
{` `}
|
{` `}
|
||||||
<span className="clickable" onClick={() => setShowingExplanation({ role: "servant", item: "subject" })}>{roleIcon.servant}</span>
|
<span className="clickable" onClick={() => setShowingExplanation({ role: "servant", item: "subject" })}>{roleIcon.servant}</span>
|
||||||
{` `}
|
{` `}
|
||||||
|
@ -117,6 +124,7 @@ function VPPicker({ opts, vps, onChange, entryFeeder }: {
|
||||||
onChange={handleSubjectChange}
|
onChange={handleSubjectChange}
|
||||||
opts={opts}
|
opts={opts}
|
||||||
isShrunk={(servantIsShrunk && roles.servant === "subject")}
|
isShrunk={(servantIsShrunk && roles.servant === "subject")}
|
||||||
|
isRemoved={roles.king === "subject" && VPS?.form.removeKing}
|
||||||
/>
|
/>
|
||||||
: (vps.verb && block?.type === "objectSelection" && block.selection !== "none")
|
: (vps.verb && block?.type === "objectSelection" && block.selection !== "none")
|
||||||
? <div className="my-2" style={{ background: (servantIsShrunk && roles.servant === "object") ? shrunkenBackground : "inherit" }}>
|
? <div className="my-2" style={{ background: (servantIsShrunk && roles.servant === "object") ? shrunkenBackground : "inherit" }}>
|
||||||
|
@ -130,9 +138,16 @@ function VPPicker({ opts, vps, onChange, entryFeeder }: {
|
||||||
: <NPPicker
|
: <NPPicker
|
||||||
phraseIsComplete={phraseIsComplete}
|
phraseIsComplete={phraseIsComplete}
|
||||||
heading={roles.king === "object"
|
heading={roles.king === "object"
|
||||||
? <div className="h5 text-center clickable" onClick={() => setShowingExplanation({ role: "king", item: "object" })}>Object {roleIcon.king}</div>
|
? <div className="h5 text-center">
|
||||||
|
Obj. <span onClick={() => setShowingExplanation({ role: "king", item: "object" })}>{roleIcon.king}</span>
|
||||||
|
{(rendered && rendered.whatsAdjustable !== "servant") &&
|
||||||
|
<span onClick={() => adjustVps({ type: "toggle king remove" })} className="mx-2 clickable">
|
||||||
|
{!VPS?.form.removeKing ? "🚫" : "🙈"}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
: <div className="h5 text-center">
|
: <div className="h5 text-center">
|
||||||
Object
|
Obj.
|
||||||
{` `}
|
{` `}
|
||||||
<span className="clickable" onClick={() => setShowingExplanation({ role: "servant", item: "object" })}>{roleIcon.servant}</span>
|
<span className="clickable" onClick={() => setShowingExplanation({ role: "servant", item: "object" })}>{roleIcon.servant}</span>
|
||||||
{` `}
|
{` `}
|
||||||
|
@ -141,6 +156,11 @@ function VPPicker({ opts, vps, onChange, entryFeeder }: {
|
||||||
{!servantIsShrunk ? "🪄" : "👶"}
|
{!servantIsShrunk ? "🪄" : "👶"}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
{(rendered && rendered.whatsAdjustable !== "servant") &&
|
||||||
|
<span onClick={() => adjustVps({ type: "toggle king remove" })} className="mx-2 clickable">
|
||||||
|
{!VPS?.form.removeKing ? "🚫" : "🙈"}
|
||||||
|
</span>
|
||||||
|
}
|
||||||
</div>}
|
</div>}
|
||||||
entryFeeder={entryFeeder}
|
entryFeeder={entryFeeder}
|
||||||
role="object"
|
role="object"
|
||||||
|
@ -149,6 +169,7 @@ function VPPicker({ opts, vps, onChange, entryFeeder }: {
|
||||||
onChange={handleObjectChange}
|
onChange={handleObjectChange}
|
||||||
opts={opts}
|
opts={opts}
|
||||||
isShrunk={(servantIsShrunk && roles.servant === "object")}
|
isShrunk={(servantIsShrunk && roles.servant === "object")}
|
||||||
|
isRemoved={roles.king === "object" && VPS?.form.removeKing}
|
||||||
/>}
|
/>}
|
||||||
</div>
|
</div>
|
||||||
: null}
|
: null}
|
||||||
|
|
|
@ -53,6 +53,8 @@ export type VpsReducerAction = {
|
||||||
} | {
|
} | {
|
||||||
type: "toggle servant shrink",
|
type: "toggle servant shrink",
|
||||||
} | {
|
} | {
|
||||||
|
type: "toggle king remove",
|
||||||
|
} |{
|
||||||
type: "set verb",
|
type: "set verb",
|
||||||
payload: T.VerbEntry,
|
payload: T.VerbEntry,
|
||||||
} | {
|
} | {
|
||||||
|
@ -251,6 +253,15 @@ export function vpsReducer(vps: T.VPSelectionState, action: VpsReducerAction, se
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (action.type === "toggle king remove") {
|
||||||
|
return {
|
||||||
|
...vps,
|
||||||
|
form: {
|
||||||
|
...vps.form,
|
||||||
|
removeKing: !vps.form.removeKing,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
if (action.type === "set verb") {
|
if (action.type === "set verb") {
|
||||||
return makeVPSelectionState(action.payload, vps);
|
return makeVPSelectionState(action.payload, vps);
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,15 @@ export function getEnglishPersonInfo(person: T.Person, version?: "short" | "long
|
||||||
return `${p} ${n}. ${g}.`;
|
return `${p} ${n}. ${g}.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getEnglishParticipleInflection(person: T.Person, version?: "short" | "long"): string {
|
||||||
|
const number = personIsPlural(person) ? "plural" : "singular";
|
||||||
|
const n = version === "short"
|
||||||
|
? (number === "plural" ? "plur." : "sing.") : number;
|
||||||
|
const gender = personGender(person);
|
||||||
|
const g = gender;
|
||||||
|
return `${g}. ${n}`;
|
||||||
|
}
|
||||||
|
|
||||||
export function randomNumber(minInclusive: number, maxExclusive: number): number {
|
export function randomNumber(minInclusive: number, maxExclusive: number): number {
|
||||||
return Math.floor(Math.random() * (maxExclusive - minInclusive) + minInclusive);
|
return Math.floor(Math.random() * (maxExclusive - minInclusive) + minInclusive);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue