better UI and refactor re tenseCategory
This commit is contained in:
parent
b6b742c905
commit
875237439b
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@lingdocs/pashto-inflector",
|
||||
"version": "2.1.1",
|
||||
"version": "2.1.2",
|
||||
"author": "lingdocs.com",
|
||||
"description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations",
|
||||
"homepage": "https://verbs.lingdocs.com",
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import { getTenseVerbForm } from "../../lib/phrase-building/vp-tools";
|
||||
import {
|
||||
getTenseVerbForm,
|
||||
getTenseFromVerbSelection,
|
||||
} from "../../lib/phrase-building/vp-tools";
|
||||
import VerbFormDisplay from "../VerbFormDisplay";
|
||||
import { conjugateVerb } from "../../lib/verb-conjugation";
|
||||
import * as T from "../../types";
|
||||
|
@ -13,7 +16,7 @@ function ChartDisplay({ VS, opts }: { VS: T.VerbSelection, opts: T.TextOptions }
|
|||
: ("transitive" in rawConjugations)
|
||||
? rawConjugations[VS.transitivity === "grammatically transitive" ? "grammaticallyTransitive" : "transitive"]
|
||||
: rawConjugations;
|
||||
const form = getTenseVerbForm(conjugations, VS.tense, VS.tenseCategory, VS.voice);
|
||||
const form = getTenseVerbForm(conjugations, getTenseFromVerbSelection(VS), VS.voice);
|
||||
return <div className="mb-4">
|
||||
<VerbFormDisplay
|
||||
displayForm={form}
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
} from "../np-picker/picker-tools";
|
||||
import * as T from "../../types";
|
||||
import ButtonSelect from "../ButtonSelect";
|
||||
import { isPerfectTense } from "../../lib/phrase-building/vp-tools";
|
||||
import { isModalTense, isPerfectTense, isVerbTense } from "../../lib/type-predicates";
|
||||
|
||||
const verbTenseOptions: { label: string | JSX.Element, value: T.VerbTense }[] = [{
|
||||
label: <div><i className="fas fa-video mr-2" />present</div>,
|
||||
|
@ -34,32 +34,37 @@ const verbTenseOptions: { label: string | JSX.Element, value: T.VerbTense }[] =
|
|||
|
||||
const perfectTenseOptions: { label: string | JSX.Element, value: T.PerfectTense }[] = [{
|
||||
label: "Present Perfect",
|
||||
value: "present perfect",
|
||||
value: "presentPerfect",
|
||||
}, {
|
||||
label: "Habitual Perfect",
|
||||
value: "habitual perfect",
|
||||
value: "habitualPerfect",
|
||||
}, {
|
||||
label: "Subjunctive Perfect",
|
||||
value: "subjunctive perfect",
|
||||
value: "subjunctivePerfect",
|
||||
}, {
|
||||
label: "Future Perfect",
|
||||
value: "future perfect",
|
||||
value: "futurePerfect",
|
||||
}, {
|
||||
label: "Past Perfect",
|
||||
value: "past perfect",
|
||||
value: "pastPerfect",
|
||||
}, {
|
||||
label: `"Would Be" Perfect`,
|
||||
value: "wouldBe perfect",
|
||||
value: "wouldBePerfect",
|
||||
}, {
|
||||
label: "Past Subjunctive Perfect",
|
||||
value: "pastSubjunctive perfect",
|
||||
value: "pastSubjunctivePerfect",
|
||||
}];
|
||||
|
||||
export function getRandomTense(type: "basic" | "modal", o?: T.VerbTense): T.VerbTense;
|
||||
export function getRandomTense(type: "perfect", o?: T.PerfectTense | T.VerbTense): T.PerfectTense;
|
||||
export function getRandomTense(type: "basic" | "modal" | "perfect", o?: T.PerfectTense | T.VerbTense): T.PerfectTense | T.VerbTense {
|
||||
let tns: T.PerfectTense | T.VerbTense;
|
||||
const tenseOptions = type === "perfect" ? perfectTenseOptions : verbTenseOptions;
|
||||
export function getRandomTense(o?: T.PerfectTense | T.VerbTense | T.ModalTense): T.PerfectTense | T.VerbTense | T.ModalTense {
|
||||
let tns: T.PerfectTense | T.VerbTense | T.ModalTense;
|
||||
const oldTenseCategory = !o
|
||||
? undefined
|
||||
: getTenseCategory(o);
|
||||
const tenseOptions = oldTenseCategory === "perfect"
|
||||
? perfectTenseOptions
|
||||
: oldTenseCategory === "modal"
|
||||
? verbTenseOptions.map(x => ({ ...x, value: `${x.value}Modal` as T.ModalTense }))
|
||||
: verbTenseOptions;
|
||||
do {
|
||||
tns = tenseOptions[
|
||||
Math.floor(Math.random()*tenseOptions.length)
|
||||
|
@ -68,40 +73,49 @@ export function getRandomTense(type: "basic" | "modal" | "perfect", o?: T.Perfec
|
|||
return tns;
|
||||
}
|
||||
|
||||
function TensePicker({ onChange, vps, mode }: {
|
||||
function TensePicker(props: ({
|
||||
vps: T.VPSelection,
|
||||
} | {
|
||||
vpsComplete: T.VPSelectionComplete,
|
||||
}) & {
|
||||
onChange: (p: T.VPSelection) => void,
|
||||
mode: "charts" | "phrases" | "quiz",
|
||||
}) {
|
||||
function onTenseSelect(o: { value: T.VerbTense | T.PerfectTense } | null) {
|
||||
if ("vpsComplete" in props) return;
|
||||
const value = o?.value ? o.value : undefined;
|
||||
if (vps.verb && value) {
|
||||
if (props.vps.verb && value) {
|
||||
if (isPerfectTense(value)) {
|
||||
onChange({
|
||||
...vps,
|
||||
props.onChange({
|
||||
...props.vps,
|
||||
verb: {
|
||||
...vps.verb,
|
||||
tense: value,
|
||||
...props.vps.verb,
|
||||
perfectTense: value,
|
||||
tenseCategory: "perfect",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
onChange({
|
||||
...vps,
|
||||
props.onChange({
|
||||
...props.vps,
|
||||
verb: {
|
||||
...vps.verb,
|
||||
tense: value,
|
||||
tenseCategory: vps.verb.tenseCategory === "perfect" ? "basic" : vps.verb.tenseCategory,
|
||||
...props.vps.verb,
|
||||
verbTense: value,
|
||||
tenseCategory: props.vps.verb.tenseCategory === "perfect"
|
||||
? "basic"
|
||||
: props.vps.verb.tenseCategory,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
function moveTense(dir: "forward" | "back") {
|
||||
if (!vps.verb) return;
|
||||
if ("vpsComplete" in props) return;
|
||||
if (!props.vps.verb) return;
|
||||
return () => {
|
||||
const tenses = vps.verb.tenseCategory === "perfect" ? perfectTenseOptions : verbTenseOptions;
|
||||
const currIndex = tenses.findIndex(tn => tn.value === vps.verb.tense)
|
||||
const tenses = props.vps.verb.tenseCategory === "perfect" ? perfectTenseOptions : verbTenseOptions;
|
||||
const currIndex = tenses.findIndex(tn => tn.value === props.vps.verb[
|
||||
props.vps.verb.tenseCategory === "perfect" ? "perfectTense" : "verbTense"
|
||||
]);
|
||||
if (currIndex === -1) {
|
||||
console.error("error moving tense", dir);
|
||||
return;
|
||||
|
@ -114,48 +128,42 @@ function TensePicker({ onChange, vps, mode }: {
|
|||
};
|
||||
}
|
||||
function onPosNegSelect(value: string) {
|
||||
if (vps.verb) {
|
||||
onChange({
|
||||
...vps,
|
||||
if ("vpsComplete" in props) return;
|
||||
if (props.vps.verb) {
|
||||
props.onChange({
|
||||
...props.vps,
|
||||
verb: {
|
||||
...vps.verb,
|
||||
...props.vps.verb,
|
||||
negative: value === "true",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
function onTenseCategorySelect(value: "basic" | "modal" | "perfect") {
|
||||
if (vps.verb) {
|
||||
if (value === "perfect") {
|
||||
onChange({
|
||||
...vps,
|
||||
if ("vpsComplete" in props) return;
|
||||
if (props.vps.verb) {
|
||||
props.onChange({
|
||||
...props.vps,
|
||||
verb: {
|
||||
...vps.verb,
|
||||
...props.vps.verb,
|
||||
tenseCategory: value,
|
||||
tense: isPerfectTense(vps.verb.tense) ? vps.verb.tense : "present perfect",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
onChange({
|
||||
...vps,
|
||||
verb: {
|
||||
...vps.verb,
|
||||
tenseCategory: value,
|
||||
tense: isPerfectTense(vps.verb.tense) ? "presentVerb" : vps.verb.tense,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
const tOptions = (vps.verb?.tenseCategory === "perfect") ? perfectTenseOptions : verbTenseOptions;
|
||||
const tOptions = ("vps" in props && (props.vps.verb?.tenseCategory === "perfect"))
|
||||
? perfectTenseOptions
|
||||
: verbTenseOptions;
|
||||
return <div>
|
||||
<div style={{ maxWidth: "300px", minWidth: "250px", margin: "0 auto" }}>
|
||||
<div className="d-flex flex-row justify-content-between align-items-center">
|
||||
<div className="h5">Tense:</div>
|
||||
{vps.verb && <div className="mb-2">
|
||||
{("vpsComplete" in props || props.vps.verb) && <div className="mb-2">
|
||||
<ButtonSelect
|
||||
small
|
||||
value={vps.verb.tenseCategory}
|
||||
value={"vpsComplete" in props
|
||||
? getTenseCategory(props.vpsComplete.verb.tense)
|
||||
: props.vps.verb.tenseCategory}
|
||||
options={[{
|
||||
label: "Basic",
|
||||
value: "basic",
|
||||
|
@ -166,26 +174,32 @@ function TensePicker({ onChange, vps, mode }: {
|
|||
label: "Modal",
|
||||
value: "modal",
|
||||
}]}
|
||||
handleChange={mode !== "quiz" ? onTenseCategorySelect : () => null}
|
||||
handleChange={props.mode !== "quiz" ? onTenseCategorySelect : () => null}
|
||||
/>
|
||||
</div>}
|
||||
</div>
|
||||
<Select
|
||||
{"vpsComplete" in props
|
||||
? <div style={{ fontSize: "larger" }} className="mb-3">
|
||||
{[...verbTenseOptions, ...perfectTenseOptions].find(o => o.value === props.vpsComplete.verb.tense)?.label}
|
||||
</div>
|
||||
: <Select
|
||||
isSearchable={false}
|
||||
// for some reason can't use tOptions with find here;
|
||||
value={vps.verb && ([...verbTenseOptions, ...perfectTenseOptions].find(o => o.value === vps.verb.tense))}
|
||||
value={props.vps.verb && ([...verbTenseOptions, ...perfectTenseOptions].find(o => o.value === props.vps.verb[
|
||||
props.vps.verb.tenseCategory === "perfect" ? "perfectTense" : "verbTense"
|
||||
]))}
|
||||
onChange={onTenseSelect}
|
||||
className="mb-2"
|
||||
options={tOptions}
|
||||
{...zIndexProps}
|
||||
/>
|
||||
{vps.verb && (mode !== "quiz") && <div className="d-flex flex-row justify-content-between align-items-center mt-3 mb-1" style={{ width: "100%" }}>
|
||||
/>}
|
||||
{"vps" in props && props.vps.verb && (props.mode !== "quiz") && <div className="d-flex flex-row justify-content-between align-items-center mt-3 mb-1" style={{ width: "100%" }}>
|
||||
<div className="btn btn-light clickable" onClick={moveTense("back")}>
|
||||
<i className="fas fa-chevron-left" />
|
||||
</div>
|
||||
{mode === "phrases" && <ButtonSelect
|
||||
{props.mode === "phrases" && <ButtonSelect
|
||||
small
|
||||
value={vps.verb.negative.toString()}
|
||||
value={props.vps.verb.negative.toString()}
|
||||
options={[{
|
||||
label: "Pos.",
|
||||
value: "false",
|
||||
|
@ -204,3 +218,16 @@ function TensePicker({ onChange, vps, mode }: {
|
|||
}
|
||||
|
||||
export default TensePicker;
|
||||
|
||||
function getTenseCategory(tense: T.VerbTense | T.PerfectTense | T.ModalTense): "basic" | "perfect" | "modal" {
|
||||
if (isPerfectTense(tense)) {
|
||||
return "perfect";
|
||||
}
|
||||
if (isVerbTense(tense)) {
|
||||
return "basic";
|
||||
}
|
||||
if (isModalTense(tense)) {
|
||||
return "modal";
|
||||
}
|
||||
throw new Error("can't catagorize tense");
|
||||
}
|
|
@ -2,14 +2,17 @@ import { renderVP, compileVP } from "../../lib/phrase-building/index";
|
|||
import * as T from "../../types";
|
||||
import InlinePs from "../InlinePs";
|
||||
import AbbreviationFormSelector from "./AbbreviationFormSelector";
|
||||
import { isPastTense } from "../../lib/phrase-building/vp-tools";
|
||||
import {
|
||||
isPastTense,
|
||||
completeVPSelection,
|
||||
} from "../../lib/phrase-building/vp-tools";
|
||||
import { useStickyState } from "../../library";
|
||||
import { isVPSelectionComplete } from "../../lib/type-predicates";
|
||||
|
||||
function VPDisplay({ VP, opts }: { VP: T.VPSelection | T.VPSelectionComplete, opts: T.TextOptions }) {
|
||||
function VPDisplay({ VP, opts }: { VP: T.VPSelection, opts: T.TextOptions }) {
|
||||
const [form, setForm] = useStickyState<T.FormVersion>({ removeKing: false, shrinkServant: false }, "abbreviationForm");
|
||||
const [OSV, setOSV] = useStickyState<boolean>(false, "includeOSV");
|
||||
if (!isVPSelectionComplete(VP)) {
|
||||
const VPComplete = completeVPSelection(VP);
|
||||
if (!VPComplete) {
|
||||
return <div className="lead text-muted text-center mt-4">
|
||||
{(() => {
|
||||
const twoNPs = (VP.subject === undefined) && (VP.verb.object === undefined);
|
||||
|
@ -17,7 +20,7 @@ function VPDisplay({ VP, opts }: { VP: T.VPSelection | T.VPSelectionComplete, op
|
|||
})()}
|
||||
</div>;
|
||||
}
|
||||
const result = compileVP(renderVP(VP), { ...form, OSV });
|
||||
const result = compileVP(renderVP(VPComplete), { ...form, OSV });
|
||||
return <div className="text-center mt-2">
|
||||
{VP.verb.transitivity === "transitive" && <div className="form-check mb-2">
|
||||
<input
|
||||
|
@ -32,7 +35,7 @@ function VPDisplay({ VP, opts }: { VP: T.VPSelection | T.VPSelectionComplete, op
|
|||
</label>
|
||||
</div>}
|
||||
<AbbreviationFormSelector
|
||||
adjustable={whatsAdjustable(VP)}
|
||||
adjustable={whatsAdjustable(VPComplete)}
|
||||
form={form}
|
||||
onChange={setForm}
|
||||
/>
|
||||
|
|
|
@ -48,7 +48,7 @@ export function VPExplorer(props: {
|
|||
})) {
|
||||
const [vps, setVps] = useStickyState<T.VPSelection>(
|
||||
savedVps => makeVPSelectionState(props.verb, savedVps),
|
||||
"vpsState1",
|
||||
"vpsState2",
|
||||
);
|
||||
const [mode, setMode] = useStickyState<"charts" | "phrases" | "quiz">(
|
||||
savedMode => {
|
||||
|
@ -59,7 +59,10 @@ export function VPExplorer(props: {
|
|||
"verbExplorerMode",
|
||||
);
|
||||
const [showingExplanation, setShowingExplanation] = useState<{ role: "servant" | "king", item: "subject" | "object" } | false>(false);
|
||||
const roles = getKingAndServant(isPastTense(vps.verb.tense), vps.verb.transitivity !== "intransitive");
|
||||
const roles = getKingAndServant(
|
||||
isPastTense(vps.verb.tenseCategory === "perfect" ? vps.verb.perfectTense : vps.verb.verbTense),
|
||||
vps.verb.transitivity !== "intransitive",
|
||||
);
|
||||
useEffect(() => {
|
||||
setVps(oldVps => {
|
||||
if (mode === "quiz") {
|
||||
|
|
|
@ -9,7 +9,7 @@ import InlinePs from "../InlinePs";
|
|||
import { psStringEquals } from "../../lib/p-text-helpers";
|
||||
import { renderVP, compileVP } from "../../lib/phrase-building/index";
|
||||
import { getRandomTense } from "./TensePicker";
|
||||
import { removeBa, switchSubjObj } from "../../lib/phrase-building/vp-tools";
|
||||
import { getTenseFromVerbSelection, removeBa, switchSubjObj } from "../../lib/phrase-building/vp-tools";
|
||||
import playAudio from "../../lib/play-audio";
|
||||
import TensePicker from "./TensePicker";
|
||||
import Keyframes from "../Keyframes";
|
||||
|
@ -57,7 +57,7 @@ function VPExplorerQuiz(props: {
|
|||
opts: T.TextOptions,
|
||||
vps: T.VPSelection,
|
||||
}) {
|
||||
const startingQs = tickQuizState(props.vps);
|
||||
const startingQs = tickQuizState(completeVPs(props.vps));
|
||||
const [quizState, setQuizState] = useState<QuizState>(startingQs);
|
||||
const [showCheck, setShowCheck] = useState<boolean>(false);
|
||||
const [answerBlank, setAnswerBlank] = useState<string>("");
|
||||
|
@ -115,7 +115,7 @@ function VPExplorerQuiz(props: {
|
|||
</div>}
|
||||
<div className="my-2">
|
||||
<TensePicker
|
||||
vps={quizState.vps}
|
||||
vpsComplete={quizState.vps}
|
||||
onChange={() => null}
|
||||
mode={"quiz"}
|
||||
/>
|
||||
|
@ -278,7 +278,7 @@ function QuizNPDisplay({ children, stage, opts }: {
|
|||
* @param startingWith
|
||||
* @returns
|
||||
*/
|
||||
function tickQuizState(startingWith: T.VPSelection | QuizState): QuizState {
|
||||
function tickQuizState(startingWith: T.VPSelectionComplete | QuizState): QuizState {
|
||||
function makeRes(x: T.VPSelectionComplete) {
|
||||
return compileVP(renderVP(x), { removeKing: false, shrinkServant: false });
|
||||
}
|
||||
|
@ -369,13 +369,54 @@ function getOptionFromResult(r: {
|
|||
return ps[0];
|
||||
}
|
||||
|
||||
function completeVPs(vps: T.VPSelection): T.VPSelectionComplete {
|
||||
const oldSubj = vps.subject?.type === "pronoun"
|
||||
? vps.subject.person
|
||||
: undefined;
|
||||
const oldObj = (typeof vps.verb.object === "object" && vps.verb.object.type === "pronoun")
|
||||
? vps.verb.object.person
|
||||
: undefined;
|
||||
const { subj, obj } = randomSubjObj(
|
||||
oldSubj === undefined
|
||||
? undefined
|
||||
: {
|
||||
subj: oldSubj,
|
||||
obj: oldObj,
|
||||
}
|
||||
);
|
||||
const verb: T.VerbSelectionComplete = {
|
||||
...vps.verb,
|
||||
object: (
|
||||
(typeof vps.verb.object === "object" && !(vps.verb.object.type === "noun" && vps.verb.object.dynamicComplement))
|
||||
||
|
||||
vps.verb.object === undefined
|
||||
)
|
||||
? {
|
||||
type: "pronoun",
|
||||
distance: "far",
|
||||
person: obj,
|
||||
}
|
||||
: vps.verb.object,
|
||||
tense: getTenseFromVerbSelection(vps.verb),
|
||||
};
|
||||
return {
|
||||
...vps,
|
||||
subject: {
|
||||
type: "pronoun",
|
||||
distance: "far",
|
||||
person: subj,
|
||||
},
|
||||
verb,
|
||||
};
|
||||
}
|
||||
|
||||
function getRandomVPSelection(mix: MixType = "both") {
|
||||
// TODO: Type safety to make sure it's safe?
|
||||
return ({ subject, verb }: T.VPSelection): T.VPSelectionComplete => {
|
||||
const oldSubj = (subject?.type === "pronoun")
|
||||
return ({ subject, verb }: T.VPSelectionComplete): T.VPSelectionComplete => {
|
||||
const oldSubj = (subject.type === "pronoun")
|
||||
? subject.person
|
||||
: undefined;
|
||||
const oldObj = (typeof verb?.object === "object" && verb.object.type === "pronoun")
|
||||
const oldObj = (typeof verb.object === "object" && verb.object.type === "pronoun")
|
||||
? verb.object.person
|
||||
: undefined;
|
||||
const { subj, obj } = randomSubjObj(
|
||||
|
@ -401,7 +442,6 @@ function getRandomVPSelection(mix: MixType = "both") {
|
|||
if (mix === "tenses") {
|
||||
return {
|
||||
subject: subject !== undefined ? subject : randSubj,
|
||||
// @ts-ignore
|
||||
verb: randomizeTense(verb, true),
|
||||
}
|
||||
}
|
||||
|
@ -426,9 +466,6 @@ function randomizeTense(verb: T.VerbSelectionComplete, dontRepeatTense: boolean)
|
|||
return {
|
||||
...verb,
|
||||
tense: getRandomTense(
|
||||
// TODO: WHY ISN'T THE OVERLOADING ON THIS
|
||||
// @ts-ignore
|
||||
verb.tenseCategory,
|
||||
dontRepeatTense ? verb.tense : undefined,
|
||||
),
|
||||
};
|
||||
|
|
|
@ -3,7 +3,6 @@ import {
|
|||
} from "../np-picker/picker-tools";
|
||||
import * as T from "../../types";
|
||||
import { getVerbInfo } from "../../lib/verb-info";
|
||||
import { isPerfectTense } from "../../lib/phrase-building/vp-tools";
|
||||
|
||||
export function makeVPSelectionState(
|
||||
verb: T.VerbEntry,
|
||||
|
@ -46,28 +45,15 @@ export function makeVPSelectionState(
|
|||
: "dynamic" in info
|
||||
? { entry: info.dynamic.auxVerb } as T.VerbEntry
|
||||
: undefined;
|
||||
const tenseSelection = ((): { tenseCategory: "perfect", tense: T.PerfectTense } | {
|
||||
tenseCategory: "basic" | "modal",
|
||||
tense: T.VerbTense,
|
||||
} => {
|
||||
if (!os) {
|
||||
return { tense: "presentVerb", tenseCategory: "basic" };
|
||||
}
|
||||
if (os.verb.tenseCategory === "modal") {
|
||||
return { tenseCategory: "modal", tense: isPerfectTense(os.verb.tense) ? "presentVerb" : os.verb.tense };
|
||||
}
|
||||
if (os.verb.tenseCategory === "basic") {
|
||||
return { tenseCategory: "basic", tense: isPerfectTense(os.verb.tense) ? "presentVerb" : os.verb.tense };
|
||||
}
|
||||
return { tenseCategory: "perfect", tense: isPerfectTense(os.verb.tense) ? os.verb.tense : "present perfect" };
|
||||
})();
|
||||
return {
|
||||
subject,
|
||||
verb: {
|
||||
type: "verb",
|
||||
verb: verb,
|
||||
dynAuxVerb,
|
||||
...tenseSelection,
|
||||
verbTense: os ? os.verb.verbTense : "presentVerb",
|
||||
perfectTense: os ? os.verb.perfectTense : "presentPerfect",
|
||||
tenseCategory: os ? os.verb.tenseCategory : "basic",
|
||||
object,
|
||||
transitivity,
|
||||
isCompound,
|
||||
|
|
|
@ -674,6 +674,22 @@ const nouns: Array<{
|
|||
}
|
||||
}
|
||||
},
|
||||
// TODO: uncomment this
|
||||
// {
|
||||
// in: {"ts":1527812591,"i":6286,"p":"دواړه","f":"dwáaRu","g":"dwaaRu","e":"both","c":"n. m. pl. unisex / adj."},
|
||||
// out: {
|
||||
// plural: {
|
||||
// masc: [
|
||||
// [{ p: "دواړه", f: "dwáaRu" }],
|
||||
// [{ p: "دواړو", f: "dwáaRo" }],
|
||||
// ],
|
||||
// fem: [
|
||||
// [{ p: "دواړې", f: "dwáaRe" }],
|
||||
// [{ p: "دواړو", f: "dwáaRo" }],
|
||||
// ],
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// Masculine non-inflecting
|
||||
{
|
||||
in: {
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
removeBa,
|
||||
removeDuplicates,
|
||||
} from "./vp-tools";
|
||||
import { isModalTense, isPerfectTense } from "../type-predicates";
|
||||
|
||||
type Form = T.FormVersion & { OSV?: boolean };
|
||||
export function compileVP(VP: T.VPRendered, form: Form): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] };
|
||||
|
@ -129,7 +130,7 @@ function putKidsInKidsSection(segments: Segment[], kids: Segment[]): Segment[] {
|
|||
}
|
||||
|
||||
function arrangeVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[], V: T.VerbRendered): Segment[][] {
|
||||
const hasLeapfrog = V.tenseCategory === "modal" || V.tenseCategory === "perfect";
|
||||
const hasLeapfrog = isPerfectTense(V.tense) || isModalTense(V.tense);
|
||||
const rest = (() => {
|
||||
if (hasLeapfrog) {
|
||||
const [restF, restLast] = splitOffLeapfrogWord(restRaw);
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
import * as T from "../../types";
|
||||
import { getVerbBlockPosFromPerson, parseEc } from "../misc-helpers";
|
||||
import * as grammarUnits from "../grammar-units";
|
||||
import {
|
||||
isPerfectTense,
|
||||
isVerbTense,
|
||||
// isModalTense,
|
||||
} from "../type-predicates";
|
||||
|
||||
function engHave(s: T.Person): string {
|
||||
function isThirdPersonSing(p: T.Person): boolean {
|
||||
|
@ -15,7 +20,7 @@ function engHave(s: T.Person): string {
|
|||
export function renderEnglishVPBase({ subjectPerson, object, vs }: {
|
||||
subjectPerson: T.Person,
|
||||
object: T.NPSelection | T.ObjectNP,
|
||||
vs: T.VerbSelection,
|
||||
vs: T.VerbSelectionComplete,
|
||||
}): string[] {
|
||||
const ec = parseEc(vs.verb.entry.ec || "");
|
||||
const ep = vs.verb.entry.ep;
|
||||
|
@ -79,34 +84,34 @@ export function renderEnglishVPBase({ subjectPerson, object, vs }: {
|
|||
]),
|
||||
};
|
||||
const modalBuilders: Record<
|
||||
T.VerbTense,
|
||||
T.ModalTense,
|
||||
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
||||
> = {
|
||||
presentVerb: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
presentVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ can${n ? "'t" : ""} ${isToBe(v) ? "be" : v[0]}`,
|
||||
]),
|
||||
subjunctiveVerb: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
subjunctiveVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`that $SUBJ can${n ? "'t" : ""} ${isToBe(v) ? "be" : v[0]}`,
|
||||
]),
|
||||
imperfectiveFuture: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
imperfectiveFutureModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ will${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
|
||||
]),
|
||||
perfectiveFuture: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
perfectiveFutureModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ will${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
|
||||
]),
|
||||
imperfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
imperfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ ${engEquative("past", s)} ${n ? " not" : ""} able to ${isToBe(v) ? "be" : v[0]}`,
|
||||
`$SUBJ could${n ? " not" : ""} ${v[0]}`,
|
||||
]),
|
||||
perfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
perfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ ${engEquative("past", s)} ${n ? " not" : ""} able to ${isToBe(v) ? "be" : v[0]}`,
|
||||
`$SUBJ could${n ? " not" : ""} ${isToBe(v) ? "be" : v[0]}`,
|
||||
]),
|
||||
habitualImperfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
habitualImperfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ used to ${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
|
||||
`$SUBJ would ${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
|
||||
]),
|
||||
habitualPerfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
habitualPerfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ used to ${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
|
||||
`$SUBJ would ${n ? " not" : ""} be able to ${isToBe(v) ? "be" : v[0]}`,
|
||||
]),
|
||||
|
@ -115,25 +120,25 @@ export function renderEnglishVPBase({ subjectPerson, object, vs }: {
|
|||
T.PerfectTense,
|
||||
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
||||
> = {
|
||||
"present perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
presentPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ ${engHave(s)}${n ? " not" : ""} ${v[4]}`,
|
||||
]),
|
||||
"past perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
pastPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ had${n ? " not" : ""} ${v[4]}`,
|
||||
]),
|
||||
"habitual perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
habitualPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ ${engHave(s)}${n ? " not" : ""} ${v[4]}`,
|
||||
]),
|
||||
"subjunctive perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
subjunctivePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`that $SUBJ will have${n ? " not" : ""} ${v[4]}`,
|
||||
]),
|
||||
"future perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
futurePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ will${n ? " not" : ""} have ${v[4]}`,
|
||||
]),
|
||||
"wouldBe perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
wouldBePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ would${n ? " not" : ""} have ${v[4]}`,
|
||||
]),
|
||||
"pastSubjunctive perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
pastSubjunctivePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ would${n ? " not" : ""} have ${v[4]}`,
|
||||
`$SUBJ should${n ? " not" : ""} have ${v[4]}`,
|
||||
]),
|
||||
|
@ -173,64 +178,64 @@ export function renderEnglishVPBase({ subjectPerson, object, vs }: {
|
|||
T.PerfectTense,
|
||||
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
||||
> = {
|
||||
"present perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
presentPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ ${engHave(s)}${n ? " not" : ""} been ${v[4]}`,
|
||||
]),
|
||||
"past perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
pastPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ had${n ? " not" : ""} been ${v[4]}`,
|
||||
]),
|
||||
"habitual perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
habitualPerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ ${engHave(s)}${n ? " not" : ""} been ${v[4]}`,
|
||||
]),
|
||||
"subjunctive perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
subjunctivePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`that $SUBJ will${n ? " not" : ""} have been ${v[4]}`,
|
||||
]),
|
||||
"future perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
futurePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ will${n ? " not" : ""} have been ${v[4]}`,
|
||||
]),
|
||||
"wouldBe perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
wouldBePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ will${n ? " not" : ""} have been ${v[4]}`,
|
||||
]),
|
||||
"pastSubjunctive perfect": (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
pastSubjunctivePerfect: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ would${n ? " not" : ""} have been ${v[4]}`,
|
||||
]),
|
||||
}
|
||||
const passiveModalBuilders: Record<
|
||||
T.VerbTense,
|
||||
T.ModalTense,
|
||||
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
||||
> = {
|
||||
presentVerb: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
presentVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ can${n ? " not" : ""} be ${v[4]}`,
|
||||
`$SUBJ ${engEquative("present", s)}${n ? " not" : ""} able to be ${v[4]}`,
|
||||
]),
|
||||
subjunctiveVerb: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
subjunctiveVerbModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`that $SUBJ will${n ? " not" : ""} be able to be ${v[4]}`,
|
||||
`that $SUBJ ${n ? " not" : ""} be able to be ${v[4]}`,
|
||||
]),
|
||||
imperfectiveFuture: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
imperfectiveFutureModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ will${n ? " not" : ""} be able to be ${v[4]}`,
|
||||
]),
|
||||
perfectiveFuture: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
perfectiveFutureModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ will${n ? " not" : ""} be able to be ${v[4]}`,
|
||||
]),
|
||||
imperfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
imperfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ would${n ? " not" : ""} be able to be ${v[4]}`,
|
||||
`$SUBJ ${engEquative("past", s)}${n ? " not" : ""} being able to be ${v[4]}`,
|
||||
]),
|
||||
perfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
perfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ ${engEquative("past", s)}${n ? " not" : ""} able to be ${v[4]}`,
|
||||
]),
|
||||
habitualPerfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
habitualPerfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ would${n ? " not" : ""} be able to be ${v[4]}`,
|
||||
]),
|
||||
habitualImperfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
habitualImperfectivePastModal: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||
`$SUBJ would${n ? " not" : ""} be able to be ${v[4]}`,
|
||||
]),
|
||||
};
|
||||
const base = (
|
||||
(vs.tenseCategory === "perfect")
|
||||
isPerfectTense(vs.tense)
|
||||
? (vs.voice === "active" ? perfectBuilders : passivePerfectBuilders)[vs.tense]
|
||||
: vs.tenseCategory === "basic"
|
||||
: isVerbTense(vs.tense)
|
||||
? (vs.voice === "active" ? basicBuilders : passiveBasicBuilders)[vs.tense]
|
||||
: (vs.voice === "active" ? modalBuilders : passiveModalBuilders)[vs.tense])(subjectPerson, ec, vs.negative);
|
||||
return base.map(b => `${b}${typeof object === "object" ? " $OBJ" : ""}${ep ? ` ${ep}` : ""}`);
|
||||
|
|
|
@ -19,10 +19,12 @@ import {
|
|||
getPersonFromNP,
|
||||
removeBa,
|
||||
isPastTense,
|
||||
isPerfectTense,
|
||||
getTenseVerbForm,
|
||||
} from "./vp-tools";
|
||||
import { isPattern4Entry } from "../type-predicates";
|
||||
import {
|
||||
isPattern4Entry,
|
||||
isPerfectTense,
|
||||
} from "../type-predicates";
|
||||
import { renderEnglishVPBase } from "./english-vp-rendering";
|
||||
|
||||
// TODO: ISSUE GETTING SPLIT HEAD NOT MATCHING WITH FUTURE VERBS
|
||||
|
@ -129,7 +131,7 @@ function renderParticipleSelection(p: T.ParticipleSelection, inflected: boolean)
|
|||
};
|
||||
}
|
||||
|
||||
function renderVerbSelection(vs: T.VerbSelection, person: T.Person, objectPerson: T.Person | undefined): T.VerbRendered {
|
||||
function renderVerbSelection(vs: T.VerbSelectionComplete, person: T.Person, objectPerson: T.Person | undefined): T.VerbRendered {
|
||||
const v = vs.dynAuxVerb || vs.verb;
|
||||
const conjugations = conjugateVerb(v.entry, v.complement);
|
||||
// TODO: error handle this?
|
||||
|
@ -148,14 +150,14 @@ function renderVerbSelection(vs: T.VerbSelection, person: T.Person, objectPerson
|
|||
}
|
||||
}
|
||||
|
||||
function getPsVerbConjugation(conj: T.VerbConjugation, vs: T.VerbSelection, person: T.Person, objectPerson: T.Person | undefined): {
|
||||
function getPsVerbConjugation(conj: T.VerbConjugation, vs: T.VerbSelectionComplete, person: T.Person, objectPerson: T.Person | undefined): {
|
||||
ps: {
|
||||
head: T.PsString | undefined,
|
||||
rest: T.SingleOrLengthOpts<T.PsString[]>,
|
||||
},
|
||||
hasBa: boolean,
|
||||
} {
|
||||
const f = getTenseVerbForm(conj, vs.tense, vs.tenseCategory, vs.voice);
|
||||
const f = getTenseVerbForm(conj, vs.tense, vs.voice);
|
||||
const block = getMatrixBlock(f, objectPerson, person);
|
||||
const perfective = isPerfective(vs.tense);
|
||||
const verbForm = getVerbFromBlock(block, person);
|
||||
|
@ -324,7 +326,7 @@ function isFirstOrSecondPersPronoun(o: "none" | T.NPSelection | T.Person.ThirdPl
|
|||
return [0,1,2,3,6,7,8,9].includes(o.person);
|
||||
}
|
||||
|
||||
function isPerfective(t: T.VerbTense | T.PerfectTense): boolean {
|
||||
function isPerfective(t: T.VerbTense | T.PerfectTense | T.ModalTense): boolean {
|
||||
if (isPerfectTense(t)) return false;
|
||||
if (t === "presentVerb" || t === "imperfectiveFuture" || t === "imperfectivePast" || t === "habitualImperfectivePast") {
|
||||
return false;
|
||||
|
@ -332,6 +334,9 @@ function isPerfective(t: T.VerbTense | T.PerfectTense): boolean {
|
|||
if (t === "perfectiveFuture" || t === "subjunctiveVerb" || t === "perfectivePast" || t === "habitualPerfectivePast") {
|
||||
return true;
|
||||
}
|
||||
if (t === "perfectiveFutureModal" || t === "subjunctiveVerbModal" || t === "perfectivePastModal" || t === "habitualPerfectivePastModal") {
|
||||
return true;
|
||||
}
|
||||
throw new Error("tense not implemented yet");
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
psRemove,
|
||||
psStringEquals,
|
||||
} from "../../lib/p-text-helpers";
|
||||
import { isPerfectTense } from "../type-predicates";
|
||||
import * as grammarUnits from "../../lib/grammar-units";
|
||||
|
||||
export function isInvalidSubjObjCombo(subj: T.Person, obj: T.Person): boolean {
|
||||
|
@ -26,9 +27,8 @@ export function isInvalidSubjObjCombo(subj: T.Person, obj: T.Person): boolean {
|
|||
);
|
||||
}
|
||||
|
||||
export function getTenseVerbForm(conjR: T.VerbConjugation, tense: T.VerbTense | T.PerfectTense, tenseCategory: "basic" | "modal" | "perfect", voice: "active" | "passive"): T.VerbForm {
|
||||
export function getTenseVerbForm(conjR: T.VerbConjugation, tense: T.VerbTense | T.PerfectTense | T.ModalTense, voice: "active" | "passive"): T.VerbForm {
|
||||
const conj = (voice === "passive" && conjR.passive) ? conjR.passive : conjR;
|
||||
if (tenseCategory === "basic") {
|
||||
if (tense === "presentVerb") {
|
||||
return conj.imperfective.nonImperative;
|
||||
}
|
||||
|
@ -53,52 +53,49 @@ export function getTenseVerbForm(conjR: T.VerbConjugation, tense: T.VerbTense |
|
|||
if (tense === "habitualPerfectivePast") {
|
||||
return conj.perfective.habitualPast;
|
||||
}
|
||||
}
|
||||
if (tenseCategory === "modal") {
|
||||
if (tense === "presentVerb") {
|
||||
if (tense === "presentVerbModal") {
|
||||
return conj.imperfective.modal.nonImperative;
|
||||
}
|
||||
if (tense === "subjunctiveVerb") {
|
||||
if (tense === "subjunctiveVerbModal") {
|
||||
return conj.perfective.modal.nonImperative;
|
||||
}
|
||||
if (tense === "imperfectiveFuture") {
|
||||
if (tense === "imperfectiveFutureModal") {
|
||||
return conj.imperfective.modal.future;
|
||||
}
|
||||
if (tense === "perfectiveFuture") {
|
||||
if (tense === "perfectiveFutureModal") {
|
||||
return conj.perfective.modal.future;
|
||||
}
|
||||
if (tense === "imperfectivePast") {
|
||||
if (tense === "imperfectivePastModal") {
|
||||
return conj.imperfective.modal.past;
|
||||
}
|
||||
if (tense === "perfectivePast") {
|
||||
if (tense === "perfectivePastModal") {
|
||||
return conj.perfective.modal.past;
|
||||
}
|
||||
if (tense === "habitualImperfectivePast") {
|
||||
if (tense === "habitualImperfectivePastModal") {
|
||||
return conj.imperfective.modal.habitualPast;
|
||||
}
|
||||
if (tense === "habitualPerfectivePast") {
|
||||
if (tense === "habitualPerfectivePastModal") {
|
||||
return conj.perfective.modal.habitualPast;
|
||||
}
|
||||
}
|
||||
if (tense === "present perfect") {
|
||||
if (tense === "presentPerfect") {
|
||||
return conj.perfect.present;
|
||||
}
|
||||
if (tense === "past perfect") {
|
||||
if (tense === "pastPerfect") {
|
||||
return conj.perfect.past;
|
||||
}
|
||||
if (tense === "future perfect") {
|
||||
if (tense === "futurePerfect") {
|
||||
return conj.perfect.future;
|
||||
}
|
||||
if (tense === "habitual perfect") {
|
||||
if (tense === "habitualPerfect") {
|
||||
return conj.perfect.habitual;
|
||||
}
|
||||
if (tense === "subjunctive perfect") {
|
||||
if (tense === "subjunctivePerfect") {
|
||||
return conj.perfect.subjunctive;
|
||||
}
|
||||
if (tense === "wouldBe perfect") {
|
||||
if (tense === "wouldBePerfect") {
|
||||
return conj.perfect.affirmational;
|
||||
}
|
||||
if (tense === "pastSubjunctive perfect") {
|
||||
if (tense === "pastSubjunctivePerfect") {
|
||||
return conj.perfect.pastSubjunctiveHypothetical;
|
||||
}
|
||||
throw new Error("unknown tense");
|
||||
|
@ -126,23 +123,45 @@ export function removeBa(ps: T.PsString): T.PsString {
|
|||
return psRemove(ps, concatPsString(grammarUnits.baParticle, " "));
|
||||
}
|
||||
|
||||
export function isEquativeTense(t: T.VerbTense | T.EquativeTense | T.PerfectTense): t is T.EquativeTense {
|
||||
return (t === "present" || t === "future" || t === "habitual" || t === "past" || t === "wouldBe" || t === "subjunctive" || t === "pastSubjunctive");
|
||||
export function getTenseFromVerbSelection(vs: T.VerbSelection): T.VerbTense | T.PerfectTense | T.ModalTense {
|
||||
function verbTenseToModalTense(tn: T.VerbTense): T.ModalTense {
|
||||
if (tn === "presentVerb") {
|
||||
return "presentVerbModal";
|
||||
}
|
||||
if (tn === "subjunctiveVerb") {
|
||||
return "subjunctiveVerbModal";
|
||||
}
|
||||
if (tn === "imperfectiveFuture") {
|
||||
return "imperfectiveFutureModal";
|
||||
}
|
||||
if (tn === "perfectiveFuture") {
|
||||
return "perfectiveFutureModal";
|
||||
}
|
||||
if (tn === "perfectivePast") {
|
||||
return "perfectiveFutureModal";
|
||||
}
|
||||
if (tn === "imperfectivePast") {
|
||||
return "imperfectivePastModal";
|
||||
}
|
||||
if (tn === "habitualImperfectivePast") {
|
||||
return "habitualImperfectivePastModal";
|
||||
}
|
||||
if (tn === "habitualPerfectivePast") {
|
||||
return "habitualPerfectivePastModal";
|
||||
}
|
||||
throw new Error("can't convert non verbTense to modalTense");
|
||||
}
|
||||
if (vs.tenseCategory === "basic") {
|
||||
return vs.verbTense;
|
||||
}
|
||||
if (vs.tenseCategory === "perfect") {
|
||||
return vs.perfectTense;
|
||||
}
|
||||
// vs.tenseCategory === "modal"
|
||||
return verbTenseToModalTense(vs.verbTense);
|
||||
}
|
||||
|
||||
export function isPerfectTense(t: T.VerbTense | T.EquativeTense | T.PerfectTense): t is T.PerfectTense {
|
||||
return (
|
||||
t === "present perfect" ||
|
||||
t === "habitual perfect" ||
|
||||
t === "future perfect" ||
|
||||
t === "past perfect" ||
|
||||
t === "wouldBe perfect" ||
|
||||
t === "subjunctive perfect" ||
|
||||
t === "pastSubjunctive perfect"
|
||||
);
|
||||
}
|
||||
|
||||
export function isPastTense(tense: T.VerbTense | T.PerfectTense): boolean {
|
||||
export function isPastTense(tense: T.VerbTense | T.PerfectTense | T.ModalTense): boolean {
|
||||
if (isPerfectTense(tense)) return true;
|
||||
return tense.toLowerCase().includes("past");
|
||||
}
|
||||
|
@ -155,15 +174,52 @@ export function removeDuplicates(psv: T.PsString[]): T.PsString[] {
|
|||
));
|
||||
}
|
||||
|
||||
export function switchSubjObj({ subject, verb }: T.VPSelection): T.VPSelection {
|
||||
if (!subject|| !verb || !verb.object || !(typeof verb.object === "object")) {
|
||||
return { subject, verb };
|
||||
export function switchSubjObj(vps: T.VPSelection): T.VPSelection;
|
||||
export function switchSubjObj(vps: T.VPSelectionComplete): T.VPSelectionComplete;
|
||||
export function switchSubjObj(vps: T.VPSelection | T.VPSelectionComplete): T.VPSelection | T.VPSelectionComplete {
|
||||
if ("tenseCategory" in vps.verb) {
|
||||
if (!vps.subject || !(typeof vps.verb.object === "object")) {
|
||||
return vps;
|
||||
}
|
||||
return {
|
||||
subject: verb.object,
|
||||
...vps,
|
||||
subject: vps.verb.object,
|
||||
verb: {
|
||||
...verb,
|
||||
object: subject,
|
||||
...vps.verb,
|
||||
object: vps.subject,
|
||||
},
|
||||
};
|
||||
}
|
||||
if (!vps.subject|| !vps.verb || !(typeof vps.verb.object === "object")) {
|
||||
return vps;
|
||||
}
|
||||
return {
|
||||
...vps,
|
||||
subject: vps.verb.object,
|
||||
verb: {
|
||||
...vps.verb,
|
||||
object: vps.subject,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function completeVPSelection(vps: T.VPSelection): T.VPSelectionComplete | undefined {
|
||||
if (vps.subject === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
if (vps.verb.object === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
// necessary for this version on typscript ...
|
||||
const verb: T.VerbSelectionComplete = {
|
||||
...vps.verb,
|
||||
object: vps.verb.object,
|
||||
tense: getTenseFromVerbSelection(vps.verb),
|
||||
};
|
||||
const subject = vps.subject;
|
||||
return {
|
||||
...vps,
|
||||
subject,
|
||||
verb,
|
||||
};
|
||||
}
|
|
@ -160,9 +160,30 @@ export function isArrayOneOrMore<U>(a: U[]): a is T.ArrayOneOrMore<U> {
|
|||
return a.length > 0;
|
||||
}
|
||||
|
||||
export function isVPSelectionComplete(vps: T.VPSelection | T.VPSelectionComplete): vps is T.VPSelectionComplete {
|
||||
if ((vps.subject !== undefined) && (vps.verb.object !== undefined)) {
|
||||
return true;
|
||||
export function isPerfectTense(tense: T.VerbTense | T.EquativeTense | T.ModalTense | T.PerfectTense): tense is T.PerfectTense {
|
||||
return tense.endsWith("Perfect");
|
||||
}
|
||||
return false;
|
||||
|
||||
export function isVerbTense(tense: T.VerbTense | T.EquativeTense | T.ModalTense | T.PerfectTense): tense is T.VerbTense {
|
||||
const verbTenses: T.VerbTense[] = [
|
||||
"presentVerb",
|
||||
"subjunctiveVerb",
|
||||
"perfectiveFuture",
|
||||
"imperfectiveFuture",
|
||||
"perfectivePast",
|
||||
"imperfectivePast",
|
||||
"habitualPerfectivePast",
|
||||
"habitualImperfectivePast",
|
||||
];
|
||||
return verbTenses.some(x => x === tense);
|
||||
}
|
||||
|
||||
export function isModalTense(tense: T.VerbTense | T.EquativeTense | T.ModalTense | T.PerfectTense): tense is T.ModalTense {
|
||||
return tense.endsWith("Modal");
|
||||
}
|
||||
|
||||
export function isEquativeTense(t: T.VerbTense | T.EquativeTense | T.PerfectTense | T.ModalTense): t is T.EquativeTense {
|
||||
return (t === "present" || t === "future" || t === "habitual" || t === "past" || t === "wouldBe" || t === "subjunctive" || t === "pastSubjunctive");
|
||||
}
|
||||
|
||||
|
||||
|
|
21
src/types.ts
21
src/types.ts
|
@ -535,7 +535,8 @@ export type VerbTense = "presentVerb"
|
|||
export type EquativeTense = "present" | "subjunctive" | "habitual" | "past" | "future" | "wouldBe" | "pastSubjunctive";
|
||||
export type NounNumber = "singular" | "plural";
|
||||
|
||||
export type PerfectTense = `${EquativeTense} perfect`;
|
||||
export type PerfectTense = `${EquativeTense}Perfect`;
|
||||
export type ModalTense = `${VerbTense}Modal`;
|
||||
|
||||
export type VPSelection = {
|
||||
subject: NPSelection | undefined,
|
||||
|
@ -547,9 +548,10 @@ export type VPSelectionComplete = {
|
|||
verb: VerbSelectionComplete,
|
||||
};
|
||||
|
||||
export type VerbSelectionComplete = Exclude<VerbSelection, "object"> & {
|
||||
export type VerbSelectionComplete = Omit<VerbSelection, "object" | "verbTense" | "perfectTense" | "tenseCategory"> & {
|
||||
object: Exclude<VerbObject, undefined>,
|
||||
};
|
||||
tense: VerbTense | PerfectTense | ModalTense,
|
||||
}
|
||||
|
||||
export type VerbSelection = {
|
||||
type: "verb",
|
||||
|
@ -565,15 +567,12 @@ export type VerbSelection = {
|
|||
// TODO: changeStativeDynamic
|
||||
// TODO: add in aspect element here??
|
||||
negative: boolean,
|
||||
} & ({
|
||||
tense: VerbTense,
|
||||
tenseCategory: "basic" | "modal",
|
||||
} | {
|
||||
tense: PerfectTense,
|
||||
tenseCategory: "perfect"
|
||||
});
|
||||
verbTense: VerbTense,
|
||||
perfectTense: PerfectTense,
|
||||
tenseCategory: "basic" | "modal" | "perfect",
|
||||
};
|
||||
|
||||
export type VerbRendered = Omit<VerbSelection, "object"> & {
|
||||
export type VerbRendered = Omit<VerbSelectionComplete, "object"> & {
|
||||
ps: {
|
||||
head: PsString | undefined,
|
||||
rest: SingleOrLengthOpts<
|
||||
|
|
Loading…
Reference in New Issue