ba particles working and a couple of bugs with past tense and nouns etc
This commit is contained in:
parent
004bdeb352
commit
9204ca150c
|
@ -14,6 +14,12 @@ const tenseOptions: { label: string, value: VerbTense }[] = [{
|
||||||
}, {
|
}, {
|
||||||
label: "subjunctive",
|
label: "subjunctive",
|
||||||
value: "subjunctive",
|
value: "subjunctive",
|
||||||
|
}, {
|
||||||
|
label: "imperf. future",
|
||||||
|
value: "imperfectiveFuture",
|
||||||
|
}, {
|
||||||
|
label: "perf. future",
|
||||||
|
value: "perfectiveFuture",
|
||||||
}, {
|
}, {
|
||||||
label: "simple past",
|
label: "simple past",
|
||||||
value: "perfectivePast",
|
value: "perfectivePast",
|
||||||
|
@ -73,7 +79,7 @@ function VerbPicker({ onChange, verb, verbs }: { verbs: VerbEntry[], verb: VerbS
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return <div style={{ maxWidth: "225px" }}>
|
return <div style={{ maxWidth: "225px", minWidth: "10px" }}>
|
||||||
<div>Verb:</div>
|
<div>Verb:</div>
|
||||||
<Select
|
<Select
|
||||||
value={verb && verb.verb.entry.ts.toString()}
|
value={verb && verb.verb.entry.ts.toString()}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { useState } from "react";
|
||||||
import { nouns, verbs } from "../../words/words";
|
import { nouns, verbs } from "../../words/words";
|
||||||
// import { capitalizeFirstLetter } from "../../lib/text-tools";
|
// import { capitalizeFirstLetter } from "../../lib/text-tools";
|
||||||
|
|
||||||
const npTypes: NPType[] = ["noun", "pronoun", "participle"];
|
const npTypes: NPType[] = ["pronoun", "noun", "participle"];
|
||||||
|
|
||||||
function NPPicker({ np, onChange, counterPart }: { onChange: (nps: NPSelection | undefined) => void, np: NPSelection | undefined, counterPart: NPSelection | VerbObject | undefined }) {
|
function NPPicker({ np, onChange, counterPart }: { onChange: (nps: NPSelection | undefined) => void, np: NPSelection | undefined, counterPart: NPSelection | VerbObject | undefined }) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
|
@ -35,9 +35,8 @@ function NPPicker({ np, onChange, counterPart }: { onChange: (nps: NPSelection |
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return <div style={{ maxWidth: "300px"}}>
|
return <div style={{ maxWidth: "300px"}}>
|
||||||
{!npType ?
|
{!npType ? <div className="text-center mt-3">
|
||||||
<div>
|
{npTypes.map((npt) => <div className="mb-2">
|
||||||
{npTypes.map((npt) => (
|
|
||||||
<button
|
<button
|
||||||
key={npt}
|
key={npt}
|
||||||
type="button"
|
type="button"
|
||||||
|
@ -46,7 +45,7 @@ function NPPicker({ np, onChange, counterPart }: { onChange: (nps: NPSelection |
|
||||||
>
|
>
|
||||||
{npt}
|
{npt}
|
||||||
</button>
|
</button>
|
||||||
))}
|
</div>)}
|
||||||
</div>
|
</div>
|
||||||
: <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>}
|
: <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>}
|
||||||
{np ?
|
{np ?
|
||||||
|
|
|
@ -111,7 +111,7 @@ function PronounPicker({ onChange, pronoun, isObject }: {
|
||||||
/>
|
/>
|
||||||
<button className="btn btn-sm btn-outline-secondary" onClick={handleDisplayChange}>{display === "persons" ? "#" : display === "p" ? "PS" : "EN"}</button>
|
<button className="btn btn-sm btn-outline-secondary" onClick={handleDisplayChange}>{display === "persons" ? "#" : display === "p" ? "PS" : "EN"}</button>
|
||||||
</div>
|
</div>
|
||||||
<table className="table table-bordered" style={{ textAlign: "center", minWidth: "200px", tableLayout: "fixed" }}>
|
<table className="table table-bordered" style={{ textAlign: "center", minWidth: "160px", tableLayout: "fixed" }}>
|
||||||
<tbody>
|
<tbody>
|
||||||
{pSpec.map((rw, i) => (
|
{pSpec.map((rw, i) => (
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
grammarUnits,
|
grammarUnits,
|
||||||
getVerbBlockPosFromPerson,
|
getVerbBlockPosFromPerson,
|
||||||
} from "@lingdocs/pashto-inflector";
|
} from "@lingdocs/pashto-inflector";
|
||||||
|
import { hasBaParticle, psRemove } from "@lingdocs/pashto-inflector/dist/lib/p-text-helpers";
|
||||||
|
|
||||||
type ListOfEntities = (T.PsString & { isVerbPrefix?: boolean, prefixFollowedByParticle?: boolean })[][];
|
type ListOfEntities = (T.PsString & { isVerbPrefix?: boolean, prefixFollowedByParticle?: boolean })[][];
|
||||||
|
|
||||||
|
@ -49,11 +50,15 @@ function compilePs(
|
||||||
} : {},
|
} : {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
const { hasBa, verbEntities } = compileVerbWNegative(head, rest, negative)
|
||||||
const entities: ListOfEntities = [
|
const entities: ListOfEntities = [
|
||||||
...nps,
|
...nps,
|
||||||
...compileVerbWNegative(head, rest, negative),
|
...verbEntities,
|
||||||
];
|
];
|
||||||
const entitiesWKids = putKidsInKidsSection(entities, kids);
|
const entitiesWKids = putKidsInKidsSection(
|
||||||
|
entities,
|
||||||
|
hasBa ? [[grammarUnits.baParticle], ...kids] : kids,
|
||||||
|
);
|
||||||
return combineEntities(entitiesWKids);
|
return combineEntities(entitiesWKids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +82,10 @@ function shrinkEntitiesAndGatherKids(VP: VPRendered, form: FormVersion): { kids:
|
||||||
(VP.king === "object" && !removeKing && king) || (VP.servant === "object" && !shrinkServant)
|
(VP.king === "object" && !removeKing && king) || (VP.servant === "object" && !shrinkServant)
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
kids: [...toShrink ? [shrink(toShrink)] : []],
|
kids: [
|
||||||
|
...toShrink
|
||||||
|
? [shrink(toShrink)] : [],
|
||||||
|
],
|
||||||
NPs: [
|
NPs: [
|
||||||
...showSubject ? [main.subject] : [],
|
...showSubject ? [main.subject] : [],
|
||||||
...(showObject && main.object) ? [main.object] : [],
|
...(showObject && main.object) ? [main.object] : [],
|
||||||
|
@ -86,11 +94,7 @@ function shrinkEntitiesAndGatherKids(VP: VPRendered, form: FormVersion): { kids:
|
||||||
}
|
}
|
||||||
|
|
||||||
function shrink(np: Rendered<NPSelection>): T.PsString[] {
|
function shrink(np: Rendered<NPSelection>): T.PsString[] {
|
||||||
const person: T.Person = np.type === "participle"
|
const [row, col] = getVerbBlockPosFromPerson(np.person);
|
||||||
? T.Person.ThirdPlurMale
|
|
||||||
// @ts-ignore
|
|
||||||
: np.person;
|
|
||||||
const [row, col] = getVerbBlockPosFromPerson(person);
|
|
||||||
return grammarUnits.pronouns.mini[row][col];
|
return grammarUnits.pronouns.mini[row][col];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,27 +128,43 @@ function combineEntities(loe: ListOfEntities): T.PsString[] {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function compileVerbWNegative(head: T.PsString | undefined, rest: T.PsString[], negative: boolean): ListOfEntities {
|
function compileVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[], negative: boolean): {
|
||||||
|
hasBa: boolean,
|
||||||
|
verbEntities: ListOfEntities,
|
||||||
|
} {
|
||||||
|
const hasBa = hasBaParticle(restRaw[0]);
|
||||||
|
const rest = hasBa
|
||||||
|
? restRaw.map(ps => psRemove(ps, concatPsString(grammarUnits.baParticle, " ")))
|
||||||
|
: restRaw;
|
||||||
if (!negative) {
|
if (!negative) {
|
||||||
return [
|
return {
|
||||||
|
hasBa,
|
||||||
|
verbEntities: [
|
||||||
...head ? [[{...head, isVerbPrefix: true}]] : [],
|
...head ? [[{...head, isVerbPrefix: true}]] : [],
|
||||||
rest,
|
rest,
|
||||||
];
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
const nu: T.PsString = { p: "نه", f: "nú" };
|
const nu: T.PsString = { p: "نه", f: "nú" };
|
||||||
if (!head) {
|
if (!head) {
|
||||||
return [
|
return {
|
||||||
|
hasBa,
|
||||||
|
verbEntities: [
|
||||||
[nu],
|
[nu],
|
||||||
rest.map(r => removeAccents(r)),
|
rest.map(r => removeAccents(r)),
|
||||||
];
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// const regularPrefix = head.p === "و" || head.p === "وا";
|
// const regularPrefix = head.p === "و" || head.p === "وا";
|
||||||
// if (regularPrefix) {
|
// if (regularPrefix) {
|
||||||
// dashes for oo-nu etc
|
// dashes for oo-nu etc
|
||||||
return [
|
return {
|
||||||
|
hasBa,
|
||||||
|
verbEntities: [
|
||||||
[{ ...removeAccents(head), isVerbPrefix: true }],
|
[{ ...removeAccents(head), isVerbPrefix: true }],
|
||||||
rest.map(r => concatPsString(nu, " ", removeAccents(r)))
|
rest.map(r => concatPsString(nu, " ", removeAccents(r))),
|
||||||
];
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function compileEnglish(VP: VPRendered): string[] | undefined {
|
function compileEnglish(VP: VPRendered): string[] | undefined {
|
||||||
|
|
|
@ -8,9 +8,11 @@ import {
|
||||||
conjugateVerb,
|
conjugateVerb,
|
||||||
concatPsString,
|
concatPsString,
|
||||||
removeAccents,
|
removeAccents,
|
||||||
|
getPersonNumber,
|
||||||
} from "@lingdocs/pashto-inflector";
|
} from "@lingdocs/pashto-inflector";
|
||||||
import {
|
import {
|
||||||
psStringFromEntry,
|
psStringFromEntry,
|
||||||
|
getLong,
|
||||||
} from "../text-tools";
|
} from "../text-tools";
|
||||||
import {
|
import {
|
||||||
getPersonFromNP,
|
getPersonFromNP,
|
||||||
|
@ -30,7 +32,7 @@ export function renderVP(VP: VPSelection): VPRendered {
|
||||||
const subjectPerson = getPersonFromNP(VP.subject);
|
const subjectPerson = getPersonFromNP(VP.subject);
|
||||||
const objectPerson = getPersonFromNP(VP.object);
|
const objectPerson = getPersonFromNP(VP.object);
|
||||||
// TODO: also don't inflect if it's a pattern one animate noun
|
// TODO: also don't inflect if it's a pattern one animate noun
|
||||||
const inflectSubject = isPast && isTransitive && !isSingularAnimatePattern4(VP.subject);
|
const inflectSubject = isPast && isTransitive && !isMascSingAnimatePattern4(VP.subject);
|
||||||
const inflectObject = !isPast && isFirstOrSecondPersPronoun(VP.object);
|
const inflectObject = !isPast && isFirstOrSecondPersPronoun(VP.object);
|
||||||
// Render Elements
|
// Render Elements
|
||||||
return {
|
return {
|
||||||
|
@ -88,6 +90,7 @@ function renderNounSelection(n: NounSelection, inflected: boolean): Rendered<Nou
|
||||||
})();
|
})();
|
||||||
return {
|
return {
|
||||||
...n,
|
...n,
|
||||||
|
person: getPersonNumber(n.gender, n.number),
|
||||||
inflected,
|
inflected,
|
||||||
ps: pashto,
|
ps: pashto,
|
||||||
e: english,
|
e: english,
|
||||||
|
@ -108,6 +111,7 @@ function renderParticipleSelection(p: ParticipleSelection, inflected: boolean):
|
||||||
return {
|
return {
|
||||||
...p,
|
...p,
|
||||||
inflected,
|
inflected,
|
||||||
|
person: T.Person.ThirdPlurMale,
|
||||||
// TODO: More robust inflection of inflecting pariticiples - get from the conjugation engine
|
// TODO: More robust inflection of inflecting pariticiples - get from the conjugation engine
|
||||||
ps: [psStringFromEntry(p.verb.entry)].map(ps => inflected ? concatPsString(ps, { p: "و", f: "o" }) : ps),
|
ps: [psStringFromEntry(p.verb.entry)].map(ps => inflected ? concatPsString(ps, { p: "و", f: "o" }) : ps),
|
||||||
e: getEnglishParticiple(p.verb.entry),
|
e: getEnglishParticiple(p.verb.entry),
|
||||||
|
@ -155,6 +159,9 @@ function renderEnglishVPBase({ subjectPerson, object, vs }: {
|
||||||
function isToBe(v: T.EnglishVerbConjugationEc): boolean {
|
function isToBe(v: T.EnglishVerbConjugationEc): boolean {
|
||||||
return (v[2] === "being");
|
return (v[2] === "being");
|
||||||
}
|
}
|
||||||
|
const futureEngBuilder: T.EnglishBuilder = (s: T.Person, ec: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||||
|
`$SUBJ will${n ? " not" : ""} ${isToBe(ec) ? "be" : ec[0]}`,
|
||||||
|
]);
|
||||||
const builders: Record<
|
const builders: Record<
|
||||||
VerbTense,
|
VerbTense,
|
||||||
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
||||||
|
@ -169,6 +176,8 @@ function renderEnglishVPBase({ subjectPerson, object, vs }: {
|
||||||
`that $SUBJ ${n ? " won't" : " will"} ${isToBe(ec) ? "be" : ec[0]}`,
|
`that $SUBJ ${n ? " won't" : " will"} ${isToBe(ec) ? "be" : ec[0]}`,
|
||||||
`should $SUBJ ${n ? " not" : ""} ${isToBe(ec) ? "be" : ec[0]}`,
|
`should $SUBJ ${n ? " not" : ""} ${isToBe(ec) ? "be" : ec[0]}`,
|
||||||
]),
|
]),
|
||||||
|
imperfectiveFuture: futureEngBuilder,
|
||||||
|
perfectiveFuture: futureEngBuilder,
|
||||||
imperfectivePast: (s: T.Person, ec: T.EnglishVerbConjugationEc, n: boolean) => ([
|
imperfectivePast: (s: T.Person, ec: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||||
// - subj pastEquative (N && "not") ec.2 obj
|
// - subj pastEquative (N && "not") ec.2 obj
|
||||||
`$SUBJ ${engEquative("past", s)}${n ? " not" : ""} ${ec[2]}`,
|
`$SUBJ ${engEquative("past", s)}${n ? " not" : ""} ${ec[2]}`,
|
||||||
|
@ -180,7 +189,8 @@ function renderEnglishVPBase({ subjectPerson, object, vs }: {
|
||||||
perfectivePast: (s: T.Person, ec: T.EnglishVerbConjugationEc, n: boolean) => ([
|
perfectivePast: (s: T.Person, ec: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||||
`$SUBJ${isToBe(ec)
|
`$SUBJ${isToBe(ec)
|
||||||
? ` ${engEquative("past", s)}${n ? " not" : ""}`
|
? ` ${engEquative("past", s)}${n ? " not" : ""}`
|
||||||
: `${n ? " did not" : ""} ${ec[3]}`}`,
|
: (n ? ` did not ${ec[0]}` : ` ${ec[3]}`)
|
||||||
|
}`
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
const base = builders[tense](subjectPerson, ec, vs.negative);
|
const base = builders[tense](subjectPerson, ec, vs.negative);
|
||||||
|
@ -252,12 +262,6 @@ function removeHead(head: T.PsString, rest: T.SingleOrLengthOpts<T.PsString[]>):
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLong<U>(x: T.SingleOrLengthOpts<U>): U {
|
|
||||||
if ("long" in x) {
|
|
||||||
return x.long;
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
function getMatrixBlock<U>(f: {
|
function getMatrixBlock<U>(f: {
|
||||||
mascSing: T.SingleOrLengthOpts<U>;
|
mascSing: T.SingleOrLengthOpts<U>;
|
||||||
mascPlur: T.SingleOrLengthOpts<U>;
|
mascPlur: T.SingleOrLengthOpts<U>;
|
||||||
|
@ -291,6 +295,12 @@ function getTenseVerbForm(conj: T.VerbConjugation, tense: VerbTense): T.VerbForm
|
||||||
if (tense === "subjunctive") {
|
if (tense === "subjunctive") {
|
||||||
return conj.perfective.nonImperative;
|
return conj.perfective.nonImperative;
|
||||||
}
|
}
|
||||||
|
if (tense === "imperfectiveFuture") {
|
||||||
|
return conj.imperfective.future;
|
||||||
|
}
|
||||||
|
if (tense === "perfectiveFuture") {
|
||||||
|
return conj.perfective.future;
|
||||||
|
}
|
||||||
if (tense === "imperfectivePast") {
|
if (tense === "imperfectivePast") {
|
||||||
return conj.imperfective.past;
|
return conj.imperfective.past;
|
||||||
}
|
}
|
||||||
|
@ -371,18 +381,21 @@ function isFirstOrSecondPersPronoun(o: "none" | NPSelection | T.Person.ThirdPlur
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPerfective(t: VerbTense): boolean {
|
function isPerfective(t: VerbTense): boolean {
|
||||||
if (t === "present" || t === "imperfectivePast") {
|
if (t === "present" || t === "imperfectiveFuture" || t === "imperfectivePast") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (t === "perfectivePast" || t === "subjunctive") {
|
if (t === "perfectiveFuture" || t === "subjunctive" || t === "perfectivePast") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
throw new Error("tense not implemented yet");
|
throw new Error("tense not implemented yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
function isSingularAnimatePattern4(np: NPSelection): boolean {
|
function isMascSingAnimatePattern4(np: NPSelection): boolean {
|
||||||
if (np.type !== "noun") {
|
if (np.type !== "noun") {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return isPattern4Entry(np.entry) && np.entry.c.includes("anim.") && (np.number === "singular");
|
return isPattern4Entry(np.entry)
|
||||||
|
&& np.entry.c.includes("anim.")
|
||||||
|
&& (np.number === "singular")
|
||||||
|
&& (np.gender === "masc");
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,13 @@ export function psStringFromEntry(entry: T.PsString): T.PsString {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLong<U>(x: T.SingleOrLengthOpts<U>): U {
|
||||||
|
if ("long" in x) {
|
||||||
|
return x.long;
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
export function capitalizeFirstLetter(string: string) {
|
export function capitalizeFirstLetter(string: string) {
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
}
|
}
|
|
@ -25,7 +25,7 @@ type VPRendered = {
|
||||||
englishBase?: string[],
|
englishBase?: string[],
|
||||||
}
|
}
|
||||||
|
|
||||||
type VerbTense = "present" | "subjunctive" | "perfectivePast" | "imperfectivePast";
|
type VerbTense = "present" | "subjunctive" | "perfectiveFuture" | "imperfectiveFuture" | "perfectivePast" | "imperfectivePast";
|
||||||
|
|
||||||
type VerbSelection = {
|
type VerbSelection = {
|
||||||
type: "verb",
|
type: "verb",
|
||||||
|
@ -104,6 +104,7 @@ type Rendered<T extends NPSelection> = ReplaceKey<
|
||||||
ps: import("@lingdocs/pashto-inflector").Types.PsString[],
|
ps: import("@lingdocs/pashto-inflector").Types.PsString[],
|
||||||
e?: string,
|
e?: string,
|
||||||
inflected: boolean,
|
inflected: boolean,
|
||||||
|
person: T.Person,
|
||||||
};
|
};
|
||||||
// TODO: recursive changing this down into the possesor etc.
|
// TODO: recursive changing this down into the possesor etc.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue