getting EP blocks working

This commit is contained in:
lingdocs 2022-06-04 20:42:35 -05:00
parent 41bd7bfab7
commit 370ba3e521
9 changed files with 110 additions and 76 deletions

View File

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

@ -21,7 +21,7 @@ function Block({ opts, block }: {
if (block.type === "predicateSelection") {
const english = getEnglishFromRendered(block.selection);
return <div className="text-center">
<div>Pred</div>
<div><strong>Predicate</strong></div>
{block.selection.type === "EQComp"
? <EqCompBlock opts={opts} comp={block.selection.selection} />
: <NPBlock opts={opts} english={english}>{block.selection}</NPBlock>}
@ -49,12 +49,8 @@ function NUBlock({ opts }: {
>
nu
</div>
<div className="small text-muted text-center" style={{
// TODO: find a better way to keep this limited to the width of the div above
// don't let this make the div above expand
margin: "0 auto",
maxWidth: "300px",
}}>not</div>
<div>Neg.</div>
<EnglishBelow>not</EnglishBelow>
</div>;
}
@ -73,6 +69,8 @@ function EquativeBlock({ opts, eq }: {
>
{"short" in eq.ps ? eq.ps.short[0].f : eq.ps[0].f}
</div>
<div>Equative</div>
<EnglishBelow>{"="}</EnglishBelow>
</div>;
}
@ -82,7 +80,7 @@ function SubjectBlock({ opts, np }: {
}) {
const english = getEnglishFromRendered(np);
return <div className="text-center">
<div>Subject</div>
<div><strong>Subject</strong></div>
<NPBlock opts={opts} english={english}>{np}</NPBlock>
</div>;
}
@ -107,12 +105,7 @@ function EqCompBlock({ opts, comp }: {
{adj.ps[0].f}
</div>
<div>Adj.</div>
{adj.e && <div className="small text-muted text-center" style={{
// TODO: find a better way to keep this limited to the width of the div above
// don't let this make the div above expand
margin: "0 auto",
maxWidth: "300px",
}}>{adj.e}</div>}
<EnglishBelow>{adj.e}</EnglishBelow>
</div>;
}
@ -132,16 +125,11 @@ function EqCompBlock({ opts, comp }: {
{adv.ps[0].f}
</div>
<div>Loc. Adv.</div>
{adv.e && <div className="small text-muted text-center" style={{
// TODO: find a better way to keep this limited to the width of the div above
// don't let this make the div above expand
margin: "0 auto",
maxWidth: "300px",
}}>{adv.e}</div>}
<EnglishBelow>{adv.e}</EnglishBelow>
</div>;
}
return <div className="text-center mb-2">
return <div className="text-center">
<div>Comp.</div>
{comp.type === "adjective"
? <AdjectiveBlock opts={opts} adj={comp} />
@ -150,6 +138,7 @@ function EqCompBlock({ opts, comp }: {
: <div>
<Sandwich opts={opts} sandwich={comp} />
<div>Sandwich</div>
<EnglishBelow>{comp.e}</EnglishBelow>
</div>}
</div>;
}
@ -184,12 +173,7 @@ export function APBlock({ opts, children, english }: {
return <div>
<Sandwich opts={opts} sandwich={ap.selection} />
<div>AP</div>
{english && <div className="small text-muted text-center" style={{
// TODO: find a better way to keep this limited to the width of the div above
// don't let this make the div above expand
margin: "0 auto",
maxWidth: "300px",
}}>{english}</div>}
<EnglishBelow>{english}</EnglishBelow>
</div>;
}
@ -226,7 +210,7 @@ export function NPBlock({ opts, children, inside, english }: {
english?: string,
}) {
const np = children;
const hasPossesor = !!(np.selection.type !== "pronoun" && np.selection.possesor);
const hasPossesor = !!(np.selection.type !== "pronoun" && np.selection.possesor && !np.selection.possesor.shrunken);
return <div>
<div
className={classNames("d-flex flex-row justify-content-center align-items-center", { "pt-2": !inside && hasPossesor })}
@ -241,12 +225,7 @@ export function NPBlock({ opts, children, inside, english }: {
<div> {np.selection.ps[0].f}</div>
</div>
<div className={inside ? "small" : ""}>NP</div>
{english && <div className="small text-muted text-center" style={{
// TODO: find a better way to keep this limited to the width of the div above
// don't let this make the div above expand
margin: "0 auto",
maxWidth: "300px",
}}>{english}</div>}
<EnglishBelow>{english}</EnglishBelow>
</div>
}
@ -257,6 +236,9 @@ function Possesors({ opts, children }: {
if (!children) {
return null;
}
if (children.shrunken) {
return null;
}
const contraction = checkForContraction(children.np);
return <div className="d-flex flex-row mr-1 align-items-end" style={{
marginBottom: "0.5rem",
@ -304,3 +286,11 @@ function Adjectives({ opts, children }: {
{children.map(a => a.ps[0].f).join(" ")}{` `}
</em>
}
function EnglishBelow({ children: e }: { children: string | undefined }) {
return <div className="small text-muted text-center" style={{
margin: "0 auto",
maxWidth: "300px",
height: "1rem",
}}>{e ? e : ""}</div>;
}

View File

@ -0,0 +1,16 @@
import { baParticle } from "../../lib/grammar-units";
import * as T from "../../types";
import Phonetics from "../Phonetics";
function KidDisplay({ opts, kid }: {
opts: T.TextOptions,
kid: T.Kid,
}) {
return <div className="mx-1">
{kid.type === "ba"
? <Phonetics opts={opts}>{baParticle}</Phonetics>
: <Phonetics opts={opts}>{kid.ps}</Phonetics>}
</div>
}
export default KidDisplay;

View File

@ -1,18 +1,41 @@
import * as T from "../../types";
import Block from "../blocks/Block";
import KidDisplay from "../blocks/KidDisplay";
function EPBlocksDisplay({ opts, rendered }: { opts: T.TextOptions, rendered: T.EPRendered }) {
function EPBlocksDisplay({ opts, rendered }: {
opts: T.TextOptions,
rendered: T.EPRendered,
}) {
const blocks = rendered.omitSubject
? rendered.blocks.filter(b => b.type !== "subjectSelection")
: rendered.blocks;
return <div className="d-flex flex-row justify-content-center align-items-end mt-3">
{blocks.map((block, i) => (
return <div>
<div className="d-flex flex-row justify-content-center align-items-end mt-3">
<div key={Math.random()} className="mr-2">
<Block opts={opts} block={block} />
<Block opts={opts} block={blocks[0]} />
</div>
))}
</div>;
<KidsSection opts={opts} kids={rendered.kids} />
{blocks.slice(1).map((block, i) => (
<div key={Math.random()} className="mr-2">
<Block opts={opts} block={block} />
</div>
))}
</div>
</div>
}
function KidsSection({ opts, kids }: {
opts: T.TextOptions,
kids: T.Kid[],
}) {
return kids.length > 0 ? <div className="text-center mx-1 mr-3" style={{ paddingBottom: "1rem"}}>
<div className="d-flex flex-row mb-3 justify-content-center">
{kids.map(kid => (
<KidDisplay key={Math.random()} opts={opts} kid={kid} />
))}
</div>
<div><strong>kids</strong></div>
</div> : null;
}
export default EPBlocksDisplay;

View File

@ -8,12 +8,14 @@ import EPTextDisplay from "./EPTextDisplay";
import EPBlocksDisplay from "./EPBlocksDisplay";
type Mode = "text" | "blocks";
// BIG TODO: FIGRUE OUT A WAY TO HANDLE OMITING SUBJECT
function EPDisplay({ eps, opts, setOmitSubject }: {
eps: T.EPSelectionState,
opts: T.TextOptions,
setOmitSubject: (value: "true" | "false") => void,
}) {
const [mode] = useState<Mode>("text");
const [mode, setMode] = useState<Mode>("text");
const EP = completeEPSelection(eps);
const subject = getSubjectSelection(eps.blocks);
@ -34,7 +36,7 @@ function EPDisplay({ eps, opts, setOmitSubject }: {
const renderedPredicate = getPredicateSelectionFromBlocks(rendered.blocks).selection;
return <div className="text-center pt-3">
<div className="mb-2 d-flex flex-row justify-content-between align-items-center">
{/* <ModeSelect value={mode} onChange={setMode} /> */}
<ModeSelect value={mode} onChange={setMode} />
<ButtonSelect
small
value={(eps.omitSubject ? "true" : "false") as "true" | "false"}
@ -49,6 +51,9 @@ function EPDisplay({ eps, opts, setOmitSubject }: {
{mode === "text"
? <EPTextDisplay opts={opts} compiled={result} />
: <EPBlocksDisplay opts={opts} rendered={rendered} />}
{result.e && <div className="text-muted mt-3">
{result.e.map((e, i) => <div key={i}>{e}</div>)}
</div>}
{EP.predicate.selection.selection.type === "participle" && <div style={{ maxWidth: "6 00px", margin: "0 auto" }} className="alert alert-warning mt-3 pt-4">
<p> NOTE: This means that the subject {renderedSubject.selection.e ? `(${renderedSubject.selection.e})` : ""} is <strong>the action/idea</strong> of
{` `}
@ -58,14 +63,14 @@ function EPDisplay({ eps, opts, setOmitSubject }: {
</div>
}
// function ModeSelect({ value, onChange }: { value: Mode, onChange: (m: Mode) => void }) {
// return <div style={{ fontSize: "larger" }}>
// {value === "text" ? <div className="clickable" onClick={() => onChange("blocks")}>
// <i className="fas fa-cubes" />
// </div> : <div className="clickable" onClick={() => onChange("text")}>
// <i className="fas fa-align-left" />
// </div>}
// </div>;
// }
function ModeSelect({ value, onChange }: { value: Mode, onChange: (m: Mode) => void }) {
return <div style={{ fontSize: "larger" }}>
{value === "text" ? <div className="clickable" onClick={() => onChange("blocks")}>
<i className="fas fa-cubes" />
</div> : <div className="clickable" onClick={() => onChange("text")}>
<i className="fas fa-align-left" />
</div>}
</div>;
}
export default EPDisplay;

View File

@ -38,7 +38,7 @@ function EPExplorer(props: {
entryFeeder: T.EntryFeeder,
}) {
const [mode, setMode] = useStickyState<"charts" | "phrases">("charts", "EPExplorerMode");
const [eps, adjustEps] = useStickyReducer(epsReducer, blankEps, "EPState6", flashMessage);
const [eps, adjustEps] = useStickyReducer(epsReducer, blankEps, "EPState7", flashMessage);
const [alert, setAlert] = useState<string | undefined>(undefined);
const [showClipped, setShowClipped] = useState<string>("");
const parent = useRef<HTMLDivElement>(null);

View File

@ -19,9 +19,6 @@ function EPTextDisplay({ compiled, opts }: { compiled: {
</div>
: <VariationLayer vs={compiled.ps} />
}
{compiled.e && <div className="text-muted mt-3">
{compiled.e.map((e, i) => <div key={i}>{e}</div>)}
</div>}
</div>;
}

View File

@ -263,23 +263,26 @@ function arrangeVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[
export function compileEP(EP: T.EPRendered): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string[] };
export function compileEP(EP: T.EPRendered, combineLengths: true, blankOut?: BlankoutOptions): { ps: T.PsString[], e?: string[] };
export function compileEP(EP: T.EPRendered, combineLengths?: boolean, blankOut?: BlankoutOptions): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string[] } {
const psResult = compileEPPs(EP.blocks, EP.kids, blankOut);
const psResult = compileEPPs(EP.blocks, EP.kids, EP.omitSubject, blankOut);
return {
ps: combineLengths ? flattenLengths(psResult) : psResult,
e: compileEnglishEP(EP),
};
}
function compileEPPs(blocks: T.Block[], kids: T.Kid[], blankOut?: BlankoutOptions): T.SingleOrLengthOpts<T.PsString[]> {
function compileEPPs(blocks: T.Block[], kids: T.Kid[], omitSubject: boolean, blankOut?: BlankoutOptions): T.SingleOrLengthOpts<T.PsString[]> {
if (hasEquativeWithLengths(blocks)) {
return {
long: compileEPPs(specifyEquativeLength(blocks, "long"), kids, blankOut) as T.PsString[],
short: compileEPPs(specifyEquativeLength(blocks, "short"), kids, blankOut) as T.PsString[],
long: compileEPPs(specifyEquativeLength(blocks, "long"), kids, omitSubject, blankOut) as T.PsString[],
short: compileEPPs(specifyEquativeLength(blocks, "short"), kids, omitSubject, blankOut) as T.PsString[],
};
}
const subjectPerson = getSubjectSelectionFromBlocks(blocks)
.selection.selection.person;
const blocksWKids = putKidsInKidsSection(blocks, kids);
const blocksWKids = putKidsInKidsSection(
omitSubject ? blocks.filter(b => b.type !== "subjectSelection") : blocks,
kids,
);
return removeDuplicates(combineIntoText(blocksWKids, subjectPerson));
}

View File

@ -39,7 +39,7 @@ function getEPSBlocksAndKids(EP: T.EPSelectionComplete): { kids: T.Kid[], blocks
const commandingPerson = getPersonFromNP(commandingNP);
const equative: T.EquativeBlock = { type: "equative", equative: renderEquative(EP.equative, commandingPerson) };
const blocks: T.Block[] = [
...renderEPSBlocks(EP.omitSubject ? EP.blocks.filter(b => b.block.type !== "subjectSelection") : EP.blocks),
...renderEPSBlocks(EP.blocks),
{
type: "predicateSelection",
selection: EP.predicate.selection.type === "NP"
@ -122,19 +122,19 @@ function findPossesivesToShrink(blocks: (T.EPSBlockComplete | T.SubjectSelection
function findShrunkenPossInNP(NP: T.NPSelection): T.MiniPronoun[] {
if (NP.selection.type === "pronoun") return [];
if (!NP.selection.possesor) return [];
if (NP.selection.type === "noun") {
if (NP.selection.adjectives) {
const { adjectives, ...rest } = NP.selection;
return [
// TODO: ability to find possesives shrinkage in sandwiches in adjectives
// ...findShrunkenPossInAdjectives(adjectives),
...findShrunkenPossInNP({ type: "NP", selection: {
...rest,
adjectives: [],
}}),
];
}
}
// if (NP.selection.type === "noun") {
// if (NP.selection.adjectives) {
// const { adjectives, ...rest } = NP.selection;
// return [
// // TODO: ability to find possesives shrinkage in sandwiches in adjectives
// // ...findShrunkenPossInAdjectives(adjectives),
// ...findShrunkenPossInNP({ type: "NP", selection: {
// ...rest,
// adjectives: [],
// }}),
// ];
// }
// }
if (NP.selection.possesor.shrunken) {
const person = getPersonFromNP(NP.selection.possesor.np);
const miniP: T.MiniPronoun = {