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", "name": "@lingdocs/pashto-inflector",
"version": "0.4.6", "version": "0.4.7",
"author": "lingdocs.com", "author": "lingdocs.com",
"description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations", "description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations",
"homepage": "https://verbs.lingdocs.com", "homepage": "https://verbs.lingdocs.com",

View File

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

View File

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

View File

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

View File

@ -63,7 +63,7 @@ type Pronouns = undefined | {
const nuParticle = { p: "نه", f: "nú" }; 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, s: T.SentenceForm,
subject: T.Person, subject: T.Person,
object: T.Person, object: T.Person,
@ -73,13 +73,14 @@ export default function addPronouns({ s, subject, object, info, displayForm, int
ergative: boolean, ergative: boolean,
matrixKey: T.PersonInflectionsField, matrixKey: T.PersonInflectionsField,
negative: boolean, negative: boolean,
englishConjugation?: T.EnglishVerbConjugation,
}): T.SentenceForm { }): T.SentenceForm {
if ("long" in s) { if ("long" in s) {
return { return {
long: addPronouns({ s: s.long, 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, 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 ? { ...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, object: nearPronounPossible(object) ? [objectPronoun, nearObjectPronoun] : objectPronoun,
mini: miniPronoun, 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> { function attachPronounsToVariation(ps: T.PsString, prns: Pronouns): T.ArrayOneOrMore<T.PsString> {
if (!prns) { if (!prns) {
@ -170,7 +176,7 @@ export default function addPronouns({ s, subject, object, info, displayForm, int
...canWorkWithOnlyMini ...canWorkWithOnlyMini
? makeOnlyMiniForm(ps, splitHead, displayForm, info, negative, prns.mini) ? 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 // @ts-ignore
@ -485,3 +491,21 @@ function getObjComplement(info: T.NonComboVerbInfo): T.PsString | undefined {
(info.objComplement.plural ? info.objComplement.plural : info.objComplement.entry) : (info.objComplement.plural ? info.objComplement.plural : info.objComplement.entry) :
undefined; 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.)";
}

View File

@ -6,13 +6,31 @@
* *
*/ */
// FOR ENGLISH FORMS
// GIVEN VERB INFO LIKE THIS
// ["hit", "hits", "hitting", "hit", "hit"]
// ["eat", "eats", "eating", "ate", "eaten"]
// ["see", "sees", "seeing", "saw", "seen"]
// Present Perfect
// Past Perfect
// - subj "had" (N && "not") v.4 obj
// Future Perfect
// - subj "will have" (N && "not") v.4 obj
import { import {
getPersonInflectionsKey, getPersonInflectionsKey,
pickPersInf, pickPersInf,
getPersonFromVerbForm, getPersonFromVerbForm,
getBlockRowCol,
} from "./misc-helpers"; } from "./misc-helpers";
import addPronouns from "./add-pronouns"; import addPronouns from "./add-pronouns";
import * as T from "../types"; import * as T from "../types";
import { englishEquative } from "./grammar-units";
type FilterFunc = (form: any) => boolean; type FilterFunc = (form: any) => boolean;
type MapFunc = (opts: { type MapFunc = (opts: {
@ -21,6 +39,7 @@ type MapFunc = (opts: {
displayForm: T.DisplayFormForSentence, displayForm: T.DisplayFormForSentence,
info: T.NonComboVerbInfo, info: T.NonComboVerbInfo,
negative: boolean, negative: boolean,
englishConjugation?: T.EnglishVerbConjugation,
}) => T.DisplayFormItem; }) => T.DisplayFormItem;
/** /**
@ -67,22 +86,22 @@ const formMap = (
subject: T.Person, subject: T.Person,
object: T.Person, object: T.Person,
negative: boolean, negative: boolean,
englishConjugation?: T.EnglishVerbConjugation,
): T.DisplayFormItem[] => { ): T.DisplayFormItem[] => {
return ( return input.map((f) => (
input.map((f) => (
"content" in f "content" in f
? { ...f, content: formMap(f.content, func, info, subject, object, negative) } ? { ...f, content: formMap(f.content, func, info, subject, object, negative, englishConjugation) }
: func({ displayForm: f as T.DisplayFormForSentence, info, subject, object, negative }) : func({ displayForm: f as T.DisplayFormForSentence, info, subject, object, negative, englishConjugation })
)) ));
);
}; };
const makeSentence = ({ subject, object, info, displayForm, negative }: { const makeSentence = ({ subject, object, info, displayForm, englishConjugation, negative }: {
subject: T.Person, subject: T.Person,
object: T.Person, object: T.Person,
info: T.NonComboVerbInfo, info: T.NonComboVerbInfo,
displayForm: T.DisplayFormForSentence, displayForm: T.DisplayFormForSentence,
negative: boolean, negative: boolean,
englishConjugation?: T.EnglishVerbConjugation,
}): T.DisplayForm => { }): T.DisplayForm => {
const intransitive = info.transitivity === "intransitive" || !!displayForm.passive; const intransitive = info.transitivity === "intransitive" || !!displayForm.passive;
const ergative = !intransitive && !!displayForm.past; const ergative = !intransitive && !!displayForm.past;
@ -107,6 +126,7 @@ const makeSentence = ({ subject, object, info, displayForm, negative }: {
ergative, ergative,
matrixKey, matrixKey,
negative, negative,
englishConjugation,
}); });
return { return {
...displayForm, ...displayForm,
@ -114,21 +134,17 @@ const makeSentence = ({ subject, object, info, displayForm, negative }: {
}; };
} }
export const getForms = ({ conj, filterFunc, mode, subject, object, negative } : { const formsOfConjugation = (conj: T.VerbConjugation): T.DisplayFormItem[] => [
conj: T.VerbConjugation,
filterFunc?: FilterFunc | FilterFunc[],
mode: "chart" | "sentence",
subject: T.Person,
object: T.Person,
negative: boolean,
}): T.DisplayFormItem[] => {
const forms: T.DisplayFormItem[] = [
{ {
label: "Present", label: "Present",
aspect: "imperfective", aspect: "imperfective",
form: conj.imperfective.nonImperative, form: conj.imperfective.nonImperative,
formula: "Imperfective Stem + Present Ending", formula: "Imperfective Stem + Present Ending",
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} ${n ? `${engPresC(s, ["don't", "doesn't"])} ` : ""}${n ? v[0] : engPresC(s, v)}`,
`${engSubj(s)} ${engEquative("present", s)}${n ? " not" : ""} ${v[2]}`,
]),
explanation: "Something that is happening, happens generally, or is definitely about to happen. ('I am ____ing', 'I _____')", explanation: "Something that is happening, happens generally, or is definitely about to happen. ('I am ____ing', 'I _____')",
}, },
{ {
@ -137,6 +153,10 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.perfective.nonImperative, form: conj.perfective.nonImperative,
formula: "Perfective Stem + Present Ending", formula: "Perfective Stem + Present Ending",
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`that ${engSubj(s, true)}${n ? " won't" : "'ll"} ${v[0]}`,
`should ${engSubj(s, true)}${n ? " not" : ""} ${v[0]}`,
]),
explanation: "Used for hypothetical statements about the desire, necessity, purpose, or possibility of something happening. Or for saying something should or shouldn't happen. ('Should I ____?', 'so that'll I'll _____')" explanation: "Used for hypothetical statements about the desire, necessity, purpose, or possibility of something happening. Or for saying something should or shouldn't happen. ('Should I ____?', 'so that'll I'll _____')"
}, },
{ {
@ -146,6 +166,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
advanced: true, advanced: true,
formula: "به - ba + Present", formula: "به - ba + Present",
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} will${n ? " not" : ""} ${v[0]}`,
]),
explanation: "Saying something will happen, repeatedly or as an ongoing action", explanation: "Saying something will happen, repeatedly or as an ongoing action",
}, },
{ {
@ -155,6 +178,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
advanced: true, advanced: true,
formula: "به - ba + Subjunctive", formula: "به - ba + Subjunctive",
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} will${n ? " not" : ""} ${v[0]}`,
]),
explanation: "Saying something will happen as a one-time event - May also used when there is some doubt", explanation: "Saying something will happen as a one-time event - May also used when there is some doubt",
}, },
{ {
@ -163,6 +189,12 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.imperfective.past, form: conj.imperfective.past,
formula: "Imperfective Root + Past Ending", formula: "Imperfective Root + Past Ending",
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
// - subj "was" (N && "not") v.2 obj
`${engSubj(s)} ${engEquative("past", s)}${n ? " not" : ""} ${v[2]}`,
// - subj "would" (N && "not") v.0 obj
`${engSubj(s)} would${n ? " not" : ""} ${v[0]}`,
]),
explanation: "Saying something was happening, or would happen ('I was ____ing', 'I would ____')", explanation: "Saying something was happening, or would happen ('I was ____ing', 'I would ____')",
past: true, past: true,
}, },
@ -172,6 +204,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.perfective.past, form: conj.perfective.past,
formula: "Perfective Root + Past Ending", formula: "Perfective Root + Past Ending",
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)}${n ? " did not" : ""} ${v[3]}`,
]),
explanation: "Saying something happened ('I ____ed')", explanation: "Saying something happened ('I ____ed')",
past: true, past: true,
}, },
@ -185,6 +220,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
aspect: "imperfective", aspect: "imperfective",
form: conj.imperfective.modal.nonImperative, form: conj.imperfective.modal.nonImperative,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} can${n ? "'t" : ""} ${v[0]}`,
]),
formula: "Imperfective Root + Non-Inflectinig Ey-Tail + Subjunctive کېدل - to become", formula: "Imperfective Root + Non-Inflectinig Ey-Tail + Subjunctive کېدل - to become",
explanation: "saying that something is possible currently or in general ('I can ____')", explanation: "saying that something is possible currently or in general ('I can ____')",
reorderWithNegative: true, reorderWithNegative: true,
@ -195,6 +233,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.perfective.modal.nonImperative, form: conj.perfective.modal.nonImperative,
advanced: true, advanced: true,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`that ${engSubj(s, true)} can${n ? "'t" : ""} ${v[0]}`,
]),
formula: "Perfective Root + Non-Inflectinig Ey-Tail + Subjunctive کېدل - to become", formula: "Perfective Root + Non-Inflectinig Ey-Tail + Subjunctive کېدل - to become",
explanation: "talking about the possibility of something in a subjunctive way ('so that I can ____')", explanation: "talking about the possibility of something in a subjunctive way ('so that I can ____')",
reorderWithNegative: true, reorderWithNegative: true,
@ -205,6 +246,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.imperfective.modal.future, form: conj.imperfective.modal.future,
advanced: true, advanced: true,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} will${n ? " not" : ""} be able to ${v[0]}`,
]),
formula: "به - ba + Present Modal", formula: "به - ba + Present Modal",
explanation: "saying that something will be possible in general or in an ongoing sense in the future ('I'll be able to ____')", explanation: "saying that something will be possible in general or in an ongoing sense in the future ('I'll be able to ____')",
reorderWithNegative: true, reorderWithNegative: true,
@ -215,6 +259,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.perfective.modal.future, form: conj.perfective.modal.future,
advanced: true, advanced: true,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} will${n ? " not" : ""} be able to ${v[0]}`,
]),
formula: "به - ba + Subjunctive Modal", formula: "به - ba + Subjunctive Modal",
explanation: "saying that something will be possible at a certain point in the future ('I'll be able to ____')", explanation: "saying that something will be possible at a certain point in the future ('I'll be able to ____')",
reorderWithNegative: true, reorderWithNegative: true,
@ -226,6 +273,10 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
advanced: true, advanced: true,
past: true, past: true,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} ${engEquative("past", s)} ${n ? " not" : ""} able to ${v[0]}`,
`${engSubj(s)} could${n ? " not" : ""} ${v[0]}`,
]),
formula: "Imperfective Root + Non-Inflectinig Ey-Tail + Simple Past کېدل - to become", formula: "Imperfective Root + Non-Inflectinig Ey-Tail + Simple Past کېدل - to become",
explanation: "saying that something was possible in general, in an ongoing sense ('I was able to ____', ie. 'I could do ____ any time')", explanation: "saying that something was possible in general, in an ongoing sense ('I was able to ____', ie. 'I could do ____ any time')",
reorderWithNegative: true, reorderWithNegative: true,
@ -237,6 +288,10 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
formula: "Perfective Root + Non-Inflectinig Ey-Tail + Simple Past کېدل - to become", formula: "Perfective Root + Non-Inflectinig Ey-Tail + Simple Past کېدل - to become",
explanation: "saying that something was possible at a certain point in time ('I was able to ____, at one particular point in time')", explanation: "saying that something was possible at a certain point in time ('I was able to ____, at one particular point in time')",
past: true, past: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} ${engEquative("past", s)} ${n ? " not" : ""} able to ${v[0]}`,
`${engSubj(s)} could${n ? " not" : ""} ${v[0]}`,
]),
sentence: true, sentence: true,
advanced: true, advanced: true,
reorderWithNegative: true, reorderWithNegative: true,
@ -270,6 +325,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
label: "Imperfective Imperative", label: "Imperfective Imperative",
aspect: "imperfective", aspect: "imperfective",
form: conj.imperfective.imperative, form: conj.imperfective.imperative,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${v[0]}`,
]),
formula: "Imperfective Stem + Imperative Ending", formula: "Imperfective Stem + Imperative Ending",
explanation: "Commanding someone/people to do something repeatedly, or in general", explanation: "Commanding someone/people to do something repeatedly, or in general",
} as T.DisplayForm] : [], } as T.DisplayForm] : [],
@ -278,6 +336,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
label: "Perfective Imperative", label: "Perfective Imperative",
aspect: "perfective", aspect: "perfective",
form: conj.perfective.imperative, form: conj.perfective.imperative,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${v[0]}`,
]),
formula: "Perfective Stem + Imperative Ending", formula: "Perfective Stem + Imperative Ending",
explanation: "Commanding someone/people to do something one time", explanation: "Commanding someone/people to do something one time",
} as T.DisplayForm] : [], } as T.DisplayForm] : [],
@ -291,6 +352,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.perfect.halfPerfect, form: conj.perfect.halfPerfect,
past: true, past: true,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} ${engHave(s)}${n ? " not" : ""} ${v[4]}`,
]),
formula: "Past participle inflected", formula: "Past participle inflected",
secondPronounNeeded: true, secondPronounNeeded: true,
explanation: "The base of all perfect forms. Used on it's own as a sort of weaker form of the present perfect.", explanation: "The base of all perfect forms. Used on it's own as a sort of weaker form of the present perfect.",
@ -300,6 +364,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.perfect.past, form: conj.perfect.past,
past: true, past: true,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} had${n ? " not" : ""} ${v[4]}`,
]),
formula: "Past participle inflected + Past Equative", formula: "Past participle inflected + Past Equative",
explanation: "Talking about events that had happened in the past, or had affected a past situation ('I had ____ed')", explanation: "Talking about events that had happened in the past, or had affected a past situation ('I had ____ed')",
reorderWithNegative: true, reorderWithNegative: true,
@ -309,6 +376,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.perfect.present, form: conj.perfect.present,
past: true, past: true,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} ${engHave(s)}${n ? " not" : ""} ${v[4]}`,
]),
formula: "Past participle inflected + Present Equative", formula: "Past participle inflected + Present Equative",
explanation: "Talking about that something happened in the past and it affects the present ('I have _____ed')", explanation: "Talking about that something happened in the past and it affects the present ('I have _____ed')",
reorderWithNegative: true, reorderWithNegative: true,
@ -318,6 +388,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.perfect.subjunctive, form: conj.perfect.subjunctive,
past: true, past: true,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`that ${engSubj(s, true)} will have${n ? " not" : ""} ${v[4]}`,
]),
formula: "Past participle inflected + Subjunctive/Habitual Equative", formula: "Past participle inflected + Subjunctive/Habitual Equative",
explanation: "Talking about something that will have happened habitually, or expressing hope, desire, or judgement about an action having happened", explanation: "Talking about something that will have happened habitually, or expressing hope, desire, or judgement about an action having happened",
reorderWithNegative: true, reorderWithNegative: true,
@ -328,6 +401,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
advanced: true, advanced: true,
past: true, past: true,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} will${n ? " not" : ""} have ${v[4]}`,
]),
formula: "به - ba + Past participle Inflected + Future Equative", formula: "به - ba + Past participle Inflected + Future Equative",
explanation: "Talking about something that will have happened in the future, or guessing that the event will have occured presently ('I will have ____ed')", explanation: "Talking about something that will have happened in the future, or guessing that the event will have occured presently ('I will have ____ed')",
reorderWithNegative: true, reorderWithNegative: true,
@ -338,6 +414,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
advanced: true, advanced: true,
past: true, past: true,
sentence: true, sentence: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} will${n ? " not" : ""} have ${v[4]}`,
]),
explanation: "Affirming that an event will have taken place ('I will have ____ed')", explanation: "Affirming that an event will have taken place ('I will have ____ed')",
formula: "به - ba + Past Participle Inflected + Past Equative", formula: "به - ba + Past Participle Inflected + Past Equative",
reorderWithNegative: true, reorderWithNegative: true,
@ -396,6 +475,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.passive.imperfective.nonImperative, form: conj.passive.imperfective.nonImperative,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} ${engEquative("present", s)}${n ? " not" : ""} being ${v[4]}`,
]),
formula: "Long Imperfective Root + Present کېدل - to become", formula: "Long Imperfective Root + Present کېدل - to become",
explanation: "Saying that something is being done or is done in general, without mentioning the subject/agent. ('I am being ____en')", explanation: "Saying that something is being done or is done in general, without mentioning the subject/agent. ('I am being ____en')",
}, },
@ -405,6 +487,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.passive.perfective.nonImperative, form: conj.passive.perfective.nonImperative,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`that ${engSubj(s, true)} will${n ? " not" : ""} be ${v[4]}`,
]),
formula: "Long Perfective Root + Subjunctive کېدل - to become", formula: "Long Perfective Root + Subjunctive کېدل - to become",
explanation: "Saying that something should be done, or giving a purpose for something being done etc., without mentioning the subject/agent. ('Should I be ____en?', 'So that I'll be ____en')" explanation: "Saying that something should be done, or giving a purpose for something being done etc., without mentioning the subject/agent. ('Should I be ____en?', 'So that I'll be ____en')"
}, },
@ -414,6 +499,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.passive.imperfective.future, form: conj.passive.imperfective.future,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} will${n ? " not" : ""} be ${v[4]}`,
]),
formula: "به - ba + Passive Present", formula: "به - ba + Passive Present",
explanation: "Saying something will be done as a one-time event, without mentioning the subject/agent.", explanation: "Saying something will be done as a one-time event, without mentioning the subject/agent.",
}, },
@ -423,6 +511,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
form: conj.passive.perfective.future, form: conj.passive.perfective.future,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} will${n ? " not" : ""} be ${v[4]}`,
]),
formula: "به - ba + Passive Subjunctive", formula: "به - ba + Passive Subjunctive",
explanation: "Saying something will be done in an ongoing or repeated sense, without mentioning the subject/agent." explanation: "Saying something will be done in an ongoing or repeated sense, without mentioning the subject/agent."
}, },
@ -433,6 +524,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
past: true, past: true,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} ${engEquative("past", s)}${n ? " not" : ""} being ${v[4]}`,
]),
formula: "Long Imperfective Root + Continuous Past کېدل - to become", formula: "Long Imperfective Root + Continuous Past کېدل - to become",
explanation: "Saying that something was being done, or would be done, without mentioning the subject/agent. ('I was being ____en', 'I would be ____en')", explanation: "Saying that something was being done, or would be done, without mentioning the subject/agent. ('I was being ____en', 'I would be ____en')",
}, },
@ -443,6 +537,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
past: true, past: true,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} ${engEquative("past", s)}${n ? " not" : ""} ${v[4]}`,
]),
formula: "Long Perfective Root + Simple Past کېدل - to become", formula: "Long Perfective Root + Simple Past کېدل - to become",
explanation: "Saying that was done as a one-time event, without mentioning the subject/agent. ('I was ____en')" explanation: "Saying that was done as a one-time event, without mentioning the subject/agent. ('I was ____en')"
}, },
@ -458,6 +555,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
past: true, past: true,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} ${engHave(s)}${n ? " not" : ""} been ${v[4]}`,
]),
formula: "Infinitive + کېدل (to be) past participle inflected", formula: "Infinitive + کېدل (to be) past participle inflected",
explanation: "The base of all perfect forms. Used on it's own as a sort of weaker form of the present perfect. (Passive voice)", explanation: "The base of all perfect forms. Used on it's own as a sort of weaker form of the present perfect. (Passive voice)",
}, },
@ -467,6 +567,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
past: true, past: true,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} had${n ? " not" : ""} been ${v[4]}`,
]),
formula: "Infinitive + کېدل (to be) past participle inflected + Past Equative", formula: "Infinitive + کېدل (to be) past participle inflected + Past Equative",
explanation: "Talking about events that had happened in the past, or had affected a past situation (Passive voice) ('I had been ____ed')", explanation: "Talking about events that had happened in the past, or had affected a past situation (Passive voice) ('I had been ____ed')",
}, },
@ -476,6 +579,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
past: true, past: true,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} ${engHave(s)}${n ? " not" : ""} been ${v[4]}`,
]),
formula: "Infinitive + کېدل (to be) past participle inflected + Present Equative", formula: "Infinitive + کېدل (to be) past participle inflected + Present Equative",
explanation: "Talking about that something happened in the past and it affects the present (Passive voice) ('I have been _____ed')", explanation: "Talking about that something happened in the past and it affects the present (Passive voice) ('I have been _____ed')",
}, },
@ -485,6 +591,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
past: true, past: true,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`that ${engSubj(s, true)} will have been ${v[4]}`,
]),
formula: "Infinitive + کېدل (to be) past participle inflected + Subjunctive/Habitual Equative", formula: "Infinitive + کېدل (to be) past participle inflected + Subjunctive/Habitual Equative",
}, },
{ {
@ -494,6 +603,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
past: true, past: true,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} will have been ${v[4]}`,
]),
formula: "به - ba + Infinitive + کېدل (to be) past participle inflected + Future Equative", formula: "به - ba + Infinitive + کېدل (to be) past participle inflected + Future Equative",
explanation: "Talking about something that will have happened in the future, or guessing that the event will have occured presently (Passive voice) ('I will have been ____ed')", explanation: "Talking about something that will have happened in the future, or guessing that the event will have occured presently (Passive voice) ('I will have been ____ed')",
}, },
@ -504,6 +616,9 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
past: true, past: true,
sentence: true, sentence: true,
passive: true, passive: true,
englishBuilder: (s: T.Person, v: T.EnglishVerbConjugation, n: boolean) => ([
`${engSubj(s)} will have been ${v[4]}`,
]),
explanation: "Affirming that an event will have taken place (Passive voice) ('I will have been ____ed')", explanation: "Affirming that an event will have taken place (Passive voice) ('I will have been ____ed')",
formula: "به - ba + Infinitive + کېدل (to be) past participle inflected + Past Equative" formula: "به - ba + Infinitive + کېدل (to be) past participle inflected + Past Equative"
}, },
@ -523,17 +638,73 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, negative } :
} as T.DisplayFormSubgroup] } as T.DisplayFormSubgroup]
: [], : [],
]; ];
const initialFilter = filterFunc
export const getForms = ({ conj, filterFunc, mode, subject, object, englishConjugation, negative } : {
conj: T.VerbConjugation,
englishConjugation?: T.EnglishVerbConjugation
filterFunc?: FilterFunc | FilterFunc[],
mode: "chart" | "sentence",
subject: T.Person,
object: T.Person,
negative: boolean,
}): T.DisplayFormItem[] => {
const forms = formsOfConjugation(conj);
const formsToUse = filterFunc
? formFilter(forms, filterFunc) ? formFilter(forms, filterFunc)
: forms; : forms;
return mode === "chart" return mode === "chart"
? initialFilter ? formsToUse
: formMap( : formMap(
formFilter(initialFilter, (f) => f.sentence), // TODO: somewhere in one of these the english conjugations are being stripped out for the past tense items
formFilter(formsToUse, (f) => f.sentence),
makeSentence, makeSentence,
conj.info, conj.info,
subject, subject,
object, object,
negative, negative,
englishConjugation,
); );
} }
function isThirdPerson(p: T.Person): boolean {
return (
p === T.Person.ThirdSingMale ||
p === T.Person.ThirdSingFemale ||
p === T.Person.ThirdPlurMale ||
p === T.Person.ThirdPlurFemale
);
}
function engPresC(s: T.Person, ec: T.EnglishVerbConjugation | [string, string]): string {
return isThirdPerson(s) ? ec[1] : ec[0];
}
function engEquative(tense: "past" | "present", s: T.Person): string {
const [row, col] = getBlockRowCol(s);
return englishEquative[tense][row][col];
}
function engHave(s: T.Person): string {
return isThirdPerson(s) ? "has" : "have";
}
function engSubj(s: T.Person, lowerCase?: boolean): string {
const pronoun = (s === T.Person.FirstSingMale || s === T.Person.FirstSingFemale)
? "I"
: (s === T.Person.FirstPlurMale || s === T.Person.FirstPlurFemale)
? "We"
: (s === T.Person.SecondSingMale || s === T.Person.SecondSingFemale)
? "You"
: (s === T.Person.SecondPlurMale || s === T.Person.SecondPlurFemale)
? "You (pl.)"
: (s === T.Person.ThirdSingMale)
? "He/it"
: (s === T.Person.ThirdSingFemale)
? "She/it"
: (s === T.Person.ThirdPlurMale)
? "They"
: "They (f.)";
return (lowerCase && pronoun !== "I")
? pronoun.toLowerCase()
: pronoun;
}

View File

@ -149,6 +149,31 @@ export const subjPastEquative: T.PsString = {
f: "w" + aayTail.f, 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: { export const equativeEndings: {
past: T.LengthOptions<T.VerbBlock>, past: T.LengthOptions<T.VerbBlock>,
present: 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; 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 // not being used
// export function isImperativeBlock(f: any): boolean { // export function isImperativeBlock(f: any): boolean {
// function isPersonLine(g: any): boolean { // function isPersonLine(g: any): boolean {

View File

@ -106,6 +106,9 @@ export type DictionaryEntry = {
// PHONETICS - PASHTO - DIACRITICS INFO // PHONETICS - PASHTO - DIACRITICS INFO
/** Is an exception to the rules of diacritics for Pashto/Phonetics */ /** Is an exception to the rules of diacritics for Pashto/Phonetics */
diacExcept?: boolean; 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"; 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 0: T
} & Array<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 DisplayFormItem = DisplayForm | DisplayFormSubgroup | DisplayFormForSentence;
export type DisplayForm = { export type DisplayForm = {
@ -390,6 +396,7 @@ export type DisplayForm = {
aspect?: Aspect, aspect?: Aspect,
form: VerbForm | ImperativeForm | ParticipleForm | SentenceForm, form: VerbForm | ImperativeForm | ParticipleForm | SentenceForm,
advanced?: boolean, advanced?: boolean,
englishBuilder?: (subject: Person, ec: EnglishVerbConjugation, neg: boolean) => string[],
formula: React.ReactNode, formula: React.ReactNode,
explanation: React.ReactNode, explanation: React.ReactNode,
sentence?: boolean, sentence?: boolean,
@ -402,6 +409,7 @@ export type DisplayFormForSentence = {
aspect?: Aspect, aspect?: Aspect,
form: VerbForm, form: VerbForm,
advanced?: boolean, advanced?: boolean,
englishBuilder?: (subject: Person, ec: EnglishVerbConjugation, neg: boolean) => string[],
formula: React.ReactNode, formula: React.ReactNode,
secondPronounNeeded?: boolean, secondPronounNeeded?: boolean,
explanation: React.ReactNode, explanation: React.ReactNode,