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:
parent
1d465c61ef
commit
aee3257ea3
|
@ -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",
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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.)";
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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,
|
||||||
|
|
|
@ -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"]);
|
||||||
|
});
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue