proper verb showcases - but now the sandwich english is broken

This commit is contained in:
lingdocs 2022-06-21 17:29:54 -05:00
parent 8ec6f0f2ec
commit 17f62439b5
11 changed files with 248 additions and 120 deletions

View File

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

View File

@ -0,0 +1,211 @@
import {
Types as T,
RootsAndStems,
conjugateVerb,
VerbTable,
renderVP,
compileVP,
ButtonSelect,
getEnglishVerb,
InlinePs,
removeFVarients,
} from "@lingdocs/pashto-inflector";
import { isImperativeTense } from "@lingdocs/pashto-inflector/dist/lib/type-predicates";
import { useState } from "react";
import Carousel from "./Carousel";
import { basicVerbs } from "../content/verbs/basic-present-verbs";
function BasicVerbShowCase({ opts, tense }: {
opts: T.TextOptions,
tense: T.VerbTense | T.ImperativeTense,
}) {
return <Carousel stickyTitle items={basicVerbs} render={(item) => {
return {
title: <InlinePs opts={opts}>{{
...removeFVarients(item.entry),
e: undefined,
}}</InlinePs>,
body: <BasicVerbChart
verb={item}
opts={opts}
tense={tense}
/>,
};
}}/>
}
export default BasicVerbShowCase;
function BasicVerbChart({ verb, opts, tense }: {
verb: T.VerbEntry,
opts: T.TextOptions,
tense: T.VerbTense | T.ImperativeTense,
}) {
const [negative, setNegative] = useState<boolean>(false);
const c = conjugateVerb(verb.entry, verb.complement);
const conjugations = "stative" in c
? c.stative
: "grammaticallyTransitive" in c
? c.grammaticallyTransitive
: c;
const phrasesForTable = makeExamplePhrases(verb, tense, negative)
return <div>
<div>
{getEnglishVerb(verb.entry)}
</div>
<RootsAndStems
textOptions={opts}
info={conjugations.info}
hidePastParticiple={true}
highlighted={[tenseToStem(tense)]}
/>
<div className="my-3">
<ButtonSelect
handleChange={(value) => setNegative(value === "true")}
value={String(negative)}
small
options={[
{ value: "true", label: "Neg." },
{ value: "false", label: "Pos." },
]}
/>
</div>
<div className="text-left">
<VerbTable
textOptions={opts}
block={phrasesForTable.ps}
english={phrasesForTable.e}
/>
</div>
</div>
}
function makeExamplePhrases(verb: T.VerbEntry, tense: T.VerbTense | T.ImperativeTense, negative: boolean): { ps: T.VerbBlock | T.ImperativeBlock, e: T.EnglishBlock } {
function makeSelection(person: T.Person): T.VPSelectionComplete{
return {
"blocks": [
{"key":Math.random(),"block":{"type":"subjectSelection","selection":{"type":"NP","selection":{"type":"pronoun","person": person,"distance":"far"}}}},
{
key: Math.random(),
// @ts-ignore
block: verb.entry.c?.includes("intrans.")
? {"type":"objectSelection","selection":"none"}
: {"type":"objectSelection", "selection":{"type":"NP","selection":{"type":"noun","entry":{"ts":1527812817,"i":10011,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},"gender":"masc","genderCanChange":false,"number":"singular","numberCanChange":true,"adjectives":[]}}},
},
],
"verb":{
"type":"verb",
verb,
tense,
"transitivity":"intransitive",
"isCompound":false,
"voice":"active",
negative,
"canChangeTransitivity":false,
"canChangeVoice":false,
"canChangeStatDyn":false,
},
"form":{"removeKing":false,"shrinkServant":false},
};
}
function makePhrase(person: T.Person): { ps: T.ArrayOneOrMore<T.PsString>, e: string } {
const selection = makeSelection(person);
const rendered = renderVP(selection);
const compiled = compileVP(rendered, rendered.form, true);
return {
ps: [modifyP(compiled.ps[0])],
e: compiled.e ? modifyEnglish(compiled.e.join(" • ")) : "",
};
}
return createVerbTable(makePhrase, isImperativeTense(tense) ? "imperative" : "nonImperative");
}
function modifyP(ps: T.PsString): T.PsString {
return {
p: ps.p.replace(" کتاب ", ""),
f: ps.f.replace(" kitáab ", ""),
};
}
function modifyEnglish(e: string): string {
// "kitaab" used as a dummy object
return e
.replace(/\(a\/the\) +book/ig, "")
.replace(/he\/it/ig, "he/she/it")
.replace(/We \(m\. pl\.\)/ig, "We ")
.replace(/They \(m\. pl\.\)/ig, "They ")
.replace(/\(m\. pl\.\)/ig, "(pl.)")
.replace(/\(m\.\)/ig, "");
}
function tenseToStem(t: T.VerbTense | T.ImperativeTense): "imperfective stem" | "perfective stem" | "imperfective root" | "perfective root" {
return t === "presentVerb"
? "imperfective stem"
: t === "subjunctiveVerb"
? "perfective stem"
: t === "imperfectiveFuture"
? "imperfective stem"
: t === "perfectiveFuture"
? "perfective stem"
: t === "imperfectivePast"
? "imperfective root"
: t === "perfectivePast"
? "perfective root"
: t === "habitualImperfectivePast"
? "imperfective root"
: t === "habitualPerfectivePast"
? "perfective root"
: t === "imperfectiveImperative"
? "imperfective root"
: "perfective root";
}
function createVerbTable(f: (person: T.Person) => { ps: T.ArrayOneOrMore<T.PsString>, e: string }, type: "imperative" | "nonImperative"): { ps: T.VerbBlock | T.ImperativeBlock, e: T.EnglishBlock } {
if (type === "imperative") {
const b = [
[f(2), f(8)],
[f(3), f(9)],
];
return {
ps: [
[b[0][0].ps, b[0][1].ps],
[b[1][0].ps, b[1][1].ps],
],
e: [
[b[0][0].e, b[0][1].e],
[b[1][0].e, b[1][1].e],
[b[0][0].e, b[0][1].e],
[b[1][0].e, b[1][1].e],
[b[0][0].e, b[0][1].e],
[b[1][0].e, b[1][1].e],
],
};
}
const b = [
[f(0), f(6)],
[f(1), f(7)],
[f(2), f(8)],
[f(3), f(9)],
[f(4), f(10)],
[f(5), f(11)],
];
return {
ps: [
[b[0][0].ps, b[0][1].ps],
[b[1][0].ps, b[1][1].ps],
[b[2][0].ps, b[2][1].ps],
[b[3][0].ps, b[3][1].ps],
[b[4][0].ps, b[4][1].ps],
[b[5][0].ps, b[5][1].ps],
],
e: [
[b[0][0].e, b[0][1].e],
[b[1][0].e, b[1][1].e],
[b[2][0].e, b[2][1].e],
[b[3][0].e, b[3][1].e],
[b[4][0].e, b[4][1].e],
[b[5][0].e, b[5][1].e],
],
};
}

