fix equatives

This commit is contained in:
lingdocs 2022-02-20 10:50:09 +04:00
parent 6cb2d5dbc5
commit 6c8831484b
9 changed files with 235 additions and 19 deletions

View File

@ -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;

View File

@ -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;

View File

@ -160,7 +160,7 @@ This is used for:
{ p: "...", f: "..." },
" ",
],
grammarUnits.equativeEndings.subjunctive,
grammarUnits.equativeEndings.habitual,
),
english: [
["I will be ...", "We will be ..."],
@ -177,7 +177,7 @@ This is used for:
" ",
{ p: "...", f: "..." },
" ",
], grammarUnits.equativeEndings.subjunctive)
], grammarUnits.equativeEndings.habitual)
},
}}
opts={opts}

View File

@ -80,6 +80,8 @@ import * as games from "!babel-loader!@lingdocs/mdx-loader!./games.mdx";
// @ts-ignore
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 = [
{
@ -256,6 +258,10 @@ const contentTree = [
import: pronounPicker,
slug: "pronoun-picker",
},
{
import: phraseBuilder,
slug: "phrase-builder",
},
],
},
];

View File

@ -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 />

View File

@ -8,19 +8,14 @@ import {
InlinePs,
} from "@lingdocs/pashto-inflector";
import { useState } from "react";
export function randomP(p) {
let newP = 0;
do {
newP = Math.floor(Math.random() * 12);
} while (newP === p);
return newP;
}
import {
randomPerson,
} from "../../lib/np-tools";
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() {
const person = randomP(pronoun.person);
const person = randomPerson(pronoun.person);
setPronoun({
...pronoun,
person,

View File

@ -11,6 +11,14 @@ import {
psStringFromEntry,
} 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 {
if (np.type === "participle") {
return T.Person.ThirdPlurMale;

View File

@ -6,10 +6,13 @@
type NPSelection = NounSelection | PronounSelection | ParticipleSelection;
type NPType = "noun" | "pronoun" | "participle";
// TODO require/import Person and PsString
type NounSelection = {
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
e: {
sing: string,
@ -22,23 +25,22 @@ type NounSelection = {
// TODO: Implement
// possesor: NPSelection | undefined,
/* 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 */
changeNumber?: (number: "sing" | "plur") => NounWord,
changeNumber?: (number: "sing" | "plur") => NounSelection,
};
// take an argument for subject/object in rendering English
type PronounSelection = {
type: "pronoun",
e: string,
person: Person,
person: import("@lingdocs/pashto-inflector").Types.Person,
distance: "near" | "far",
changeDistance: (distance: "near" | "far") => PronounSelection,
};
type ParticipleSelection = {
type: "participle",
ps: string,
ps: import("@lingdocs/pashto-inflector").Types.PsString,
e: string | undefined,
// 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<
Omit<T, "changeGender" | "changeNumber" | "changeDistance">,
"e",
string,
string
> & { inflected: boolean };
// TODO: recursive changing this down into the possesor etc.