AP and NP block diagrams working

This commit is contained in:
lingdocs 2022-06-11 11:25:28 -04:00
parent f4dc09e941
commit 2ba678b1ff
10 changed files with 238 additions and 308 deletions

View File

@ -6,7 +6,7 @@
"@formkit/auto-animate": "^1.0.0-beta.1", "@formkit/auto-animate": "^1.0.0-beta.1",
"@fortawesome/fontawesome-free": "^5.15.4", "@fortawesome/fontawesome-free": "^5.15.4",
"@lingdocs/lingdocs-main": "^0.3.1", "@lingdocs/lingdocs-main": "^0.3.1",
"@lingdocs/pashto-inflector": "^2.6.8", "@lingdocs/pashto-inflector": "^2.8.2",
"@testing-library/jest-dom": "^5.11.4", "@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0", "@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10", "@testing-library/user-event": "^12.1.10",

View File

@ -0,0 +1,45 @@
import {
Types as T,
Examples,
renderEP,
compileEP,
} from "@lingdocs/pashto-inflector";
import { completeEPSelection } from "@lingdocs/pashto-inflector/dist/lib/phrase-building/render-ep";
import { useState } from "react";
// import EPBlocks from "./EPBlocks";
function getShort<X>(i: T.SingleOrLengthOpts<X>): X {
if ("long" in i) {
return i.long;
}
return i;
}
function EditableExample({ children: eps, opts }: { children: T.EPSelectionState, opts: T.TextOptions }) {
const [mode, setMode] = useState<"example" | "blocks">("example");
const EPS = completeEPSelection(eps);
if (!EPS) {
return <div>Error: Invalid/incomplete Phrase</div>;
}
const rendered = renderEP(EPS);
const compiled = compileEP(rendered);
const text: T.PsString = {
...getShort(compiled.ps)[0],
e: compiled.e ? compiled.e.join(" / ") : undefined,
};
return <div>
<div className="d-flex flex-row justify-content-beginning">
{mode === "example" ? <div className="clickable" onClick={() => setMode("blocks")}>
<i className="fas fa-cubes" />
</div> : <div className="clickable" onClick={() => setMode("example")}>
<i className="fas fa-align-left" />
</div>}
</div>
{/* {mode === "example"
? <Examples opts={opts}>{[text]}</Examples>
: <EPBlocks opts={opts}>{rendered}</EPBlocks>} */}
</div>;
}
export default EditableExample;

View File

