ba particles working and a couple of bugs with past tense and nouns etc

This commit is contained in:
lingdocs 2022-03-20 11:05:17 +05:00
parent 004bdeb352
commit 9204ca150c
7 changed files with 96 additions and 50 deletions

View File

@ -14,6 +14,12 @@ const tenseOptions: { label: string, value: VerbTense }[] = [{
}, {
label: "subjunctive",
value: "subjunctive",
}, {
label: "imperf. future",
value: "imperfectiveFuture",
}, {
label: "perf. future",
value: "perfectiveFuture",
}, {
label: "simple past",
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>
<Select
value={verb && verb.verb.entry.ts.toString()}

View File

@ -8,7 +8,7 @@ import { useState } from "react";
import { nouns, verbs } from "../../words/words";
// 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 }) {
// eslint-disable-next-line
@ -35,9 +35,8 @@ function NPPicker({ np, onChange, counterPart }: { onChange: (nps: NPSelection |
}
}
return <div style={{ maxWidth: "300px"}}>
{!npType ?
<div>
{npTypes.map((npt) => (
{!npType ? <div className="text-center mt-3">
{npTypes.map((npt) => <div className="mb-2">
<button
key={npt}
type="button"
@ -46,7 +45,7 @@ function NPPicker({ np, onChange, counterPart }: { onChange: (nps: NPSelection |
>
{npt}
</button>
))}
</div>)}
</div>
: <button className="btn btn-sm btn-light mb-2" onClick={handleClear}>X</button>}
{np ?

View File

@ -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>
</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>
{pSpec.map((rw, i) => (
<tr>

View File

@ -5,6 +5,7 @@ import {
grammarUnits,
getVerbBlockPosFromPerson,
} from "@lingdocs/pashto-inflector";
import { hasBaParticle, psRemove } from "@lingdocs/pashto-inflector/dist/lib/p-text-helpers";
type ListOfEntities = (T.PsString & { isVerbPrefix?: boolean, prefixFollowedByParticle?: boolean })[][];
@ -49,11 +50,15 @@ function compilePs(
} : {},
};
}
const { hasBa, verbEntities } = compileVerbWNegative(head, rest, negative)
const entities: ListOfEntities = [
...nps,
...compileVerbWNegative(head, rest, negative),
...verbEntities,
];
const entitiesWKids = putKidsInKidsSection(entities, kids);
const entitiesWKids = putKidsInKidsSection(
entities,
hasBa ? [[grammarUnits.baParticle], ...kids] : kids,
);
return combineEntities(entitiesWKids);
}
@ -77,7 +82,10 @@ function shrinkEntitiesAndGatherKids(VP: VPRendered, form: FormVersion): { kids:
(VP.king === "object" && !removeKing && king) || (VP.servant === "object" && !shrinkServant)
);
return {
kids: [...toShrink ? [shrink(toShrink)] : []],
kids: [
...toShrink
? [shrink(toShrink)] : [],
],
NPs: [
...showSubject ? [main.subject] : [],
...(showObject && main.object) ? [main.object] : [],
@ -86,11 +94,7 @@ function shrinkEntitiesAndGatherKids(VP: VPRendered, form: FormVersion): { kids:
}
function shrink(np: Rendered<NPSelection>): T.PsString[] {
const person: T.Person = np.type === "participle"
? T.Person.ThirdPlurMale
// @ts-ignore
: np.person;
const [row, col] = getVerbBlockPosFromPerson(person);
const [row, col] = getVerbBlockPosFromPerson(np.person);
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) {
return [
return {
hasBa,
verbEntities: [
...head ? [[{...head, isVerbPrefix: true}]] : [],
rest,
];
],
};
}
const nu: T.PsString = { p: "نه", f: "nú" };
if (!head) {
return [
return {
hasBa,
verbEntities: [
[nu],
rest.map(r => removeAccents(r)),
];
],
};
}
// const regularPrefix = head.p === "و" || head.p === "وا";
// if (regularPrefix) {
// dashes for oo-nu etc
return [
return {
hasBa,
verbEntities: [
[{ ...removeAccents(head), isVerbPrefix: true }],
rest.map(r => concatPsString(nu, " ", removeAccents(r)))
];
rest.map(r => concatPsString(nu, " ", removeAccents(r))),
],
};
}
function compileEnglish(VP: VPRendered): string[] | undefined {

View File

@ -8,9 +8,11 @@ import {
conjugateVerb,
concatPsString,
removeAccents,
getPersonNumber,
} from "@lingdocs/pashto-inflector";
import {
psStringFromEntry,
getLong,
} from "../text-tools";
import {
getPersonFromNP,
@ -30,7 +32,7 @@ export function renderVP(VP: VPSelection): VPRendered {
const subjectPerson = getPersonFromNP(VP.subject);
const objectPerson = getPersonFromNP(VP.object);
// 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);
// Render Elements
return {
@ -88,6 +90,7 @@ function renderNounSelection(n: NounSelection, inflected: boolean): Rendered<Nou
})();
return {
...n,
person: getPersonNumber(n.gender, n.number),
inflected,
ps: pashto,
e: english,
@ -108,6 +111,7 @@ function renderParticipleSelection(p: ParticipleSelection, inflected: boolean):
return {
...p,
inflected,
person: T.Person.ThirdPlurMale,
// 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),
e: getEnglishParticiple(p.verb.entry),
@ -155,6 +159,9 @@ function renderEnglishVPBase({ subjectPerson, object, vs }: {
function isToBe(v: T.EnglishVerbConjugationEc): boolean {
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<
VerbTense,
(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]}`,
`should $SUBJ ${n ? " not" : ""} ${isToBe(ec) ? "be" : ec[0]}`,
]),
imperfectiveFuture: futureEngBuilder,
perfectiveFuture: futureEngBuilder,
imperfectivePast: (s: T.Person, ec: T.EnglishVerbConjugationEc, n: boolean) => ([
// - subj pastEquative (N && "not") ec.2 obj
`$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) => ([
`$SUBJ${isToBe(ec)
? ` ${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);
@ -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: {
mascSing: T.SingleOrLengthOpts<U>;
mascPlur: T.SingleOrLengthOpts<U>;
@ -291,6 +295,12 @@ function getTenseVerbForm(conj: T.VerbConjugation, tense: VerbTense): T.VerbForm
if (tense === "subjunctive") {
return conj.perfective.nonImperative;
}
if (tense === "imperfectiveFuture") {
return conj.imperfective.future;
}
if (tense === "perfectiveFuture") {
return conj.perfective.future;
}
if (tense === "imperfectivePast") {
return conj.imperfective.past;
}
@ -371,18 +381,21 @@ function isFirstOrSecondPersPronoun(o: "none" | NPSelection | T.Person.ThirdPlur
}
function isPerfective(t: VerbTense): boolean {
if (t === "present" || t === "imperfectivePast") {
if (t === "present" || t === "imperfectiveFuture" || t === "imperfectivePast") {
return false;
}
if (t === "perfectivePast" || t === "subjunctive") {
if (t === "perfectiveFuture" || t === "subjunctive" || t === "perfectivePast") {
return true;
}
throw new Error("tense not implemented yet");
}
function isSingularAnimatePattern4(np: NPSelection): boolean {
function isMascSingAnimatePattern4(np: NPSelection): boolean {
if (np.type !== "noun") {
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");
}

View File

@ -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) {
return string.charAt(0).toUpperCase() + string.slice(1);
}

View File

@ -25,7 +25,7 @@ type VPRendered = {
englishBase?: string[],
}
type VerbTense = "present" | "subjunctive" | "perfectivePast" | "imperfectivePast";
type VerbTense = "present" | "subjunctive" | "perfectiveFuture" | "imperfectiveFuture" | "perfectivePast" | "imperfectivePast";
type VerbSelection = {
type: "verb",
@ -104,6 +104,7 @@ type Rendered<T extends NPSelection> = ReplaceKey<
ps: import("@lingdocs/pashto-inflector").Types.PsString[],
e?: string,
inflected: boolean,
person: T.Person,
};
// TODO: recursive changing this down into the possesor etc.