some refactoring
This commit is contained in:
parent
a8bd1a337f
commit
e4cf7558ee
|
@ -5,6 +5,7 @@ import {
|
||||||
} from "./np-picker/picker-tools";
|
} from "./np-picker/picker-tools";
|
||||||
import {
|
import {
|
||||||
Types as T,
|
Types as T,
|
||||||
|
// ButtonSelect,
|
||||||
} from "@lingdocs/pashto-inflector";
|
} from "@lingdocs/pashto-inflector";
|
||||||
|
|
||||||
const tenseOptions: { label: string, value: VerbTense }[] = [{
|
const tenseOptions: { label: string, value: VerbTense }[] = [{
|
||||||
|
@ -42,6 +43,7 @@ function makeVerbSelection(verb: VerbEntry, oldVerbSelection?: VerbSelection): V
|
||||||
verb,
|
verb,
|
||||||
tense: oldVerbSelection ? oldVerbSelection.tense : "present",
|
tense: oldVerbSelection ? oldVerbSelection.tense : "present",
|
||||||
object,
|
object,
|
||||||
|
negative: oldVerbSelection ? oldVerbSelection.negative : false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +65,14 @@ function VerbPicker({ onChange, verb, verbs }: { verbs: VerbEntry[], verb: VerbS
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// function onPosNegSelect(value: string) {
|
||||||
|
// if (verb) {
|
||||||
|
// onChange({
|
||||||
|
// ...verb,
|
||||||
|
// negative: value === "true",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
return <div style={{ maxWidth: "225px" }}>
|
return <div style={{ maxWidth: "225px" }}>
|
||||||
<div>Verb:</div>
|
<div>Verb:</div>
|
||||||
<Select
|
<Select
|
||||||
|
@ -89,6 +99,21 @@ function VerbPicker({ onChange, verb, verbs }: { verbs: VerbEntry[], verb: VerbS
|
||||||
placeholder={verb ? tenseOptions.find(o => o.value === verb.tense)?.label : "Select Tense..."}
|
placeholder={verb ? tenseOptions.find(o => o.value === verb.tense)?.label : "Select Tense..."}
|
||||||
{...zIndexProps}
|
{...zIndexProps}
|
||||||
/>
|
/>
|
||||||
|
{/* The negative is not ready yet for people to use */}
|
||||||
|
{/* {verb && <div className="text-center my-3">
|
||||||
|
<ButtonSelect
|
||||||
|
small
|
||||||
|
value={verb.negative.toString()}
|
||||||
|
options={[{
|
||||||
|
label: "Pos.",
|
||||||
|
value: "false",
|
||||||
|
}, {
|
||||||
|
label: "Neg.",
|
||||||
|
value: "true",
|
||||||
|
}]}
|
||||||
|
handleChange={onPosNegSelect}
|
||||||
|
/>
|
||||||
|
</div>} */}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { renderVP, compileVP } from "../../lib/eval-vp";
|
import { renderVP, compileVP } from "../../lib/phrase-building";
|
||||||
import {
|
import {
|
||||||
InlinePs,
|
InlinePs,
|
||||||
defaultTextOptions as opts,
|
defaultTextOptions as opts,
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import {
|
||||||
|
Types as T,
|
||||||
|
concatPsString,
|
||||||
|
} from "@lingdocs/pashto-inflector";
|
||||||
|
|
||||||
|
const nu: T.PsString = { p: "نه", f: "nu" };
|
||||||
|
|
||||||
|
export function compileVP(VP: VPRendered): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] } {
|
||||||
|
function insertEWords(e: string, { subject, object }: { subject: string, object?: string }): string {
|
||||||
|
return e.replace("$SUBJ", subject).replace("$OBJ", object || "");
|
||||||
|
}
|
||||||
|
// TODO: display of short and long options etc.
|
||||||
|
const vPs = "long" in VP.verb.ps ? VP.verb.ps.long : VP.verb.ps;
|
||||||
|
const engSubj = VP.subject.e || undefined;
|
||||||
|
const engObj = (typeof VP.object === "object" && VP.object.e) ? VP.object.e : undefined;
|
||||||
|
// require all English parts for making the English phrase
|
||||||
|
const e = (VP.englishBase && engSubj && engObj) ? VP.englishBase.map(e => insertEWords(e, {
|
||||||
|
subject: engSubj,
|
||||||
|
object: engObj,
|
||||||
|
})) : undefined;
|
||||||
|
const obj = typeof VP.object === "object" ? VP.object : undefined;
|
||||||
|
const ps = VP.subject.ps.flatMap(s => (
|
||||||
|
obj ? obj.ps.flatMap(o => (
|
||||||
|
vPs.flatMap(v => (
|
||||||
|
VP.verb.negative
|
||||||
|
// this will not work yet for perfectives etc - super rough start
|
||||||
|
? concatPsString(s, " ", o, " ", nu, " ", v)
|
||||||
|
: concatPsString(s, " ", o, " ", v)
|
||||||
|
))
|
||||||
|
)) : vPs.flatMap(v => (
|
||||||
|
VP.verb.negative
|
||||||
|
? concatPsString(s, " ", nu, " ", v)
|
||||||
|
: concatPsString(s, " ", v)
|
||||||
|
))
|
||||||
|
));
|
||||||
|
return { ps, e };
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { renderVP } from "./render-vp";
|
||||||
|
import { compileVP } from "./compile-vp";
|
||||||
|
|
||||||
|
export {
|
||||||
|
renderVP,
|
||||||
|
compileVP,
|
||||||
|
};
|
|
@ -10,112 +10,120 @@ import {
|
||||||
} from "@lingdocs/pashto-inflector";
|
} from "@lingdocs/pashto-inflector";
|
||||||
import {
|
import {
|
||||||
psStringFromEntry,
|
psStringFromEntry,
|
||||||
} from "./text-tools";
|
} from "../text-tools";
|
||||||
|
|
||||||
export function renderVP(VP: VPSelection): VPRendered {
|
export function renderVP(VP: VPSelection): VPRendered {
|
||||||
// TODO: Will be based on past tense etc
|
// Sentence Rules Logic
|
||||||
const isPast = isPastTense(VP.verb.tense);
|
const isPast = isPastTense(VP.verb.tense);
|
||||||
const isTransitive = VP.object !== "none";
|
const isTransitive = VP.object !== "none";
|
||||||
const { king, /* servant */ } = getKingAndServant(isPast, isTransitive);
|
const { king, /* servant */ } = getKingAndServant(isPast, isTransitive);
|
||||||
console.log({ king, isPast, isTransitive });
|
const kingPerson = getPersonFromNP(VP[king]);
|
||||||
const verbPerson = getPersonFromNP(VP[king]);
|
|
||||||
const subjectPerson = getPersonFromNP(VP.subject);
|
const subjectPerson = getPersonFromNP(VP.subject);
|
||||||
|
// 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;
|
const inflectSubject = isPast && isTransitive;
|
||||||
console.log({ inflectSubject });
|
|
||||||
const subject: Rendered<NPSelection> = {
|
|
||||||
...VP.subject,
|
|
||||||
inflected: inflectSubject,
|
|
||||||
...textOfNP(VP.subject, inflectSubject, false),
|
|
||||||
};
|
|
||||||
const inflectObject = !isPast && isFirstOrSecondPersPronoun(VP.object);
|
const inflectObject = !isPast && isFirstOrSecondPersPronoun(VP.object);
|
||||||
const object: "none" | Rendered<NPSelection> | T.Person.ThirdPlurMale = typeof VP.object === "object"
|
// Render Elements
|
||||||
? {
|
return {
|
||||||
...VP.subject,
|
type: "VPRendered",
|
||||||
inflected: inflectObject,
|
subject: renderNPSelection(VP.subject, inflectSubject, false, "subject"),
|
||||||
...textOfNP(VP.object, inflectObject, true),
|
object: renderNPSelection(VP.object, inflectObject, true, "object"),
|
||||||
} : VP.object;
|
verb: renderVerbSelection(VP.verb, kingPerson),
|
||||||
|
englishBase: renderEnglishVPBase({
|
||||||
|
subjectPerson,
|
||||||
|
object: VP.object,
|
||||||
|
vs: VP.verb,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderNPSelection(NP: NPSelection, inflected: boolean, inflectEnglish: boolean, role: "subject"): Rendered<NPSelection>
|
||||||
|
function renderNPSelection(NP: NPSelection | ObjectNP, inflected: boolean, inflectEnglish: boolean, role: "object"): Rendered<NPSelection> | T.Person.ThirdPlurMale | "none";
|
||||||
|
function renderNPSelection(NP: NPSelection | ObjectNP, inflected: boolean, inflectEnglish: boolean, role: "subject" | "object"): Rendered<NPSelection> | T.Person.ThirdPlurMale | "none" {
|
||||||
|
if (typeof NP !== "object") {
|
||||||
|
if (role !== "object") {
|
||||||
|
throw new Error("ObjectNP only allowed for objects");
|
||||||
|
}
|
||||||
|
return NP;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...NP,
|
||||||
|
inflected,
|
||||||
|
...textOfNP(NP, inflected, inflectEnglish),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function renderVerbSelection(vs: VerbSelection, person: T.Person): VerbRendered {
|
||||||
|
const conjugations = conjugateVerb(vs.verb.entry, vs.verb.complement);
|
||||||
// TODO: error handle this?
|
// TODO: error handle this?
|
||||||
const conjugations = conjugateVerb(VP.verb.verb.entry, VP.verb.verb.complement);
|
|
||||||
// TODO: option to manually select these
|
// TODO: option to manually select these
|
||||||
const conj = "grammaticallyTransitive" in conjugations
|
const conj = "grammaticallyTransitive" in conjugations
|
||||||
? conjugations.grammaticallyTransitive
|
? conjugations.grammaticallyTransitive
|
||||||
: "stative" in conjugations
|
: "stative" in conjugations
|
||||||
? conjugations.stative
|
? conjugations.stative
|
||||||
: conjugations;
|
: conjugations;
|
||||||
|
// TODO: get the object person from the matrix on stative compounds
|
||||||
return {
|
return {
|
||||||
type: "VPRendered",
|
...vs,
|
||||||
subject,
|
person,
|
||||||
object,
|
ps: getPsVerbConjugation(conj, vs.tense, person),
|
||||||
verb: {
|
}
|
||||||
...VP.verb,
|
}
|
||||||
person: verbPerson,
|
|
||||||
ps: getPsVerbConjugation(conj, VP.verb.tense, verbPerson),
|
function renderEnglishVPBase({ subjectPerson, object, vs }: {
|
||||||
e: getEnglishVerbConjugation({
|
subjectPerson: T.Person,
|
||||||
subjectPerson,
|
object: NPSelection | ObjectNP,
|
||||||
object: VP.object,
|
vs: VerbSelection,
|
||||||
v: parseEc(VP.verb.verb.entry.ec || ""),
|
}): string[] {
|
||||||
ep: VP.verb.verb.entry.ep,
|
const ec = parseEc(vs.verb.entry.ec || "");
|
||||||
tense: VP.verb.tense,
|
const ep = vs.verb.entry.ep;
|
||||||
n: false,
|
const tense = vs.tense;
|
||||||
}),
|
function engEquative(tense: "past" | "present", s: T.Person): string {
|
||||||
},
|
const [row, col] = getVerbBlockPosFromPerson(s);
|
||||||
|
return grammarUnits.englishEquative[tense][row][col];
|
||||||
|
}
|
||||||
|
function engPresC(s: T.Person, ec: T.EnglishVerbConjugationEc | [string, string]): string {
|
||||||
|
function isThirdPersonSing(p: T.Person): boolean {
|
||||||
|
return (
|
||||||
|
p === T.Person.ThirdSingMale ||
|
||||||
|
p === T.Person.ThirdSingFemale
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return isThirdPersonSing(s) ? ec[1] : ec[0];
|
||||||
|
}
|
||||||
|
function isToBe(v: T.EnglishVerbConjugationEc): boolean {
|
||||||
|
return (v[2] === "being");
|
||||||
|
}
|
||||||
|
const builders: Record<
|
||||||
|
VerbTense,
|
||||||
|
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
||||||
|
> = {
|
||||||
|
present: (s: T.Person, ec: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||||
|
`$SUBJ ${isToBe(ec)
|
||||||
|
? `${engEquative("present", s)}${n ? " not" : ""}`
|
||||||
|
: `${n ? engPresC(s, ["don't", "doesn't"]) : ""} ${n ? ec[0] : engPresC(s, ec)}`}`,
|
||||||
|
`$SUBJ ${engEquative("present", s)}${n ? " not" : ""} ${ec[2]}`,
|
||||||
|
]),
|
||||||
|
subjunctive: (s: T.Person, ec: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||||
|
`that $SUBJ ${n ? " won't" : " will"} ${isToBe(ec) ? "be" : ec[0]}`,
|
||||||
|
`should $SUBJ ${n ? " not" : ""} ${isToBe(ec) ? "be" : ec[0]}`,
|
||||||
|
]),
|
||||||
|
imperfectivePast: (s: T.Person, ec: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||||
|
// - subj pastEquative (N && "not") ec.2 obj
|
||||||
|
`$SUBJ ${engEquative("past", s)}${n ? " not" : ""} ${ec[2]}`,
|
||||||
|
// - subj "would" (N && "not") ec.0 obj
|
||||||
|
`$SUBJ would${n ? " not" : ""} ${isToBe(ec) ? "be" : ec[0]}`,
|
||||||
|
// - subj pastEquative (N && "not") going to" ec.0 obj
|
||||||
|
`$SUBJ ${engEquative("past", s)}${n ? " not" : ""} going to ${isToBe(ec) ? "be" : ec[0]}`,
|
||||||
|
]),
|
||||||
|
perfectivePast: (s: T.Person, ec: T.EnglishVerbConjugationEc, n: boolean) => ([
|
||||||
|
`$SUBJ${isToBe(ec)
|
||||||
|
? ` ${engEquative("past", s)}${n ? " not" : ""}`
|
||||||
|
: `${n ? " did not" : ""} ${ec[3]}`}`,
|
||||||
|
]),
|
||||||
};
|
};
|
||||||
}
|
const base = builders[tense](subjectPerson, ec, vs.negative);
|
||||||
|
return base.map(b => `${b}${typeof object === "object" ? " $OBJ" : ""}${ep ? ` ${ep}` : ""}`);
|
||||||
export function compileVP(VP: VPRendered | VPSelection): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] } {
|
|
||||||
if (VP.type === "VPSelection") {
|
|
||||||
return compileVP(renderVP(VP));
|
|
||||||
}
|
|
||||||
function insertEWords(e: string, { subject, object }: { subject: string, object?: string }): string {
|
|
||||||
return e.replace("$SUBJ", subject).replace("$OBJ", object || "");
|
|
||||||
}
|
|
||||||
// TODO: display of short and long options etc.
|
|
||||||
const vPs = "long" in VP.verb.ps ? VP.verb.ps.long : VP.verb.ps;
|
|
||||||
const engSubj = VP.subject.e || undefined;
|
|
||||||
const engObj = (typeof VP.object === "object" && VP.object.e) ? VP.object.e : undefined;
|
|
||||||
// require all English parts for making the English phrase
|
|
||||||
const e = (VP.verb.e && engSubj && engObj) ? VP.verb.e.map(e => insertEWords(e, {
|
|
||||||
subject: engSubj,
|
|
||||||
object: engObj,
|
|
||||||
})) : undefined;
|
|
||||||
const obj = typeof VP.object === "object" ? VP.object : undefined;
|
|
||||||
const ps = VP.subject.ps.flatMap(s => (
|
|
||||||
obj ? obj.ps.flatMap(o => (
|
|
||||||
vPs.flatMap(v => (
|
|
||||||
concatPsString(s, " ", o, " ", v)
|
|
||||||
))
|
|
||||||
)) : vPs.flatMap(v => (
|
|
||||||
concatPsString(s, " ", v)
|
|
||||||
))
|
|
||||||
));
|
|
||||||
return { ps, e };
|
|
||||||
}
|
|
||||||
|
|
||||||
function isPastTense(tense: VerbTense): boolean {
|
|
||||||
return tense.toLowerCase().includes("past");
|
|
||||||
}
|
|
||||||
|
|
||||||
function getKingAndServant(isPast: boolean, isTransitive: boolean):
|
|
||||||
{ king: "subject", servant: "object" } |
|
|
||||||
{ king: "object", servant: "subject" } |
|
|
||||||
{ king: "subject", servant: undefined } {
|
|
||||||
if (!isTransitive) {
|
|
||||||
return { king: "subject", servant: undefined };
|
|
||||||
}
|
|
||||||
return isPast ? {
|
|
||||||
king: "object",
|
|
||||||
servant: "subject",
|
|
||||||
} : {
|
|
||||||
king: "subject",
|
|
||||||
servant: "object",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function isFirstOrSecondPersPronoun(o: "none" | NPSelection | T.Person.ThirdPlurMale): boolean {
|
|
||||||
if (typeof o !== "object") return false;
|
|
||||||
if (o.type !== "pronoun") return false;
|
|
||||||
return [0,1,2,3,6,7,8,9].includes(o.person);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPsVerbConjugation(conj: T.VerbConjugation, tense: VerbTense, person: T.Person): T.SingleOrLengthOpts<T.PsString[]> {
|
function getPsVerbConjugation(conj: T.VerbConjugation, tense: VerbTense, person: T.Person): T.SingleOrLengthOpts<T.PsString[]> {
|
||||||
|
@ -156,63 +164,7 @@ function getTenseVerbForm(conj: T.VerbConjugation, tense: VerbTense): T.VerbForm
|
||||||
throw new Error("unknown tense");
|
throw new Error("unknown tense");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEnglishVerbConjugation({ subjectPerson, object, ep, v, tense, n }: {
|
function getPersonFromNP(np: NPSelection | ObjectNP): T.Person {
|
||||||
subjectPerson: T.Person,
|
|
||||||
object: "none" | NPSelection | T.Person.ThirdPlurMale,
|
|
||||||
v: T.EnglishVerbConjugationEc,
|
|
||||||
ep: string | undefined,
|
|
||||||
tense: VerbTense,
|
|
||||||
n: boolean,
|
|
||||||
}): string[] {
|
|
||||||
function engEquative(tense: "past" | "present", s: T.Person): string {
|
|
||||||
const [row, col] = getVerbBlockPosFromPerson(s);
|
|
||||||
return grammarUnits.englishEquative[tense][row][col];
|
|
||||||
}
|
|
||||||
function engPresC(s: T.Person, ec: T.EnglishVerbConjugationEc | [string, string]): string {
|
|
||||||
function isThirdPersonSing(p: T.Person): boolean {
|
|
||||||
return (
|
|
||||||
p === T.Person.ThirdSingMale ||
|
|
||||||
p === T.Person.ThirdSingFemale
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return isThirdPersonSing(s) ? ec[1] : ec[0];
|
|
||||||
}
|
|
||||||
function isToBe(v: T.EnglishVerbConjugationEc): boolean {
|
|
||||||
return (v[2] === "being");
|
|
||||||
}
|
|
||||||
const builders: Record<
|
|
||||||
VerbTense,
|
|
||||||
(s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => string[]
|
|
||||||
> = {
|
|
||||||
present: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
|
||||||
`$SUBJ ${isToBe(v)
|
|
||||||
? `${engEquative("present", s)}${n ? " not" : ""}`
|
|
||||||
: `${n ? engPresC(s, ["don't", "doesn't"]) : ""} ${n ? v[0] : engPresC(s, v)}`}`,
|
|
||||||
`$SUBJ ${engEquative("present", s)}${n ? " not" : ""} ${v[2]}`,
|
|
||||||
]),
|
|
||||||
subjunctive: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
|
||||||
`that $SUBJ ${n ? " won't" : " will"} ${isToBe(v) ? "be" : v[0]}`,
|
|
||||||
`should $SUBJ ${n ? " not" : ""} ${isToBe(v) ? "be" : v[0]}`,
|
|
||||||
]),
|
|
||||||
imperfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
|
||||||
// - subj pastEquative (N && "not") v.2 obj
|
|
||||||
`$SUBJ ${engEquative("past", s)}${n ? " not" : ""} ${v[2]}`,
|
|
||||||
// - subj "would" (N && "not") v.0 obj
|
|
||||||
`$SUBJ would${n ? " not" : ""} ${isToBe(v) ? "be" : v[0]}`,
|
|
||||||
// - subj pastEquative (N && "not") going to" v.0 obj
|
|
||||||
`$SUBJ ${engEquative("past", s)}${n ? " not" : ""} going to ${isToBe(v) ? "be" : v[0]}`,
|
|
||||||
]),
|
|
||||||
perfectivePast: (s: T.Person, v: T.EnglishVerbConjugationEc, n: boolean) => ([
|
|
||||||
`$SUBJ${isToBe(v)
|
|
||||||
? ` ${engEquative("past", s)}${n ? " not" : ""}`
|
|
||||||
: `${n ? " did not" : ""} ${v[3]}`}`,
|
|
||||||
]),
|
|
||||||
};
|
|
||||||
const base = builders[tense](subjectPerson, v, n);
|
|
||||||
return base.map(b => `${b}${typeof object === "object" ? " $OBJ" : ""}${ep ? ` ${ep}` : ""}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPersonFromNP(np: NPSelection | T.Person.ThirdPlurMale | "none"): T.Person {
|
|
||||||
if (np === "none") {
|
if (np === "none") {
|
||||||
throw new Error("empty entity");
|
throw new Error("empty entity");
|
||||||
}
|
}
|
||||||
|
@ -247,6 +199,19 @@ function textOfParticiple({ verb: { entry }}: ParticipleSelection, inflected: bo
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEnglishParticiple(entry: T.DictionaryEntry): string {
|
||||||
|
if (!entry.ec) {
|
||||||
|
console.log("errored participle");
|
||||||
|
console.log(entry);
|
||||||
|
throw new Error("no english information for participle");
|
||||||
|
}
|
||||||
|
const ec = parseEc(entry.ec);
|
||||||
|
const participle = ec[2];
|
||||||
|
return (entry.ep)
|
||||||
|
? `${participle} ${entry.ep}`
|
||||||
|
: participle;
|
||||||
|
}
|
||||||
|
|
||||||
function textOfPronoun(p: PronounSelection, inflected: boolean, englishInflected: boolean): { ps: T.PsString[], e: string } {
|
function textOfPronoun(p: PronounSelection, inflected: boolean, englishInflected: boolean): { ps: T.PsString[], e: string } {
|
||||||
// TODO: Will need to handle inflecting and inflecting english pronouns etc.
|
// TODO: Will need to handle inflecting and inflecting english pronouns etc.
|
||||||
const [row, col] = getVerbBlockPosFromPerson(p.person);
|
const [row, col] = getVerbBlockPosFromPerson(p.person);
|
||||||
|
@ -256,6 +221,24 @@ function textOfPronoun(p: PronounSelection, inflected: boolean, englishInflected
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function textOfNoun(n: NounSelection, inflected: boolean): { ps: T.PsString[], e: string } {
|
||||||
|
const english = getEnglishFromNoun(n.entry, n.number);
|
||||||
|
const pashto = ((): T.PsString[] => {
|
||||||
|
const infs = inflectWord(n.entry);
|
||||||
|
const ps = n.number === "singular"
|
||||||
|
? getInf(infs, "inflections", n.gender, false, inflected)
|
||||||
|
: [
|
||||||
|
...getInf(infs, "plural", n.gender, true, inflected),
|
||||||
|
...getInf(infs, "arabicPlural", n.gender, true, inflected),
|
||||||
|
...getInf(infs, "inflections", n.gender, true, inflected),
|
||||||
|
];
|
||||||
|
return ps.length > 0
|
||||||
|
? ps
|
||||||
|
: [psStringFromEntry(n.entry)];
|
||||||
|
})();
|
||||||
|
return { ps: pashto, e: english };
|
||||||
|
}
|
||||||
|
|
||||||
function getEnglishFromNoun(entry: T.DictionaryEntry, number: NounNumber): string {
|
function getEnglishFromNoun(entry: T.DictionaryEntry, number: NounNumber): string {
|
||||||
const articles = {
|
const articles = {
|
||||||
singular: "(a/the)",
|
singular: "(a/the)",
|
||||||
|
@ -276,24 +259,6 @@ function getEnglishFromNoun(entry: T.DictionaryEntry, number: NounNumber): strin
|
||||||
return addArticle(e.singular);
|
return addArticle(e.singular);
|
||||||
}
|
}
|
||||||
|
|
||||||
function textOfNoun(n: NounSelection, inflected: boolean): { ps: T.PsString[], e: string } {
|
|
||||||
const english = getEnglishFromNoun(n.entry, n.number);
|
|
||||||
const pashto = ((): T.PsString[] => {
|
|
||||||
const infs = inflectWord(n.entry);
|
|
||||||
const ps = n.number === "singular"
|
|
||||||
? getInf(infs, "inflections", n.gender, false, inflected)
|
|
||||||
: [
|
|
||||||
...getInf(infs, "plural", n.gender, true, inflected),
|
|
||||||
...getInf(infs, "arabicPlural", n.gender, true, inflected),
|
|
||||||
...getInf(infs, "inflections", n.gender, true, inflected),
|
|
||||||
];
|
|
||||||
return ps.length > 0
|
|
||||||
? ps
|
|
||||||
: [psStringFromEntry(n.entry)];
|
|
||||||
})();
|
|
||||||
return { ps: pashto, e: english };
|
|
||||||
}
|
|
||||||
|
|
||||||
function getInf(infs: T.InflectorOutput, t: "plural" | "arabicPlural" | "inflections", gender: T.Gender, plural: boolean, inflected: boolean): T.PsString[] {
|
function getInf(infs: T.InflectorOutput, t: "plural" | "arabicPlural" | "inflections", gender: T.Gender, plural: boolean, inflected: boolean): T.PsString[] {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (infs && t in infs && infs[t] !== undefined && gender in infs[t] && infs[t][gender] !== undefined) {
|
if (infs && t in infs && infs[t] !== undefined && gender in infs[t] && infs[t][gender] !== undefined) {
|
||||||
|
@ -306,15 +271,28 @@ function getInf(infs: T.InflectorOutput, t: "plural" | "arabicPlural" | "inflect
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEnglishParticiple(entry: T.DictionaryEntry): string {
|
function isPastTense(tense: VerbTense): boolean {
|
||||||
if (!entry.ec) {
|
return tense.toLowerCase().includes("past");
|
||||||
console.log("errored participle");
|
}
|
||||||
console.log(entry);
|
|
||||||
throw new Error("no english information for participle");
|
function getKingAndServant(isPast: boolean, isTransitive: boolean):
|
||||||
}
|
{ king: "subject", servant: "object" } |
|
||||||
const ec = parseEc(entry.ec);
|
{ king: "object", servant: "subject" } |
|
||||||
const participle = ec[2];
|
{ king: "subject", servant: undefined } {
|
||||||
return (entry.ep)
|
if (!isTransitive) {
|
||||||
? `${participle} ${entry.ep}`
|
return { king: "subject", servant: undefined };
|
||||||
: participle;
|
}
|
||||||
|
return isPast ? {
|
||||||
|
king: "object",
|
||||||
|
servant: "subject",
|
||||||
|
} : {
|
||||||
|
king: "subject",
|
||||||
|
servant: "object",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFirstOrSecondPersPronoun(o: "none" | NPSelection | T.Person.ThirdPlurMale): boolean {
|
||||||
|
if (typeof o !== "object") return false;
|
||||||
|
if (o.type !== "pronoun") return false;
|
||||||
|
return [0,1,2,3,6,7,8,9].includes(o.person);
|
||||||
}
|
}
|
|
@ -16,8 +16,9 @@ type VPSelection = {
|
||||||
type VPRendered = {
|
type VPRendered = {
|
||||||
type: "VPRendered",
|
type: "VPRendered",
|
||||||
subject: Rendered<NPSelection>,
|
subject: Rendered<NPSelection>,
|
||||||
object: "none" | Rendered<NPSelection> | import("@lingdocs/pashto-inflector").Types.Person.ThirdPlurMale,
|
object: Rendered<NPSelection> | ObjectNP,
|
||||||
verb: VerbRendered,
|
verb: VerbRendered,
|
||||||
|
englishBase?: string[],
|
||||||
}
|
}
|
||||||
|
|
||||||
type VerbTense = "present" | "subjunctive" | "perfectivePast" | "imperfectivePast";
|
type VerbTense = "present" | "subjunctive" | "perfectivePast" | "imperfectivePast";
|
||||||
|
@ -27,6 +28,7 @@ type VerbSelection = {
|
||||||
verb: VerbEntry,
|
verb: VerbEntry,
|
||||||
tense: VerbTense,
|
tense: VerbTense,
|
||||||
object: VerbObject,
|
object: VerbObject,
|
||||||
|
negative: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
type VerbRendered = Omit<VerbSelection, "object"> & {
|
type VerbRendered = Omit<VerbSelection, "object"> & {
|
||||||
|
@ -34,22 +36,23 @@ type VerbRendered = Omit<VerbSelection, "object"> & {
|
||||||
import("@lingdocs/pashto-inflector").Types.PsString[]
|
import("@lingdocs/pashto-inflector").Types.PsString[]
|
||||||
>,
|
>,
|
||||||
person: import("@lingdocs/pashto-inflector").Types.Person,
|
person: import("@lingdocs/pashto-inflector").Types.Person,
|
||||||
e?: string[],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type VerbObject = // intransitive verb
|
type VerbObject =
|
||||||
"none" |
|
|
||||||
// transitive verb - object not selected yet
|
// transitive verb - object not selected yet
|
||||||
undefined |
|
undefined |
|
||||||
// transitive verb - obect selected
|
// transitive verb - obect selected
|
||||||
NPSelection |
|
NPSelection |
|
||||||
// grammatically transitive verb with unspoken 3rd pers masc plur entity
|
// grammatically transitive verb with unspoken 3rd pers masc plur entity
|
||||||
import("@lingdocs/pashto-inflector").Types.Person.ThirdPlurMale;
|
// or intransitive "none"
|
||||||
|
ObjectNP
|
||||||
|
|
||||||
type NPSelection = NounSelection | PronounSelection | ParticipleSelection;
|
type NPSelection = NounSelection | PronounSelection | ParticipleSelection;
|
||||||
|
|
||||||
type NPType = "noun" | "pronoun" | "participle";
|
type NPType = "noun" | "pronoun" | "participle";
|
||||||
|
|
||||||
|
type ObjectNP = "none" | import("@lingdocs/pashto-inflector").Types.Person.ThirdPlurMale;
|
||||||
|
|
||||||
// TODO require/import Person and PsString
|
// TODO require/import Person and PsString
|
||||||
type NounSelection = {
|
type NounSelection = {
|
||||||
type: "noun",
|
type: "noun",
|
||||||
|
|
Loading…
Reference in New Issue