diff --git a/package.json b/package.json index 05271b5..839ae62 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lingdocs/pashto-inflector", - "version": "0.6.9", + "version": "0.7.0", "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", diff --git a/src/components/ConjugationViewer.tsx b/src/components/ConjugationViewer.tsx index 322f9e6..176634e 100644 --- a/src/components/ConjugationViewer.tsx +++ b/src/components/ConjugationViewer.tsx @@ -7,7 +7,7 @@ */ import { useEffect, useReducer } from "react"; -import VerbInfo from "./verb-info/VerbInfo"; +import VerbInfo, { RootsAndStems } from "./verb-info/VerbInfo"; import VerbFormDisplay from "./VerbFormDisplay"; import ButtonSelect from "./ButtonSelect"; import Hider from "./Hider"; @@ -172,11 +172,15 @@ const initialState: State = { formsOpened: [], }; -function ConjugationViewer({ entry, complement, textOptions, aayTailType }: { +function ConjugationViewer({ entry, complement, textOptions, aayTailType, showOnly, highlightInRootsAndStems, hidePastParticiple, sentenceLevel }: { entry: T.DictionaryEntry, complement?: T.DictionaryEntry, textOptions: T.TextOptions, aayTailType?: T.AayTail, + showOnly?: string | string[], + highlightInRootsAndStems?: T.RootsOrStemsToHighlight, + hidePastParticiple?: boolean, + sentenceLevel?: "easy" | "medium" | "hard", }) { const [state, dispatch] = useReducer(reducer, initialState); useEffect(() => { @@ -223,13 +227,22 @@ function ConjugationViewer({ entry, complement, textOptions, aayTailType }: { const filterDifficulty = (f: T.DisplayForm): boolean => ( state.difficulty === "advanced" || !f.advanced ); + const limitTo = !showOnly + ? undefined + : Array.isArray(showOnly) + ? showOnly + : [showOnly]; const forms = getForms({ conj: verbConj, - filterFunc: filterDifficulty, + filterFunc: [ + filterDifficulty, + ...limitTo ? [(f: T.DisplayForm): boolean => limitTo.includes(f.label)] : [], + ], mode: state.mode, subject: state.subject, object: state.object, negative: state.negative, + sentenceLevel, englishConjugation, }); return
@@ -282,44 +295,57 @@ function ConjugationViewer({ entry, complement, textOptions, aayTailType }: { />
} - dispatch({ type: "toggle showingStemsAndRoots" })} - /> + {!limitTo ? + dispatch({ type: "toggle showingStemsAndRoots" })} + hidePastParticiple={hidePastParticiple} + /> + : + + }
dispatch({ type: "setMode", payload: p as "chart" | "sentence" })} />
-
- dispatch({ type: "set difficulty", payload: p as Difficulty })} - /> -
-
- { - dispatch({ type: "setShowingFormInfo", payload: e.target.checked }) - }} - /> - -
+ {!limitTo && <> +
+ dispatch({ type: "set difficulty", payload: p as Difficulty })} + /> +
+
+ { + dispatch({ type: "setShowingFormInfo", payload: e.target.checked }) + }} + /> + +
+ }
{state.mode === "sentence" &&
@@ -352,7 +378,7 @@ function ConjugationViewer({ entry, complement, textOptions, aayTailType }: { state={state} handleChange={(payload: string) => dispatch({ type: "set forms opened", payload })} verbConj={verbConj} - textOptions={textOptions} + textOptions={textOptions} />
; } @@ -381,6 +407,7 @@ function FormsDisplay({ forms, state, handleChange, textOptions, verbConj }: { aspect={"aspect" in f ? f.aspect : undefined} showing={state.formsOpened.includes(f.label)} handleChange={() => handleChange(f.label)} + ignore={forms.length === 1} > {"content" in f ? drawLevel(f.content, level + 1) diff --git a/src/components/Hider.tsx b/src/components/Hider.tsx index bf10934..f93ee44 100644 --- a/src/components/Hider.tsx +++ b/src/components/Hider.tsx @@ -27,11 +27,17 @@ function Hider(props: { handleChange: () => void, children: React.ReactNode, hLevel?: number, + ignore?: boolean, }) { const hLev = Math.min((props.hLevel ? props.hLevel : defaultLevel), 6); const extraMargin = (props.hLevel && (props.hLevel > indentAfterLevel)) ? `ml-${(props.hLevel - indentAfterLevel) + 1}` : ""; + if (props.ignore) { + return <> + {props.children} + ; + } return
{createElement( `h${hLev}`, diff --git a/src/components/PersonSelection.tsx b/src/components/PersonSelection.tsx index 7456771..2c3e175 100644 --- a/src/components/PersonSelection.tsx +++ b/src/components/PersonSelection.tsx @@ -64,7 +64,8 @@ function PersonSelection(props: {
void, + hidePastParticiple?: boolean, }) { const inf = noPersInfs(info.root.imperfective).long; return ( @@ -195,6 +197,8 @@ function VerbInfo({ info, textOptions, showingStemsAndRoots, toggleShowingSar }:
diff --git a/src/components/verb-info/VerbTypeInfo.tsx b/src/components/verb-info/VerbTypeInfo.tsx index aea8112..097470f 100644 --- a/src/components/verb-info/VerbTypeInfo.tsx +++ b/src/components/verb-info/VerbTypeInfo.tsx @@ -254,17 +254,17 @@ function VerbTypeInfo({ info, textOptions }: {
This is a verb and it's
diff --git a/src/lib/add-pronouns.ts b/src/lib/add-pronouns.ts index 93555e3..51c40c2 100644 --- a/src/lib/add-pronouns.ts +++ b/src/lib/add-pronouns.ts @@ -63,7 +63,7 @@ type Pronouns = undefined | { const nuParticle = { p: "ู†ู‡", f: "nรบ" }; -export default function addPronouns({ s, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative }: { +export default function addPronouns({ s, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative, sentenceLevel = "hard" }: { s: T.SentenceForm, subject: T.Person, object: T.Person, @@ -74,13 +74,14 @@ export default function addPronouns({ s, subject, object, info, displayForm, int matrixKey: T.PersonInflectionsField, negative: boolean, englishConjugation?: T.EnglishVerbConjugation, + sentenceLevel?: "easy" | "medium" | "hard", }): T.SentenceForm { if ("long" in s) { return { - long: addPronouns({ s: s.long, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative }) as T.ArrayOneOrMore, - short: addPronouns({ s: s.short, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative }) as T.ArrayOneOrMore, + long: addPronouns({ s: s.long, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative, sentenceLevel }) as T.ArrayOneOrMore, + short: addPronouns({ s: s.short, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative, sentenceLevel }) as T.ArrayOneOrMore, ...s.mini ? { - mini: addPronouns({ s: s.mini, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative }) as T.ArrayOneOrMore, + mini: addPronouns({ s: s.mini, subject, object, info, displayForm, intransitive, ergative, matrixKey, englishConjugation, negative, sentenceLevel }) as T.ArrayOneOrMore, } : {}, } } @@ -126,11 +127,11 @@ export default function addPronouns({ s, subject, object, info, displayForm, int ? undefined : noObjectPronoun ? { - subject: nearPronounPossible(subject) ? [subjectPronoun, nearSubjectPronoun] : subjectPronoun, + subject: ((sentenceLevel === "hard") && nearPronounPossible(subject)) ? [subjectPronoun, nearSubjectPronoun] : subjectPronoun, mini: miniPronoun, } : { - subject: nearPronounPossible(subject) ? [subjectPronoun, nearSubjectPronoun] : subjectPronoun, - object: nearPronounPossible(object) ? [objectPronoun, nearObjectPronoun] : objectPronoun, + subject: ((sentenceLevel === "hard") && nearPronounPossible(subject)) ? [subjectPronoun, nearSubjectPronoun] : subjectPronoun, + object: ((sentenceLevel === "hard") && nearPronounPossible(object)) ? [objectPronoun, nearObjectPronoun] : objectPronoun, mini: miniPronoun, }; const english = (displayForm.englishBuilder && englishConjugation) @@ -163,7 +164,7 @@ export default function addPronouns({ s, subject, object, info, displayForm, int // basic form two full pronouns ...makeBasicPronounForm(ps, splitHead, displayForm, info, negative, prns.subject, prns.object), // basic form one full, one mini pronoun - ...makeBasicPronounForm( + ...sentenceLevel !== "easy" ? makeBasicPronounForm( ps, splitHead, displayForm, @@ -171,7 +172,7 @@ export default function addPronouns({ s, subject, object, info, displayForm, int negative, ergative ? prns.object : prns.subject, prns.mini, - ), + ) : [], ] as T.ArrayOneOrMore; const ergativeGrammTrans = (info.transitivity === "grammatically transitive" && ergative); @@ -179,7 +180,7 @@ export default function addPronouns({ s, subject, object, info, displayForm, int || transDynCompPast || ergativeGrammTrans; return [ ...basicForms, - ...canWorkWithOnlyMini + ...(sentenceLevel !== "easy" && canWorkWithOnlyMini) ? makeOnlyMiniForm(ps, splitHead, displayForm, info, negative, prns.mini) : [], ].map((ps) => english ? { ...ps, e: english } : ps) as T.ArrayOneOrMore; diff --git a/src/lib/conjugation-forms.tsx b/src/lib/conjugation-forms.tsx index c39ede2..085e1d6 100644 --- a/src/lib/conjugation-forms.tsx +++ b/src/lib/conjugation-forms.tsx @@ -40,6 +40,7 @@ type MapFunc = (opts: { info: T.NonComboVerbInfo, negative: boolean, englishConjugation?: T.EnglishVerbConjugation, + sentenceLevel?: "easy" | "medium" | "hard", }) => T.DisplayFormItem; /** @@ -87,20 +88,22 @@ const formMap = ( object: T.Person, negative: boolean, englishConjugation?: T.EnglishVerbConjugation, + sentenceLevel?: "easy" | "medium" | "hard", ): T.DisplayFormItem[] => { return input.map((f) => ( "content" in f - ? { ...f, content: formMap(f.content, func, info, subject, object, negative, englishConjugation) } - : func({ displayForm: f as T.DisplayFormForSentence, info, subject, object, negative, englishConjugation }) + ? { ...f, content: formMap(f.content, func, info, subject, object, negative, englishConjugation, sentenceLevel) } + : func({ displayForm: f as T.DisplayFormForSentence, info, subject, object, negative, englishConjugation, sentenceLevel }) )); }; -const makeSentence = ({ subject, object, info, displayForm, englishConjugation, negative }: { +const makeSentence = ({ subject, object, info, displayForm, englishConjugation, negative, sentenceLevel }: { subject: T.Person, object: T.Person, info: T.NonComboVerbInfo, displayForm: T.DisplayFormForSentence, negative: boolean, + sentenceLevel?: "easy" | "medium" | "hard", englishConjugation?: T.EnglishVerbConjugation, }): T.DisplayForm => { const intransitive = info.transitivity === "intransitive" || !!displayForm.passive; @@ -127,6 +130,7 @@ const makeSentence = ({ subject, object, info, displayForm, englishConjugation, matrixKey, negative, englishConjugation, + sentenceLevel, }); return { ...displayForm, @@ -641,13 +645,14 @@ const formsOfConjugation = (conj: T.VerbConjugation): T.DisplayFormItem[] => [ : [], ]; -export const getForms = ({ conj, filterFunc, mode, subject, object, englishConjugation, negative } : { +export const getForms = ({ conj, filterFunc, mode, subject, object, sentenceLevel, englishConjugation, negative } : { conj: T.VerbConjugation, englishConjugation?: T.EnglishVerbConjugation filterFunc?: FilterFunc | FilterFunc[], mode: "chart" | "sentence", subject: T.Person, object: T.Person, + sentenceLevel?: "easy" | "medium" | "hard", negative: boolean, }): T.DisplayFormItem[] => { const forms = formsOfConjugation(conj); @@ -665,6 +670,7 @@ export const getForms = ({ conj, filterFunc, mode, subject, object, englishConju object, negative, englishConjugation, + sentenceLevel, ); } diff --git a/src/types.ts b/src/types.ts index 70125fa..7a84446 100644 --- a/src/types.ts +++ b/src/types.ts @@ -389,6 +389,8 @@ export type ArrayOneOrMore = { 0: T } & Array +export type RootsOrStemsToHighlight = ("imperfective root" | "perfective root" | "imperfective stem" | "perfective stem" | "past participle")[]; + /* i.e. ec: ["take", "takes", "taking", "took", "taken"], ep: out */ export type EnglishVerbConjugationEc = [string, string, string, string, string]; export type EnglishVerbConjugation = {