fix inflection pattern

This commit is contained in:
adueck 2023-08-18 21:28:14 +04:00
parent 16757d1e49
commit 1da82dc4da
1 changed files with 221 additions and 173 deletions

View File

@ -11,191 +11,239 @@ import HumanReadableInflectionPattern from "../components/src/HumanReadableInfle
import leftChevron from "./chevron_left-24px.svg"; import leftChevron from "./chevron_left-24px.svg";
import rightChevron from "./chevron_right-24px.svg"; import rightChevron from "./chevron_right-24px.svg";
const chevStyle = { const chevStyle = {
height: "2rem", height: "2rem",
width: "2rem", width: "2rem",
color: "#ccc", color: "#ccc",
}; };
const nounsAdjs = nounsAdjsUnsafe const nounsAdjs = nounsAdjsUnsafe.filter(
.filter(x => tp.isNounEntry(x) || tp.isAdjectiveEntry(x)) as (T.NounEntry | T.AdjectiveEntry)[]; (x) => tp.isNounEntry(x) || tp.isAdjectiveEntry(x)
) as (T.NounEntry | T.AdjectiveEntry)[];
function InflectionDemo({ opts }: { function InflectionDemo({ opts }: { opts: T.TextOptions }) {
opts: T.TextOptions, const [pattern, setPattern] = useState<T.InflectionPattern | "all">("all");
}) { const [word, setWord] = useState<T.NounEntry | T.AdjectiveEntry | undefined>(
const [pattern, setPattern] = useState<T.InflectionPattern | "all">("all"); undefined
const [word, setWord] = useState<T.NounEntry | T.AdjectiveEntry | undefined>(undefined) );
const patterns: { const patterns: {
value: T.InflectionPattern | "all", value: T.InflectionPattern | "all";
label: JSX.Element | string, label: JSX.Element | string;
}[] = [ }[] = [
{ {
value: "all", value: "all",
label: "all types", label: "all types",
}, },
{ {
value: 0, value: 0,
label: "no inflection", label: "no inflection",
}, { },
value: 1, {
label: "basic", value: 1,
}, { label: "basic",
value: 2, },
label: <>unstressed <InlinePs opts={opts}>{{ p: "ی", f: "ey" }}</InlinePs></>, {
}, { value: 2,
value: 3, label: (
label: <>stressed <InlinePs opts={opts}>{{ p: "ی", f: "éy" }}</InlinePs></>, <>
}, { unstressed <InlinePs opts={opts}>{{ p: "ی", f: "ay" }}</InlinePs>
value: 4, </>
label: '"Pashtoon" pattern', ),
}, { },
value: 5, {
label: "short squish", value: 3,
}, { label: (
value: 6, <>
label: <>fem. inan. <InlinePs opts={opts}>{{ p: "ي", f: "ee" }}</InlinePs></>, stressed <InlinePs opts={opts}>{{ p: "ی", f: "áy" }}</InlinePs>
}, </>
]; ),
const entries = (nounsAdjs as (T.NounEntry | T.AdjectiveEntry)[]).filter(tp.isPattern(pattern)) },
function handlePatternChange(e: React.ChangeEvent<HTMLInputElement>) { {
const v = e.target.value; value: 4,
const value = v === "all" ? v : (Number(v) as T.InflectionPattern); label: '"Pashtoon" pattern',
setPattern(value); },
console.log({ word }); {
if (word && !tp.isPattern(value)(word)) { value: 5,
setWord(undefined); label: "short squish",
} },
{
value: 6,
label: (
<>
fem. inan. <InlinePs opts={opts}>{{ p: "ي", f: "ee" }}</InlinePs>
</>
),
},
];
const entries = (nounsAdjs as (T.NounEntry | T.AdjectiveEntry)[]).filter(
tp.isPattern(pattern)
);
function handlePatternChange(e: React.ChangeEvent<HTMLInputElement>) {
const v = e.target.value;
const value = v === "all" ? v : (Number(v) as T.InflectionPattern);
setPattern(value);
console.log({ word });
if (word && !tp.isPattern(value)(word)) {
setWord(undefined);
} }
function wordForward() { }
if (!word) { function wordForward() {
setWord(entries[0]); if (!word) {
return; setWord(entries[0]);
} return;
const oldIndex = entries.findIndex(e => e.ts === word.ts);
const newIndex = entries.length === (oldIndex + 1)
? 0 : (oldIndex + 1);
setWord(entries[newIndex]);
} }
function wordBack() { const oldIndex = entries.findIndex((e) => e.ts === word.ts);
if (!word) { const newIndex = entries.length === oldIndex + 1 ? 0 : oldIndex + 1;
setWord(entries[entries.length - 1]); setWord(entries[newIndex]);
return; }
} function wordBack() {
const oldIndex = entries.findIndex(e => e.ts === word.ts); if (!word) {
const newIndex = oldIndex === 0 setWord(entries[entries.length - 1]);
? (entries.length - 1) : (oldIndex + 1); return;
setWord(entries[newIndex]);
} }
const inf = ((): T.InflectorOutput | false => { const oldIndex = entries.findIndex((e) => e.ts === word.ts);
if (!word) return false; const newIndex = oldIndex === 0 ? entries.length - 1 : oldIndex + 1;
try { setWord(entries[newIndex]);
return inflectWord(word); }
} catch (e) { const inf = ((): T.InflectorOutput | false => {
console.error("error inflecting entry", word); if (!word) return false;
return false; try {
} return inflectWord(word);
})(); } catch (e) {
return <div style={{ paddingBottom: "20px" }}> console.error("error inflecting entry", word);
<p> return false;
Produces the inflections and plural forms (Pashto and Arabic plurals where applicable) for words }
</p> })();
<div className="d-block mx-auto card" style={{ maxWidth: "700px", background: "var(--closer)"}}> return (
<div className="card-body"> <div style={{ paddingBottom: "20px" }}>
<div className="row"> <p>
<div className="col-sm-6"> Produces the inflections and plural forms (Pashto and Arabic plurals
<div> where applicable) for words
<h6 className="my-2">Filter words by <a href="https://grammar.lingdocs.com/inflection/inflection-patterns/">inflection pattern</a>:</h6> </p>
<div> <div
{patterns.map(({ value, label}) => ( className="d-block mx-auto card"
<div key={value} className="form-check"> style={{ maxWidth: "700px", background: "var(--closer)" }}
<input >
className="form-check-input" <div className="card-body">
type="radio" <div className="row">
name="verb-type" <div className="col-sm-6">
checked={pattern === value} <div>
value={value} <h6 className="my-2">
onChange={handlePatternChange} Filter words by{" "}
/> <a href="https://grammar.lingdocs.com/inflection/inflection-patterns/">
<label className="form-check-label"> inflection pattern
{label} </a>
</label> :
</div> </h6>
))} <div>
</div> {patterns.map(({ value, label }) => (
</div> <div key={value} className="form-check">
</div> <input
<div className="col-sm-6"> className="form-check-input"
<h6 className="my-2">Select word:</h6> type="radio"
<EntrySelect name="verb-type"
entryFeeder={entries} checked={pattern === value}
value={word} value={value}
onChange={setWord} onChange={handlePatternChange}
opts={opts} />
name="word-select" <label className="form-check-label">{label}</label>
// @ts-ignore
style={{ width: "18rem" }}
/>
<div
className="d-flex flex-row justify-content-between align-items-center"
style={{ width: "18rem" }}
>
<img
src={leftChevron}
className="clickable"
style={chevStyle}
alt={"previous"}
onClick={wordBack}
/>
<img
src={rightChevron}
className="clickable"
style={chevStyle}
onClick={wordForward}
alt={"next"}
/>
</div>
</div> </div>
))}
</div> </div>
</div>
</div> </div>
<div className="col-sm-6">
<h6 className="my-2">Select word:</h6>
<EntrySelect
entryFeeder={entries}
value={word}
onChange={setWord}
opts={opts}
name="word-select"
// @ts-ignore
style={{ width: "18rem" }}
/>
<div
className="d-flex flex-row justify-content-between align-items-center"
style={{ width: "18rem" }}
>
<img
src={leftChevron}
className="clickable"
style={chevStyle}
alt={"previous"}
onClick={wordBack}
/>
<img
src={rightChevron}
className="clickable"
style={chevStyle}
onClick={wordForward}
alt={"next"}
/>
</div>
</div>
</div>
</div> </div>
{inf ? <div className="mt-3"> </div>
{inf.inflections && word && (() => { {inf ? (
const pattern = getInflectionPattern(word); <div className="mt-3">
return <div> {inf.inflections &&
<a href={`https://grammar.lingdocs.com/inflection/inflection-patterns/${inflectionSubUrl(pattern)}`} rel="noreferrer" target="_blank"> word &&
<div className="badge bg-light mb-2">Inflection pattern {HumanReadableInflectionPattern(pattern, opts)} (() => {
</div> const pattern = getInflectionPattern(word);
</a> return (
<InflectionsTable inf={inf.inflections} textOptions={opts} /> <div>
</div>; <a
})()} href={`https://grammar.lingdocs.com/inflection/inflection-patterns/${inflectionSubUrl(
{"plural" in inf && inf.plural !== undefined && <div> pattern
<h5>Plural</h5> )}`}
<InflectionsTable inf={inf.plural} textOptions={opts} /> rel="noreferrer"
</div>} target="_blank"
{"arabicPlural" in inf && inf.arabicPlural !== undefined && <div> >
<h5>Arabic Plural</h5> <div className="badge bg-light mb-2">
<InflectionsTable inf={inf.arabicPlural} textOptions={opts} /> Inflection pattern{" "}
</div>} {HumanReadableInflectionPattern(pattern, opts)}
</div> : <div> </div>
</div>} </a>
</div>; <InflectionsTable inf={inf.inflections} textOptions={opts} />
</div>
);
})()}
{"plural" in inf && inf.plural !== undefined && (
<div>
<h5>Plural</h5>
<InflectionsTable inf={inf.plural} textOptions={opts} />
</div>
)}
{"arabicPlural" in inf && inf.arabicPlural !== undefined && (
<div>
<h5>Arabic Plural</h5>
<InflectionsTable inf={inf.arabicPlural} textOptions={opts} />
</div>
)}
</div>
) : (
<div></div>
)}
</div>
);
} }
function inflectionSubUrl(pattern: T.InflectionPattern): string { function inflectionSubUrl(pattern: T.InflectionPattern): string {
return pattern === 0 return pattern === 0
? "" ? ""
: pattern === 1 : pattern === 1
? "#1-basic" ? "#1-basic"
: pattern === 2 : pattern === 2
? "#2-words-ending-in-an-unstressed-ی---ey" ? "#2-words-ending-in-an-unstressed-ی---ey"
: pattern === 3 : pattern === 3
? "#3-words-ending-in-a-stressed-ی---éy" ? "#3-words-ending-in-a-stressed-ی---éy"
: pattern === 4 : pattern === 4
? "#4-words-with-the-pashtoon-pattern" ? "#4-words-with-the-pashtoon-pattern"
: pattern === 5 : pattern === 5
? "#5-shorter-words-that-squish" ? "#5-shorter-words-that-squish"
// : pattern === 6 : // : pattern === 6
: "#6-inanimate-feminine-nouns-ending-in-ي---ee" "#6-inanimate-feminine-nouns-ending-in-ي---ee";
} }
export default InflectionDemo; export default InflectionDemo;