a bit rough but support for participles in subject
This commit is contained in:
parent
9212c89c64
commit
cb1ea724d8
|
@ -11,9 +11,9 @@ import {
|
||||||
import {
|
import {
|
||||||
equativeMachine,
|
equativeMachine,
|
||||||
assembleEquativeOutput,
|
assembleEquativeOutput,
|
||||||
NounInput,
|
SubjectInput,
|
||||||
} from "../../lib/equative-machine";
|
} from "../../lib/equative-machine";
|
||||||
import { isPluralEntry, isSingularEntry } from "../../lib/type-predicates";
|
import { isNoun, isPluralEntry } from "../../lib/type-predicates";
|
||||||
|
|
||||||
function EquativeDisplay({ state }: { state: ExplorerState }) {
|
function EquativeDisplay({ state }: { state: ExplorerState }) {
|
||||||
if (state.subjectType === "pronouns") {
|
if (state.subjectType === "pronouns") {
|
||||||
|
@ -23,18 +23,14 @@ function EquativeDisplay({ state }: { state: ExplorerState }) {
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
const entry = state.subjectsSelected[state.subjectType];
|
const entry = state.subjectsSelected[state.subjectType];
|
||||||
const nounInput: NounInput = isSingularEntry(entry) ? {
|
// @ts-ignore - TODO: safer and for use with unisex nouns
|
||||||
|
const subjInput: SubjectInput = isNoun(entry) ? {
|
||||||
entry,
|
entry,
|
||||||
plural: state.subjectsSelected.info.plural,
|
plural: isPluralEntry(entry) ? true : state.subjectsSelected.info.plural,
|
||||||
} : isPluralEntry(entry) ? {
|
} : entry;
|
||||||
entry,
|
|
||||||
plural: true,
|
|
||||||
} : {
|
|
||||||
entry: entry as SingularEntry<Noun>,
|
|
||||||
plural: state.subjectsSelected.info.plural,
|
|
||||||
};
|
|
||||||
const eq = assembleEquativeOutput(
|
const eq = assembleEquativeOutput(
|
||||||
equativeMachine(nounInput, state.predicatesSelected[state.predicateType])
|
equativeMachine(subjInput, state.predicatesSelected[state.predicateType])
|
||||||
);
|
);
|
||||||
if ("short" in eq) return <div>length options not supported yet</div>;
|
if ("short" in eq) return <div>length options not supported yet</div>;
|
||||||
return <div>
|
return <div>
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
defaultUnisexNoun,
|
defaultUnisexNoun,
|
||||||
defaultAdjective,
|
defaultAdjective,
|
||||||
defaultNoun,
|
defaultNoun,
|
||||||
|
defaultParticiple,
|
||||||
} from "./explorer-inputs";
|
} from "./explorer-inputs";
|
||||||
import EquativeDisplay from "./EquativeDisplay";
|
import EquativeDisplay from "./EquativeDisplay";
|
||||||
|
|
||||||
|
@ -26,6 +27,7 @@ const defaultState: ExplorerState = {
|
||||||
},
|
},
|
||||||
subjectsSelected: {
|
subjectsSelected: {
|
||||||
noun: defaultNoun,
|
noun: defaultNoun,
|
||||||
|
participle: defaultParticiple,
|
||||||
info: {
|
info: {
|
||||||
plural: false,
|
plural: false,
|
||||||
gender: "masc",
|
gender: "masc",
|
||||||
|
|
|
@ -6,10 +6,13 @@ import {
|
||||||
import {
|
import {
|
||||||
equativeMachine,
|
equativeMachine,
|
||||||
assembleEquativeOutput,
|
assembleEquativeOutput,
|
||||||
|
ParticipleInput,
|
||||||
|
isParticipleInput,
|
||||||
|
getEnglishParticiple,
|
||||||
} from "../../lib/equative-machine";
|
} from "../../lib/equative-machine";
|
||||||
|
|
||||||
export function sort<T extends (Adjective | Noun)>(arr: T[]): T[] {
|
export function sort<T extends (Adjective | Noun | ParticipleInput)>(arr: Readonly<T[]>): T[] {
|
||||||
return arr.sort((a, b) => a.p.localeCompare(b.p));
|
return [...arr].sort((a, b) => a.p.localeCompare(b.p));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeBlockWPronouns(e: Adjective | UnisexNoun): T.VerbBlock {
|
export function makeBlockWPronouns(e: Adjective | UnisexNoun): T.VerbBlock {
|
||||||
|
@ -28,7 +31,7 @@ export function makeBlockWPronouns(e: Adjective | UnisexNoun): T.VerbBlock {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function makeOptionLabel(e: T.DictionaryEntry): string {
|
export function makeOptionLabel(e: T.DictionaryEntry): string {
|
||||||
const eng = getEnglishWord(e);
|
const eng = (isParticipleInput(e)) ? getEnglishParticiple(e) : getEnglishWord(e);
|
||||||
const english = typeof eng === "string"
|
const english = typeof eng === "string"
|
||||||
? eng
|
? eng
|
||||||
: !eng
|
: !eng
|
||||||
|
|
|
@ -1,20 +1,27 @@
|
||||||
import { nouns, adjectives } from "../../words/words";
|
import { nouns, adjectives, verbs } from "../../words/words";
|
||||||
import {
|
import {
|
||||||
isUnisexNoun,
|
isUnisexNoun,
|
||||||
} from "../../lib/type-predicates";
|
} from "../../lib/type-predicates";
|
||||||
import { sort } from "./explorer-helpers";
|
import { sort } from "./explorer-helpers";
|
||||||
|
import {
|
||||||
|
ParticipleInput,
|
||||||
|
} from "../../lib/equative-machine";
|
||||||
|
|
||||||
const unisexNouns = nouns.filter(x => isUnisexNoun(x)) as UnisexNoun[];
|
const unisexNouns = nouns.filter(x => isUnisexNoun(x)) as UnisexNoun[];
|
||||||
const nonUnisexNouns = nouns.filter(x => !isUnisexNoun(x)) as (MascNoun | FemNoun)[];
|
const nonUnisexNouns = nouns.filter(x => !isUnisexNoun(x)) as (MascNoun | FemNoun)[];
|
||||||
|
|
||||||
|
|
||||||
const inputs = {
|
const inputs = {
|
||||||
adjective: sort(adjectives),
|
adjective: sort(adjectives),
|
||||||
unisexNoun: sort(unisexNouns),
|
unisexNoun: sort(unisexNouns),
|
||||||
noun: sort(nonUnisexNouns),
|
noun: sort(nonUnisexNouns),
|
||||||
|
// @ts-ignore
|
||||||
|
participle: sort(verbs.map(e => e.entry) as ParticipleInput[]),
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultAdjective = inputs.adjective.find(ps => ps.p === "ستړی") || inputs.adjective[0];
|
export const defaultAdjective = inputs.adjective.find(ps => ps.p === "زوړ") || inputs.adjective[0];
|
||||||
export const defaultUnisexNoun = inputs.unisexNoun.find(ps => ps.p === "پښتون") || inputs.unisexNoun[0];
|
export const defaultUnisexNoun = inputs.unisexNoun.find(ps => ps.p === "پښتون") || inputs.unisexNoun[0];
|
||||||
export const defaultNoun = inputs.noun.find(ps => ps.p === "کتاب") || inputs.noun[0];
|
export const defaultNoun = inputs.noun.find(ps => ps.p === "کتاب") || inputs.noun[0];
|
||||||
|
export const defaultParticiple = inputs.participle.find(ps => ps.p === "لیکل") || inputs.participle[0];
|
||||||
|
|
||||||
export default inputs;
|
export default inputs;
|
|
@ -31,6 +31,7 @@ export function reducer(state: ExplorerState, action: ExplorerReducerAction): Ex
|
||||||
if (action.type === "setSubject") {
|
if (action.type === "setSubject") {
|
||||||
if (state.subjectType === "pronouns") return state;
|
if (state.subjectType === "pronouns") return state;
|
||||||
const pile = inputs[state.subjectType];
|
const pile = inputs[state.subjectType];
|
||||||
|
// @ts-ignore
|
||||||
const subject = (pile.find(p => p.ts === action.payload) || pile[0]);
|
const subject = (pile.find(p => p.ts === action.payload) || pile[0]);
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|
|
@ -12,6 +12,98 @@ import {
|
||||||
import { isPluralEntry } from "../../lib/type-predicates";
|
import { isPluralEntry } from "../../lib/type-predicates";
|
||||||
import Select from "react-select";
|
import Select from "react-select";
|
||||||
|
|
||||||
|
export function SubjectSelector({ state, dispatch }: {
|
||||||
|
state: ExplorerState,
|
||||||
|
dispatch: (action: ExplorerReducerAction) => void,
|
||||||
|
}) {
|
||||||
|
function onTypeSelect(e: React.ChangeEvent<HTMLInputElement>) {
|
||||||
|
const t = e.target.value as SubjectType;
|
||||||
|
dispatch({ type: "setSubjectType", payload: t });
|
||||||
|
}
|
||||||
|
function onSubjectSelect({ value }: any) {
|
||||||
|
dispatch({ type: "setSubject", payload: parseInt(value) });
|
||||||
|
}
|
||||||
|
const pluralNounSelected = (
|
||||||
|
state.subjectType === "noun" && isPluralEntry(state.subjectsSelected.noun)
|
||||||
|
);
|
||||||
|
const options = state.subjectType === "pronouns"
|
||||||
|
? []
|
||||||
|
: inputs[state.subjectType].map(e => ({
|
||||||
|
value: e.ts.toString(),
|
||||||
|
label: makeOptionLabel(e),
|
||||||
|
}));
|
||||||
|
const subject = state.subjectType === "pronouns"
|
||||||
|
? undefined
|
||||||
|
: state.subjectsSelected[state.subjectType];
|
||||||
|
return <div className="form-group mr-2 flex-fill">
|
||||||
|
<label htmlFor="predicate-select"><strong>Subject:</strong></label>
|
||||||
|
<div className="form-check">
|
||||||
|
<input
|
||||||
|
className="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="pronounsSubjectRadio"
|
||||||
|
id="pronounsSubjectRadio"
|
||||||
|
value="pronouns"
|
||||||
|
checked={state.subjectType === "pronouns"}
|
||||||
|
onChange={onTypeSelect}
|
||||||
|
/>
|
||||||
|
<label className="form-check-label" htmlFor="adjectivesPredicateRadio">
|
||||||
|
Pronouns
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="form-check">
|
||||||
|
<input
|
||||||
|
className="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="nounsSubjectRadio"
|
||||||
|
id="nounsSubjectRadio"
|
||||||
|
value="noun"
|
||||||
|
checked={state.subjectType === "noun"}
|
||||||
|
onChange={onTypeSelect}
|
||||||
|
/>
|
||||||
|
<label className="form-check-label" htmlFor="unisexNounsPredicateRadio">
|
||||||
|
Nouns
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="form-check mb-2">
|
||||||
|
<input
|
||||||
|
className="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="participlesSubjectRadio"
|
||||||
|
id="participlesSubjectRadio"
|
||||||
|
value="participle"
|
||||||
|
checked={state.subjectType === "participle"}
|
||||||
|
onChange={onTypeSelect}
|
||||||
|
/>
|
||||||
|
<label className="form-check-label" htmlFor="unisexNounsPredicateRadio">
|
||||||
|
Participles
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{state.subjectType !== "pronouns" &&
|
||||||
|
<>
|
||||||
|
<Select
|
||||||
|
value={subject?.ts.toString()}
|
||||||
|
onChange={onSubjectSelect}
|
||||||
|
className="mb-2"
|
||||||
|
// @ts-ignore
|
||||||
|
options={options}
|
||||||
|
isSearchable
|
||||||
|
placeholder={options.find(o => o.value === subject?.ts.toString())?.label}
|
||||||
|
/>
|
||||||
|
{state.subjectType === "noun" && <ButtonSelect
|
||||||
|
small
|
||||||
|
options={[
|
||||||
|
...!pluralNounSelected ? [{ label: "Singular", value: "singular" }] : [],
|
||||||
|
{ label: "Plural", value: "plural" },
|
||||||
|
]}
|
||||||
|
value={(state.subjectsSelected.info.plural || pluralNounSelected) ? "plural" : "singular"}
|
||||||
|
handleChange={(p) => dispatch({ type: "setSubjectPlural", payload: p === "plural" ? true : false })}
|
||||||
|
/>}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
export function PredicateSelector({ state, dispatch }: {
|
export function PredicateSelector({ state, dispatch }: {
|
||||||
state: ExplorerState,
|
state: ExplorerState,
|
||||||
dispatch: (action: ExplorerReducerAction) => void,
|
dispatch: (action: ExplorerReducerAction) => void,
|
||||||
|
@ -71,80 +163,3 @@ export function PredicateSelector({ state, dispatch }: {
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SubjectSelector({ state, dispatch }: {
|
|
||||||
state: ExplorerState,
|
|
||||||
dispatch: (action: ExplorerReducerAction) => void,
|
|
||||||
}) {
|
|
||||||
function onTypeSelect(e: React.ChangeEvent<HTMLInputElement>) {
|
|
||||||
const t = e.target.value as SubjectType;
|
|
||||||
dispatch({ type: "setSubjectType", payload: t });
|
|
||||||
}
|
|
||||||
function onSubjectSelect({ value }: any) {
|
|
||||||
dispatch({ type: "setSubject", payload: parseInt(value) });
|
|
||||||
}
|
|
||||||
const pluralNounSelected = (
|
|
||||||
state.subjectType === "noun" && isPluralEntry(state.subjectsSelected.noun)
|
|
||||||
);
|
|
||||||
const options = state.subjectType === "pronouns"
|
|
||||||
? []
|
|
||||||
: inputs[state.subjectType].map(e => ({
|
|
||||||
value: e.ts.toString(),
|
|
||||||
label: makeOptionLabel(e),
|
|
||||||
}));
|
|
||||||
const subject = state.subjectType === "pronouns"
|
|
||||||
? undefined
|
|
||||||
: state.subjectsSelected[state.subjectType]
|
|
||||||
return <div className="form-group mr-2 flex-fill">
|
|
||||||
<label htmlFor="predicate-select"><strong>Subject:</strong></label>
|
|
||||||
<div className="form-check">
|
|
||||||
<input
|
|
||||||
className="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="pronounsSubjectRadio"
|
|
||||||
id="pronounsSubjectRadio"
|
|
||||||
value="pronouns"
|
|
||||||
checked={state.subjectType === "pronouns"}
|
|
||||||
onChange={onTypeSelect}
|
|
||||||
/>
|
|
||||||
<label className="form-check-label" htmlFor="adjectivesPredicateRadio">
|
|
||||||
Pronouns
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div className="form-check mb-2">
|
|
||||||
<input
|
|
||||||
className="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="nounsSubjectRadio"
|
|
||||||
id="nounsSubjectRadio"
|
|
||||||
value="noun"
|
|
||||||
checked={state.subjectType === "noun"}
|
|
||||||
onChange={onTypeSelect}
|
|
||||||
/>
|
|
||||||
<label className="form-check-label" htmlFor="unisexNounsPredicateRadio">
|
|
||||||
Nouns
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
{state.subjectType !== "pronouns" &&
|
|
||||||
<>
|
|
||||||
<Select
|
|
||||||
value={subject?.ts.toString()}
|
|
||||||
onChange={onSubjectSelect}
|
|
||||||
className="mb-2"
|
|
||||||
// @ts-ignore
|
|
||||||
options={options}
|
|
||||||
isSearchable
|
|
||||||
placeholder={options.find(o => o.value === subject?.ts.toString())?.label}
|
|
||||||
/>
|
|
||||||
<ButtonSelect
|
|
||||||
small
|
|
||||||
options={[
|
|
||||||
...!pluralNounSelected ? [{ label: "Singular", value: "singular" }] : [],
|
|
||||||
{ label: "Plural", value: "plural" },
|
|
||||||
]}
|
|
||||||
value={(state.subjectsSelected.info.plural || pluralNounSelected) ? "plural" : "singular"}
|
|
||||||
handleChange={(p) => dispatch({ type: "setSubjectPlural", payload: p === "plural" ? true : false })}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
</div>;
|
|
||||||
}
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { Types as T } from "@lingdocs/pashto-inflector";
|
import { Types as T } from "@lingdocs/pashto-inflector";
|
||||||
|
import { ParticipleInput } from "../../lib/equative-machine";
|
||||||
|
|
||||||
export type PredicateType = keyof PredicatesSelected;
|
export type PredicateType = keyof PredicatesSelected;
|
||||||
export type SubjectType = "noun" | "pronouns";
|
export type SubjectType = "noun" | "pronouns" | "participle";
|
||||||
|
|
||||||
export type ExplorerState = {
|
export type ExplorerState = {
|
||||||
subjectType: SubjectType,
|
subjectType: SubjectType,
|
||||||
|
@ -15,6 +16,7 @@ type PredicatesSelected = {
|
||||||
};
|
};
|
||||||
type SubjectSelected = {
|
type SubjectSelected = {
|
||||||
noun: Noun,
|
noun: Noun,
|
||||||
|
participle: ParticipleInput,
|
||||||
info: {
|
info: {
|
||||||
plural: boolean,
|
plural: boolean,
|
||||||
gender: T.Gender,
|
gender: T.Gender,
|
||||||
|
|
|
@ -282,7 +282,7 @@ function psStringFromEntry(entry: T.DictionaryEntry, e: string): T.PsString {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEnglishParticiple(entry: T.DictionaryEntry): string {
|
export function getEnglishParticiple(entry: T.DictionaryEntry): string {
|
||||||
if (!entry.ec) throw new Error("no english information for participle");
|
if (!entry.ec) throw new Error("no english information for participle");
|
||||||
const ec = parseEc(entry.ec);
|
const ec = parseEc(entry.ec);
|
||||||
const participle = ec[2];
|
const participle = ec[2];
|
||||||
|
@ -291,11 +291,11 @@ function getEnglishParticiple(entry: T.DictionaryEntry): string {
|
||||||
: participle;
|
: participle;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPersonInput(e: EntityInput): e is PersonInput {
|
export function isPersonInput(e: EntityInput | T.DictionaryEntry): e is PersonInput {
|
||||||
return typeof e === "number";
|
return typeof e === "number";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isNounInput(e: EntityInput): e is NounInput {
|
export function isNounInput(e: EntityInput | T.DictionaryEntry): e is NounInput {
|
||||||
if (isPersonInput(e)) return false;
|
if (isPersonInput(e)) return false;
|
||||||
if ("entry" in e && !("gender" in e)) {
|
if ("entry" in e && !("gender" in e)) {
|
||||||
// e
|
// e
|
||||||
|
@ -304,7 +304,7 @@ export function isNounInput(e: EntityInput): e is NounInput {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isParticipleInput(e: EntityInput): e is ParticipleInput {
|
export function isParticipleInput(e: EntityInput | T.DictionaryEntry): e is ParticipleInput {
|
||||||
if (isPersonInput(e)) return false;
|
if (isPersonInput(e)) return false;
|
||||||
if ("entry" in e) return false;
|
if ("entry" in e) return false;
|
||||||
return !!e.c?.startsWith("v.");
|
return !!e.c?.startsWith("v.");
|
||||||
|
|
Loading…
Reference in New Issue