started working on new verb rendering function

This commit is contained in:
adueck 2023-03-17 16:29:36 +05:00
parent 1ebe2256da
commit 68189ea4ba
3 changed files with 153 additions and 5 deletions

View File

@ -21,6 +21,7 @@ import { entryFeeder } from "./demo-components/entryFeeder";
import { Hider } from "./components/library"; import { Hider } from "./components/library";
import InflectionDemo from "./demo-components/InflectionDemo"; import InflectionDemo from "./demo-components/InflectionDemo";
import SpellingDemo from "./demo-components/SpellingDemo"; import SpellingDemo from "./demo-components/SpellingDemo";
import { renderVerb } from "./lib/src/render-verb";
function App() { function App() {
const [showingTextOptions, setShowingTextOptions] = useStickyState<boolean>(false, "showTextOpts1"); const [showingTextOptions, setShowingTextOptions] = useStickyState<boolean>(false, "showTextOpts1");
@ -35,8 +36,17 @@ function App() {
useEffect(() => { useEffect(() => {
document.documentElement.setAttribute("data-theme", theme); document.documentElement.setAttribute("data-theme", theme);
}, [theme]); }, [theme]);
const rv = renderVerb({
verb: { entry: {"ts":1527815399,"i":15035,"p":"وهل","f":"wahul","g":"wahul","e":"to hit","r":4,"c":"v. trans.","tppp":"واهه","tppf":"waahu","ec":"hit,hits,hitting,hit,hit"} as T.VerbDictionaryEntry},
aspect: "imperfective",
tense: "habitualPast",
person: 9,
});
return <> return <>
<main className="flex-shrink-0 mb-4"> <main className="flex-shrink-0 mb-4">
<pre>
{JSON.stringify(rv, null, " ")}
</pre>
<div className="container" style={{ maxWidth: "800px" }}> <div className="container" style={{ maxWidth: "800px" }}>
<div style={{ position: "absolute", top: "1.5rem", right: "1.5rem", display: "flex", flexDirection: "row" }}> <div style={{ position: "absolute", top: "1.5rem", right: "1.5rem", display: "flex", flexDirection: "row" }}>
<div <div

View File

@ -25,11 +25,7 @@ export function entryOfFull(e: T.FullEntry): T.DictionaryEntry {
} }
// just for type safety // just for type safety
export function noPersInfs(s: T.OptionalPersonInflections<T.LengthOptions<T.PsString>>): T.LengthOptions<T.PsString>; export function noPersInfs<S extends object>(s: T.OptionalPersonInflections<S>): S {
export function noPersInfs(s: T.FullForm<T.PsString>): T.SingleOrLengthOpts<T.PsString>;
export function noPersInfs(s:
T.OptionalPersonInflections<T.LengthOptions<T.PsString>> | T.FullForm<T.PsString>
): T.SingleOrLengthOpts<T.PsString> | T.LengthOptions<T.PsString> {
if ("mascSing" in s) { if ("mascSing" in s) {
// this path shouldn't be used, just for type safety // this path shouldn't be used, just for type safety
return s.mascSing; return s.mascSing;

142
src/lib/src/render-verb.ts Normal file
View File

@ -0,0 +1,142 @@
import {
getVerbBlockPosFromPerson,
noPersInfs,
} from "./misc-helpers";
import * as T from "../../types";
import { concatPsString, getVerbInfo } from "../library";
import {
presentEndings,
pastEndings,
} from "./grammar-units";
// export type RenderedVerbB = VerbRenderedBlock
// | PerfectiveHeadBlock
// | ModalVerbBlock
// | ModalVerbKedulPart
// | PerfectEquativeBlock
// | PerfectParticipleBlock;
// export type PerfectiveHeadBlock = { type: "perfectiveHead", ps: PsString };
// export type VerbRenderedBlock = {
// type: "verb",
// block: Omit<VerbSelectionComplete, "object"> & {
// hasBa: boolean,
// ps: SingleOrLengthOpts<PsString[]>,
// person: Person,
// complementWelded: undefined | Rendered<ComplementSelection> | Rendered<UnselectedComplementSelection>,
// },
// };
type PerfectiveHeadBlock = {
type: "perfectiveHead",
ps: T.PsString,
};
type VerbBlock = {
type: "verb",
hasBa: boolean,
ps: T.SingleOrLengthOpts<T.PsString[]>,
person: T.Person,
aspect: T.Aspect,
tense: keyof T.AspectContent,
};
export function renderVerb({ verb, aspect, tense, person }: {
verb: T.VerbEntry,
aspect: T.Aspect,
tense: keyof T.AspectContent,
person: T.Person,
}): {
hasBa: boolean,
verbBlocks: [PerfectiveHeadBlock, VerbBlock] | [VerbBlock]
} {
// WARNING: this only works with simple verbs
const isPast = tense === "past" || tense === "habitualPast";
const hasBa = tense === "future" || tense === "habitualPast";
const { perfectiveHead, rootStem } = getRootStem(verb, aspect, isPast);
const ending = getEnding(person, isPast);
const verbPs = addEnding(rootStem, ending);
const verbBlock: VerbBlock = {
type: "verb",
hasBa,
ps: verbPs,
person,
aspect,
tense,
};
const perfectiveHeadBlock: PerfectiveHeadBlock | undefined = perfectiveHead ? {
type: "perfectiveHead",
ps: noPersInfs(perfectiveHead),
} : undefined;
return {
hasBa,
verbBlocks: perfectiveHeadBlock ? [
perfectiveHeadBlock, verbBlock,
] : [verbBlock],
}
}
function addEnding(rootStem: T.FullForm<T.PsString>, ending: T.SingleOrLengthOpts<T.PsString[]>): T.SingleOrLengthOpts<T.PsString[]> {
const rs = noPersInfs(rootStem);
const end = noPersInfs(ending);
if ("long" in rs) {
if ("long" in end) {
return {
long: end.long.map((e) => concatPsString(rs.long, e)),
short: end.short.map((e) => concatPsString(rs.short, e)),
};
} else {
return {
long: end.map((e) => concatPsString(rs.long, e)),
short: end.map((e) => concatPsString(rs.short, e)),
};
}
}
if ("long" in end) {
throw new Error("should not be using verb stems with long and short endings");
}
return end.map((e) => concatPsString(rs, e));
}
function getRootStem(verb: T.VerbEntry, aspect: T.Aspect, isPast: boolean): {
perfectiveHead: undefined | T.OptionalPersonInflections<T.PsString>,
rootStem: T.OptionalPersonInflections<T.SingleOrLengthOpts<T.PsString>>,
} {
const vInfo = getVerbInfo(verb.entry) as T.SimpleVerbInfo;
const rs = vInfo[isPast ? "root" : "stem"];
if (aspect === "perfective" && rs.perfectiveSplit) {
return extractPerfectiveSplit(rs.perfectiveSplit);
}
return {
perfectiveHead: undefined,
rootStem: rs[aspect],
}
function extractPerfectiveSplit(splitInfo: T.SplitInfo): ReturnType<typeof getRootStem> {
// TODO: allow for infs
const si = noPersInfs(splitInfo);
if ("long" in si) {
return {
perfectiveHead: si.long[0],
rootStem: {
long: si.long[1],
short: si.short[1],
}
}
} else {
return {
perfectiveHead: si[0],
rootStem: si[1],
}
}
}
}
function getEnding(person: T.Person, isPast: boolean) {
const [row, col] = getVerbBlockPosFromPerson(person);
return isPast ? {
long: pastEndings.long[row][col],
short: pastEndings.short[row][col],
} : presentEndings[row][col];
}