added event emitter for VPExplorer for monitoring events
This commit is contained in:
parent
b5e33b1db9
commit
23f3dcd2c5
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "pashto-inflector",
|
||||
"version": "7.0.9",
|
||||
"version": "7.0.11",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "pashto-inflector",
|
||||
"version": "7.0.9",
|
||||
"version": "7.0.11",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "pashto-inflector",
|
||||
"version": "7.0.9",
|
||||
"version": "7.0.11",
|
||||
"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,12 +1,12 @@
|
|||
{
|
||||
"name": "@lingdocs/ps-react",
|
||||
"version": "7.0.9",
|
||||
"version": "7.0.11",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@lingdocs/ps-react",
|
||||
"version": "7.0.9",
|
||||
"version": "7.0.11",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@formkit/auto-animate": "^1.0.0-beta.3",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@lingdocs/ps-react",
|
||||
"version": "7.0.9",
|
||||
"version": "7.0.11",
|
||||
"description": "Pashto inflector library module with React components",
|
||||
"main": "dist/components/library.js",
|
||||
"module": "dist/components/library.js",
|
||||
|
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 71 KiB |
|
@ -10,7 +10,10 @@ import { completeVPSelection } from "../../../lib/src/phrase-building/vp-tools";
|
|||
import VPExplorerQuiz from "./VPExplorerQuiz";
|
||||
// @ts-ignore
|
||||
import LZString from "lz-string";
|
||||
import { vpsReducer } from "../../../lib/src/phrase-building/vps-reducer";
|
||||
import {
|
||||
VpsReducerAction,
|
||||
vpsReducer,
|
||||
} from "../../../lib/src/phrase-building/vps-reducer";
|
||||
import { getObjectSelection } from "../../../lib/src/phrase-building/blocks-utils";
|
||||
import VPPicker from "./VPPicker";
|
||||
import AllTensesDisplay from "./AllTensesDisplay";
|
||||
|
@ -34,6 +37,7 @@ function VPExplorer(props: {
|
|||
handleLinkClick: ((ts: number) => void) | "none";
|
||||
entryFeeder: T.EntryFeeder;
|
||||
onlyPhrases?: boolean;
|
||||
eventEmitter?: (e: string) => void;
|
||||
}) {
|
||||
const [vps, adjustVps] = useStickyReducer(
|
||||
vpsReducer,
|
||||
|
@ -85,7 +89,7 @@ function VPExplorer(props: {
|
|||
const VPSFromUrl = getVPSFromUrl();
|
||||
if (VPSFromUrl) {
|
||||
setMode("phrases");
|
||||
adjustVps({
|
||||
eventWrapper(adjustVps)({
|
||||
type: "load vps",
|
||||
payload: VPSFromUrl,
|
||||
});
|
||||
|
@ -93,7 +97,15 @@ function VPExplorer(props: {
|
|||
// eslint-disable-next-line
|
||||
}, []);
|
||||
function handleSubjObjSwap() {
|
||||
adjustVps({ type: "swap subj/obj" });
|
||||
eventWrapper(adjustVps)({ type: "swap subj/obj" });
|
||||
}
|
||||
function eventWrapper(f: (a: VpsReducerAction) => void) {
|
||||
return function (action: VpsReducerAction) {
|
||||
if (props.eventEmitter) {
|
||||
props.eventEmitter(`VP exlorer ${props.verb.entry.p}`);
|
||||
}
|
||||
return f(action);
|
||||
};
|
||||
}
|
||||
function quizLock<T>(f: T) {
|
||||
if (mode === "quiz") {
|
||||
|
@ -105,7 +117,7 @@ function VPExplorer(props: {
|
|||
return f;
|
||||
}
|
||||
function handleSetForm(form: T.FormVersion) {
|
||||
adjustVps({
|
||||
eventWrapper(adjustVps)({
|
||||
type: "set form",
|
||||
payload: form,
|
||||
});
|
||||
|
@ -134,7 +146,7 @@ function VPExplorer(props: {
|
|||
<div className="mt-3" style={{ maxWidth: "950px" }}>
|
||||
<VerbPicker
|
||||
vps={vps}
|
||||
onChange={quizLock(adjustVps)}
|
||||
onChange={quizLock(eventWrapper(adjustVps))}
|
||||
opts={props.opts}
|
||||
handleLinkClick={props.handleLinkClick}
|
||||
/>
|
||||
|
@ -190,13 +202,19 @@ function VPExplorer(props: {
|
|||
<VPPicker
|
||||
opts={props.opts}
|
||||
entryFeeder={props.entryFeeder}
|
||||
onChange={(payload) => adjustVps({ type: "load vps", payload })}
|
||||
onChange={(payload) =>
|
||||
eventWrapper(adjustVps)({ type: "load vps", payload })
|
||||
}
|
||||
vps={vps}
|
||||
/>
|
||||
)}
|
||||
{mode !== "phrases" && (
|
||||
<div className="my-2">
|
||||
<TensePicker vps={vps} onChange={adjustVps} mode={mode} />
|
||||
<TensePicker
|
||||
vps={vps}
|
||||
onChange={eventWrapper(adjustVps)}
|
||||
mode={mode}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{mode === "phrases" && (
|
||||
|
@ -207,7 +225,7 @@ function VPExplorer(props: {
|
|||
object={object}
|
||||
VS={vps.verb}
|
||||
opts={props.opts}
|
||||
onChange={adjustVps}
|
||||
onChange={eventWrapper(adjustVps)}
|
||||
/>
|
||||
)}
|
||||
{mode === "quiz" && <VPExplorerQuiz opts={props.opts} vps={vps} />}
|
||||
|
|
|
@ -5,12 +5,8 @@ import Phonetics from "../components/src/Phonetics";
|
|||
import { getVerbInfo } from "../lib/src/verb-info";
|
||||
import verbs from "../verbs";
|
||||
import { useStickyState } from "../components/library";
|
||||
import {
|
||||
clamp
|
||||
} from "../lib/src/p-text-helpers";
|
||||
import {
|
||||
randomNumber,
|
||||
} from "../lib/src/misc-helpers";
|
||||
import { clamp } from "../lib/src/p-text-helpers";
|
||||
import { randomNumber } from "../lib/src/misc-helpers";
|
||||
import { entryFeeder } from "./entryFeeder";
|
||||
|
||||
const transitivities: T.Transitivity[] = [
|
||||
|
@ -19,10 +15,12 @@ const transitivities: T.Transitivity[] = [
|
|||
"grammatically transitive",
|
||||
];
|
||||
|
||||
const allVerbs = verbs.map((v: { entry: T.DictionaryEntry, complement?: T.DictionaryEntry }) => ({
|
||||
const allVerbs = verbs.map(
|
||||
(v: { entry: T.DictionaryEntry; complement?: T.DictionaryEntry }) => ({
|
||||
verb: v,
|
||||
info: getVerbInfo(v.entry, v.complement),
|
||||
}));
|
||||
})
|
||||
);
|
||||
|
||||
type VerbType = "simple" | "stative compound" | "dynamic compound";
|
||||
const verbTypes: VerbType[] = [
|
||||
|
@ -31,12 +29,14 @@ const verbTypes: VerbType[] = [
|
|||
"dynamic compound",
|
||||
];
|
||||
|
||||
function VPBuilderDemo({ opts }: {
|
||||
opts: T.TextOptions,
|
||||
}) {
|
||||
function VPBuilderDemo({ opts }: { opts: T.TextOptions }) {
|
||||
const [verbTs, setVerbTs] = useStickyState<number>(0, "verbTs1");
|
||||
const [verbTypeShowing, setVerbTypeShowing] = useStickyState<VerbType>("simple", "vTypeShowing");
|
||||
const [transitivityShowing, setTransitivityShowing] = useStickyState<T.Transitivity>("intransitive", "transitivityShowing1");
|
||||
const [verbTypeShowing, setVerbTypeShowing] = useStickyState<VerbType>(
|
||||
"simple",
|
||||
"vTypeShowing"
|
||||
);
|
||||
const [transitivityShowing, setTransitivityShowing] =
|
||||
useStickyState<T.Transitivity>("intransitive", "transitivityShowing1");
|
||||
// const onlyGrammTrans = (arr: Transitivity[]) => (
|
||||
// arr.length === 1 && arr[0] === "grammatically transitive"
|
||||
// );
|
||||
|
@ -47,46 +47,56 @@ function VPBuilderDemo({ opts }: {
|
|||
// }
|
||||
const handleVerbIndexChange = (e: any) => {
|
||||
setVerbTs(parseInt(e.target.value));
|
||||
}
|
||||
};
|
||||
const handleTypeSelection = (e: any) => {
|
||||
const type = e.target.value as VerbType;
|
||||
if (type === "dynamic compound") {
|
||||
setTransitivityShowing("transitive");
|
||||
}
|
||||
if (type === "stative compound" && transitivityShowing === "grammatically transitive") {
|
||||
if (
|
||||
type === "stative compound" &&
|
||||
transitivityShowing === "grammatically transitive"
|
||||
) {
|
||||
setTransitivityShowing("transitive");
|
||||
}
|
||||
setVerbTypeShowing(type);
|
||||
}
|
||||
};
|
||||
const handleTransitivitySelection = (e: any) => {
|
||||
const transitivity = e.target.value as T.Transitivity;
|
||||
if (transitivity === "grammatically transitive") {
|
||||
setVerbTypeShowing("simple");
|
||||
}
|
||||
if (transitivity === "intransitive" && verbTypeShowing === "dynamic compound") {
|
||||
if (
|
||||
transitivity === "intransitive" &&
|
||||
verbTypeShowing === "dynamic compound"
|
||||
) {
|
||||
setTransitivityShowing("transitive");
|
||||
return;
|
||||
}
|
||||
setTransitivityShowing(e.target.value as T.Transitivity);
|
||||
}
|
||||
const verbsAvailable = allVerbs.filter((verb) => (
|
||||
(
|
||||
(verb.info.type === "transitive or grammatically transitive simple" && verbTypeShowing === "simple") && (transitivityShowing === "transitive" || transitivityShowing === "grammatically transitive")
|
||||
) ||
|
||||
((
|
||||
verbTypeShowing === verb.info.type ||
|
||||
(verbTypeShowing === "stative compound" && verb.info.type === "dynamic or stative compound") ||
|
||||
(verbTypeShowing === "dynamic compound" && verb.info.type === "dynamic or stative compound") ||
|
||||
(verbTypeShowing === "dynamic compound" && verb.info.type === "dynamic or generative stative compound") ||
|
||||
(verbTypeShowing === "stative compound" && verb.info.type === "dynamic or generative stative compound")
|
||||
};
|
||||
const verbsAvailable = allVerbs
|
||||
.filter(
|
||||
(verb) =>
|
||||
(verb.info.type === "transitive or grammatically transitive simple" &&
|
||||
verbTypeShowing === "simple" &&
|
||||
(transitivityShowing === "transitive" ||
|
||||
transitivityShowing === "grammatically transitive")) ||
|
||||
((verbTypeShowing === verb.info.type ||
|
||||
(verbTypeShowing === "stative compound" &&
|
||||
verb.info.type === "dynamic or stative compound") ||
|
||||
(verbTypeShowing === "dynamic compound" &&
|
||||
verb.info.type === "dynamic or stative compound") ||
|
||||
(verbTypeShowing === "dynamic compound" &&
|
||||
verb.info.type === "dynamic or generative stative compound") ||
|
||||
(verbTypeShowing === "stative compound" &&
|
||||
verb.info.type === "dynamic or generative stative compound")) &&
|
||||
transitivityShowing === verb.info.transitivity)
|
||||
)
|
||||
&& (
|
||||
transitivityShowing === verb.info.transitivity
|
||||
))
|
||||
)).sort((a, b) => a.verb.entry.p.localeCompare(b.verb.entry.p, "ps"));
|
||||
.sort((a, b) => a.verb.entry.p.localeCompare(b.verb.entry.p, "ps"));
|
||||
|
||||
const v = (() => {
|
||||
const vFound = verbsAvailable.find(v => v.verb.entry.ts === verbTs);
|
||||
const vFound = verbsAvailable.find((v) => v.verb.entry.ts === verbTs);
|
||||
if (vFound) return vFound;
|
||||
if (verbsAvailable.length === 0) return undefined;
|
||||
const vTopOfList = verbsAvailable[0];
|
||||
|
@ -98,34 +108,46 @@ function VPBuilderDemo({ opts }: {
|
|||
let newIndex: number;
|
||||
do {
|
||||
newIndex = randomNumber(0, verbsAvailable.length);
|
||||
} while(verbsAvailable[newIndex].verb.entry.ts === verbTs);
|
||||
} while (verbsAvailable[newIndex].verb.entry.ts === verbTs);
|
||||
setVerbTs(verbsAvailable[newIndex].verb.entry.ts);
|
||||
};
|
||||
const makeVerbLabel = (entry: T.DictionaryEntry): string => (
|
||||
`${entry.p} - ${clamp(entry.e, 20)}`
|
||||
);
|
||||
const makeVerbLabel = (entry: T.DictionaryEntry): string =>
|
||||
`${entry.p} - ${clamp(entry.e, 20)}`;
|
||||
// const rs = v ? getAllRs(v.verb as T.VerbEntry) : undefined
|
||||
return <div className="mt-4">
|
||||
<div className="d-block mx-auto card" style={{ maxWidth: "700px", background: "var(--closer)"}}>
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<div
|
||||
className="d-block mx-auto card"
|
||||
style={{ maxWidth: "700px", background: "var(--closer)" }}
|
||||
>
|
||||
<div className="card-body">
|
||||
<div className="row">
|
||||
<div className="col-sm-6">
|
||||
{v ?
|
||||
{v ? (
|
||||
<div>
|
||||
<div className="mb-1">Select a verb:</div>
|
||||
<div className="input-group">
|
||||
<select className="custom-select" value={verbTs} onChange={handleVerbIndexChange}>
|
||||
{verbsAvailable.length
|
||||
? verbsAvailable.map((v, i) => (
|
||||
<select
|
||||
className="custom-select"
|
||||
value={verbTs}
|
||||
onChange={handleVerbIndexChange}
|
||||
>
|
||||
{verbsAvailable.length ? (
|
||||
verbsAvailable.map((v, i) => (
|
||||
<option value={v.verb.entry.ts} key={i} dir="ltr">
|
||||
{"\u200E"}{makeVerbLabel(v.verb.entry)}
|
||||
{"\u200E"}
|
||||
{makeVerbLabel(v.verb.entry)}
|
||||
</option>
|
||||
))
|
||||
: <option>Select a verb type</option>
|
||||
}
|
||||
) : (
|
||||
<option>Select a verb type</option>
|
||||
)}
|
||||
</select>
|
||||
<div className="input-group-append">
|
||||
<button className="btn btn-secondary" onClick={pickRandomVerb}>
|
||||
<button
|
||||
className="btn btn-secondary"
|
||||
onClick={pickRandomVerb}
|
||||
>
|
||||
<i className="fas fa-random" />
|
||||
</button>
|
||||
</div>
|
||||
|
@ -143,10 +165,11 @@ function VPBuilderDemo({ opts }: {
|
|||
<div className="ml-3">{v.verb.entry.e}</div>
|
||||
</div>
|
||||
</div>
|
||||
: <div className="alert alert-warning mb-4" role="alert">
|
||||
) : (
|
||||
<div className="alert alert-warning mb-4" role="alert">
|
||||
No such verbs available...
|
||||
</div>
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
<div className="col-sm-6">
|
||||
<h6>Verb type:</h6>
|
||||
|
@ -161,9 +184,7 @@ function VPBuilderDemo({ opts }: {
|
|||
value={type}
|
||||
onChange={() => null}
|
||||
/>
|
||||
<label className="form-check-label">
|
||||
{type}
|
||||
</label>
|
||||
<label className="form-check-label">{type}</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
@ -179,9 +200,7 @@ function VPBuilderDemo({ opts }: {
|
|||
onChange={() => null}
|
||||
value={transitivity}
|
||||
/>
|
||||
<label className="form-check-label">
|
||||
{transitivity}
|
||||
</label>
|
||||
<label className="form-check-label">{transitivity}</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
@ -189,15 +208,18 @@ function VPBuilderDemo({ opts }: {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{v?.verb.entry && <div style={{ paddingBottom: "20px" }}>
|
||||
{v?.verb.entry && (
|
||||
<div style={{ paddingBottom: "20px" }}>
|
||||
<PhraseBuilder
|
||||
handleLinkClick="none"
|
||||
verb={v.verb as T.VerbEntry}
|
||||
entryFeeder={entryFeeder}
|
||||
opts={opts}
|
||||
/>
|
||||
</div>}
|
||||
</div>;
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default VPBuilderDemo;
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@lingdocs/inflect",
|
||||
"version": "7.0.9",
|
||||
"version": "7.0.11",
|
||||
"description": "Pashto inflector library",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/lib/library.d.ts",
|
||||
|
|
|
@ -4,9 +4,9 @@ import { parseEquative } from "./parse-equative";
|
|||
import { parseKidsSection } from "./parse-kids-section";
|
||||
import { parseNeg } from "./parse-negative";
|
||||
import { parseNPAP } from "./parse-npap";
|
||||
import { parsePastPart } from "./parse-past-part";
|
||||
import { parseVBP } from "./parse-vbp";
|
||||
import { parsePH } from "./parse-ph";
|
||||
import { parseVerb } from "./parse-verb";
|
||||
import { parseVBE } from "./parse-vbe";
|
||||
import {
|
||||
bindParseResult,
|
||||
returnParseResult,
|
||||
|
@ -14,6 +14,7 @@ import {
|
|||
isParsedVBP,
|
||||
startsVerbSection,
|
||||
} from "./utils";
|
||||
import { isKedulStatEntry } from "./parse-verb-helpers";
|
||||
|
||||
export function parseBlocks(
|
||||
tokens: Readonly<T.Token[]>,
|
||||
|
@ -32,14 +33,15 @@ export function parseBlocks(
|
|||
(b): b is T.ParsedPH => b.type === "PH"
|
||||
);
|
||||
|
||||
// TOOD: rather parse VBP / VBE
|
||||
const allBlocks: T.ParseResult<T.ParsedBlock | T.ParsedKidsSection>[] = [
|
||||
...(!inVerbSection ? parseNPAP(tokens, lookup) : []),
|
||||
// ensure at most one of each PH, VBE, VBP
|
||||
...(prevPh ? [] : parsePH(tokens)),
|
||||
...(blocks.some(isParsedVBE)
|
||||
? []
|
||||
: [...parseVerb(tokens, lookup), ...parseEquative(tokens)]),
|
||||
...(blocks.some(isParsedVBP) ? [] : parsePastPart(tokens, lookup)),
|
||||
: [...parseVBE(tokens, lookup), ...parseEquative(tokens)]),
|
||||
...(blocks.some(isParsedVBP) ? [] : parseVBP(tokens, lookup)),
|
||||
...(blocks.some((b) => b.type === "negative") ? [] : parseNeg(tokens)),
|
||||
...parseKidsSection(tokens, []),
|
||||
];
|
||||
|
@ -82,12 +84,24 @@ function phMatches(
|
|||
if (!ph) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!vb) {
|
||||
return true;
|
||||
}
|
||||
if (vb.info.type !== "verb") {
|
||||
return false;
|
||||
}
|
||||
if (["را", "در", "ور"].includes(ph?.s)) {
|
||||
if (
|
||||
isKedulStatEntry(vb.info.verb.entry) &&
|
||||
vb.info.base === "stem" &&
|
||||
vb.info.aspect === "perfective"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
// TODO: handle را غل etc! ? or is
|
||||
return false;
|
||||
}
|
||||
const verbPh = getPhFromVerb(vb.info.verb, vb.info.base);
|
||||
return verbPh === ph.s;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,245 @@
|
|||
/* eslint-disable jest/valid-title */
|
||||
import * as T from "../../../types";
|
||||
import { parseKedul } from "./parse-kedul";
|
||||
import { kedulDyn, kedulStat } from "./irreg-verbs";
|
||||
import { tokenizer } from "./tokenizer";
|
||||
import { getPeople, removeKeys } from "./utils";
|
||||
|
||||
const tests: {
|
||||
label: string;
|
||||
cases: {
|
||||
input: string;
|
||||
output: T.ParsedVBE[];
|
||||
}[];
|
||||
}[] = [
|
||||
{
|
||||
label: "keG-",
|
||||
cases: [
|
||||
{
|
||||
input: "کېږې",
|
||||
output: getPeople(2, "sing").flatMap<T.ParsedVBE>((person) => [
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb: kedulStat,
|
||||
},
|
||||
person,
|
||||
},
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb: kedulDyn,
|
||||
},
|
||||
person,
|
||||
},
|
||||
]),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "ked-",
|
||||
cases: [
|
||||
{
|
||||
input: "کېدم",
|
||||
output: getPeople(1, "sing").flatMap<T.ParsedVBE>((person) => [
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulStat,
|
||||
},
|
||||
person,
|
||||
},
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulDyn,
|
||||
},
|
||||
person,
|
||||
},
|
||||
]),
|
||||
},
|
||||
{
|
||||
input: "کېدل",
|
||||
output: [
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulStat,
|
||||
},
|
||||
person: T.Person.ThirdPlurMale,
|
||||
},
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulDyn,
|
||||
},
|
||||
person: T.Person.ThirdPlurMale,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "کېدلل",
|
||||
output: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "sh-",
|
||||
cases: [
|
||||
{
|
||||
input: "شې",
|
||||
output: getPeople(2, "sing").flatMap<T.ParsedVBE>((person) => [
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb: kedulStat,
|
||||
},
|
||||
person,
|
||||
},
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb: kedulDyn,
|
||||
},
|
||||
person,
|
||||
},
|
||||
]),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "shw-",
|
||||
cases: [
|
||||
{
|
||||
input: "شوم",
|
||||
output: getPeople(1, "sing").flatMap<T.ParsedVBE>((person) => [
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulStat,
|
||||
},
|
||||
person,
|
||||
},
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulDyn,
|
||||
},
|
||||
person,
|
||||
},
|
||||
]),
|
||||
},
|
||||
{
|
||||
input: "شول",
|
||||
output: [
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulStat,
|
||||
},
|
||||
person: T.Person.ThirdPlurMale,
|
||||
},
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulDyn,
|
||||
},
|
||||
person: T.Person.ThirdPlurMale,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "شولل",
|
||||
output: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "sho",
|
||||
cases: [
|
||||
{
|
||||
input: "شو",
|
||||
output: [
|
||||
...[
|
||||
T.Person.ThirdSingMale,
|
||||
T.Person.FirstPlurMale,
|
||||
T.Person.FirstPlurFemale,
|
||||
].flatMap((person) =>
|
||||
[kedulStat, kedulDyn].map<T.ParsedVBE>((verb) => ({
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb,
|
||||
},
|
||||
person,
|
||||
}))
|
||||
),
|
||||
...[T.Person.FirstPlurMale, T.Person.FirstPlurFemale].flatMap(
|
||||
(person) =>
|
||||
[kedulStat, kedulDyn].map<T.ParsedVBE>((verb) => ({
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb,
|
||||
},
|
||||
person,
|
||||
}))
|
||||
),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
tests.forEach(({ label, cases }) => {
|
||||
test(label, () => {
|
||||
cases.forEach(({ input, output }) => {
|
||||
const tokens = tokenizer(input);
|
||||
const vbe = parseKedul(tokens);
|
||||
expect(vbe.every((v) => v.errors.length === 0)).toBe(true);
|
||||
expect(removeKeys(vbe.map((v) => v.body))).toIncludeSameMembers(
|
||||
removeKeys(output)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,154 @@
|
|||
import * as T from "../../../types";
|
||||
import { getVerbEnding } from "./parse-verb-helpers";
|
||||
import { kedulDyn, kedulStat } from "./irreg-verbs";
|
||||
import { returnParseResults } from "./utils";
|
||||
|
||||
export function parseKedul(
|
||||
tokens: Readonly<T.Token[]>
|
||||
): T.ParseResult<T.ParsedVBE>[] {
|
||||
const [first, ...rest] = tokens;
|
||||
const start = first.s.slice(0, -1);
|
||||
const ending = first.s.at(-1) || "";
|
||||
const people = getVerbEnding(ending);
|
||||
if (first.s === "شو") {
|
||||
return returnParseResults<T.ParsedVBE>(rest, [
|
||||
...[
|
||||
T.Person.ThirdSingMale,
|
||||
T.Person.FirstPlurMale,
|
||||
T.Person.FirstPlurFemale,
|
||||
].flatMap((person) =>
|
||||
[kedulStat, kedulDyn].map<T.ParsedVBE>((verb) => ({
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb,
|
||||
},
|
||||
person,
|
||||
}))
|
||||
),
|
||||
...[T.Person.FirstPlurMale, T.Person.FirstPlurFemale].flatMap((person) =>
|
||||
[kedulStat, kedulDyn].map<T.ParsedVBE>((verb) => ({
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb,
|
||||
},
|
||||
person,
|
||||
}))
|
||||
),
|
||||
]);
|
||||
}
|
||||
if (start === "کېږ") {
|
||||
return returnParseResults<T.ParsedVBE>(
|
||||
rest,
|
||||
people.stem.flatMap<T.ParsedVBE>((person) => [
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb: kedulStat,
|
||||
},
|
||||
person,
|
||||
},
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb: kedulDyn,
|
||||
},
|
||||
person,
|
||||
},
|
||||
])
|
||||
);
|
||||
}
|
||||
if (start === "کېد" || (start === "کېدل" && ending !== "ل")) {
|
||||
return returnParseResults<T.ParsedVBE>(
|
||||
rest,
|
||||
people.root.flatMap<T.ParsedVBE>((person) => [
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulStat,
|
||||
},
|
||||
person,
|
||||
},
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "imperfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulDyn,
|
||||
},
|
||||
person,
|
||||
},
|
||||
])
|
||||
);
|
||||
}
|
||||
if (start === "ش") {
|
||||
return returnParseResults<T.ParsedVBE>(
|
||||
rest,
|
||||
people.stem.flatMap<T.ParsedVBE>((person) => [
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb: kedulStat,
|
||||
},
|
||||
person,
|
||||
},
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb: kedulDyn,
|
||||
},
|
||||
person,
|
||||
},
|
||||
])
|
||||
);
|
||||
}
|
||||
if (start === "شو" || (start === "شول" && ending !== "ل")) {
|
||||
return returnParseResults<T.ParsedVBE>(
|
||||
rest,
|
||||
people.root.flatMap<T.ParsedVBE>((person) => [
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulStat,
|
||||
},
|
||||
person,
|
||||
},
|
||||
{
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb: kedulDyn,
|
||||
},
|
||||
person,
|
||||
},
|
||||
])
|
||||
);
|
||||
}
|
||||
return [];
|
||||
}
|
|
@ -9,7 +9,7 @@ import {
|
|||
raatlul,
|
||||
} from "./irreg-verbs";
|
||||
import { lookup, wordQuery } from "./lookup";
|
||||
import { parseVerb } from "./parse-verb";
|
||||
import { parseVBE } from "./parse-vbe";
|
||||
import { tokenizer } from "./tokenizer";
|
||||
import { getPeople, removeKeys } from "./utils";
|
||||
|
||||
|
@ -935,9 +935,6 @@ const tests: {
|
|||
},
|
||||
],
|
||||
},
|
||||
// TODO: It would probably be more effecient just to return the kedul verb options
|
||||
// and then when we put things together with the perfective head parsed they could
|
||||
// become raatlul etc...
|
||||
{
|
||||
input: "شي",
|
||||
output: [
|
||||
|
@ -965,42 +962,6 @@ const tests: {
|
|||
},
|
||||
verb: kedulStat,
|
||||
},
|
||||
{
|
||||
stem: {
|
||||
persons: [
|
||||
T.Person.ThirdSingMale,
|
||||
T.Person.ThirdSingFemale,
|
||||
T.Person.ThirdPlurMale,
|
||||
T.Person.ThirdPlurFemale,
|
||||
],
|
||||
aspects: ["perfective"],
|
||||
},
|
||||
verb: raatlul,
|
||||
},
|
||||
{
|
||||
stem: {
|
||||
persons: [
|
||||
T.Person.ThirdSingMale,
|
||||
T.Person.ThirdSingFemale,
|
||||
T.Person.ThirdPlurMale,
|
||||
T.Person.ThirdPlurFemale,
|
||||
],
|
||||
aspects: ["perfective"],
|
||||
},
|
||||
verb: dartlul,
|
||||
},
|
||||
{
|
||||
stem: {
|
||||
persons: [
|
||||
T.Person.ThirdSingMale,
|
||||
T.Person.ThirdSingFemale,
|
||||
T.Person.ThirdPlurMale,
|
||||
T.Person.ThirdPlurFemale,
|
||||
],
|
||||
aspects: ["perfective"],
|
||||
},
|
||||
verb: wartlul,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
@ -1011,7 +972,7 @@ tests.forEach(({ label, cases }) => {
|
|||
test(label, () => {
|
||||
cases.forEach(({ input, output }) => {
|
||||
const tokens = tokenizer(input);
|
||||
const vbs = parseVerb(tokens, lookup).map((r) => r.body);
|
||||
const vbs = parseVBE(tokens, lookup).map((r) => r.body);
|
||||
const madeVbsS = output.reduce<T.ParsedVBE[]>((acc, o) => {
|
||||
return [
|
||||
...acc,
|
|
@ -1,26 +1,22 @@
|
|||
import * as T from "../../../types";
|
||||
import { removeFVarientsFromVerb } from "../accent-and-ps-utils";
|
||||
import { isInVarients, lastVowelNotA } from "../p-text-helpers";
|
||||
import {
|
||||
dartlul,
|
||||
kedulDyn,
|
||||
kedulStat,
|
||||
raatlul,
|
||||
tlul,
|
||||
wartlul,
|
||||
} from "./irreg-verbs";
|
||||
import { dartlul, raatlul, tlul, wartlul } from "./irreg-verbs";
|
||||
import { LookupFunction } from "./lookup";
|
||||
import { shortVerbEndConsonant } from "./misc";
|
||||
import { parseKedul } from "./parse-kedul";
|
||||
import { getVerbEnding } from "./parse-verb-helpers";
|
||||
|
||||
// TODO: کول verbs!
|
||||
// check that aawu stuff is working
|
||||
// check oo`azmooy -
|
||||
// check څاته
|
||||
// laaRa shum etc
|
||||
|
||||
// TODO: proper use of perfective with sh
|
||||
// TODO: use of raa, dar, war with sh
|
||||
// TODO: هغه لاړ
|
||||
|
||||
export function parseVerb(
|
||||
export function parseVBE(
|
||||
tokens: Readonly<T.Token[]>,
|
||||
lookup: LookupFunction
|
||||
): T.ParseResult<T.ParsedVBE>[] {
|
||||
|
@ -36,6 +32,7 @@ export function parseVerb(
|
|||
errors: [],
|
||||
}));
|
||||
}
|
||||
const kedulStat = parseKedul(tokens);
|
||||
const ending = first.s.at(-1) || "";
|
||||
const people = getVerbEnding(ending);
|
||||
const imperativePeople = getImperativeVerbEnding(ending);
|
||||
|
@ -46,11 +43,14 @@ export function parseVerb(
|
|||
// console.log({ verbs: JSON.stringify(verbs) });
|
||||
// }
|
||||
// Then find out which ones match exactly and how
|
||||
return matchVerbs(first.s, verbs, people, imperativePeople).map((body) => ({
|
||||
return [
|
||||
...kedulStat,
|
||||
...matchVerbs(first.s, verbs, people, imperativePeople).map((body) => ({
|
||||
tokens: rest,
|
||||
body,
|
||||
errors: [],
|
||||
}));
|
||||
})),
|
||||
];
|
||||
}
|
||||
|
||||
function matchVerbs(
|
||||
|
@ -65,6 +65,9 @@ function matchVerbs(
|
|||
const w: T.ParsedVBE[] = [];
|
||||
const lEnding = s.endsWith("ل");
|
||||
const base = s.endsWith("ل") ? s : s.slice(0, -1);
|
||||
if (["کېږ", "کېد", "ش", "شو", "شول"].includes(base)) {
|
||||
return [];
|
||||
}
|
||||
const matchShortOrLong = (b: string, x: string) => {
|
||||
return b === x || (!lEnding && b === x.slice(0, -1));
|
||||
};
|
||||
|
@ -317,61 +320,6 @@ function getImperativeVerbEnding(e: string): T.Person[] {
|
|||
return [];
|
||||
}
|
||||
|
||||
function getVerbEnding(e: string): {
|
||||
stem: T.Person[];
|
||||
root: T.Person[];
|
||||
} {
|
||||
if (e === "م") {
|
||||
return {
|
||||
root: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||
stem: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||
};
|
||||
} else if (e === "ې") {
|
||||
return {
|
||||
root: [
|
||||
T.Person.SecondSingMale,
|
||||
T.Person.SecondSingFemale,
|
||||
T.Person.ThirdPlurFemale,
|
||||
],
|
||||
stem: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
|
||||
};
|
||||
} else if (e === "ي") {
|
||||
return {
|
||||
stem: [
|
||||
T.Person.ThirdSingMale,
|
||||
T.Person.ThirdSingFemale,
|
||||
T.Person.ThirdPlurMale,
|
||||
T.Person.ThirdPlurFemale,
|
||||
],
|
||||
root: [],
|
||||
};
|
||||
} else if (e === "و") {
|
||||
return {
|
||||
root: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
|
||||
stem: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
|
||||
};
|
||||
} else if (e === "ئ") {
|
||||
return {
|
||||
root: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||
stem: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||
};
|
||||
} else if (e === "ه") {
|
||||
return {
|
||||
root: [T.Person.ThirdSingFemale],
|
||||
stem: [],
|
||||
};
|
||||
} else if (e === "ل") {
|
||||
return {
|
||||
root: [T.Person.ThirdPlurMale],
|
||||
stem: [],
|
||||
};
|
||||
}
|
||||
return {
|
||||
root: [],
|
||||
stem: [],
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: could handle all sh- verbs for efficiencies sake
|
||||
function parseIrregularVerb(s: string): T.ParsedVBE[] {
|
||||
if (["ته", "راته", "ورته", "درته"].includes(s)) {
|
||||
|
@ -394,38 +342,6 @@ function parseIrregularVerb(s: string): T.ParsedVBE[] {
|
|||
},
|
||||
];
|
||||
}
|
||||
if (s === "شو") {
|
||||
return [
|
||||
...[
|
||||
T.Person.ThirdSingMale,
|
||||
T.Person.FirstPlurMale,
|
||||
T.Person.FirstPlurFemale,
|
||||
].flatMap((person) =>
|
||||
[kedulStat, kedulDyn].map<T.ParsedVBE>((verb) => ({
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "root",
|
||||
type: "verb",
|
||||
verb,
|
||||
},
|
||||
person,
|
||||
}))
|
||||
),
|
||||
...[T.Person.FirstPlurMale, T.Person.FirstPlurFemale].flatMap((person) =>
|
||||
[kedulStat, kedulDyn].map<T.ParsedVBE>((verb) => ({
|
||||
type: "VB",
|
||||
info: {
|
||||
aspect: "perfective",
|
||||
base: "stem",
|
||||
type: "verb",
|
||||
verb,
|
||||
},
|
||||
person,
|
||||
}))
|
||||
),
|
||||
];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import * as T from "../../../types";
|
||||
import { lookup, wordQuery } from "./lookup";
|
||||
import { tokenizer } from "./tokenizer";
|
||||
import { parsePastPart } from "./parse-past-part";
|
||||
import { parseVBP } from "./parse-vbp";
|
||||
import { kawulDyn, kawulStat, kedulDyn, kedulStat } from "./irreg-verbs";
|
||||
|
||||
const leedul = wordQuery("لیدل", "verb");
|
||||
|
@ -178,7 +178,7 @@ describe("parsing past participles", () => {
|
|||
test(label, () => {
|
||||
cases.forEach(({ input, output }) => {
|
||||
const tokens = tokenizer(input);
|
||||
const res = parsePastPart(tokens, lookup).map(({ body }) => body);
|
||||
const res = parseVBP(tokens, lookup).map(({ body }) => body);
|
||||
expect(res).toEqual(output);
|
||||
});
|
||||
});
|
|
@ -2,13 +2,23 @@ import * as T from "../../../types";
|
|||
import { LookupFunction } from "./lookup";
|
||||
import { returnParseResult } from "./utils";
|
||||
|
||||
export function parsePastPart(
|
||||
export function parseVBP(
|
||||
tokens: Readonly<T.Token[]>,
|
||||
lookup: LookupFunction
|
||||
): T.ParseResult<T.ParsedVBP>[] {
|
||||
if (tokens.length === 0) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
...parsePastPart(tokens, lookup),
|
||||
// ...parseAbility(tokens),
|
||||
];
|
||||
}
|
||||
|
||||
function parsePastPart(
|
||||
tokens: Readonly<T.Token[]>,
|
||||
lookup: LookupFunction
|
||||
): T.ParseResult<T.ParsedVBP>[] {
|
||||
const [{ s }, ...rest] = tokens;
|
||||
const ending: "ی" | "ي" | "ې" = s.at(-1) as "ی" | "ي" | "ې";
|
||||
if (!ending || !["ی", "ي", "ې"].includes(ending)) {
|
||||
|
@ -32,6 +42,34 @@ export function parsePastPart(
|
|||
.flatMap((m) => returnParseResult(rest, m));
|
||||
}
|
||||
|
||||
// function parseAbility(
|
||||
// tokens: Readonly<T.Token[]>,
|
||||
// lookup: LookupFunction
|
||||
// ): T.ParseResult<T.ParsedVBP>[] {
|
||||
// // TODO: keday
|
||||
// if (tokens.length === 0) {
|
||||
// return [];
|
||||
// }
|
||||
// const [{ s }, ...rest] = tokens;
|
||||
// const start = s.endsWith("ای")
|
||||
// ? s.slice(0, -2)
|
||||
// : s.endsWith("ی")
|
||||
// ? s.slice(0, 1)
|
||||
// : "";
|
||||
// if (!start) return [];
|
||||
// const matches = lookup(start, "ability");
|
||||
// return matches
|
||||
// .map<T.ParsedVBP>((verb) => ({
|
||||
// type: "VB",
|
||||
// info: {
|
||||
// type: "ability",
|
||||
// verb,
|
||||
// aspect: "perfective", // TODO GET ASPECT!!
|
||||
// },
|
||||
// }))
|
||||
// .flatMap((m) => returnParseResult(rest, m));
|
||||
// }
|
||||
|
||||
function endingGenderNum(ending: "ی" | "ي" | "ې"): T.GenderNumber[] {
|
||||
if (ending === "ی") {
|
||||
return [
|
|
@ -0,0 +1,60 @@
|
|||
import * as T from "../../../types";
|
||||
|
||||
export function isKedulStatEntry(v: T.VerbDictionaryEntry): boolean {
|
||||
return v.p === "کېدل" && v.e === "to become _____";
|
||||
}
|
||||
|
||||
export function getVerbEnding(e: string): {
|
||||
stem: T.Person[];
|
||||
root: T.Person[];
|
||||
} {
|
||||
if (e === "م") {
|
||||
return {
|
||||
root: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||
stem: [T.Person.FirstSingMale, T.Person.FirstSingFemale],
|
||||
};
|
||||
} else if (e === "ې") {
|
||||
return {
|
||||
root: [
|
||||
T.Person.SecondSingMale,
|
||||
T.Person.SecondSingFemale,
|
||||
T.Person.ThirdPlurFemale,
|
||||
],
|
||||
stem: [T.Person.SecondSingMale, T.Person.SecondSingFemale],
|
||||
};
|
||||
} else if (e === "ي") {
|
||||
return {
|
||||
stem: [
|
||||
T.Person.ThirdSingMale,
|
||||
T.Person.ThirdSingFemale,
|
||||
T.Person.ThirdPlurMale,
|
||||
T.Person.ThirdPlurFemale,
|
||||
],
|
||||
root: [],
|
||||
};
|
||||
} else if (e === "و") {
|
||||
return {
|
||||
root: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
|
||||
stem: [T.Person.FirstPlurMale, T.Person.FirstPlurFemale],
|
||||
};
|
||||
} else if (e === "ئ") {
|
||||
return {
|
||||
root: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||
stem: [T.Person.SecondPlurMale, T.Person.SecondPlurFemale],
|
||||
};
|
||||
} else if (e === "ه") {
|
||||
return {
|
||||
root: [T.Person.ThirdSingFemale],
|
||||
stem: [],
|
||||
};
|
||||
} else if (e === "ل") {
|
||||
return {
|
||||
root: [T.Person.ThirdPlurMale],
|
||||
stem: [],
|
||||
};
|
||||
}
|
||||
return {
|
||||
root: [],
|
||||
stem: [],
|
||||
};
|
||||
}
|
|
@ -104,6 +104,7 @@ function getTenses(
|
|||
}
|
||||
if (verb.info.type === "verb") {
|
||||
if (verb.info.aspect === "perfective") {
|
||||
// TODO: handle kedul sh perfective
|
||||
if (!ph) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -62,6 +62,18 @@ export function bindParseResult<C, D>(
|
|||
return cleanOutResults(nextPossibilities);
|
||||
}
|
||||
|
||||
export function returnParseResults<D>(
|
||||
tokens: Readonly<T.Token[]>,
|
||||
body: D[],
|
||||
errors?: T.ParseError[]
|
||||
): T.ParseResult<D>[] {
|
||||
return body.map<T.ParseResult<D>>((b) => ({
|
||||
tokens,
|
||||
body: b,
|
||||
errors: errors || [],
|
||||
}));
|
||||
}
|
||||
|
||||
export function returnParseResultS<D>(
|
||||
tokens: Readonly<T.Token[]>,
|
||||
body: D,
|
||||
|
|
|
@ -34,6 +34,8 @@ type BlankoutOptions = {
|
|||
predicate?: boolean;
|
||||
};
|
||||
|
||||
// TODO: Should there be a way to get length options on compiled VP ?
|
||||
|
||||
// function compilePs({ blocks, kids, verb: { head, rest }, VP }: CompilePsInput): T.SingleOrLengthOpts<T.PsString[]> {
|
||||
// if ("long" in rest) {
|
||||
// return {
|
||||
|
@ -87,13 +89,13 @@ export function compileVP(
|
|||
export function compileVP(
|
||||
VP: T.VPRendered,
|
||||
form: T.FormVersion,
|
||||
combineLengths: true,
|
||||
combineLengths: boolean,
|
||||
blankOut?: BlankoutOptions
|
||||
): { ps: T.PsString[]; e?: string[] };
|
||||
export function compileVP(
|
||||
VP: T.VPRendered,
|
||||
form: T.FormVersion,
|
||||
combineLengths?: true,
|
||||
combineLengths?: boolean,
|
||||
blankOut?: BlankoutOptions
|
||||
): { ps: T.SingleOrLengthOpts<T.PsString[]>; e?: string[] } {
|
||||
// const verb = getVerbFromBlocks(VP.blocks).block;
|
||||
|
|
|
@ -868,6 +868,14 @@ export type PossesorSelection = {
|
|||
np: NPSelection;
|
||||
};
|
||||
|
||||
export type Noun = {
|
||||
entry: NounEntry;
|
||||
gender: Gender;
|
||||
number: "sing" | "plur";
|
||||
adjectives: AdjectiveSelection[];
|
||||
possesor: undefined | Noun;
|
||||
};
|
||||
|
||||
// TODO require/import Person and PsString
|
||||
export type NounSelection = {
|
||||
type: "noun";
|
||||
|
|
Loading…
Reference in New Issue