NP sweetness!
This commit is contained in:
parent
81bbb79654
commit
d5e12bd62d
|
@ -5,7 +5,7 @@
|
|||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@lingdocs/lingdocs-main": "^0.2.0",
|
||||
"@lingdocs/pashto-inflector": "^2.5.1",
|
||||
"@lingdocs/pashto-inflector": "^2.5.4",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import {
|
||||
Types as T,
|
||||
NPPicker,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import entryFeeder from "../lib/entry-feeder";
|
||||
import { useState } from "react";
|
||||
import PhraseDiagram from "./phrase-diagram/PhraseDiagram";
|
||||
|
||||
function NPPlayground({ opts }: {
|
||||
opts: T.TextOptions,
|
||||
}) {
|
||||
const [np, setNp] = useState<T.NPSelection | undefined>(undefined);
|
||||
return <div className="d-flex flex-column align-items-center">
|
||||
<div style={{ maxWidth: "225px", marginBottom: "2rem" }}>
|
||||
<NPPicker
|
||||
opts={opts}
|
||||
np={np}
|
||||
onChange={setNp}
|
||||
entryFeeder={entryFeeder}
|
||||
role="subject"
|
||||
counterPart={undefined}
|
||||
phraseIsComplete={false}
|
||||
/>
|
||||
</div>
|
||||
{np && <PhraseDiagram opts={opts}>{[
|
||||
{ type: "NP", block: np },
|
||||
]}</PhraseDiagram>}
|
||||
</div>
|
||||
}
|
||||
|
||||
export default NPPlayground;
|
|
@ -0,0 +1,91 @@
|
|||
import {
|
||||
renderNPSelection,
|
||||
Types as T,
|
||||
getEnglishFromRendered,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
|
||||
type BlockInput = { type: "NP", block: T.NPSelection };
|
||||
|
||||
function PhraseDiagram({ opts, children }: {
|
||||
opts: T.TextOptions,
|
||||
children: BlockInput[]
|
||||
}) {
|
||||
return <div className="d-flex flex-row justify-content-center flex-wrap">
|
||||
{children.map(block => (
|
||||
<Block opts={opts}>{block}</Block>
|
||||
))}
|
||||
</div>;
|
||||
}
|
||||
|
||||
function Block({ opts, children }: {
|
||||
opts: T.TextOptions,
|
||||
children: BlockInput,
|
||||
}) {
|
||||
// const possesor = children.block.possesor;
|
||||
const rendered = renderNPSelection(children.block, false, false, "subject", "none");
|
||||
const english = getEnglishFromRendered(rendered)
|
||||
return <div className="text-center mb-2">
|
||||
<NP opts={opts}>{rendered}</NP>
|
||||
{english && <div className="small text-muted">{english}</div>}
|
||||
</div>;
|
||||
}
|
||||
|
||||
function NP({ opts, children, inside }: {
|
||||
opts: T.TextOptions,
|
||||
children: T.Rendered<T.NPSelection>,
|
||||
inside?: boolean,
|
||||
}) {
|
||||
const np = children;
|
||||
return <div>
|
||||
<div className="d-flex justify-content-center align-items-center" style={{
|
||||
border: "2px solid black",
|
||||
padding: inside ? "0.3rem" : "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>NP</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
function Possesors({ opts, children }: {
|
||||
opts: T.TextOptions,
|
||||
children: { shrunken: boolean, np: T.Rendered<T.NPSelection> } | undefined,
|
||||
}) {
|
||||
if (!children) {
|
||||
return null;
|
||||
}
|
||||
const hasPossesor = !!(children.np.type !== "pronoun" && children.np.possesor);
|
||||
return <div className="d-flex flex-row mr-1 align-items-end" style={{
|
||||
marginBottom: "0.5rem",
|
||||
borderBottom: "1px solid grey",
|
||||
marginTop: hasPossesor ? "0.5rem" : "",
|
||||
}}>
|
||||
{children.np.type !== "pronoun" && <Possesors opts={opts}>{children.np.possesor}</Possesors>}
|
||||
<div>
|
||||
<div className="d-flex flex-row align-items-center">
|
||||
<div className="mr-1 pb-2">du</div>
|
||||
<div>
|
||||
<NP opts={opts} inside>{children.np}</NP>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
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;
|
|
@ -19,6 +19,9 @@ import * as otherEquatives from "!babel-loader!@lingdocs/mdx-loader!./equatives/
|
|||
// @ts-ignore
|
||||
import * as equativeExplorer from "!babel-loader!@lingdocs/mdx-loader!./equatives/equative-explorer.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as NPIntro from "!babel-loader!@lingdocs/mdx-loader!./phrase-structure/np.mdx";
|
||||
|
||||
// @ts-ignore
|
||||
import * as nounsGender from "!babel-loader!@lingdocs/mdx-loader!./nouns/nouns-gender.mdx";
|
||||
// @ts-ignore
|
||||
|
@ -94,6 +97,16 @@ const contentTree = [
|
|||
import: intro,
|
||||
slug: "intro",
|
||||
},
|
||||
{
|
||||
heading: "Phrase Structure",
|
||||
subdirectory: "phrase-structure",
|
||||
chapters: [
|
||||
{
|
||||
import: NPIntro,
|
||||
slug: "np",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
heading: "Equatives",
|
||||
subdirectory: "equatives",
|
||||
|
|
|
@ -0,0 +1,226 @@
|
|||
---
|
||||
title: NPs
|
||||
---
|
||||
|
||||
import {
|
||||
defaultTextOptions as opts,
|
||||
InlinePs,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import Link from "../../components/Link";
|
||||
import PhraseDiagram from "../../components/phrase-diagram/PhraseDiagram";
|
||||
import NPPlayground from "../../components/NPPlayground";
|
||||
|
||||
👷 * this page is correct, but incomplete - in progress* 🚧
|
||||
|
||||
## Basic building blocks
|
||||
|
||||
Pashto phrases are built with a few basic ingredients: NPs, APs, Particles, Verbs, Equatives.
|
||||
|
||||
<div className="d-flex flex-row justify-content-center">
|
||||
<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>AP</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 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>V</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.
|
||||
|
||||
### A Noun Phrase (NP)
|
||||
|
||||
A noun phrase (NP) in Pashto is one of the following:
|
||||
|
||||
- a noun
|
||||
- a pronoun
|
||||
- a participle
|
||||
|
||||
#### Nouns
|
||||
|
||||
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>{[
|
||||
{
|
||||
type: "NP",
|
||||
block: {
|
||||
type: "noun",
|
||||
entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
|
||||
gender: "masc",
|
||||
genderCanChange: false,
|
||||
number: "singular",
|
||||
numberCanChange: true,
|
||||
adjectives: [],
|
||||
possesor: undefined,
|
||||
},
|
||||
},
|
||||
]}</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.
|
||||
|
||||
<PhraseDiagram>{[
|
||||
{
|
||||
type: "NP",
|
||||
block: {
|
||||
type: "noun",
|
||||
entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
|
||||
gender: "masc",
|
||||
genderCanChange: false,
|
||||
number: "singular",
|
||||
numberCanChange: true,
|
||||
adjectives: [{
|
||||
type: "adjective",
|
||||
entry: {"ts":1527815451,"i":7245,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"},
|
||||
}],
|
||||
possesor: undefined,
|
||||
},
|
||||
},
|
||||
]}</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.
|
||||
|
||||
<PhraseDiagram>{[
|
||||
{
|
||||
type: "NP",
|
||||
block: {
|
||||
type: "noun",
|
||||
entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
|
||||
gender: "masc",
|
||||
genderCanChange: false,
|
||||
number: "singular",
|
||||
numberCanChange: true,
|
||||
adjectives: [
|
||||
{
|
||||
type: "adjective",
|
||||
entry: {"ts":1527812625,"i":9119,"p":"غټ","f":"ghuT, ghaT","g":"ghuT,ghaT","e":"big, fat","c":"adj."},
|
||||
},
|
||||
{
|
||||
type: "adjective",
|
||||
entry: {"ts":1527815451,"i":7245,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"},
|
||||
},
|
||||
{
|
||||
type: "adjective",
|
||||
entry: {"ts":1578329248464,"i":7542,"p":"سپین","f":"speen","g":"speen","e":"white (fig. clear, honest, beautiful)","c":"adj."},
|
||||
},
|
||||
],
|
||||
possesor: undefined,
|
||||
},
|
||||
},
|
||||
]}</PhraseDiagram>
|
||||
|
||||
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>{[
|
||||
{
|
||||
type: "NP",
|
||||
block: {
|
||||
type: "noun",
|
||||
entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
|
||||
gender: "masc",
|
||||
genderCanChange: false,
|
||||
number: "singular",
|
||||
numberCanChange: true,
|
||||
adjectives: [
|
||||
{
|
||||
type: "adjective",
|
||||
entry: {"ts":1527815451,"i":7245,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"},
|
||||
},
|
||||
],
|
||||
possesor: {
|
||||
shrunken: false,
|
||||
np: {
|
||||
type: "noun",
|
||||
entry: {"ts":1527812881,"i":11694,"p":"ماشوم","f":"maashoom","g":"maashoom","e":"child, kid","c":"n. m. anim. unisex","ec":"child","ep":"children"},
|
||||
gender: "masc",
|
||||
genderCanChange: true,
|
||||
number: "singular",
|
||||
numberCanChange: true,
|
||||
adjectives: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]}</PhraseDiagram>
|
||||
|
||||
If we add another noun like this, we can add a possesor to *it*. This is *recursion*! (Nerdy math word 🤓)
|
||||
|
||||
<PhraseDiagram>{[
|
||||
{
|
||||
type: "NP",
|
||||
block: {
|
||||
type: "noun",
|
||||
entry: {"ts":1527812817,"i":9999,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
|
||||
gender: "masc",
|
||||
genderCanChange: false,
|
||||
number: "singular",
|
||||
numberCanChange: true,
|
||||
adjectives: [
|
||||
{
|
||||
type: "adjective",
|
||||
entry: {"ts":1527815451,"i":7245,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"},
|
||||
},
|
||||
],
|
||||
possesor: {
|
||||
shrunken: false,
|
||||
np: {
|
||||
type: "noun",
|
||||
entry: {"ts":1527812881,"i":11694,"p":"ماشوم","f":"maashoom","g":"maashoom","e":"child, kid","c":"n. m. anim. unisex","ec":"child","ep":"children"},
|
||||
gender: "masc",
|
||||
genderCanChange: true,
|
||||
number: "singular",
|
||||
numberCanChange: true,
|
||||
adjectives: [],
|
||||
possesor: {
|
||||
shrunken: false,
|
||||
np: {
|
||||
type: "noun",
|
||||
entry: {"ts":1527815177,"i":2530,"p":"پلار","f":"plaar","g":"plaar","e":"father","c":"n. m."},
|
||||
gender: "masc",
|
||||
genderCanChange: false,
|
||||
number: "singular",
|
||||
numberCanChange: true,
|
||||
adjectives: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]}</PhraseDiagram>
|
||||
|
||||
#### Pronouns
|
||||
|
||||
coming soon
|
||||
|
||||
#### Participles
|
||||
|
||||
coming soon
|
||||
|
||||
Now try to make your own!
|
||||
|
||||
<NPPlayground opts={opts} />
|
|
@ -1,4 +1,5 @@
|
|||
module.exports = [
|
||||
{ ts: 1527815177, e: "father" }, // پلار
|
||||
{ ts: 1527812432, e: `sky, heaven` }, // آسمان - aasmaan
|
||||
{ ts: 1527812431, e: `mango` }, // آم - aam
|
||||
{ ts: 1527812434, e: `sound, voice` }, // آواز - aawaaz
|
||||
|
|
|
@ -1684,10 +1684,10 @@
|
|||
pbf "^3.2.1"
|
||||
rambda "^6.7.0"
|
||||
|
||||
"@lingdocs/pashto-inflector@^2.4.9":
|
||||
version "2.5.0"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.5.0.tgz#4f90a1d2db15e8389cd84f0a576c37b814f303fd"
|
||||
integrity sha512-RwlBQNwNsKxvICHjx6MwOwetzGQWLdrwjWOBLMfSqbRqQzNWQrjm/Gp4+TfIT89IUtutxVSxLXlgwgUq6ebKpA==
|
||||
"@lingdocs/pashto-inflector@^2.5.4":
|
||||
version "2.5.4"
|
||||
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.5.4.tgz#9cf0029b4aeb6e1c41aa65bac0b98028d3db2dba"
|
||||
integrity sha512-KSzTlN+lVZbkoQ61GdgnVvLknaCcwrAx48PHogmSuDnZbQeObqgBt1PHTV7KUw+aBDQaUjQmrm/oe+HKfEnDOw==
|
||||
dependencies:
|
||||
classnames "^2.2.6"
|
||||
jsurl2 "^2.1.0"
|
||||
|
|
Loading…
Reference in New Issue