fix equatives
This commit is contained in:
parent
6cb2d5dbc5
commit
6c8831484b
|
@ -0,0 +1,51 @@
|
||||||
|
import PronounPicker from "./NPPronounPicker";
|
||||||
|
// import { ButtonSelect } from "@lingdocs/pashto-inflector";
|
||||||
|
import { randomPerson } from "../../lib/np-tools";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
const npTypes: NPType[] = ["noun", "pronoun", "participle"];
|
||||||
|
|
||||||
|
function NPPicker({ np, onChange }: { onChange: (nps: NPSelection | undefined) => void, np: NPSelection | undefined }) {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
const [npType, setNpType] = useState<NPType | undefined>(np ? np.type : undefined);
|
||||||
|
function handleClear() {
|
||||||
|
setNpType(undefined);
|
||||||
|
onChange(undefined);
|
||||||
|
}
|
||||||
|
function handleNPTypeChange(ntp: NPType) {
|
||||||
|
if (ntp === "pronoun") {
|
||||||
|
const pronoun: PronounSelection = {
|
||||||
|
type: "pronoun",
|
||||||
|
e: "not done",
|
||||||
|
person: randomPerson(),
|
||||||
|
distance: "far",
|
||||||
|
};
|
||||||
|
onChange(pronoun);
|
||||||
|
} else {
|
||||||
|
setNpType(ntp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return <div>
|
||||||
|
{!np ?
|
||||||
|
<div>
|
||||||
|
{npTypes.map((npt) => (
|
||||||
|
<button
|
||||||
|
key={npt}
|
||||||
|
type="button"
|
||||||
|
className="mr-2 btn btn-sm btn-outline-secondary"
|
||||||
|
onClick={() => handleNPTypeChange(npt)}
|
||||||
|
>
|
||||||
|
{npt}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
: <div onClick={handleClear}>X</div>}
|
||||||
|
{np &&
|
||||||
|
(np.type === "pronoun"
|
||||||
|
? <PronounPicker pronoun={np} onChange={onChange} />
|
||||||
|
: <div>Not Implemented</div>)
|
||||||
|
}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NPPicker;
|
|
@ -0,0 +1,136 @@
|
||||||
|
import {
|
||||||
|
Types as T,
|
||||||
|
ButtonSelect,
|
||||||
|
} from "@lingdocs/pashto-inflector";
|
||||||
|
import useStickyState from "../../useStickyState";
|
||||||
|
|
||||||
|
const gColors = {
|
||||||
|
masc: "LightSkyBlue",
|
||||||
|
fem: "pink",
|
||||||
|
};
|
||||||
|
|
||||||
|
const labels = {
|
||||||
|
persons: [
|
||||||
|
["1st", "1st pl."],
|
||||||
|
["2nd", "2nd pl."],
|
||||||
|
["3rd", "3rd pl."],
|
||||||
|
],
|
||||||
|
e: [
|
||||||
|
["I", "We"],
|
||||||
|
["You", "You pl."],
|
||||||
|
[{ masc: "He/It", fem: "She/It"}, "They"],
|
||||||
|
],
|
||||||
|
p: {
|
||||||
|
far: [
|
||||||
|
["زه", "مونږ"],
|
||||||
|
["ته", "تاسو"],
|
||||||
|
["هغه", "هغوي"],
|
||||||
|
],
|
||||||
|
near: [
|
||||||
|
["زه", "مونږ"],
|
||||||
|
["ته", "تاسو"],
|
||||||
|
[{ masc: "دی", fem: "دا" }, "دوي"],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
type PickerState = { row: number, col: number, gender: T.Gender };
|
||||||
|
|
||||||
|
function personToPickerState(person: T.Person): PickerState {
|
||||||
|
const col = person > 5 ? 1 : 0;
|
||||||
|
const row = Math.floor((person > 5 ? (person - 6) : person) / 2);
|
||||||
|
const gender: T.Gender = (person % 2) ? "fem" : "masc";
|
||||||
|
return { col, row, gender };
|
||||||
|
}
|
||||||
|
|
||||||
|
function pickerStateToPerson(s: PickerState): T.Person {
|
||||||
|
return (s.row * 2)
|
||||||
|
+ (s.gender === "masc" ? 0 : 1)
|
||||||
|
+ (6 * s.col);
|
||||||
|
}
|
||||||
|
|
||||||
|
function PronounPicker({ onChange, pronoun }: { pronoun: PronounSelection, onChange: (p: PronounSelection) => void }) {
|
||||||
|
const [display, setDisplay] = useStickyState<"persons" | "p" | "e">("persons", "prounoun-picker-display");
|
||||||
|
|
||||||
|
const p = personToPickerState(pronoun.person);
|
||||||
|
function handleClick(row: number, col: number) {
|
||||||
|
onChange({
|
||||||
|
...pronoun,
|
||||||
|
person: pickerStateToPerson({
|
||||||
|
...p,
|
||||||
|
row,
|
||||||
|
col,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function handleGenderChange(gender: T.Gender) {
|
||||||
|
onChange({
|
||||||
|
...pronoun,
|
||||||
|
person: pickerStateToPerson({
|
||||||
|
...p,
|
||||||
|
gender,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function handlePronounTypeChange(distance: "far" | "near") {
|
||||||
|
onChange({
|
||||||
|
...pronoun,
|
||||||
|
distance,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function handleDisplayChange() {
|
||||||
|
const newPerson = display === "persons"
|
||||||
|
? "p"
|
||||||
|
: display === "p"
|
||||||
|
? "e"
|
||||||
|
: "persons";
|
||||||
|
setDisplay(newPerson);
|
||||||
|
}
|
||||||
|
const prs = labels[display];
|
||||||
|
const pSpec = "near" in prs ? prs[pronoun.distance] : prs;
|
||||||
|
return <div>
|
||||||
|
<div className="d-flex flex-row justify-content-around mb-3">
|
||||||
|
<ButtonSelect
|
||||||
|
xSmall
|
||||||
|
options={[
|
||||||
|
{ label: "Far", value: "far" },
|
||||||
|
{ label: "Near", value: "near" },
|
||||||
|
]}
|
||||||
|
value={pronoun.distance}
|
||||||
|
handleChange={(g) => handlePronounTypeChange(g as "far" | "near")}
|
||||||
|
/>
|
||||||
|
<button className="btn btn-sm btn-outline" onClick={handleDisplayChange}>{display === "persons" ? "#" : display === "p" ? "PS" : "EN"}</button>
|
||||||
|
</div>
|
||||||
|
<table className="table table-bordered" style={{ textAlign: "center", minWidth: "200px", tableLayout: "fixed" }}>
|
||||||
|
<tbody>
|
||||||
|
{pSpec.map((rw, i) => (
|
||||||
|
<tr>
|
||||||
|
{rw.map((r, j) => {
|
||||||
|
const active = (p.row === i && p.col === j)
|
||||||
|
return <td
|
||||||
|
onClick={() => handleClick(i, j)}
|
||||||
|
className={active ? "table-active" : ""}
|
||||||
|
style={active ? { backgroundColor: gColors[p.gender] } : {}}
|
||||||
|
>
|
||||||
|
{typeof r === "string" ? r : r[p.gender]}
|
||||||
|
</td>;
|
||||||
|
})}
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div className="text-center">
|
||||||
|
<ButtonSelect
|
||||||
|
options={[
|
||||||
|
{ label: "Masc.", value: "masc", color: gColors.masc },
|
||||||
|
{ label: "Fem.", value: "fem", color: gColors.fem },
|
||||||
|
]}
|
||||||
|
value={p.gender}
|
||||||
|
handleChange={(g) => handleGenderChange(g as T.Gender)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PronounPicker;
|
|
@ -160,7 +160,7 @@ This is used for:
|
||||||
{ p: "...", f: "..." },
|
{ p: "...", f: "..." },
|
||||||
" ",
|
" ",
|
||||||
],
|
],
|
||||||
grammarUnits.equativeEndings.subjunctive,
|
grammarUnits.equativeEndings.habitual,
|
||||||
),
|
),
|
||||||
english: [
|
english: [
|
||||||
["I will be ...", "We will be ..."],
|
["I will be ...", "We will be ..."],
|
||||||
|
@ -177,7 +177,7 @@ This is used for:
|
||||||
" ",
|
" ",
|
||||||
{ p: "...", f: "..." },
|
{ p: "...", f: "..." },
|
||||||
" ",
|
" ",
|
||||||
], grammarUnits.equativeEndings.subjunctive)
|
], grammarUnits.equativeEndings.habitual)
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
opts={opts}
|
opts={opts}
|
||||||
|
|
|
@ -80,6 +80,8 @@ import * as games from "!babel-loader!@lingdocs/mdx-loader!./games.mdx";
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import * as pronounPicker from "!babel-loader!@lingdocs/mdx-loader!./practice-tools/pronoun-picker.mdx";
|
import * as pronounPicker from "!babel-loader!@lingdocs/mdx-loader!./practice-tools/pronoun-picker.mdx";
|
||||||
|
// @ts-ignore
|
||||||
|
import * as phraseBuilder from "!babel-loader!@lingdocs/mdx-loader!./practice-tools/phrase-builder.mdx";
|
||||||
|
|
||||||
const contentTree = [
|
const contentTree = [
|
||||||
{
|
{
|
||||||
|
@ -256,6 +258,10 @@ const contentTree = [
|
||||||
import: pronounPicker,
|
import: pronounPicker,
|
||||||
slug: "pronoun-picker",
|
slug: "pronoun-picker",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
import: phraseBuilder,
|
||||||
|
slug: "phrase-builder",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
title: Phrase Builder
|
||||||
|
---
|
||||||
|
|
||||||
|
import NPPicker from "../../components/np-picker/NPPicker";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export function Display() {
|
||||||
|
const [np, setNp] = useState(undefined);
|
||||||
|
return <div>
|
||||||
|
<NPPicker np={np} onChange={setNp} />
|
||||||
|
<pre>
|
||||||
|
{JSON.stringify(np, null, " ")}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<Display />
|
|
@ -8,19 +8,14 @@ import {
|
||||||
InlinePs,
|
InlinePs,
|
||||||
} from "@lingdocs/pashto-inflector";
|
} from "@lingdocs/pashto-inflector";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import {
|
||||||
export function randomP(p) {
|
randomPerson,
|
||||||
let newP = 0;
|
} from "../../lib/np-tools";
|
||||||
do {
|
|
||||||
newP = Math.floor(Math.random() * 12);
|
|
||||||
} while (newP === p);
|
|
||||||
return newP;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function RPicker() {
|
export function RPicker() {
|
||||||
const [pronoun, setPronoun] = useState({ type: "pronoun", pronounType: "far", person: randomP() });
|
const [pronoun, setPronoun] = useState({ type: "pronoun", pronounType: "far", person: randomPerson() });
|
||||||
function handleRandom() {
|
function handleRandom() {
|
||||||
const person = randomP(pronoun.person);
|
const person = randomPerson(pronoun.person);
|
||||||
setPronoun({
|
setPronoun({
|
||||||
...pronoun,
|
...pronoun,
|
||||||
person,
|
person,
|
||||||
|
|
|
@ -11,6 +11,14 @@ import {
|
||||||
psStringFromEntry,
|
psStringFromEntry,
|
||||||
} from "./text-tools";
|
} from "./text-tools";
|
||||||
|
|
||||||
|
export function randomPerson(p?: T.Person) {
|
||||||
|
let newP = 0;
|
||||||
|
do {
|
||||||
|
newP = Math.floor(Math.random() * 12);
|
||||||
|
} while (newP === p);
|
||||||
|
return newP;
|
||||||
|
}
|
||||||
|
|
||||||
export function personFromNP(np: NounPhrase): T.Person {
|
export function personFromNP(np: NounPhrase): T.Person {
|
||||||
if (np.type === "participle") {
|
if (np.type === "participle") {
|
||||||
return T.Person.ThirdPlurMale;
|
return T.Person.ThirdPlurMale;
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
|
|
||||||
type NPSelection = NounSelection | PronounSelection | ParticipleSelection;
|
type NPSelection = NounSelection | PronounSelection | ParticipleSelection;
|
||||||
|
|
||||||
|
type NPType = "noun" | "pronoun" | "participle";
|
||||||
|
|
||||||
// TODO require/import Person and PsString
|
// TODO require/import Person and PsString
|
||||||
type NounSelection = {
|
type NounSelection = {
|
||||||
type: "noun",
|
type: "noun",
|
||||||
ps: string,
|
ps: import("@lingdocs/pashto-inflector").Types.PsString,
|
||||||
|
entry: import("@lingdocs/pashto-inflector").Types.DictionaryEntry,
|
||||||
// BETTER TO USE (or keep handy) FULL ENTRY FOR USE WITH INFLECTING
|
// BETTER TO USE (or keep handy) FULL ENTRY FOR USE WITH INFLECTING
|
||||||
e: {
|
e: {
|
||||||
sing: string,
|
sing: string,
|
||||||
|
@ -22,23 +25,22 @@ type NounSelection = {
|
||||||
// TODO: Implement
|
// TODO: Implement
|
||||||
// possesor: NPSelection | undefined,
|
// possesor: NPSelection | undefined,
|
||||||
/* method only present if it's possible to change gender */
|
/* method only present if it's possible to change gender */
|
||||||
changeGender?: (gender: "masc" | "fem") => NounWord,
|
changeGender?: (gender: "masc" | "fem") => NounSelection,
|
||||||
/* method only present if it's possible to change number */
|
/* method only present if it's possible to change number */
|
||||||
changeNumber?: (number: "sing" | "plur") => NounWord,
|
changeNumber?: (number: "sing" | "plur") => NounSelection,
|
||||||
};
|
};
|
||||||
|
|
||||||
// take an argument for subject/object in rendering English
|
// take an argument for subject/object in rendering English
|
||||||
type PronounSelection = {
|
type PronounSelection = {
|
||||||
type: "pronoun",
|
type: "pronoun",
|
||||||
e: string,
|
e: string,
|
||||||
person: Person,
|
person: import("@lingdocs/pashto-inflector").Types.Person,
|
||||||
distance: "near" | "far",
|
distance: "near" | "far",
|
||||||
changeDistance: (distance: "near" | "far") => PronounSelection,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type ParticipleSelection = {
|
type ParticipleSelection = {
|
||||||
type: "participle",
|
type: "participle",
|
||||||
ps: string,
|
ps: import("@lingdocs/pashto-inflector").Types.PsString,
|
||||||
e: string | undefined,
|
e: string | undefined,
|
||||||
// entry in here
|
// entry in here
|
||||||
}
|
}
|
||||||
|
@ -52,7 +54,7 @@ type ReplaceKey<T, K extends string, R> = T extends Record<K, unknown> ? (Omit<T
|
||||||
type Rendered<T extends NPSelection> = ReplaceKey<
|
type Rendered<T extends NPSelection> = ReplaceKey<
|
||||||
Omit<T, "changeGender" | "changeNumber" | "changeDistance">,
|
Omit<T, "changeGender" | "changeNumber" | "changeDistance">,
|
||||||
"e",
|
"e",
|
||||||
string,
|
string
|
||||||
> & { inflected: boolean };
|
> & { inflected: boolean };
|
||||||
// TODO: recursive changing this down into the possesor etc.
|
// TODO: recursive changing this down into the possesor etc.
|
||||||
|
|
Loading…
Reference in New Issue