This commit is contained in:
lingdocs 2022-05-26 15:44:05 -05:00
parent e9fd455037
commit 7e3d644380
9 changed files with 170 additions and 60 deletions

View File

@ -3,9 +3,10 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@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.2", "@lingdocs/pashto-inflector": "^2.6.4",
"@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

@ -1,32 +0,0 @@
import {
Types as T,
NPPicker,
} from "@lingdocs/pashto-inflector";
import { useState } from "react";
import PhraseDiagram from "./phrase-diagram/PhraseDiagram";
import entryFeeder from "../lib/entry-feeder";
function NPPlayground({ opts, npIn }: {
opts: T.TextOptions,
npIn: T.NPSelection | undefined,
}) {
const [np, setNp] = useState<T.NPSelection | undefined>(npIn);
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;

View File

@ -1,9 +1,16 @@
import { import {
Types as T, Types as T,
NPPicker,
APPicker,
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
import {
useEffect,
useRef,
} from "react";
import { useState } from "react"; import { useState } from "react";
import PhraseDiagram from "./PhraseDiagram"; import PhraseDiagram from "./PhraseDiagram";
import NPPlayground from "../NPPlayground"; import entryFeeder from "../../lib/entry-feeder";
import autoAnimate from "@formkit/auto-animate";
export function EditIcon() { export function EditIcon() {
return <i className="fas fa-edit" />; return <i className="fas fa-edit" />;
@ -13,19 +20,64 @@ function EditablePhraseDiagram({ opts, children }: {
opts: T.TextOptions, opts: T.TextOptions,
children: BlockInput[], children: BlockInput[],
}) { }) {
const np = children[0].block; const block = children[0];
const parent = useRef<HTMLDivElement>(null);
useEffect(() => {
parent.current && autoAnimate(parent.current)
}, [parent]);
const [editing, setEditing] = useState<boolean>(false); const [editing, setEditing] = useState<boolean>(false);
const [edited, setEdited] = useState<{
type: "NP",
block: T.NPSelection | undefined,
} | {
type: "AP",
block: T.APSelection | undefined,
}>(block);
if (children.length === 0) return null; if (children.length === 0) return null;
function handleNPChange(np: T.NPSelection | undefined) {
setEdited({ type: "NP", block: np });
}
function handleAPChange(ap: T.APSelection | undefined) {
setEdited({ type: "AP", block: ap });
}
function handleReset() {
setEdited(block);
setEditing(false);
}
return <div> return <div>
<div className="text-right clickable" onClick={() => setEditing(e => !e)}> <div
className="text-right clickable"
onClick={editing ? handleReset : () => setEditing(true)}
>
{!editing ? <EditIcon /> : <i className="fas fa-undo" />} {!editing ? <EditIcon /> : <i className="fas fa-undo" />}
</div> </div>
<div> <div ref={parent} className="d-flex flex-column align-items-center">
{editing {editing && <div style={{ maxWidth: "225px", marginBottom: "2rem" }}>
? <NPPlayground opts={opts} npIn={np} /> {edited.type === "NP"
: <PhraseDiagram opts={opts}>{[ ? <NPPicker
{ type: "NP", block: np }, opts={opts}
]}</PhraseDiagram>} np={edited.block}
onChange={handleNPChange}
entryFeeder={entryFeeder}
role="subject"
counterPart={undefined}
phraseIsComplete={false}
/>
: <APPicker
opts={opts}
AP={edited.block}
onChange={handleAPChange}
entryFeeder={entryFeeder}
phraseIsComplete={false}
cantClear
onRemove={() => null}
/>
}
</div>}
{edited.block
&& <PhraseDiagram opts={opts}>
{[edited] as BlockInput[]}
</PhraseDiagram>}
</div> </div>
</div>; </div>;
} }

View File

@ -2,6 +2,7 @@ import {
renderNPSelection, renderNPSelection,
Types as T, Types as T,
getEnglishFromRendered, getEnglishFromRendered,
renderAPSelection,
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
import classNames from "classnames"; import classNames from "classnames";
@ -22,12 +23,50 @@ function Block({ opts, children }: {
opts: T.TextOptions, opts: T.TextOptions,
children: BlockInput, children: BlockInput,
}) { }) {
// const possesor = children.block.possesor; if (children.type === "NP") {
const rendered = renderNPSelection(children.block, false, false, "subject", "none"); const rendered = renderNPSelection(children.block, false, false, "subject", "none");
const english = getEnglishFromRendered(rendered) const english = getEnglishFromRendered(rendered)
return <div className="text-center mb-2"> return <div className="text-center mb-2">
<NP opts={opts} english={english}>{rendered}</NP> <NP opts={opts} english={english}>{rendered}</NP>
</div>; </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>
Will implement sandwich
</div>;
} }
function NP({ opts, children, inside, english }: { function NP({ opts, children, inside, english }: {

View File

@ -21,6 +21,8 @@ import * as equativeExplorer from "!babel-loader!@lingdocs/mdx-loader!./equative
// @ts-ignore // @ts-ignore
import * as NPIntro from "!babel-loader!@lingdocs/mdx-loader!./phrase-structure/np.mdx"; import * as NPIntro from "!babel-loader!@lingdocs/mdx-loader!./phrase-structure/np.mdx";
// @ts-ignore
import * as APIntro from "!babel-loader!@lingdocs/mdx-loader!./phrase-structure/ap.mdx";
// @ts-ignore // @ts-ignore
import * as nounsGender from "!babel-loader!@lingdocs/mdx-loader!./nouns/nouns-gender.mdx"; import * as nounsGender from "!babel-loader!@lingdocs/mdx-loader!./nouns/nouns-gender.mdx";
@ -105,6 +107,10 @@ const contentTree = [
import: NPIntro, import: NPIntro,
slug: "np", slug: "np",
}, },
{
import: APIntro,
slug: "ap",
},
], ],
}, },
{ {

View File

@ -2,4 +2,48 @@
title: APs title: APs
--- ---
AP page here import {
defaultTextOptions as opts,
InlinePs,
Examples,
} from "@lingdocs/pashto-inflector";
import psmd from "../../lib/psmd";
import Link from "../../components/Link";
import EditablePhraseDiagram, {
EditIcon,
} from "../../components/phrase-diagram/EditablePhraseDiagram";
Another building block we have in Pashto phrases in the **AP (Adverb Phrase)**. Adverb Phrases are used to give more information about the phrase in terms of time, manner, place, degree, etc.
An AP is either:
- an adverb, or
- a sandwich
### Adverb
An adverb is a word or expression that modifies the time, manner, place, etc. of a phrase.
<EditablePhraseDiagram opts={opts}>{[
{
type: "AP",
block: {
type: "adverb",
entry: {"ts":1527815160,"i":2394,"p":"پرون","f":"paroon","g":"paroon","e":"yesterday","c":"adv."},
},
},
]}</EditablePhraseDiagram>
<EditablePhraseDiagram opts={opts}>{[
{
type: "AP",
block: {
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."},
},
},
]}</EditablePhraseDiagram>
### Sandwich
Coming soon...

View File

@ -12,7 +12,7 @@ import Link from "../../components/Link";
import EditablePhraseDiagram, { import EditablePhraseDiagram, {
EditIcon, EditIcon,
} from "../../components/phrase-diagram/EditablePhraseDiagram"; } from "../../components/phrase-diagram/EditablePhraseDiagram";
import NPPlayground from "../../components/NPPlayground"; // import NPPlayground from "../../components/NPPlayground";
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 basic **building blocks** 🧱 like NPs, APs, verbs, and equatives. We can think of phrases in Pashto as a line of blocks like this:
@ -409,8 +409,8 @@ An **NP** is one of the following:
Notice how NPs can contain other NPs, and therefore go on foreeeever. So you could have like 50 words packed together and it would all be **one single NP**, **one building block** in a sentence. Notice how NPs can contain other NPs, and therefore go on foreeeever. So you could have like 50 words packed together and it would all be **one single NP**, **one building block** in a sentence.
## NP Playground <!-- ## NP Playground
Now try making your own NPs from scratch! 👩‍🍳 See if you can make really big ones like "hitting my good old friend's brother's father's big dog." Now try making your own NPs from scratch! 👩‍🍳 See if you can make really big ones like "hitting my good old friend's brother's father's big dog."
<NPPlayground opts={opts} /> <NPPlayground opts={opts} /> -->

View File

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

View File

@ -1695,13 +1695,12 @@
rambda "^6.7.0" rambda "^6.7.0"
react-select "^5.2.2" react-select "^5.2.2"
"@lingdocs/pashto-inflector@^2.6.2": "@lingdocs/pashto-inflector@^2.6.4":
version "2.6.2" version "2.6.5"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.6.2.tgz#41c6a18a67aa9dff8ade2fd49ad8b27d04ecb4f8" resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-2.6.5.tgz#9cd8efd14d48d0a9aa9ff8439b2bdc135a855f57"
integrity sha512-GSiJ7FFoDEDIfDcPv10SienHYQr/8lRmBP6fbwDV2vFVf9vJ4+nywuhFmU0JuBL2HILG/e6CQ3tvQZvoquopCg== integrity sha512-y1prO4ASg1P2v5960twoYD2NOfN4P6vc9cM2/QqMIHQX7TkXwzFnjKKu9MD3dCOH0FPOv1V6NAEgbBMJGJa1Pw==
dependencies: dependencies:
"@formkit/auto-animate" "^1.0.0-beta.1" "@formkit/auto-animate" "^1.0.0-beta.1"
assert-never "^1.2.1"
classnames "^2.2.6" classnames "^2.2.6"
jsurl2 "^2.1.0" jsurl2 "^2.1.0"
lz-string "^1.4.4" lz-string "^1.4.4"
@ -2930,11 +2929,6 @@ asn1@~0.2.3:
dependencies: dependencies:
safer-buffer "~2.1.0" safer-buffer "~2.1.0"
assert-never@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe"
integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==
assert-plus@1.0.0, assert-plus@^1.0.0: assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"