@ -16,10 +16,17 @@ export function EditIcon() {
return <i className="fas fa-edit" />; return <i className="fas fa-edit" />;
} }
function selectionToBlock(s: T.NPSelection | T.APSelection): { type: "NP", block: T.NPSelection | undefined } | { type: "AP", block: T.APSelection | undefined } {
return (s.type === "AP")
? { type: "AP", block: s }
: { type: "NP", block: s };
}
function EditablePhraseDiagram({ opts, children }: { function EditablePhraseDiagram({ opts, children }: {
opts: T.TextOptions, opts: T.TextOptions,
children: BlockInput[], children: (T.NPSelection | T.APSelection)[],
}) { }) {
console.log({ aa: children[0] })
const block = children[0]; const block = children[0];
const parent = useRef<HTMLDivElement>(null); const parent = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
@ -32,8 +39,7 @@ function EditablePhraseDiagram({ opts, children }: {
} | { } | {
type: "AP", type: "AP",
block: T.APSelection | undefined, block: T.APSelection | undefined,
}>(block); }>(selectionToBlock(block));
console.log({ block });
if (children.length === 0) return null; if (children.length === 0) return null;
function handleNPChange(np: T.NPSelection | undefined) { function handleNPChange(np: T.NPSelection | undefined) {
setEdited({ type: "NP", block: np }); setEdited({ type: "NP", block: np });
@ -42,7 +48,7 @@ function EditablePhraseDiagram({ opts, children }: {
setEdited({ type: "AP", block: ap }); setEdited({ type: "AP", block: ap });
} }
function handleReset() { function handleReset() {
setEdited(block); setEdited(selectionToBlock(block));
setEditing(false); setEditing(false);
} }
return <div> return <div>
@ -76,7 +82,7 @@ function EditablePhraseDiagram({ opts, children }: {
</div>} </div>}
{edited.block {edited.block
&& <PhraseDiagram opts={opts}> && <PhraseDiagram opts={opts}>
{[edited] as BlockInput[]} {edited.block}
</PhraseDiagram>} </PhraseDiagram>}
</div> </div>
</div>; </div>;

View File

@ -1,182 +1,31 @@
import { import {
renderNPSelection, renderNPSelection,
Types as T, Types as T,
getEnglishFromRendered,
renderAPSelection, renderAPSelection,
NPBlock,
APBlock,
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
import classNames from "classnames";
function PhraseDiagram({ opts, children }: { function PhraseDiagram({ opts, children }: {
opts: T.TextOptions, opts: T.TextOptions,
children: BlockInput[] children: T.NPSelection | T.APSelection,
}) { }) {
try {
const rendered = children.type === "AP"
? renderAPSelection(children)
: renderNPSelection(children, false, false, "subject", "none");
return <div> return <div>
<div className="d-flex flex-row justify-content-center" style={{ maxWidth: "100%" }}> <div className="d-flex flex-row justify-content-center" style={{ maxWidth: "100%" }}>
{children.map((block) => ( {rendered.type === "NP"
<Block key={Math.random()} opts={opts}>{block}</Block> ? <NPBlock opts={opts}>{rendered}</NPBlock>
))} : <APBlock opts={opts}>{rendered}</APBlock>}
</div> </div>
</div>; </div>;
} catch(e) {
console.log(e);
return <div>ERROR</div>;
}
} }
function Block({ opts, children }: {
opts: T.TextOptions,
children: BlockInput,
}) {
if (children.type === "NP") {
const rendered = renderNPSelection(children.block, false, false, "subject", "none");
const english = getEnglishFromRendered(rendered)
return <div className="text-center mb-2">
<NP opts={opts} english={english}>{rendered}</NP>
</div>;
}
const rendered = renderAPSelection(children.block);
const english = getEnglishFromRendered(rendered)
return <div className="text-center mb-2">
<AP opts={opts} english={english}>{rendered}</AP>
</div>;
}
function AP({ opts, children, english }: {
opts: T.TextOptions,
children: T.Rendered<T.APSelection>,
english?: string,
}) {
const ap = children;
if (ap.type === "adverb") {
return <div>
<div
className={classNames("d-flex flex-row justify-content-center align-items-center")}
style={{
border: "2px solid black",
padding: "1rem",
textAlign: "center",
}}
>
{ap.ps[0].f}
</div>
<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>}
</div>;
}
return <div>
<div className="text-center">Sandwich 🥪</div>
<div
className={classNames("d-flex flex-row justify-content-center align-items-center")}
style={{
border: "2px solid black",
padding: "0.75rem 0.5rem 0.25rem 0.5rem",
textAlign: "center",
}}
>
<div className="d-flex flex-row justify-content-between align-items-end">
<Possesors opts={opts}>{ap.inside.type !== "pronoun" ? ap.inside.possesor : undefined}</Possesors>
<div className="mr-2 ml-1 mb-1"><strong>{ap.before ? ap.before.f : ""}</strong></div>
<div>
<NP opts={opts} inside>{ap.inside}</NP>
</div>
<div className="ml-2 mr-1 mb-1"><strong>{ap.after ? ap.after.f : ""}</strong></div>
</div>
</div>
<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>}
</div>;
}
function NP({ opts, children, inside, english }: {
opts: T.TextOptions,
children: T.Rendered<T.NPSelection>,
inside?: boolean,
english?: string,
}) {
const np = children;
const hasPossesor = !!(np.type !== "pronoun" && np.possesor);
return <div>
<div
className={classNames("d-flex flex-row justify-content-center align-items-center", { "pt-2": !inside && hasPossesor })}
style={{
border: "2px solid black",
padding: inside ? "0.3rem" : hasPossesor ? "0.5rem 1rem 0.25rem 1rem" : "1rem",
textAlign: "center",
}}
>
{!inside && <Possesors opts={opts}>{np.type !== "pronoun" ? np.possesor : undefined}</Possesors>}
<Adjectives opts={opts}>{np.adjectives}</Adjectives>
<div> {np.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>}
</div>
}
function Possesors({ opts, children }: {
opts: T.TextOptions,
children: { shrunken: boolean, np: T.Rendered<T.NPSelection> } | undefined,
}) {
if (!children) {
return null;
}
const contraction = checkForContraction(children.np);
return <div className="d-flex flex-row mr-1 align-items-end" style={{
marginBottom: "0.5rem",
borderBottom: "1px solid grey",
}}>
{children.np.type !== "pronoun" && <Possesors opts={opts}>{children.np.possesor}</Possesors>}
<div>
{contraction && <div className="mb-1">({contraction})</div>}
<div className={classNames("d-flex", "flex-row", "align-items-center", { "text-muted": contraction })}>
<div className="mr-1 pb-2">du</div>
<div>
<NP opts={opts} inside>{children.np}</NP>
</div>
</div>
</div>
</div>
}
function checkForContraction(np: T.Rendered<T.NPSelection>): string | undefined {
if (np.type !== "pronoun") return undefined;
if (np.person === T.Person.FirstSingMale || np.person === T.Person.FirstSingFemale) {
return "zmaa"
}
if (np.person === T.Person.SecondSingMale || np.person === T.Person.SecondSingFemale) {
return "staa"
}
if (np.person === T.Person.FirstPlurMale || np.person === T.Person.FirstPlurFemale) {
return "zmoonG"
}
if (np.person === T.Person.SecondPlurMale || np.person === T.Person.SecondPlurFemale) {
return "staaso"
}
return undefined;
}
function Adjectives({ opts, children }: {
opts: T.TextOptions,
children: T.Rendered<T.AdjectiveSelection>[] | undefined,
}) {
if (!children) {
return null;
}
return <em className="mr-1">
{children.map(a => a.ps[0].f).join(" ")}{` `}
</em>
}
export default PhraseDiagram; export default PhraseDiagram;

View File

@ -28,7 +28,7 @@ An adverb is a word or expression that modifies the time, manner, place, etc. of
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "AP", type: "AP",
block: { selection: {
type: "adverb", type: "adverb",
entry: {"ts":1527815160,"i":2394,"p":"پرون","f":"paroon","g":"paroon","e":"yesterday","c":"adv."}, entry: {"ts":1527815160,"i":2394,"p":"پرون","f":"paroon","g":"paroon","e":"yesterday","c":"adv."},
}, },
@ -38,7 +38,7 @@ An adverb is a word or expression that modifies the time, manner, place, etc. of
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "AP", type: "AP",
block: { selection: {
type: "adverb", type: "adverb",
entry: {"ts":1527819967,"i":5428,"p":"خامخا","f":"khaamakhaa","g":"khaamakhaa","e":"definitely, for sure, whether someone wants or not, willy-nilly (this last use more in Urdu)","c":"adv."}, entry: {"ts":1527819967,"i":5428,"p":"خامخا","f":"khaamakhaa","g":"khaamakhaa","e":"definitely, for sure, whether someone wants or not, willy-nilly (this last use more in Urdu)","c":"adv."},
}, },
@ -54,20 +54,23 @@ These "sandwiches" are also used as an adverb to give more information for the p
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "AP", type: "AP",
block: { selection: {
type: "sandwich", type: "sandwich",
before: { p: "په", f: "pu" }, before: { p: "په", f: "pu" },
after: { p: "کې", f: "ke" }, after: { p: "کې", f: "ke" },
e: "in", e: "in",
inside: { inside: {
type: "noun", type: "NP",
entry: {"ts":1527812828,"i":10539,"p":"کور","f":"kor","g":"kor","e":"house, home","c":"n. m."}, selection: {
gender: "masc", type: "noun",
genderCanChange: false, entry: {"ts":1527812828,"i":10539,"p":"کور","f":"kor","g":"kor","e":"house, home","c":"n. m."},
number: "singular", gender: "masc",
numberCanChange: true, genderCanChange: false,
adjectives: [], number: "singular",
possesor: undefined, numberCanChange: true,
adjectives: [],
possesor: undefined,
},
}, },
}, },
}, },
@ -78,23 +81,26 @@ Because the inside of a sandwich is an <Link to="/phrase-structure/np/">NP</Link
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "AP", type: "AP",
block: { selection: {
type: "sandwich", type: "sandwich",
before: { p: "په", f: "pu" }, before: { p: "په", f: "pu" },
after: { p: "کې", f: "ke" }, after: { p: "کې", f: "ke" },
e: "in", e: "in",
inside: { inside: {
type: "noun", type: "NP",
entry: {"ts":1527812828,"i":10539,"p":"کور","f":"kor","g":"kor","e":"house, home","c":"n. m."}, selection: {
gender: "masc", type: "noun",
genderCanChange: false, entry: {"ts":1527812828,"i":10539,"p":"کور","f":"kor","g":"kor","e":"house, home","c":"n. m."},
number: "singular", gender: "masc",
numberCanChange: true, genderCanChange: false,
adjectives: [{ number: "singular",
type: "adjective", numberCanChange: true,
entry: {"ts":1527812625,"i":9128,"p":"غټ","f":"ghuT, ghaT","g":"ghuT,ghaT","e":"big, fat","c":"adj."}, adjectives: [{
}], type: "adjective",
possesor: undefined, entry: {"ts":1527812625,"i":9128,"p":"غټ","f":"ghuT, ghaT","g":"ghuT,ghaT","e":"big, fat","c":"adj."},
}],
possesor: undefined,
},
}, },
}, },
}, },
@ -105,33 +111,39 @@ We can also add a possesor it hangs outside of the sandwich. All together it's s
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "AP", type: "AP",
block: { selection: {
type: "sandwich", type: "sandwich",
before: { p: "په", f: "pu" }, before: { p: "په", f: "pu" },
after: { p: "کې", f: "ke" }, after: { p: "کې", f: "ke" },
e: "in", e: "in",
inside: { inside: {
type: "noun", type: "NP",
entry: {"ts":1527812828,"i":10539,"p":"کور","f":"kor","g":"kor","e":"house, home","c":"n. m."}, selection: {
gender: "masc", type: "noun",
genderCanChange: false, entry: {"ts":1527812828,"i":10539,"p":"کور","f":"kor","g":"kor","e":"house, home","c":"n. m."},
number: "singular", gender: "masc",
numberCanChange: true, genderCanChange: false,
adjectives: [{ number: "singular",
type: "adjective", numberCanChange: true,
entry: {"ts":1527812625,"i":9128,"p":"غټ","f":"ghuT, ghaT","g":"ghuT,ghaT","e":"big, fat","c":"adj."}, adjectives: [{
}], type: "adjective",
possesor: { entry: {"ts":1527812625,"i":9128,"p":"غټ","f":"ghuT, ghaT","g":"ghuT,ghaT","e":"big, fat","c":"adj."},
shrunken: false, }],
np: { possesor: {
type: "noun", shrunken: false,
entry: {"ts":1527815251,"i":7802,"p":"سړی","f":"saRéy","g":"saRey","e":"man","c":"n. m.","ec":"man","ep":"men"}, np: {
gender: "masc", type: "NP",
genderCanChange: false, selection: {
number: "singular", type: "noun",
numberCanChange: true, entry: {"ts":1527815251,"i":7802,"p":"سړی","f":"saRéy","g":"saRey","e":"man","c":"n. m.","ec":"man","ep":"men"},
adjectives: [], gender: "masc",
possesor: undefined, genderCanChange: false,
number: "singular",
numberCanChange: true,
adjectives: [],
possesor: undefined,
},
},
}, },
}, },
}, },
@ -144,25 +156,31 @@ Here's another example using the sandwich <InlinePs opts={opts} ps={{ p: "سره
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "AP", type: "AP",
block: { selection: {
type: "sandwich", type: "sandwich",
before: { p: "له", f: "la" }, before: { p: "له", f: "la" },
after: { p: "سره", f: "sara" }, after: { p: "سره", f: "sara" },
e: "with", e: "with",
inside: { inside: {
type: "noun", type: "NP",
entry: {"ts":1527814159,"i":12723,"p":"ملګری","f":"malgúrey","g":"malgurey","e":"friend, companion","c":"n. m. anim. unisex"}, selection: {
gender: "masc", type: "noun",
genderCanChange: true, entry: {"ts":1527814159,"i":12723,"p":"ملګری","f":"malgúrey","g":"malgurey","e":"friend, companion","c":"n. m. anim. unisex"},
number: "singular", gender: "masc",
numberCanChange: true, genderCanChange: true,
adjectives: [], number: "singular",
possesor: { numberCanChange: true,
shrunken: false, adjectives: [],
np: { possesor: {
type: "pronoun", shrunken: false,
distance: "far", np: {
person: 0, type: "NP",
selection: {
type: "pronoun",
distance: "far",
person: 0,
},
},
}, },
}, },
}, },

View File

@ -10,9 +10,6 @@ import {
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
import psmd from "../../lib/psmd"; import psmd from "../../lib/psmd";
import Link from "../../components/Link"; import Link from "../../components/Link";
import EditablePhraseDiagram, {
EditIcon,
} from "../../components/phrase-diagram/EditablePhraseDiagram";
import EquativeIllustration from "../../components/EquativeIllustration"; import EquativeIllustration from "../../components/EquativeIllustration";
import BasicBlocks from "../../components/BasicBlocks" import BasicBlocks from "../../components/BasicBlocks"

View File

@ -40,7 +40,7 @@ A **noun** is a word that we use to identify people, places, things, or ideas. O
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { selection: {
type: "noun", type: "noun",
entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."}, entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
gender: "masc", gender: "masc",
@ -58,7 +58,7 @@ We can also **extend our noun by adding *adjectives***. Let's add the *adjective
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { selection: {
type: "noun", type: "noun",
entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."}, entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
gender: "masc", gender: "masc",
@ -70,7 +70,7 @@ We can also **extend our noun by adding *adjectives***. Let's add the *adjective
entry: {"ts":1527815451,"i":7245,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"}, entry: {"ts":1527815451,"i":7245,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"},
}], }],
possesor: undefined, possesor: undefined,
}, }
}, },
]}</EditablePhraseDiagram> ]}</EditablePhraseDiagram>
@ -79,7 +79,7 @@ Now we have two words, but it's still **one NP**, one building block. We can add
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { selection: {
type: "noun", type: "noun",
entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."}, entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
gender: "masc", gender: "masc",
@ -101,7 +101,7 @@ Now we have two words, but it's still **one NP**, one building block. We can add
}, },
], ],
possesor: undefined, possesor: undefined,
}, }
}, },
]}</EditablePhraseDiagram> ]}</EditablePhraseDiagram>
@ -110,7 +110,7 @@ We can also add a **possesor** by adding another NP <Link to="/sandwiches/sandwi
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { selection: {
type: "noun", type: "noun",
entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."}, entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
gender: "masc", gender: "masc",
@ -126,13 +126,16 @@ We can also add a **possesor** by adding another NP <Link to="/sandwiches/sandwi
possesor: { possesor: {
shrunken: false, shrunken: false,
np: { np: {
type: "noun", type: "NP",
entry: {"ts":1527812881,"i":11694,"p":"ماشوم","f":"maashoom","g":"maashoom","e":"child, kid","c":"n. m. anim. unisex","ec":"child","ep":"children"}, selection: {
gender: "masc", type: "noun",
genderCanChange: true, entry: {"ts":1527812881,"i":11694,"p":"ماشوم","f":"maashoom","g":"maashoom","e":"child, kid","c":"n. m. anim. unisex","ec":"child","ep":"children"},
number: "singular", gender: "masc",
numberCanChange: true, genderCanChange: true,
adjectives: [], number: "singular",
numberCanChange: true,
adjectives: [],
}
}, },
}, },
}, },
@ -144,7 +147,7 @@ If our possesor is a noun, we can add a possesor to *it*. Try clicking the <Edit
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { selection: {
type: "noun", type: "noun",
entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."}, entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
gender: "masc", gender: "masc",
@ -160,23 +163,29 @@ If our possesor is a noun, we can add a possesor to *it*. Try clicking the <Edit
possesor: { possesor: {
shrunken: false, shrunken: false,
np: { np: {
type: "noun", type: "NP",
entry: {"ts":1527812881,"i":11694,"p":"ماشوم","f":"maashoom","g":"maashoom","e":"child, kid","c":"n. m. anim. unisex","ec":"child","ep":"children"}, selection: {
gender: "masc", type: "noun",
genderCanChange: true, entry: {"ts":1527812881,"i":11694,"p":"ماشوم","f":"maashoom","g":"maashoom","e":"child, kid","c":"n. m. anim. unisex","ec":"child","ep":"children"},
number: "singular", gender: "masc",
numberCanChange: true, genderCanChange: true,
adjectives: [], number: "singular",
possesor: { numberCanChange: true,
shrunken: false, adjectives: [],
np: { possesor: {
type: "noun", shrunken: false,
entry: {"ts":1527815177,"i":2530,"p":"پلار","f":"plaar","g":"plaar","e":"father","c":"n. m."}, np: {
gender: "masc", type: "NP",
genderCanChange: false, selection: {
number: "singular", type: "noun",
numberCanChange: true, entry: {"ts":1527815177,"i":2530,"p":"پلار","f":"plaar","g":"plaar","e":"father","c":"n. m."},
adjectives: [], gender: "masc",
genderCanChange: false,
number: "singular",
numberCanChange: true,
adjectives: [],
},
},
}, },
}, },
}, },
@ -206,23 +215,21 @@ You can't add any adjectives or possesors to pronouns in Pashto. They just stand
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { selection: {
type: "pronoun", type: "pronoun",
person: 0, person: 0,
distance: "far", distance: "far",
}, }
}, },
]}</EditablePhraseDiagram> ]}</EditablePhraseDiagram>
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{type: "NP", selection:
{ {
type: "NP",
block: {
type: "pronoun", type: "pronoun",
person: 11, person: 11,
distance: "far", distance: "far",
}, }},
},
]}</EditablePhraseDiagram> ]}</EditablePhraseDiagram>
### Participle ### Participle
@ -235,12 +242,12 @@ In Pashto you can use the infinitive form of a verb as a participle, meaning you
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { selection: {
type: "participle", type: "participle",
verb: { verb: {
entry: {"ts":1527812856,"i":11617,"p":"لیکل","f":"leekul","g":"leekul","e":"to write","c":"v. trans./gramm. trans.","ec":"write,writes,writing,wrote,written"}, entry: {"ts":1527812856,"i":11617,"p":"لیکل","f":"leekul","g":"leekul","e":"to write","c":"v. trans./gramm. trans.","ec":"write,writes,writing,wrote,written"},
}, },
}, }
}, },
]}</EditablePhraseDiagram> ]}</EditablePhraseDiagram>
@ -291,12 +298,12 @@ For example, if we take the participle <InlinePs opts={opts} ps={{ p: "وهل",
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { selection: {
type: "participle", type: "participle",
verb: { verb: {
entry: {"ts":1527815399,"i":14463,"p":"وهل","f":"wahul","g":"wahul","e":"to hit","c":"v. trans.","tppp":"واهه","tppf":"waahu","ec":"hit,hits,hitting,hit,hit"}, entry: {"ts":1527815399,"i":14463,"p":"وهل","f":"wahul","g":"wahul","e":"to hit","c":"v. trans.","tppp":"واهه","tppf":"waahu","ec":"hit,hits,hitting,hit,hit"},
}, },
}, }
}, },
]}</EditablePhraseDiagram> ]}</EditablePhraseDiagram>
@ -305,7 +312,7 @@ And we can add the word <InlinePs opts={opts} ps={{ p: "ماشومان", f: "maa
<EditablePhraseDiagram opts={opts}>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { selection: {
type: "participle", type: "participle",
verb: { verb: {
entry: {"ts":1527815399,"i":14463,"p":"وهل","f":"wahul","g":"wahul","e":"to hit","c":"v. trans.","tppp":"واهه","tppf":"waahu","ec":"hit,hits,hitting,hit,hit"}, entry: {"ts":1527815399,"i":14463,"p":"وهل","f":"wahul","g":"wahul","e":"to hit","c":"v. trans.","tppp":"واهه","tppf":"waahu","ec":"hit,hits,hitting,hit,hit"},
@ -313,13 +320,16 @@ And we can add the word <InlinePs opts={opts} ps={{ p: "ماشومان", f: "maa
possesor: { possesor: {
shrunken: false, shrunken: false,
np: { np: {
type: "noun", type: "NP",
entry: {"ts":1527812881,"i":11694,"p":"ماشوم","f":"maashoom","g":"maashoom","e":"child, kid","c":"n. m. anim. unisex","ec":"child","ep":"children"}, selection: {
gender: "masc", type: "noun",
genderCanChange: true, entry: {"ts":1527812881,"i":11694,"p":"ماشوم","f":"maashoom","g":"maashoom","e":"child, kid","c":"n. m. anim. unisex","ec":"child","ep":"children"},
number: "plural", gender: "masc",
numberCanChange: true, genderCanChange: true,
adjectives: [], number: "plural",
numberCanChange: true,
adjectives: [],
},
}, },
}, },
}, },

View File

@ -218,12 +218,15 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
}; };
} }
function makeRandomEPS(l: T.EquativeTense | "allIdentify" | "allProduce"): T.EPSelectionComplete { function makeRandomEPS(l: T.EquativeTense | "allIdentify" | "allProduce"): T.EPSelectionComplete {
const subj = randFromArray([ const subj: T.NPSelection = {
makeRandPronoun, type: "NP",
makeRandPronoun, selection: randFromArray([
makeRandomNoun, makeRandPronoun,
makeRandPronoun, makeRandPronoun,
])(); makeRandomNoun,
makeRandPronoun,
])(),
};
const pred = randFromArray([...adjectives, ...locAdverbs]); const pred = randFromArray([...adjectives, ...locAdverbs]);
const tense = (l === "allIdentify" || l === "allProduce") const tense = (l === "allIdentify" || l === "allProduce")
? randFromArray(tenses) ? randFromArray(tenses)
@ -258,7 +261,7 @@ export default function EquativeGame({ id, link, level }: { id: string, link: st
question: { question: {
EPS, EPS,
phrase, phrase,
equative: EP.equative, equative: getEqFromRendered(EP),
}, },
}; };
} }
@ -478,14 +481,17 @@ function makeEPS(subject: T.NPSelection, predicate: T.AdjectiveEntry | T.Locativ
}, },
], ],
predicate: { predicate: {
type: "Complement", type: "predicateSelection",
selection: tp.isAdjectiveEntry(predicate) ? { selection: {
type: "adjective", type: "EQComp",
entry: predicate, selection: tp.isAdjectiveEntry(predicate) ? {
sandwich: undefined, type: "adjective",
} : { entry: predicate,
type: "loc. adv.", sandwich: undefined,
entry: predicate, } : {
type: "loc. adv.",
entry: predicate,
},
}, },
}, },
equative: { equative: {
@ -495,3 +501,9 @@ function makeEPS(subject: T.NPSelection, predicate: T.AdjectiveEntry | T.Locativ
omitSubject: false, omitSubject: false,
}; };
} }
function getEqFromRendered(e: T.EPRendered): T.EquativeRendered {
const eblock = e.blocks.find(x => x.type === "equative");
if (!eblock || eblock.type !== "equative") throw new Error("Error getting equative block");
return eblock.equative;
}

