very beta functionality for showing the English transations of sentences in the conjugation viewer. To do this you need to have a verb with the 'ec' field showing the English conjugation info from the dictionary.

This commit is contained in:
lingdocs 2021-07-04 12:55:26 +03:00
parent 1d465c61ef
commit aee3257ea3
10 changed files with 710 additions and 429 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@lingdocs/pashto-inflector",
"version": "0.4.6",
"version": "0.4.7",
"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",

View File

@ -40,7 +40,7 @@ const transitivities: T.Transitivity[] = [
"grammatically transitive",
];
const allVerbs = verbs.map((v: any) => ({
const allVerbs = verbs.map((v: { entry: T.DictionaryEntry, complement?: T.DictionaryEntry }) => ({
verb: v,
info: getVerbInfo(v.entry, v.complement),
}));
@ -311,6 +311,7 @@ function App() {
{conjugation && <ConjugationViewer
conjugation={conjugation}
textOptions={textOptions}
ec={v ? v.verb.entry.ec : undefined}
/>}
</div>
</main>

View File

@ -17,6 +17,7 @@ import {
personIsAllowed,
randomPerson,
incrementPerson,
parseEc,
} from "../lib/misc-helpers";
import * as T from "../types";
@ -170,9 +171,10 @@ const initialState: State = {
formsOpened: [],
};
function ConjugationViewer({ conjugation, textOptions }: {
function ConjugationViewer({ conjugation, textOptions, ec }: {
conjugation: T.VerbOutput,
textOptions: T.TextOptions,
ec?: string | undefined,
}) {
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
@ -194,6 +196,7 @@ function ConjugationViewer({ conjugation, textOptions }: {
const verbConj = (verbConj1.singularForm && state.compoundComplementVersionSelected === "sing")
? verbConj1.singularForm
: verbConj1;
const englishConjugation = parseEc(ec);
useEffect(() => {
localStorage.setItem(stateLocalStorageName, JSON.stringify(state));
@ -209,6 +212,7 @@ function ConjugationViewer({ conjugation, textOptions }: {
subject: state.subject,
object: state.object,
negative: state.negative,
englishConjugation,
});
return <div className="mb-4">
{"transitive" in conjugation && <div className="text-center my-2">

View File

@ -29,15 +29,21 @@ const indentR = {
paddingLeft: "1rem",
};
const highlight = {
background: "yellow",
};
const title: CSSProperties = {
fontWeight: "bolder",
marginBottom: "0.5rem",
marginTop: "0.5rem",
};
export function RootsAndStems({ textOptions, info }: {
export function RootsAndStems({ textOptions, info, hidePastParticiple, highlighted }: {
textOptions: T.TextOptions,
info: T.NonComboVerbInfo,
hidePastParticiple?: boolean,
highlighted?: ("imperfective root" | "perfective root" | "imperfective stem" | "perfective stem" | "past participle")[],
}) {
const hasPerfectiveSplit = !!(info.root.perfectiveSplit || info.stem.perfectiveSplit);
const showPersInf = hasPersInfs(info);
@ -64,7 +70,7 @@ export function RootsAndStems({ textOptions, info }: {
margin: "0 auto",
backgroundImage: `url(${fadedTree})`,
backgroundRepeat: "no-repeat",
backgroundPosition: "50% 35%",
backgroundPosition: hidePastParticiple ? "50% 45%" : "50% 35%",
backgroundSize: "50%",
}}>
{/* <div style={{
@ -103,7 +109,7 @@ export function RootsAndStems({ textOptions, info }: {
</div>
</div>
<div className={rowClass}>
<div className={colClass}>
<div className={colClass} style={highlighted?.includes("imperfective stem") ? highlight : {}}>
<div style={title}>
<div>Imperfective Stem</div>
</div>
@ -115,7 +121,7 @@ export function RootsAndStems({ textOptions, info }: {
/>
</div>
</div>
<div className={colClass}>
<div className={colClass} style={highlighted?.includes("perfective stem") ? highlight : {}}>
<div style={title}>
<div>Perfective Stem</div>
</div>
@ -129,7 +135,7 @@ export function RootsAndStems({ textOptions, info }: {
</div>
</div>
<div className={rowClass}>
<div className={colClass}>
<div className={colClass} style={highlighted?.includes("imperfective root") ? highlight : {}}>
<div style={title}>
<div>Imperfective Root</div>
</div>
@ -140,7 +146,7 @@ export function RootsAndStems({ textOptions, info }: {
/>
</div>
</div>
<div className={colClass}>
<div className={colClass} style={highlighted?.includes("perfective root") ? highlight : {}}>
<div>
<div style={title}>
<div>Perfective Root</div>
@ -154,13 +160,13 @@ export function RootsAndStems({ textOptions, info }: {
</div>
</div>
</div>
<div className="text-center">
{!hidePastParticiple && <div className="text-center" style={highlighted?.includes("imperfective stem") ? highlight : {}}>
<div style={title}>Past Participle</div>
<VerbInfoItemDisplay
item={pickPersInf(info.participle.past, persInf)}
textOptions={textOptions}
/>
</div>
</div>}
</div>
</div>
</div>

View File

@ -63,7 +63,7 @@ type Pronouns = undefined | {
const nuParticle = { p: "نه", f: "nú" };
export default function addPronouns({ s, subject, object, info, displayForm, intransitive, ergative, matrixKey, negative }: {
export default function addPronouns({ s, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative }: {
s: T.SentenceForm,
subject: T.Person,
object: T.Person,
@ -73,13 +73,14 @@ export default function addPronouns({ s, subject, object, info, displayForm, int
ergative: boolean,
matrixKey: T.PersonInflectionsField,
negative: boolean,
englishConjugation?: T.EnglishVerbConjugation,
}): T.SentenceForm {
if ("long" in s) {
return {
long: addPronouns({ s: s.long, subject, object, info, displayForm, intransitive, ergative, matrixKey, negative }) as T.ArrayOneOrMore<T.PsString>,
short: addPronouns({ s: s.short, subject, object, info, displayForm, intransitive, ergative, matrixKey, negative }) as T.ArrayOneOrMore<T.PsString>,
long: addPronouns({ s: s.long, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative }) as T.ArrayOneOrMore<T.PsString>,
short: addPronouns({ s: s.short, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative }) as T.ArrayOneOrMore<T.PsString>,
...s.mini ? {
mini: addPronouns({ s: s.mini, subject, object, info, displayForm, intransitive, ergative, matrixKey, negative }) as T.ArrayOneOrMore<T.PsString>,
mini: addPronouns({ s: s.mini, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative }) as T.ArrayOneOrMore<T.PsString>,
} : {},
}
}
@ -124,6 +125,11 @@ export default function addPronouns({ s, subject, object, info, displayForm, int
object: nearPronounPossible(object) ? [objectPronoun, nearObjectPronoun] : objectPronoun,
mini: miniPronoun,
};
const english = (displayForm.englishBuilder && englishConjugation)
? displayForm.englishBuilder(subject, englishConjugation, negative).map(sen => (
intransitive ? sen : `${sen} ${engObj(object)}`
)).join(" / ")
: undefined;
function attachPronounsToVariation(ps: T.PsString, prns: Pronouns): T.ArrayOneOrMore<T.PsString> {
if (!prns) {
@ -170,7 +176,7 @@ export default function addPronouns({ s, subject, object, info, displayForm, int
...canWorkWithOnlyMini
? makeOnlyMiniForm(ps, splitHead, displayForm, info, negative, prns.mini)
: [],
] as T.ArrayOneOrMore<T.PsString>;
].map((ps) => english ? { ...ps, e: english } : ps) as T.ArrayOneOrMore<T.PsString>;
}
// @ts-ignore
@ -485,3 +491,21 @@ function getObjComplement(info: T.NonComboVerbInfo): T.PsString | undefined {
(info.objComplement.plural ? info.objComplement.plural : info.objComplement.entry) :
undefined;
}
function engObj(s: T.Person): string {
return (s === T.Person.FirstSingMale || s === T.Person.FirstSingFemale)
? "me"
: (s === T.Person.FirstPlurMale || s === T.Person.FirstPlurFemale)
? "us"
: (s === T.Person.SecondSingMale || s === T.Person.SecondSingFemale)
? "you"
: (s === T.Person.SecondPlurMale || s === T.Person.SecondPlurFemale)
? "you (pl.)"
: (s === T.Person.ThirdSingMale)
? "him/it"
: (s === T.Person.ThirdSingFemale)
? "her/it"
: (s === T.Person.ThirdPlurMale)
? "them"
: "them (f.)";
}

File diff suppressed because it is too large Load Diff

View File

@ -149,6 +149,31 @@ export const subjPastEquative: T.PsString = {
f: "w" + aayTail.f,
};
export const englishEquative: {
past: T.EnglishBlock,
present: T.EnglishBlock,
// present: T.VerbBlock,
// subjunctive: T.VerbBlock,
// hypothetical: T.VerbBlock,
} = {
past: [
["was", "were"],
["was", "were"],
["were", "were"],
["were", "were"],
["was", "were"],
["was", "were"],
],
present: [
["am", "are"],
["am", "are"],
["are", "are"],
["are", "are"],
["is", "are"],
["is", "are"],
],
}
export const equativeEndings: {
past: T.LengthOptions<T.VerbBlock>,
present: T.VerbBlock,

View File

@ -0,0 +1,18 @@
/**
* Copyright (c) 2021 lingdocs.com
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import {
parseEc,
} from "./misc-helpers";
test("parseEc should work", () => {
expect(parseEc("walk")).toEqual(["walk", "walks", "walking", "walked", "walked"]);
expect(parseEc("scare")).toEqual(["scare", "scares", "scaring", "scared", "scared"]);
expect(parseEc("sew,sews,sewing,sewed,sown")).toEqual(["sew", "sews", "sewing", "sewed", "sown"]);
expect(parseEc(" sew, sews,sewing ,sewed, sown")).toEqual(["sew", "sews", "sewing", "sewed", "sown"]);
});

View File

@ -206,6 +206,30 @@ export function isNounAdjOrVerb(entry: T.DictionaryEntry): "nounAdj" | "verb" |
return false;
}
/**
* takes the ec field from a dictionary entry and produces an array of an EnglishVerbConjugation
* for use with the conjugations display for showing English translation sentences of various verb
* forms and conjugations
*
* @param ec
* @returns
*/
export function parseEc(ec: string | undefined): T.EnglishVerbConjugation | undefined {
function makeRegularConjugations(s: string): T.EnglishVerbConjugation {
const b = (s.slice(-1) === "e")
? s.slice(0, -1)
: s;
return [`${s}`, `${s}s`, `${b}ing`, `${b}ed`, `${b}ed`];
}
if (!ec) {
return undefined;
}
const items = ec.split(",").map(x => x.trim());
return (items.length !== 5)
? makeRegularConjugations(items[0])
: [items[0], items[1], items[2], items[3], items[4]];
}
// not being used
// export function isImperativeBlock(f: any): boolean {
// function isPersonLine(g: any): boolean {

View File

@ -106,6 +106,9 @@ export type DictionaryEntry = {
// PHONETICS - PASHTO - DIACRITICS INFO
/** Is an exception to the rules of diacritics for Pashto/Phonetics */
diacExcept?: boolean;
/** the English conjugations of a verb comma seperated set of 5 ie. "see,sees,seeing,saw,seen" or single word ie. "walk" if regular */
ec?: string;
}
export type DictionaryEntryTextField = "p" | "f" | "e" | "c" | "infap" | "infaf" | "infbp" | "infbf" | "app" | "apf" | "ppp" | "ppf" | "psp" | "psf" | "ssp" | "ssf" | "prp" | "prf" | "pprtp" | "pprtf" | "tppp" | "tppf";
@ -383,6 +386,9 @@ export type ArrayOneOrMore<T> = {
0: T
} & Array<T>
/* i.e. ["eat", "eats", "eating", "ate", "eaten"] */
export type EnglishVerbConjugation = [string, string, string, string, string];
export type DisplayFormItem = DisplayForm | DisplayFormSubgroup | DisplayFormForSentence;
export type DisplayForm = {
@ -390,6 +396,7 @@ export type DisplayForm = {
aspect?: Aspect,
form: VerbForm | ImperativeForm | ParticipleForm | SentenceForm,
advanced?: boolean,
englishBuilder?: (subject: Person, ec: EnglishVerbConjugation, neg: boolean) => string[],
formula: React.ReactNode,
explanation: React.ReactNode,
sentence?: boolean,
@ -402,6 +409,7 @@ export type DisplayFormForSentence = {
aspect?: Aspect,
form: VerbForm,
advanced?: boolean,
englishBuilder?: (subject: Person, ec: EnglishVerbConjugation, neg: boolean) => string[],
formula: React.ReactNode,
secondPronounNeeded?: boolean,
explanation: React.ReactNode,