This commit is contained in:
lingdocs 2022-05-14 21:19:17 -05:00
parent d5e12bd62d
commit ab12c18a1f
6 changed files with 130 additions and 32 deletions

View File

@ -6,10 +6,11 @@ import entryFeeder from "../lib/entry-feeder";
import { useState } from "react"; import { useState } from "react";
import PhraseDiagram from "./phrase-diagram/PhraseDiagram"; import PhraseDiagram from "./phrase-diagram/PhraseDiagram";
function NPPlayground({ opts }: { function NPPlayground({ opts, npIn }: {
opts: T.TextOptions, opts: T.TextOptions,
npIn: T.NPSelection | undefined,
}) { }) {
const [np, setNp] = useState<T.NPSelection | undefined>(undefined); const [np, setNp] = useState<T.NPSelection | undefined>(npIn);
return <div className="d-flex flex-column align-items-center"> return <div className="d-flex flex-column align-items-center">
<div style={{ maxWidth: "225px", marginBottom: "2rem" }}> <div style={{ maxWidth: "225px", marginBottom: "2rem" }}>
<NPPicker <NPPicker

View File

@ -0,0 +1,33 @@
import {
Types as T,
} from "@lingdocs/pashto-inflector";
import { useState } from "react";
import PhraseDiagram from "./PhraseDiagram";
import NPPlayground from "../NPPlayground";
export function EditIcon() {
return <i className="fas fa-edit" />;
}
function EditablePhraseDiagram({ opts, children }: {
opts: T.TextOptions,
children: BlockInput[],
}) {
const np = children[0].block;
const [editing, setEditing] = useState<boolean>(false);
if (children.length === 0) return null;
return <div>
<div className="text-right clickable" onClick={() => setEditing(e => !e)}>
{!editing ? <EditIcon /> : <i className="fas fa-undo" />}
</div>
<div>
{editing
? <NPPlayground opts={opts} npIn={np} />
: <PhraseDiagram opts={opts}>{[
{ type: "NP", block: np },
]}</PhraseDiagram>}
</div>
</div>;
}
export default EditablePhraseDiagram;

View File

@ -3,16 +3,15 @@ import {
Types as T, Types as T,
getEnglishFromRendered, getEnglishFromRendered,
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
import classNames from "classnames";
type BlockInput = { type: "NP", block: T.NPSelection };
function PhraseDiagram({ opts, children }: { function PhraseDiagram({ opts, children }: {
opts: T.TextOptions, opts: T.TextOptions,
children: BlockInput[] children: BlockInput[]
}) { }) {
return <div className="d-flex flex-row justify-content-center flex-wrap"> return <div className="d-flex flex-row justify-content-center flex-wrap">
{children.map(block => ( {children.map((block) => (
<Block opts={opts}>{block}</Block> <Block key={Math.random()} opts={opts}>{block}</Block>
))} ))}
</div>; </div>;
} }
@ -58,6 +57,7 @@ function Possesors({ opts, children }: {
return null; return null;
} }
const hasPossesor = !!(children.np.type !== "pronoun" && children.np.possesor); const hasPossesor = !!(children.np.type !== "pronoun" && children.np.possesor);
const contraction = checkForContraction(children.np);
return <div className="d-flex flex-row mr-1 align-items-end" style={{ return <div className="d-flex flex-row mr-1 align-items-end" style={{
marginBottom: "0.5rem", marginBottom: "0.5rem",
borderBottom: "1px solid grey", borderBottom: "1px solid grey",
@ -65,7 +65,8 @@ function Possesors({ opts, children }: {
}}> }}>
{children.np.type !== "pronoun" && <Possesors opts={opts}>{children.np.possesor}</Possesors>} {children.np.type !== "pronoun" && <Possesors opts={opts}>{children.np.possesor}</Possesors>}
<div> <div>
<div className="d-flex flex-row align-items-center"> {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 className="mr-1 pb-2">du</div>
<div> <div>
<NP opts={opts} inside>{children.np}</NP> <NP opts={opts} inside>{children.np}</NP>
@ -76,6 +77,23 @@ function Possesors({ opts, children }: {
</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 }: { function Adjectives({ opts, children }: {
opts: T.TextOptions, opts: T.TextOptions,
children: T.Rendered<T.AdjectiveSelection>[] | undefined, children: T.Rendered<T.AdjectiveSelection>[] | undefined,

View File

@ -98,7 +98,7 @@ const contentTree = [
slug: "intro", slug: "intro",
}, },
{ {
heading: "Phrase Structure", heading: "Phrase Structure 🧱",
subdirectory: "phrase-structure", subdirectory: "phrase-structure",
chapters: [ chapters: [
{ {

View File

@ -8,15 +8,16 @@ import {
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
import Link from "../../components/Link"; import Link from "../../components/Link";
import PhraseDiagram from "../../components/phrase-diagram/PhraseDiagram"; import PhraseDiagram from "../../components/phrase-diagram/PhraseDiagram";
import EditablePhraseDiagram, {
EditIcon,
} from "../../components/phrase-diagram/EditablePhraseDiagram";
import NPPlayground from "../../components/NPPlayground"; import NPPlayground from "../../components/NPPlayground";
👷 * this page is correct, but incomplete - in progress* 🚧 👷 * this page is correct, but incomplete - in progress* 🚧
## Basic building blocks Pashto phrases are built with a basic **building blocks** 🧱 like NPs, APs, verbs, and equatives. We can think of phrases in Pashto as a line of blocks like this:
Pashto phrases are built with a few basic ingredients: NPs, APs, Particles, Verbs, Equatives. <div className="d-flex flex-row justify-content-center mb-4 mt-4">
<div className="d-flex flex-row justify-content-center">
<div className="text-center mr-2"> <div className="text-center mr-2">
<div className="d-flex justify-content-center align-items-center" style={{ <div className="d-flex justify-content-center align-items-center" style={{
border: "2px solid black", border: "2px solid black",
@ -47,25 +48,54 @@ Pashto phrases are built with a few basic ingredients: NPs, APs, Particles, Verb
height: "3rem", height: "3rem",
width: "7rem", width: "7rem",
}}/> }}/>
<div>V</div> <div>Verb</div>
</div> </div>
</div> </div>
In Pashto, it's important to know how these building blocks line up. But first, what is actually inside each of these blocks? Let's take a look at the NP. Or like this...
### A Noun Phrase (NP) <div className="d-flex flex-row justify-content-center mb-4">
<div className="text-center mr-2">
<div className="d-flex justify-content-center align-items-center" style={{
border: "2px solid black",
height: "3rem",
width: "7rem",
}}/>
<div>NP</div>
</div>
<div className="text-center mr-2">
<div className="d-flex justify-content-center align-items-center" style={{
border: "2px solid black",
height: "3rem",
width: "7rem",
}}/>
<div>NP</div>
</div>
<div className="text-center">
<div className="d-flex justify-content-center align-items-center" style={{
border: "2px solid black",
height: "3rem",
width: "7rem",
}}/>
<div>Equative</div>
</div>
</div>
A noun phrase (NP) in Pashto is one of the following: In Pashto, it's important to know how these building blocks line up. But first, let's look at what these blocks actually are blocks. In this chapter we'll look at the NP.
## Noun Phrase (NP)
A noun phrase (NP) in Pashto is one of the following three things:
- a noun - a noun
- a pronoun - a pronoun
- a participle - a participle
#### Nouns ### Noun
A **noun** is a word that we use to identify people, places, things, or ideas. One of these words by itself it forms a NP, one of the basic building blocks. A **noun** is a word that we use to identify people, places, things, or ideas. One of these words by itself it forms a NP, one of the basic building blocks.
<PhraseDiagram>{[ <PhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { block: {
@ -81,9 +111,9 @@ A **noun** is a word that we use to identify people, places, things, or ideas. O
}, },
]}</PhraseDiagram> ]}</PhraseDiagram>
But we can also **extend our noun by adding *adjectives***. Let's add the *adjective* <InlinePs opts={opts} ps={{ p: "زوړ", f: "zoR", e: "old" }} /> to our NP. We can also **extend our noun by adding *adjectives***. Let's add the *adjective* <InlinePs opts={opts} ps={{ p: "زوړ", f: "zoR", e: "old" }} /> to our NP.
<PhraseDiagram>{[ <PhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { block: {
@ -102,9 +132,9 @@ But we can also **extend our noun by adding *adjectives***. Let's add the *adjec
}, },
]}</PhraseDiagram> ]}</PhraseDiagram>
Now we have two words, but it's still **one NP**, one building block. We can add as many adjectives as we want, and it still stays as one single building block. Now we have two words, but it's still **one NP**, one building block. We can add as many adjectives as we want, and it still stays as one single building block. Click on the <EditIcon /> icon below to try adding or removing more adjectives.
<PhraseDiagram>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { block: {
@ -131,11 +161,11 @@ Now we have two words, but it's still **one NP**, one building block. We can add
possesor: undefined, possesor: undefined,
}, },
}, },
]}</PhraseDiagram> ]}</EditablePhraseDiagram>
We can also add a **possesor** by adding another NP <Link to="/sandwiches/sandwiches/">sandwiched</Link> in with a <InlinePs opts={opts} ps={{ p: "د", f: "du", e: "of"}} />. Now we have a NP inside of an NP, but it's still all **one NP** or **one building block**. We can also add a **possesor** by adding another NP <Link to="/sandwiches/sandwiches/">sandwiched</Link> in with a <InlinePs opts={opts} ps={{ p: "د", f: "du", e: "of"}} />. Now we have a NP inside of an NP, but it's still all **one NP** or **one building block**.
<PhraseDiagram>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { block: {
@ -165,11 +195,11 @@ We can also add a **possesor** by adding another NP <Link to="/sandwiches/sandwi
}, },
}, },
}, },
]}</PhraseDiagram> ]}</EditablePhraseDiagram>
If we add another noun like this, we can add a possesor to *it*. This is *recursion*! (Nerdy math word 🤓) If our possesor is a noun, we can add a possesor to *it*. Try clicking the <EditIcon /> icon below and adding possesors to the possesors, you can go forever! 🤯
<PhraseDiagram>{[ <EditablePhraseDiagram opts={opts}>{[
{ {
type: "NP", type: "NP",
block: { block: {
@ -211,16 +241,30 @@ If we add another noun like this, we can add a possesor to *it*. This is *recurs
}, },
}, },
}, },
]}</PhraseDiagram> ]}</EditablePhraseDiagram>
#### Pronouns A possesor can have another possesor which can have another posseser and so-on and on *forever*. The nerdy word for this phenomenon where things reference/repeat themselves is called [recursion](https://en.wikipedia.org/wiki/Recursion). 🤓
<details>
<summary>Click here for another example of what <strong>recursion</strong> looks like</summary>
<div style={{ width: "100%", height:0, paddingBottom: "51%", position: "relative" }}>
<iframe src="https://giphy.com/embed/5xtDarxMlfVnrjN4MyQ" width="100%" height="100%" style={{ position: "absolute" }} frameBorder="0" class="giphy-embed"></iframe>
</div>
<p className="mt-1">The starbucks cup has a picture of a starbucks cup, which has a picture of a starbucks cup which has a...</p>
</details>
**So in summary:** 👨🏻‍🏫
A noun is one of three starting points for making an NP. When you start with a noun you can add adjectives and a possesor to it. (The possesor is another NP, which you can keep building on in the same way.)
### Pronoun
coming soon coming soon
#### Participles ### Participle
coming soon coming soon
Now try to make your own! Now try to make your own from scratch!
<NPPlayground opts={opts} /> <NPPlayground opts={opts} />

View File

@ -3,3 +3,5 @@ type Pronoun = {
pronounType: "near" | "far", pronounType: "near" | "far",
person: import("@lingdocs/pashto-inflector").Types.Person, person: import("@lingdocs/pashto-inflector").Types.Person,
}; };
type BlockInput = { type: "NP", block: T.NPSelection };