View File

@ -4,10 +4,3 @@ type Pronoun = {
person: import("@lingdocs/pashto-inflector").Types.Person, person: import("@lingdocs/pashto-inflector").Types.Person,
}; };
type BlockInput = {
type: "NP",
block: import("@lingdocs/pashto-inflector").Types.NPSelection,
} | {
type: "AP",
block: import("@lingdocs/pashto-inflector").Types.APSelection,
};

View File

@ -1695,10 +1695,10 @@
rambda "^6.7.0" rambda "^6.7.0"
react-select "^5.2.2" react-select "^5.2.2"
"@lingdocs/pashto-inflector@^2.6.8": "@lingdocs/pashto-inflector@^2.8.2":
version "2.6.8" version "2.8.2"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.6.8.tgz#d104620a75a4f034d3dcd9d8a097eab40b77024d" resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.8.2.tgz#006f1f3f8223f5ea67ac75106369c3f6072441a3"
integrity sha512-z2RetX9mRgZxM0FIX8R3cgCF+Exof/OigMDZIlEHLhBAljSwaojA9ZdXnyKP1zW8EDtjLIqsr3rWQre6niU80w== integrity sha512-mA9L37+Tq5teDTxczjfIBMfOStfqAzn7QFUNoRSEXl7ci4Yo+5bomHf2sjGDr0ZbneFAyp0K05tVJCWi8SBkeg==
dependencies: dependencies:
"@formkit/auto-animate" "^1.0.0-beta.1" "@formkit/auto-animate" "^1.0.0-beta.1"
classnames "^2.2.6" classnames "^2.2.6"