BIG IMPROVEMENT - passive and ability stems, simplified formulas, and avoiding picking passive ability verbs etc
This commit is contained in:
parent
8f559e0665
commit
0008f18e85
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@lingdocs/pashto-inflector",
|
"name": "@lingdocs/pashto-inflector",
|
||||||
"version": "3.5.9",
|
"version": "3.6.0",
|
||||||
"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",
|
||||||
|
|
|
@ -41,12 +41,13 @@ const title: CSSProperties = {
|
||||||
|
|
||||||
export function RootsAndStems({ textOptions, info, hidePastParticiple, highlighted, noTails }: {
|
export function RootsAndStems({ textOptions, info, hidePastParticiple, highlighted, noTails }: {
|
||||||
textOptions: T.TextOptions,
|
textOptions: T.TextOptions,
|
||||||
info: T.NonComboVerbInfo | T.PassiveRootsStems,
|
info: T.NonComboVerbInfo | T.PassiveRootsAndStems | T.AbilityRootsAndStems,
|
||||||
hidePastParticiple?: boolean,
|
hidePastParticiple?: boolean,
|
||||||
highlighted?: T.RootsOrStemsToHighlight,
|
highlighted?: T.RootsOrStemsToHighlight,
|
||||||
noTails?: boolean,
|
noTails?: boolean,
|
||||||
}) {
|
}) {
|
||||||
const hasPerfectiveSplit = !!(info.root.perfectiveSplit || info.stem.perfectiveSplit);
|
const hasPerfectiveSplit = ("perfectiveSplit" in info.root && "perfectiveSplit" in info.stem)
|
||||||
|
&& !!(info.root.perfectiveSplit || info.stem.perfectiveSplit);
|
||||||
const showPersInf = hasPersInfs(info);
|
const showPersInf = hasPersInfs(info);
|
||||||
const [persInf, setPersInf] = useState<T.PersonInflectionsField>("mascSing");
|
const [persInf, setPersInf] = useState<T.PersonInflectionsField>("mascSing");
|
||||||
const [split, setSplit] = useState<boolean>(false);
|
const [split, setSplit] = useState<boolean>(false);
|
||||||
|
@ -161,7 +162,7 @@ export function RootsAndStems({ textOptions, info, hidePastParticiple, highlight
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!hidePastParticiple && <div className="text-center" style={highlighted?.includes("past participle") ? highlight : {}}>
|
{!hidePastParticiple && "participle" in info &&<div className="text-center" style={highlighted?.includes("past participle") ? highlight : {}}>
|
||||||
<div style={title}>Past Participle</div>
|
<div style={title}>Past Participle</div>
|
||||||
<VerbInfoItemDisplay
|
<VerbInfoItemDisplay
|
||||||
item={pickPersInf(info.participle.past, persInf)}
|
item={pickPersInf(info.participle.past, persInf)}
|
||||||
|
|
|
@ -8,48 +8,50 @@ import {
|
||||||
VpsReducerAction
|
VpsReducerAction
|
||||||
} from "./vps-reducer";
|
} from "./vps-reducer";
|
||||||
|
|
||||||
const verbTenseOptions: { label: string | JSX.Element, value: T.VerbTense, formula: string, modalFormula: string, }[] = [{
|
const verbTenseOptions: { label: string | JSX.Element, value: T.VerbTense, formula: string }[] = [{
|
||||||
label: <div><i className="fas fa-video mr-2" />present</div>,
|
label: <div><i className="fas fa-video mr-2" />present</div>,
|
||||||
value: "presentVerb",
|
value: "presentVerb",
|
||||||
formula: "imperfective stem + present verb ending",
|
formula: "imperfective stem + present verb ending",
|
||||||
modalFormula: `imperfective root + tail + kedul "to become" subjunctive`,
|
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-camera mr-2" />subjunctive</div>,
|
label: <div><i className="fas fa-camera mr-2" />subjunctive</div>,
|
||||||
value: "subjunctiveVerb",
|
value: "subjunctiveVerb",
|
||||||
formula: "perfective stem + present verb ending",
|
formula: "perfective stem + present verb ending",
|
||||||
modalFormula: `perfective root + tail + kedul "to become" subjunctive`,
|
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-video mr-2" />imperfective future</div>,
|
label: <div><i className="fas fa-video mr-2" />imperfective future</div>,
|
||||||
value: "imperfectiveFuture",
|
value: "imperfectiveFuture",
|
||||||
formula: "ba + present",
|
formula: "ba + present",
|
||||||
modalFormula: `ba + present modal`,
|
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-camera mr-2" />perfective future</div>,
|
label: <div><i className="fas fa-camera mr-2" />perfective future</div>,
|
||||||
value: "perfectiveFuture",
|
value: "perfectiveFuture",
|
||||||
formula: "ba + subjunctive",
|
formula: "ba + subjunctive",
|
||||||
modalFormula: `ba + subjunctive modal`,
|
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-video mr-2" />continuous past</div>,
|
label: <div><i className="fas fa-video mr-2" />continuous past</div>,
|
||||||
value: "imperfectivePast",
|
value: "imperfectivePast",
|
||||||
formula: "imperfective root + past verb ending",
|
formula: "imperfective root + past verb ending",
|
||||||
modalFormula: `imperfective root + tail + kedul "to become" simple past`,
|
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-camera mr-2" />simple past</div>,
|
label: <div><i className="fas fa-camera mr-2" />simple past</div>,
|
||||||
value: "perfectivePast",
|
value: "perfectivePast",
|
||||||
formula: "perfective root + past verb ending",
|
formula: "perfective root + past verb ending",
|
||||||
modalFormula: `perfective root + tail + kedul "to become" simple past`,
|
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-video mr-2" />habitual continual past</div>,
|
label: <div><i className="fas fa-video mr-2" />habitual continual past</div>,
|
||||||
value: "habitualImperfectivePast",
|
value: "habitualImperfectivePast",
|
||||||
formula: "ba + contiunous past",
|
formula: "ba + continuous past",
|
||||||
modalFormula: `ba + simple past modal`,
|
|
||||||
}, {
|
}, {
|
||||||
label: <div><i className="fas fa-camera mr-2" />habitual simple past</div>,
|
label: <div><i className="fas fa-camera mr-2" />habitual simple past</div>,
|
||||||
value: "habitualPerfectivePast",
|
value: "habitualPerfectivePast",
|
||||||
formula: "ba + simple past",
|
formula: "ba + simple past",
|
||||||
modalFormula: `ba + continuous past modal`,
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
function composeFormula(formula: string, prefix: "passive" | "ability"): string {
|
||||||
|
return formula.replace(/^perfective/, `${prefix} perfective`)
|
||||||
|
.replace(/^imperfective/, `${prefix} imperfective`)
|
||||||
|
.replace("continuous", `${prefix} continuous`)
|
||||||
|
.replace("simple", `${prefix} simple`)
|
||||||
|
.replace(/present$/, `${prefix} present`)
|
||||||
|
.replace(/subjunctive$/, `${prefix} subjunctive`)
|
||||||
|
.replace("past participle", `${prefix} past participle`);
|
||||||
|
}
|
||||||
|
|
||||||
const perfectTenseOptions: { label: string | JSX.Element, value: T.PerfectTense, formula: string }[] = [{
|
const perfectTenseOptions: { label: string | JSX.Element, value: T.PerfectTense, formula: string }[] = [{
|
||||||
label: "Present Perfect",
|
label: "Present Perfect",
|
||||||
value: "presentPerfect",
|
value: "presentPerfect",
|
||||||
|
@ -181,6 +183,7 @@ 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 inPassiveVoice = ("vps" in props && props.vps.verb.voice === "passive") || ("vpsComplete" in props && props.vpsComplete.verb.voice === "passive");;
|
||||||
const canHaveFormula = "vps" in props && props.mode !== "quiz";
|
const canHaveFormula = "vps" in props && props.mode !== "quiz";
|
||||||
return <div>
|
return <div>
|
||||||
<div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
|
<div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
|
||||||
|
@ -196,6 +199,7 @@ function TensePicker(props: ({
|
||||||
value={"vpsComplete" in props
|
value={"vpsComplete" in props
|
||||||
? getTenseCategory(props.vpsComplete.verb.tense)
|
? getTenseCategory(props.vpsComplete.verb.tense)
|
||||||
: props.vps.verb.tenseCategory}
|
: props.vps.verb.tenseCategory}
|
||||||
|
// @ts-ignore
|
||||||
options={showImperativeOption ? [{
|
options={showImperativeOption ? [{
|
||||||
label: "Basic",
|
label: "Basic",
|
||||||
value: "basic",
|
value: "basic",
|
||||||
|
@ -217,7 +221,7 @@ function TensePicker(props: ({
|
||||||
}, {
|
}, {
|
||||||
label: "Ability",
|
label: "Ability",
|
||||||
value: "modal",
|
value: "modal",
|
||||||
}]}
|
}].filter(x => !(inPassiveVoice && x.value === "modal"))}
|
||||||
handleChange={props.mode !== "quiz" ? onTenseCategorySelect : () => null}
|
handleChange={props.mode !== "quiz" ? onTenseCategorySelect : () => null}
|
||||||
/>
|
/>
|
||||||
</div>}
|
</div>}
|
||||||
|
@ -276,8 +280,10 @@ function TensePicker(props: ({
|
||||||
]);
|
]);
|
||||||
const formula = !curr
|
const formula = !curr
|
||||||
? ""
|
? ""
|
||||||
: ("modalFormula" in curr && props.vps.verb.tenseCategory === "modal")
|
: (props.vps.verb.tenseCategory === "modal")
|
||||||
? curr.modalFormula
|
? composeFormula(curr.formula, "ability")
|
||||||
|
: (props.vps.verb.voice === "passive")
|
||||||
|
? composeFormula(curr.formula, "passive")
|
||||||
: curr.formula;
|
: curr.formula;
|
||||||
if (curr && "formula" in curr) {
|
if (curr && "formula" in curr) {
|
||||||
return <div className="mb-2" style={{ width: "250px", overflowY: "auto" }}>
|
return <div className="mb-2" style={{ width: "250px", overflowY: "auto" }}>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as T from "../../types";
|
import * as T from "../../types";
|
||||||
import ButtonSelect from "../ButtonSelect";
|
import ButtonSelect from "../ButtonSelect";
|
||||||
import { RootsAndStems } from "../verb-info/VerbInfo";
|
import { RootsAndStems } from "../verb-info/VerbInfo";
|
||||||
import { getPassiveRootsAndStems, getVerbInfo } from "../../lib/verb-info";
|
import { getAbilityRootsAndStems, getPassiveRootsAndStems, getVerbInfo } from "../../lib/verb-info";
|
||||||
import Hider from "../Hider";
|
import Hider from "../Hider";
|
||||||
import useStickyState from "../../lib/useStickyState";
|
import useStickyState from "../../lib/useStickyState";
|
||||||
import CompoundDisplay from "./CompoundDisplay";
|
import CompoundDisplay from "./CompoundDisplay";
|
||||||
|
@ -51,6 +51,14 @@ function VerbPicker(props: {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const passiveRootsAndStems = (info && props.vps.verb.voice === "passive") ? getPassiveRootsAndStems(info) : undefined;
|
const passiveRootsAndStems = (info && props.vps.verb.voice === "passive") ? getPassiveRootsAndStems(info) : undefined;
|
||||||
|
const abilityRootsAndStems = (() => {
|
||||||
|
try {
|
||||||
|
return (info && props.vps.verb.tenseCategory === "modal") ? getAbilityRootsAndStems(info) : undefined;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("error making ability roots and stems", e);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
})();
|
||||||
return <div className="mb-3">
|
return <div className="mb-3">
|
||||||
{info && <CompoundDisplay
|
{info && <CompoundDisplay
|
||||||
info={info}
|
info={info}
|
||||||
|
@ -60,13 +68,17 @@ function VerbPicker(props: {
|
||||||
{info && <div className="mt-3 mb-1 text-center">
|
{info && <div className="mt-3 mb-1 text-center">
|
||||||
<Hider
|
<Hider
|
||||||
showing={showRootsAndStems}
|
showing={showRootsAndStems}
|
||||||
label="🌳 Roots and Stems"
|
label={`🌳 ${passiveRootsAndStems ? "Passive" : abilityRootsAndStems ? "Ability" : ""} Roots and Stems`}
|
||||||
handleChange={() => setShowRootsAndStems(p => !p)}
|
handleChange={() => setShowRootsAndStems(p => !p)}
|
||||||
hLevel={5}
|
hLevel={5}
|
||||||
>
|
>
|
||||||
<RootsAndStems
|
<RootsAndStems
|
||||||
textOptions={props.opts}
|
textOptions={props.opts}
|
||||||
info={passiveRootsAndStems ? passiveRootsAndStems : info}
|
info={passiveRootsAndStems
|
||||||
|
? passiveRootsAndStems
|
||||||
|
: abilityRootsAndStems
|
||||||
|
? abilityRootsAndStems
|
||||||
|
: info}
|
||||||
/>
|
/>
|
||||||
</Hider>
|
</Hider>
|
||||||
</div>}
|
</div>}
|
||||||
|
@ -89,7 +101,7 @@ function VerbPicker(props: {
|
||||||
<ButtonSelect
|
<ButtonSelect
|
||||||
small
|
small
|
||||||
value={props.vps.verb.voice}
|
value={props.vps.verb.voice}
|
||||||
options={props.vps.verb.tenseCategory === "imperative"
|
options={(props.vps.verb.tenseCategory === "imperative" || props.vps.verb.tenseCategory === "modal")
|
||||||
? [{
|
? [{
|
||||||
label: "Active",
|
label: "Active",
|
||||||
value: "active",
|
value: "active",
|
||||||
|
|
|
@ -155,6 +155,7 @@ export function vpsReducer(vps: T.VPSelectionState, action: VpsReducerAction, se
|
||||||
verb: {
|
verb: {
|
||||||
...vps.verb,
|
...vps.verb,
|
||||||
voice,
|
voice,
|
||||||
|
tenseCategory: vps.verb.tenseCategory === "modal" ? "basic" : vps.verb.tenseCategory,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
@ -239,6 +240,16 @@ export function vpsReducer(vps: T.VPSelectionState, action: VpsReducerAction, se
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (category === "modal") {
|
||||||
|
return {
|
||||||
|
...vps,
|
||||||
|
verb: {
|
||||||
|
...vps.verb,
|
||||||
|
tenseCategory: category,
|
||||||
|
voice: "active",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...vps,
|
...vps,
|
||||||
verb: {
|
verb: {
|
||||||
|
|
|
@ -60,12 +60,18 @@ export function getFirstSecThird(p: T.Person): 1 | 2 | 3 {
|
||||||
// return s;
|
// return s;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
export function hasPersInfs(info: T.NonComboVerbInfo | T.PassiveRootsStems): boolean {
|
export function hasPersInfs(info: T.NonComboVerbInfo | T.PassiveRootsAndStems | T.AbilityRootsAndStems): boolean {
|
||||||
|
if ("participle" in info) {
|
||||||
|
return (
|
||||||
|
"mascSing" in info.root.perfective ||
|
||||||
|
"mascSing" in info.stem.perfective ||
|
||||||
|
("present" in info.participle && "mascSing" in info.participle.present) ||
|
||||||
|
"mascSing" in info.participle.past
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
"mascSing" in info.root.perfective ||
|
"mascSing" in info.root.perfective ||
|
||||||
"mascSing" in info.stem.perfective ||
|
"mascSing" in info.stem.perfective
|
||||||
("present" in info.participle && "mascSing" in info.participle.present) ||
|
|
||||||
"mascSing" in info.participle.past
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {
|
||||||
choosePersInf,
|
choosePersInf,
|
||||||
isUnisexSet,
|
isUnisexSet,
|
||||||
getLong,
|
getLong,
|
||||||
|
getShort,
|
||||||
} from "./p-text-helpers";
|
} from "./p-text-helpers";
|
||||||
import {
|
import {
|
||||||
makePsString,
|
makePsString,
|
||||||
|
@ -39,6 +40,7 @@ import {
|
||||||
} from "./pashto-inflector";
|
} from "./pashto-inflector";
|
||||||
import {
|
import {
|
||||||
checkForIrregularConjugation,
|
checkForIrregularConjugation,
|
||||||
|
kedulStat,
|
||||||
stativeAux,
|
stativeAux,
|
||||||
} from "./irregular-conjugations";
|
} from "./irregular-conjugations";
|
||||||
import {
|
import {
|
||||||
|
@ -53,6 +55,7 @@ import {
|
||||||
spaceInForm,
|
spaceInForm,
|
||||||
getAuxTransitivity,
|
getAuxTransitivity,
|
||||||
chooseParticipleInflection,
|
chooseParticipleInflection,
|
||||||
|
noPersInfs,
|
||||||
} from "./misc-helpers";
|
} from "./misc-helpers";
|
||||||
import * as T from "../types";
|
import * as T from "../types";
|
||||||
|
|
||||||
|
@ -982,7 +985,72 @@ function makeDynamicPerfectiveSplit(comp: T.PsString, auxSplit: T.SplitInfo): T.
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPassiveRootsAndStems(info: T.NonComboVerbInfo, withTails?: boolean): T.PassiveRootsStems | undefined {
|
export function getAbilityRootsAndStems(info: T.NonComboVerbInfo): T.AbilityRootsAndStems {
|
||||||
|
const isIntransitiveStativeCompound = info.type === "stative compound" && info.transitivity === "intransitive"
|
||||||
|
const roots = getAbilityRoots(info.root, isIntransitiveStativeCompound);
|
||||||
|
return addAbilityHelperRootsAndStems(roots, isIntransitiveStativeCompound);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addAbilityHelperRootsAndStems(roots: T.VerbRootSet, isIntransitiveStativeCompound: boolean): T.AbilityRootsAndStems {
|
||||||
|
function addAbilityHelperToRoot(
|
||||||
|
r: T.OptionalPersonInflections<T.LengthOptions<T.PsString>>,
|
||||||
|
helper: T.PsString,
|
||||||
|
): T.OptionalPersonInflections<T.LengthOptions<T.PsString>> {
|
||||||
|
if ("mascSing" in r) {
|
||||||
|
return {
|
||||||
|
mascSing: addAbilityHelperToRoot(r.mascSing, helper) as T.LengthOptions<T.PsString>,
|
||||||
|
mascPlur: addAbilityHelperToRoot(r.mascPlur, helper) as T.LengthOptions<T.PsString>,
|
||||||
|
femSing: addAbilityHelperToRoot(r.femSing, helper) as T.LengthOptions<T.PsString>,
|
||||||
|
femPlur: addAbilityHelperToRoot(r.femPlur, helper) as T.LengthOptions<T.PsString>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
long: concatPsString(r.long, " ", helper),
|
||||||
|
short: concatPsString(r.short, " ", helper),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const stemHelper = getLong(noPersInfs(kedulStat.info.stem.perfective));
|
||||||
|
const rootHelper = noPersInfs(kedulStat.info.root.perfective).long;
|
||||||
|
return {
|
||||||
|
stem: {
|
||||||
|
perfective: addAbilityHelperToRoot(roots.perfective, stemHelper),
|
||||||
|
imperfective: addAbilityHelperToRoot(roots.imperfective, stemHelper),
|
||||||
|
...roots.perfectiveSplit ? {
|
||||||
|
perfectiveSplit: addAbilityHelperToPerfectiveSplit(roots.perfectiveSplit, stemHelper),
|
||||||
|
} : {},
|
||||||
|
},
|
||||||
|
root: {
|
||||||
|
perfective: addAbilityHelperToRoot(roots.perfective, rootHelper),
|
||||||
|
imperfective: addAbilityHelperToRoot(roots.imperfective, rootHelper),
|
||||||
|
...roots.perfectiveSplit ? {
|
||||||
|
perfectiveSplit: addAbilityHelperToPerfectiveSplit(roots.perfectiveSplit, rootHelper),
|
||||||
|
} : {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function addAbilityHelperToPerfectiveSplit(s: T.SplitInfo, helper: T.PsString): T.SplitInfo {
|
||||||
|
if ("mascSing" in s) {
|
||||||
|
return {
|
||||||
|
mascSing: addAbilityHelperToPerfectiveSplit(s.mascSing, helper) as T.SingleOrLengthOpts<[T.PsString, T.PsString]>,
|
||||||
|
mascPlur: addAbilityHelperToPerfectiveSplit(s.mascPlur, helper) as T.SingleOrLengthOpts<[T.PsString, T.PsString]>,
|
||||||
|
femSing: addAbilityHelperToPerfectiveSplit(s.femSing, helper) as T.SingleOrLengthOpts<[T.PsString, T.PsString]>,
|
||||||
|
femPlur: addAbilityHelperToPerfectiveSplit(s.femPlur, helper) as T.SingleOrLengthOpts<[T.PsString, T.PsString]>,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
long: [
|
||||||
|
getLong(s)[0],
|
||||||
|
concatPsString(getLong(s)[1], " ", helper),
|
||||||
|
],
|
||||||
|
short: [
|
||||||
|
getShort(s)[0],
|
||||||
|
concatPsString(getShort(s)[1], " ", helper),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPassiveRootsAndStems(info: T.NonComboVerbInfo, withTails?: boolean): T.PassiveRootsAndStems | undefined {
|
||||||
if (info.transitivity === "intransitive") return undefined;
|
if (info.transitivity === "intransitive") return undefined;
|
||||||
return {
|
return {
|
||||||
stem: getPassiveStem(info.root, info.root.perfectiveSplit, withTails),
|
stem: getPassiveStem(info.root, info.root.perfectiveSplit, withTails),
|
||||||
|
@ -1050,6 +1118,50 @@ function getPassiveRootPerfectiveSplit(root: T.OptionalPersonInflections<T.Lengt
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const abilityTail = { p: "ی", f: "ey" };
|
||||||
|
const abilityTailAccented = { p: "ی", f: "éy" };
|
||||||
|
|
||||||
|
function getAbilityRoots(root: T.VerbRootSet, isIntransitiveStativeCompound: boolean): T.VerbRootSet {
|
||||||
|
function getAspectAbilityRoot(root: T.VerbRootSet[T.Aspect], aspect: T.Aspect): T.OptionalPersonInflections<T.LengthOptions<T.PsString>> {
|
||||||
|
if ("mascSing" in root) {
|
||||||
|
return {
|
||||||
|
mascSing: getAspectAbilityRoot(root.mascSing, aspect) as T.LengthOptions<T.PsString>,
|
||||||
|
mascPlur: getAspectAbilityRoot(root.mascPlur, aspect) as T.LengthOptions<T.PsString>,
|
||||||
|
femSing: getAspectAbilityRoot(root.femSing, aspect) as T.LengthOptions<T.PsString>,
|
||||||
|
femPlur: getAspectAbilityRoot(root.femPlur, aspect) as T.LengthOptions<T.PsString>,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
long: concatPsString(root.long, abilityTail) as T.PsString,
|
||||||
|
short: concatPsString(root.short, aspect === "imperfective" ? abilityTailAccented : abilityTail) as T.PsString,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getAbilityRootPerfectiveSplit(s: T.SplitInfo): T.SplitInfo {
|
||||||
|
if ("mascSing" in s) {
|
||||||
|
return {
|
||||||
|
mascSing: getAbilityRootPerfectiveSplit(s.mascSing) as [T.PsString, T.PsString],
|
||||||
|
mascPlur: getAbilityRootPerfectiveSplit(s.mascPlur) as [T.PsString, T.PsString],
|
||||||
|
femSing: getAbilityRootPerfectiveSplit(s.femSing) as [T.PsString, T.PsString],
|
||||||
|
femPlur: getAbilityRootPerfectiveSplit(s.femPlur) as [T.PsString, T.PsString],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
long: [getLong(s)[0], concatPsString(getLong(s)[1], abilityTail)],
|
||||||
|
short: [getShort(s)[0], concatPsString(getShort(s)[1], abilityTail)],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
perfective: getAspectAbilityRoot(
|
||||||
|
!isIntransitiveStativeCompound ? root.perfective : root.imperfective,
|
||||||
|
!isIntransitiveStativeCompound ? "perfective" : "imperfective",
|
||||||
|
),
|
||||||
|
imperfective: getAspectAbilityRoot(root.imperfective, "imperfective"),
|
||||||
|
...(root.perfectiveSplit && !isIntransitiveStativeCompound) ? {
|
||||||
|
perfectiveSplit: getAbilityRootPerfectiveSplit(root.perfectiveSplit),
|
||||||
|
} : {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function getPassiveRoot(root: T.VerbRootSet, splitInfo: T.SplitInfo | undefined, withTails?: boolean): T.VerbRootSet {
|
function getPassiveRoot(root: T.VerbRootSet, splitInfo: T.SplitInfo | undefined, withTails?: boolean): T.VerbRootSet {
|
||||||
const perfectiveRoot = withTails ? concatPsString(root.perfective, passiveRootTail) : root.perfective;
|
const perfectiveRoot = withTails ? concatPsString(root.perfective, passiveRootTail) : root.perfective;
|
||||||
const imperfectiveRoot = withTails ? concatPsString(root.imperfective, passiveRootTail) : root.imperfective;
|
const imperfectiveRoot = withTails ? concatPsString(root.imperfective, passiveRootTail) : root.imperfective;
|
||||||
|
|
|
@ -15,6 +15,7 @@ import {
|
||||||
import {
|
import {
|
||||||
getVerbInfo,
|
getVerbInfo,
|
||||||
getPassiveRootsAndStems,
|
getPassiveRootsAndStems,
|
||||||
|
getAbilityRootsAndStems,
|
||||||
} from "./lib/verb-info";
|
} from "./lib/verb-info";
|
||||||
import InflectionsTable from "./components/InflectionsTable";
|
import InflectionsTable from "./components/InflectionsTable";
|
||||||
import Pashto from "./components/Pashto";
|
import Pashto from "./components/Pashto";
|
||||||
|
@ -173,6 +174,7 @@ export {
|
||||||
conjugateVerb,
|
conjugateVerb,
|
||||||
getVerbInfo,
|
getVerbInfo,
|
||||||
getPassiveRootsAndStems,
|
getPassiveRootsAndStems,
|
||||||
|
getAbilityRootsAndStems,
|
||||||
inflectWord,
|
inflectWord,
|
||||||
addToForm,
|
addToForm,
|
||||||
concatPsString,
|
concatPsString,
|
||||||
|
|
|
@ -169,7 +169,7 @@ export type VerbInfoBase = {
|
||||||
idiosyncraticThirdMascSing?: ShortThirdPersFormSet;
|
idiosyncraticThirdMascSing?: ShortThirdPersFormSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PassiveRootsStems = {
|
export type PassiveRootsAndStems = {
|
||||||
stem: VerbStemSet,
|
stem: VerbStemSet,
|
||||||
root: VerbRootSet,
|
root: VerbRootSet,
|
||||||
participle: {
|
participle: {
|
||||||
|
@ -177,6 +177,8 @@ export type PassiveRootsStems = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type AbilityRootsAndStems = Omit<PassiveRootsAndStems, "participle">;
|
||||||
|
|
||||||
export type SimpleVerbInfo = VerbInfoBase & {
|
export type SimpleVerbInfo = VerbInfoBase & {
|
||||||
type: "simple";
|
type: "simple";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue