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: "..." },
|
||||
" ",
|
||||
],
|
||||
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}
|
||||
|
|
|
@ -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",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
|
@ -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,
|
||||
} 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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
Loading…
Reference in New Issue