more info and compound info

This commit is contained in:
lingdocs 2022-04-14 13:12:10 +05:00
parent d9c0ed9630
commit a17183db81
9 changed files with 150 additions and 5 deletions

View File

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

@ -259,6 +259,7 @@ function App() {
</div> </div>
{v?.verb.entry && <div style={{ paddingBottom: "100px" }}> {v?.verb.entry && <div style={{ paddingBottom: "100px" }}>
<PhraseBuilder <PhraseBuilder
handleLinkClick={0}
verb={v.verb as T.VerbEntry} verb={v.verb as T.VerbEntry}
nouns={nouns} nouns={nouns}
verbs={verbs} verbs={verbs}

View File

@ -0,0 +1,102 @@
import * as T from "../../types";
import Pashto from "../Pashto";
import Phonetics from "../Phonetics";
import {
makePsString,
} from "../../lib/accent-and-ps-utils";
import { ReactNode } from "react";
import classNames from "classnames";
function CompoundFormula({ a, b }: {
a: ReactNode,
b: ReactNode,
}) {
return (
<div className="row align-items-center mb-3">
<div className="col-5 text-center">
{a}
</div>
<div className="col-2 text-center" style={{ fontSize: "2.5rem" }}>
<strong>+</strong>
</div>
<div className="col-5 text-center">
{b}
</div>
</div>
);
}
function CompoundDisplay({ info, opts, handleLinkClick }: {
info: T.NonComboVerbInfo,
opts: T.TextOptions,
handleLinkClick: ((ts: number) => void) | 0,
}) {
const isComplement = ("complement" in info || "objComplement" in info);
if (!isComplement) {
return null;
}
const complement = ((): T.PsString => {
if ("objComplement" in info) {
return info.objComplement.plural
? info.objComplement.plural
: info.objComplement.entry;
}
if ("complement" in info) {
return info.complement.masc[0][0];
}
else return makePsString("aa", "aa");
})();
const aux = ((): { ps: T.PsString, e: string } => {
if (info.type === "stative compound" || info.type === "generative stative compound") {
return info.transitivity === "transitive"
? { ps: { p: "کول", f: "kawul" }, e: "to make"}
: { ps: { p: "کېدل", f: "kedul" }, e: "to become"};
}
if (!("auxVerb" in info)) return { ps: {p: "", f: ""}, e: ""};
const kawulDyn = info.type === "dynamic compound" && info.auxVerb.p === "کول";
return {
ps: makePsString(info.auxVerb.p, info.auxVerb.f),
e: kawulDyn ? "to do" : "",
}
})();
return (
<div className="d-block mx-auto my-3" style={{ maxWidth: "400px" }}>
<div className="text-center">{info.type}</div>
<CompoundFormula
a={<div
className={classNames([{ clickable: handleLinkClick }])}
onClick={(handleLinkClick)
// @ts-ignore - thinks there might not be a complement, but there will be
? () => handleLinkClick(info.entry.complement?.ts)
: undefined}
>
<div>
<Pashto opts={opts}>{complement}</Pashto>
</div>
<div>
<Phonetics opts={opts}>{complement}</Phonetics>
</div>
<div className="small text-muted">{info.entry.complement?.c}</div>
{info.type === "dynamic compound" && <div>
(Object)
</div>}
</div>}
b={<div
className={classNames([{ clickable: handleLinkClick }])}
onClick={(handleLinkClick)
? () => handleLinkClick(info.entry.entry.ts)
: undefined}>
<div>
<Pashto opts={opts}>{aux.ps}</Pashto>
</div>
<div>
<Phonetics opts={opts}>{aux.ps}</Phonetics>
</div>
{aux.e && <div>{aux.e}</div>}
</div>}
/>
</div>
);
}
export default CompoundDisplay;

View File

@ -39,6 +39,7 @@ const servantIcon = <i className="mx-1 fas fa-male" />;
export function VPExplorer(props: { export function VPExplorer(props: {
verb: T.VerbEntry, verb: T.VerbEntry,
opts: T.TextOptions, opts: T.TextOptions,
handleLinkClick: ((ts: number) => undefined) | 0,
} & ({ } & ({
nouns: T.NounEntry[], nouns: T.NounEntry[],
verbs: T.VerbEntry[], verbs: T.VerbEntry[],
@ -119,6 +120,7 @@ export function VPExplorer(props: {
vps={vps} vps={vps}
onChange={quizLock(setVps)} onChange={quizLock(setVps)}
opts={props.opts} opts={props.opts}
handleLinkClick={props.handleLinkClick}
/> />
<div className="mt-2 mb-3 text-center"> <div className="mt-2 mb-3 text-center">
<ButtonSelect <ButtonSelect
@ -142,7 +144,7 @@ export function VPExplorer(props: {
<div className="my-2"> <div className="my-2">
{roles.king === "subject" {roles.king === "subject"
? <div className="h5 text-center clickable" onClick={() => setShowingKingExplanation("subject")}>Subject {kingIcon}</div> ? <div className="h5 text-center clickable" onClick={() => setShowingKingExplanation("subject")}>Subject {kingIcon}</div>
: <div className="h5 text-center clickable" onClick={() => setShowingKingExplanation("subject")}>Subject {servantIcon}</div>} : <div className="h5 text-center clickable" onClick={() => setShowingServantExplanation("subject")}>Subject {servantIcon}</div>}
<NPPicker <NPPicker
{..."getNounByTs" in props ? { {..."getNounByTs" in props ? {
getNounByTs: props.getNounByTs, getNounByTs: props.getNounByTs,
@ -202,7 +204,7 @@ export function VPExplorer(props: {
In this tense/form, the {showingKingExplanation} is the <strong>king</strong> {kingIcon} of the phrase. That means that: In this tense/form, the {showingKingExplanation} is the <strong>king</strong> {kingIcon} of the phrase. That means that:
<ul className="mt-2"> <ul className="mt-2">
<li> <li>
<div>It controls the verb conjugation. The verb agrees with the gender and number of the king.</div> <div>It <strong>controls the verb conjugation</strong>. The verb agrees with the gender and number of the king.</div>
</li> </li>
<li> <li>
<div>👍 It <strong>can</strong> be removed / left out from the phrase.</div> <div>👍 It <strong>can</strong> be removed / left out from the phrase.</div>

View File

@ -4,7 +4,7 @@ import { RootsAndStems } from "../verb-info/VerbInfo";
import { getVerbInfo } from "../../lib/verb-info"; import { getVerbInfo } from "../../lib/verb-info";
import Hider from "../Hider"; import Hider from "../Hider";
import useStickyState from "../../lib/useStickyState"; import useStickyState from "../../lib/useStickyState";
import CompoundDisplay from "./CompoundDisplay";
// TODO: dark on past tense selecitons // TODO: dark on past tense selecitons
@ -12,6 +12,7 @@ function VerbPicker(props: {
vps: T.VPSelection, vps: T.VPSelection,
onChange: (p: T.VPSelection) => void, onChange: (p: T.VPSelection) => void,
opts: T.TextOptions, opts: T.TextOptions,
handleLinkClick: ((ts: number) => void) | 0,
}) { }) {
const [showRootsAndStems, setShowRootsAndStems] = useStickyState<boolean>(false, "showRootsAndStems"); const [showRootsAndStems, setShowRootsAndStems] = useStickyState<boolean>(false, "showRootsAndStems");
const infoRaw = props.vps.verb ? getVerbInfo(props.vps.verb.verb.entry, props.vps.verb.verb.complement) : undefined; const infoRaw = props.vps.verb ? getVerbInfo(props.vps.verb.verb.entry, props.vps.verb.verb.complement) : undefined;
@ -60,6 +61,11 @@ function VerbPicker(props: {
} }
} }
return <div className="mb-3"> return <div className="mb-3">
{info && <CompoundDisplay
info={info}
opts={props.opts}
handleLinkClick={props.handleLinkClick}
/>}
{info && <div className="mt-3 mb-1 text-center"> {info && <div className="mt-3 mb-1 text-center">
<Hider <Hider
showing={showRootsAndStems} showing={showRootsAndStems}

View File

@ -318,6 +318,9 @@ const kawulPerfectPassive: T.PerfectContent = {
export const kedulStat: T.VerbConjugation = { export const kedulStat: T.VerbConjugation = {
info: { info: {
entry: {
entry: {"ts":1581086654898,"i":10645,"p":"کېدل","f":"kedul","g":"kedul","e":"to become _____","c":"v. intrans. irreg.","ssp":"ش","ssf":"sh","prp":"شول","prf":"shwul","pprtp":"شوی","pprtf":"shúwey","noOo":true,"ec":"become","ep":"_____"} as T.VerbDictionaryEntry,
},
transitivity: "intransitive", transitivity: "intransitive",
type: "simple", type: "simple",
yulEnding: false, yulEnding: false,
@ -572,6 +575,9 @@ export const kedulStat: T.VerbConjugation = {
export const kedulDyn: T.VerbConjugation = { export const kedulDyn: T.VerbConjugation = {
info: { info: {
entry: {
entry: {"ts":1527812754,"i":10644,"p":"کېدل","f":"kedul","g":"kedul","e":"to happen, occur","c":"v. intrans. irreg.","ssp":"وش","ssf":"óosh","prp":"وشول","prf":"óoshwul","pprtp":"شوی","pprtf":"shúwey","diacExcept":true,"ec":"happen"} as T.VerbDictionaryEntry,
},
transitivity: "intransitive", transitivity: "intransitive",
type: "simple", type: "simple",
yulEnding: false, yulEnding: false,
@ -1010,6 +1016,9 @@ const kawulHypothetical: T.VerbForm = {
export const kawulStat: T.VerbConjugation = { export const kawulStat: T.VerbConjugation = {
info: { info: {
entry: {
entry: {"ts":1579015359582,"i":10579,"p":"کول","f":"kawul","g":"kawul","e":"to make ____ ____ (as in \"He's making me angry.\")","c":"v. trans. irreg.","ssp":"کړ","ssf":"kR","prp":"کړل","prf":"kRul","pprtp":"کړی","pprtf":"kúRey","noOo":true,"ec":"make,makes,making,made,made","ep":"_____"} as T.VerbDictionaryEntry,
},
transitivity: "transitive", transitivity: "transitive",
type: "simple", type: "simple",
yulEnding: false, yulEnding: false,
@ -1475,6 +1484,9 @@ export const kawulStat: T.VerbConjugation = {
// leads to possible discrepency when changing things, almost like two sources of truth? // leads to possible discrepency when changing things, almost like two sources of truth?
export const kawulDyn: T.VerbConjugation = { export const kawulDyn: T.VerbConjugation = {
info: { info: {
entry: {
entry: {"ts":1527812752,"i":10578,"p":"کول","f":"kawul","g":"kawul","e":"to do (an action or activity)","c":"v. trans. irreg.","ssp":"وکړ","ssf":"óokR","prp":"وکړل","prf":"óokRul","pprtp":"کړی","pprtf":"kúRey","diacExcept":true,"ec":"do,does,doing,did,done"} as T.VerbDictionaryEntry,
},
transitivity: "transitive", transitivity: "transitive",
type: "simple", type: "simple",
yulEnding: false, yulEnding: false,
@ -2040,6 +2052,9 @@ const tlulModal: T.ModalContent = {
export const tlul: T.VerbConjugation = { export const tlul: T.VerbConjugation = {
info: { info: {
entry: {
entry: {"ts":1527815348,"i":3638,"p":"تلل","f":"tlul","g":"tlul","e":"to go","c":"v. intrans. irreg.","psp":"ځ","psf":"dz","ssp":"لاړ ش","ssf":"láaR sh","prp":"لاړ","prf":"láaR","ec":"go,goes,going,went,gone"} as T.VerbDictionaryEntry,
},
transitivity: "intransitive", transitivity: "intransitive",
type: "simple", type: "simple",
yulEnding: false, yulEnding: false,
@ -2416,6 +2431,9 @@ export const dynamicAux = {
export const warkawul: T.VerbConjugation = { export const warkawul: T.VerbConjugation = {
info: { info: {
entry: {
entry: {"ts":1527813914,"i":14222,"p":"ورکول","f":"wărkawul","g":"warkawul","e":"to give (to him/her/it - towards third person)","c":"v. trans."} as T.VerbDictionaryEntry,
},
transitivity: "transitive", transitivity: "transitive",
type: "simple", type: "simple",
yulEnding: false, yulEnding: false,

View File

@ -27,7 +27,7 @@ export function isNounOrAdjEntry(e: T.Entry): e is (T.NounEntry | T.AdjectiveEnt
return isNounEntry(e) || isAdjectiveEntry(e); return isNounEntry(e) || isAdjectiveEntry(e);
} }
export function isVerbDictionaryEntry(e: T.DictionaryEntry): e is T.VerbDictionaryEntry { export function isVerbDictionaryEntry(e: T.DictionaryEntry | T.DictionaryEntryNoFVars): e is T.VerbDictionaryEntry {
return !!e.c?.startsWith("v."); return !!e.c?.startsWith("v.");
} }

View File

@ -137,6 +137,11 @@ export function getVerbInfo(
const idiosyncraticThirdMascSing = getIdiosyncraticThirdMascSing(entry); const idiosyncraticThirdMascSing = getIdiosyncraticThirdMascSing(entry);
const baseInfo: T.VerbInfoBase = { const baseInfo: T.VerbInfoBase = {
entry: {
// TODO: cleanup the type safety with the DictionaryNoFVars messing things up etc
entry: entry as unknown as T.VerbDictionaryEntry,
complement,
},
transitivity, transitivity,
yulEnding, yulEnding,
root, root,
@ -226,6 +231,11 @@ function getGenerativeStativeCompoundVerbInfo(
past: concatPsString(compUsed, " ", bases.participle.past), past: concatPsString(compUsed, " ", bases.participle.past),
} }
return { return {
entry: {
// TODO: cleanup the type safety with the DictionaryNoFVars messing things up etc
entry: entry as unknown as T.VerbDictionaryEntry,
complement: comp,
},
type: "generative stative compound", type: "generative stative compound",
transitivity, transitivity,
yulEnding, yulEnding,
@ -310,6 +320,11 @@ function getDynamicCompoundInfo(entry: T.DictionaryEntryNoFVars, comp: T.Diction
? makeIntransitiveFormOfEntry(entry) ? makeIntransitiveFormOfEntry(entry)
: null; : null;
return { return {
entry: {
// TODO: cleanup the type safety with the DictionaryNoFVars messing things up etc
entry: entry as unknown as T.VerbDictionaryEntry,
complement: comp,
},
type: "dynamic compound", type: "dynamic compound",
transitivity, transitivity,
yulEnding, yulEnding,

View File

@ -160,6 +160,7 @@ export enum Person {
// INPUT // INPUT
// all information to be passed to conjugating functions // all information to be passed to conjugating functions
export type VerbInfoBase = { export type VerbInfoBase = {
entry: VerbEntry,
transitivity: Transitivity; transitivity: Transitivity;
yulEnding: boolean | null; yulEnding: boolean | null;
stem: VerbStemSet; stem: VerbStemSet;