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