View File

@ -23,7 +23,7 @@ const Chapter = ({ children: chapter }) => {
});
}
return <>
<main className="col bg-faded py-3 d-flex flex-column">
<main className="col bg-faded py-3 d-flex flex-column" style={{ maxWidth: !chapter.frontMatter.fullWidth ? "850px" : undefined }}>
<div className="flex-shrink-0">
<div className="mb-2" style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
<h1>{chapter.frontMatter.title}</h1>

View File

@ -17,8 +17,8 @@ function BlockDiagram({ opts, children }: {
return <div className="mb-3">
<div className="d-flex flex-row justify-content-center" style={{ maxWidth: "100%" }}>
{rendered.type === "NP"
? <NPBlock opts={opts} english={rendered.selection.e}>{rendered}</NPBlock>
: <APBlock opts={opts} english={rendered.selection.e}>{rendered}</APBlock>}
? <NPBlock script="f" opts={opts} english={rendered.selection.e}>{rendered}</NPBlock>
: <APBlock script="f" opts={opts} english={rendered.selection.e}>{rendered}</APBlock>}
</div>
</div>;
} catch(e) {

View File

@ -0,0 +1,15 @@
import {
Types as T,
} from "@lingdocs/pashto-inflector";
// @ts-ignore
export const basicVerbs: T.VerbEntry[] = [
{"ts":1527812856,"i":11630,"p":"لیکل","f":"leekul","g":"leekul","e":"to write, draw","c":"v. trans./gramm. trans.","ec":"write,writes,writing,wrote,written"},
{"ts":1527815399,"i":14480,"p":"وهل","f":"wahul","g":"wahul","e":"to hit","c":"v. trans.","tppp":"واهه","tppf":"waahu","ec":"hit,hits,hitting,hit,hit"},
{"ts":1527817750,"i":7843,"p":"سکل","f":"skul","g":"skul","e":"to drink","c":"v. trans.","ec":"drink,drinks,drinking,drank,drank"},
{"ts":1527812752,"i":10625,"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"},
{"ts":1527812275,"i":11608,"p":"لیدل","f":"leedul","g":"leedul","e":"to see","c":"v. trans./gramm. trans.","psp":"وین","psf":"ween","tppp":"لید","tppf":"leed","ec":"see,sees,seeing,saw,seen"},
{"ts":1577049208257,"i":1068,"p":"اورېدل","f":"awredul","g":"awredul","e":"to hear, listen","c":"v. trans./gramm. trans.","psp":"اور","psf":"awr","tppp":"اورېد","tppf":"awred","ec":"hear,hears,hearing,heard"},
{"ts":1527812790,"i":5795,"p":"خوړل","f":"khoRul","g":"khoRul","e":"to eat, to bite","c":"v. trans.","psp":"خور","psf":"khor","tppp":"خوړ","tppf":"khoR","ec":"eat,eats,eating,ate,eaten"},
{"ts":1527815216,"i":6630,"p":"راتلل","f":"raatlúl","g":"raatlul","e":"to come","c":"v. intrans. irreg.","psp":"راځ","psf":"raadz","ssp":"راش","ssf":"ráash","prp":"راغلل","prf":"ráaghlul","pprtp":"راغلی","pprtf":"raaghúley","tppp":"راغی","tppf":"ráaghey","noOo":true,"separationAtP":2,"separationAtF":3,"ec":"come,comes,coming,came,come"},
].map(entry => ({ entry }));

View File

@ -6,20 +6,14 @@ import {
defaultTextOptions as opts,
Examples,
InlinePs,
removeFVarients,
ConjugationViewer,
} from "@lingdocs/pashto-inflector";
import cousins from "./cousins.png";
import psmd from "../../lib/psmd";
import Carousel from "../../components/Carousel";
import Link from "../../components/Link";
import Formula from "../../components/formula/Formula";
import { verbs } from "../../words/words";
import shuffleArray from "../../lib/shuffle-array";
import imperfectiveFuture from "./imperfective-future-graph.svg";
import perfectiveFuture from "./perfective-future-graph.svg";
export const basicVerbs = verbs.filter((v) => !v.entry.c?.includes("gramm. trans."));
import BasicVerbShowCase from "../../components/BasicVerbShowCase";
There are two kinds of future forms in Pashto:
@ -39,24 +33,9 @@ This is used to talk about something happening in the future, while thinking of
<Link to="/verbs/present-verbs/">Present</Link>
</Formula>
<Carousel stickyTitle items={shuffleArray(basicVerbs)} render={(item) => {
return {
title: <InlinePs opts={opts} ps={{
...removeFVarients(item.entry),
e: item.def,
}} />,
body: <div style={{ textAlign: "left" }}>
<ConjugationViewer
entry={item.entry}
textOptions={opts}
highlightInRootsAndStems={["imperfective stem"]}
showOnly={["Present", "Imperfective Future"]}
hidePastParticiple
sentenceLevel="easy"
/>
</div>,
};
}}/>
<BasicVerbShowCase opts={opts} tense="imperfectiveFuture" />
Notice that the <InlinePs opts={opts} ps={{ p: "به", f: "ba" }} /> goes in the <Link to="/phrase-structure/kids-section/">kid's section</Link>.
## Perfective Future
@ -71,21 +50,4 @@ This is used to talk about something happening in the future, while thinking of
<Link to="/verbs/subjunctive-verbs/">Subjunctive</Link>
</Formula>
<Carousel stickyTitle items={shuffleArray(basicVerbs)} render={(item) => {
return {
title: <InlinePs opts={opts} ps={{
...removeFVarients(item.entry),
e: item.def,
}} />,
body: <div style={{ textAlign: "left" }}>
<ConjugationViewer
entry={item.entry}
textOptions={opts}
highlightInRootsAndStems={["Perfective stem"]}
showOnly={["Subjunctive", "Perfective Future"]}
hidePastParticiple
sentenceLevel="easy"
/>
</div>,
};
}}/>
<BasicVerbShowCase opts={opts} tense="perfectiveFuture" />

View File

@ -7,7 +7,6 @@ import {
Examples,
InlinePs,
removeFVarients,
ConjugationViewer,
} from "@lingdocs/pashto-inflector";
import psmd from "../../lib/psmd";
import Carousel from "../../components/Carousel";
@ -17,6 +16,7 @@ import { verbs } from "../../words/words";
import shuffleArray from "../../lib/shuffle-array";
import imperfectiveImperative from "./imperfective-imperative.svg";
import perfectiveImperative from "./perfective-imperative.svg";
import BasicVerbShowCase from "../../components/BasicVerbShowCase";
The imperative form is used for **giving commands** (telling people to do things).
@ -39,6 +39,8 @@ The <i className="fas fa-video" /> **imperfective imperative** is used when you
<img src={imperfectiveImperative} alt="" className="img-fluid" />
</div>
<BasicVerbShowCase opts={opts} tense="imperfectiveImperative" />
## Perfective Imperative
<Formula name="Perfective Imperative">
@ -51,24 +53,7 @@ The <i className="fas fa-camera" /> **perfective imperative** is used when you w
<img src={perfectiveImperative} alt="" className="img-fluid" />
</div>
<Carousel stickyTitle items={shuffleArray(basicVerbs)} render={(item) => {
return {
title: <InlinePs opts={opts} ps={{
...removeFVarients(item.entry),
e: item.def,
}} />,
body: <div className="text-left">
<ConjugationViewer
entry={item.entry}
textOptions={opts}
highlightInRootsAndStems={["imperfective stem", "perfective stem"]}
showOnly={["Perfective Imperative", "Imperfective Imperative"]}
hidePastParticiple
sentenceLevel="easy"
/>
</div>,
};
}}/>
<BasicVerbShowCase opts={opts} tense="perfectiveImperative" />
## Using Imperatives

View File

@ -6,19 +6,13 @@ import {
defaultTextOptions as opts,
Examples,
InlinePs,
removeFVarients,
ConjugationViewer,
} from "@lingdocs/pashto-inflector";
import psmd from "../../lib/psmd";
import Carousel from "../../components/Carousel";
import Link from "../../components/Link";
import Formula from "../../components/formula/Formula";
import { verbs } from "../../words/words";
import shuffleArray from "../../lib/shuffle-array";
import realityGraph from "./reality-graph.svg";
import presentTime from "./present-time.svg";
export const basicVerbs = verbs.filter((v) => !v.entry.c?.includes("gramm. trans."));
import BasicVerbShowCase from "./../../components/BasicVerbShowCase";
The first verb form we'll learn is the **present**. This will be the first tool in our toolbox of verb forms. 🧰 With each verb form we'll learn two things:
@ -35,24 +29,7 @@ As with all verb forms, the **present form** is made by following a very simple
The <Link to="/verbs/verb-endings/">present ending</Link> will change according to what the subject is. Have a look through the verbs below and see how the present form follows the same formula for all of them. 👇
<Carousel stickyTitle items={shuffleArray(basicVerbs)} render={(item) => {
return {
title: <InlinePs opts={opts} ps={{
...removeFVarients(item.entry),
e: item.def,
}} />,
body: <div className="text-left">
<ConjugationViewer
entry={item.entry}
textOptions={opts}
highlightInRootsAndStems={["imperfective stem"]}
showOnly="Present"
hidePastParticiple
sentenceLevel="easy"
/>
</div>,
};
}}/>
<BasicVerbShowCase opts={opts} tense="presentVerb" />
**Notes:**

View File

@ -7,19 +7,14 @@ import {
Examples,
InlinePs,
removeFVarients,
ConjugationViewer,
} from "@lingdocs/pashto-inflector";
import cousins from "./cousins.png";
import psmd from "../../lib/psmd";
import Carousel from "../../components/Carousel";
import Link from "../../components/Link";
import Formula from "../../components/formula/Formula";
import { verbs } from "../../words/words";
import shuffleArray from "../../lib/shuffle-array";
import presentInReality from "./present-in-reality.svg";
import subjunctiveAboveReality from "./subjunctive-above-reality.svg";
export const basicVerbs = verbs.filter((v) => !v.entry.c?.includes("gramm. trans."));
import BasicVerbShowCase from "../../components/BasicVerbShowCase";
The **subjunctive** is a very important verb form in Pashto, but it's often ignored by English-speaking learners because we don't really have anything like it in English. So, we need to understand what it is, and then train our brains to reach for it and use it in the right situations!
@ -55,24 +50,7 @@ The subjunctive is made the same way as its cousin the <Link to="/verbs/present-
Perfective Stem + <Link to="/verbs/verb-endings/">Present Ending</Link>
</Formula>
<Carousel stickyTitle items={shuffleArray(basicVerbs)} render={(item) => {
return {
title: <InlinePs opts={opts} ps={{
...removeFVarients(item.entry),
e: item.def,
}} />,
body: <div className="text-left">
<ConjugationViewer
entry={item.entry}
textOptions={opts}
highlightInRootsAndStems={["perfective stem"]}
showOnly="Subjunctive"
hidePastParticiple
sentenceLevel="easy"
/>
</div>,
};
}}/>
<BasicVerbShowCase opts={opts} tense="subjunctiveVerb" />
## Examples

View File

@ -503,7 +503,7 @@ function makeEPS(subject: T.NPSelection, predicate: T.AdjectiveEntry | T.Locativ
}
function getEqFromRendered(e: T.EPRendered): T.EquativeRendered {
const eblock = e.blocks.find(x => x.type === "equative");
const eblock = e.blocks[0].find(x => x.type === "equative");
if (!eblock || eblock.type !== "equative") throw new Error("Error getting equative block");
return eblock.equative;
}

View File

@ -1695,10 +1695,10 @@
rambda "^6.7.0"
react-select "^5.2.2"
"@lingdocs/pashto-inflector@^2.9.7":
version "2.9.7"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.9.7.tgz#bd27694db0cd528c784847161392e115f2a00139"
integrity sha512-TNIlv9Ktv+aSZEu+BJtl0ZMBZSpD1wcBtMibhT/JEDqd7g7KzbrNW0kkbgnIZm3nvZB1UavrgVzQgATJdvdG/g==
"@lingdocs/pashto-inflector@^3.0.4":
version "3.0.4"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-3.0.4.tgz#6ea750f66509e9e88c8d6fa01298a4e9fb07a807"
integrity sha512-fUVTuQBeJ0YrtbBbj0JUlCEgrnKLadD0dL6Ig6eawDA0Fayrfp/yeuz1MsFRcYosdtNx5juY5JQyioh9AgC4YQ==
dependencies:
"@formkit/auto-animate" "^1.0.0-beta.1"
classnames "^2.2.6"