display editable VPs
This commit is contained in:
parent
f6414985a4
commit
174e34f069
|
@ -138,7 +138,7 @@ function App() {
|
|||
showing={showing === "parser"}
|
||||
handleChange={() => handleHiderClick("parser")}
|
||||
>
|
||||
<ParserDemo opts={textOptions} />
|
||||
<ParserDemo opts={textOptions} entryFeeder={entryFeeder} />
|
||||
</Hider>
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
import * as T from "../../../types";
|
||||
import { useEffect, useState } from "react";
|
||||
import VPDisplay from "./VPDisplay";
|
||||
import VPPicker from "./VPPicker";
|
||||
import { vpsReducer } from "../../../lib/src/phrase-building/vps-reducer";
|
||||
|
||||
export function EditIcon() {
|
||||
return <i className="fas fa-edit" />;
|
||||
}
|
||||
|
||||
// TODO: Ability to show all variations
|
||||
|
||||
function EditableVP({
|
||||
children,
|
||||
opts,
|
||||
formChoice,
|
||||
noEdit,
|
||||
length,
|
||||
mode,
|
||||
sub,
|
||||
allVariations,
|
||||
entryFeeder,
|
||||
}: {
|
||||
children: T.VPSelectionState;
|
||||
opts: T.TextOptions;
|
||||
formChoice?: boolean;
|
||||
noEdit?: boolean;
|
||||
length?: "long" | "short";
|
||||
mode?: "text" | "blocks";
|
||||
sub?: string | JSX.Element;
|
||||
allVariations?: boolean;
|
||||
entryFeeder: T.EntryFeeder;
|
||||
}) {
|
||||
const [editing, setEditing] = useState<boolean>(false);
|
||||
const [selectedLength, setSelectedLength] = useState<"long" | "short">(
|
||||
length || "short"
|
||||
);
|
||||
const [vps, setVps] = useState<T.VPSelectionState>({ ...children });
|
||||
useEffect(() => {
|
||||
setVps({ ...children });
|
||||
}, [children]);
|
||||
function handleReset() {
|
||||
// TODO: this is crazy, how does children get changed after calling setVps ???
|
||||
setVps(children);
|
||||
setEditing(false);
|
||||
}
|
||||
function handleSetForm(form: T.FormVersion) {
|
||||
setVps(vpsReducer(vps, { type: "set form", payload: form }));
|
||||
}
|
||||
return (
|
||||
<div className="mt-2 mb-4">
|
||||
{!noEdit && (
|
||||
<div
|
||||
className="text-left clickable mb-2"
|
||||
style={{ marginBottom: editing ? "0.5rem" : "-0.5rem" }}
|
||||
onClick={
|
||||
editing
|
||||
? handleReset
|
||||
: () => {
|
||||
setEditing(true);
|
||||
}
|
||||
}
|
||||
>
|
||||
{!editing ? <EditIcon /> : <i className="fas fa-undo" />}
|
||||
</div>
|
||||
)}
|
||||
{editing && (
|
||||
<VPPicker
|
||||
opts={opts}
|
||||
entryFeeder={entryFeeder}
|
||||
vps={vps}
|
||||
onChange={setVps}
|
||||
/>
|
||||
)}
|
||||
<VPDisplay
|
||||
opts={opts}
|
||||
VPS={vps}
|
||||
justify="left"
|
||||
onlyOne={allVariations ? false : "concat"}
|
||||
setForm={handleSetForm}
|
||||
onLengthChange={setSelectedLength}
|
||||
length={allVariations ? undefined : selectedLength}
|
||||
mode={mode}
|
||||
inlineFormChoice
|
||||
/>
|
||||
{sub && <div className="text-muted small">{sub}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default EditableVP;
|
|
@ -2,12 +2,9 @@ import { useState } from "react";
|
|||
import * as T from "../types";
|
||||
import { parsePhrase } from "../lib/src/parsing/parse-phrase";
|
||||
import { tokenizer } from "../lib/src/parsing/tokenizer";
|
||||
import {
|
||||
CompiledPTextDisplay,
|
||||
NPDisplay,
|
||||
compileVP,
|
||||
renderVP,
|
||||
} from "../components/library";
|
||||
import { NPDisplay } from "../components/library";
|
||||
import EditableVP from "../components/src/vp-explorer/EditableVP";
|
||||
import { uncompleteVPSelection } from "../lib/src/phrase-building/vp-tools";
|
||||
|
||||
const working = [
|
||||
"limited demo vocab",
|
||||
|
@ -46,7 +43,13 @@ const examples = [
|
|||
"وبه مې وینې",
|
||||
];
|
||||
|
||||
function ParserDemo({ opts }: { opts: T.TextOptions }) {
|
||||
function ParserDemo({
|
||||
opts,
|
||||
entryFeeder,
|
||||
}: {
|
||||
opts: T.TextOptions;
|
||||
entryFeeder: T.EntryFeeder;
|
||||
}) {
|
||||
const [text, setText] = useState<string>("");
|
||||
const [result, setResult] = useState<
|
||||
ReturnType<typeof parsePhrase>["success"]
|
||||
|
@ -129,29 +132,37 @@ function ParserDemo({ opts }: { opts: T.TextOptions }) {
|
|||
"inflected" in res ? (
|
||||
<NPDisplay NP={res.selection} inflected={res.inflected} opts={opts} />
|
||||
) : "verb" in res ? (
|
||||
(() => {
|
||||
try {
|
||||
const rendered = renderVP(res);
|
||||
const compiled = compileVP(rendered, res.form);
|
||||
return (
|
||||
<div>
|
||||
<CompiledPTextDisplay compiled={compiled} opts={opts} />
|
||||
{compiled.e && (
|
||||
<div className={`text-muted mt-2 text-center`}>
|
||||
{compiled.e.map((e, i) => (
|
||||
<div key={i}>{e}</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.log({ res });
|
||||
return <div>ERROR</div>;
|
||||
}
|
||||
})()
|
||||
<EditableVP
|
||||
opts={opts}
|
||||
entryFeeder={entryFeeder}
|
||||
formChoice={false}
|
||||
allVariations={true}
|
||||
>
|
||||
{uncompleteVPSelection(res)}
|
||||
</EditableVP>
|
||||
) : (
|
||||
// (() => {
|
||||
// try {
|
||||
// const rendered = renderVP(res);
|
||||
// const compiled = compileVP(rendered, res.form);
|
||||
// return (
|
||||
// <div>
|
||||
// <CompiledPTextDisplay compiled={compiled} opts={opts} />
|
||||
// {compiled.e && (
|
||||
// <div className={`text-muted mt-2 text-center`}>
|
||||
// {compiled.e.map((e, i) => (
|
||||
// <div key={i}>{e}</div>
|
||||
// ))}
|
||||
// </div>
|
||||
// )}
|
||||
// </div>
|
||||
// );
|
||||
// } catch (e) {
|
||||
// console.error(e);
|
||||
// console.log({ res });
|
||||
// return <div>ERROR</div>;
|
||||
// }
|
||||
// })()
|
||||
<samp>
|
||||
<pre>{JSON.stringify(res, null, " ")}</pre>
|
||||
</samp>
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import * as T from "../../../types";
|
||||
import { concatPsString, psRemove, psStringEquals } from "../p-text-helpers";
|
||||
import { isPerfectTense } from "../type-predicates";
|
||||
import {
|
||||
isImperativeTense,
|
||||
isPerfectTense,
|
||||
isVerbTense,
|
||||
} from "../type-predicates";
|
||||
import * as grammarUnits from "../grammar-units";
|
||||
import { isSecondPerson, randomNumber } from "../misc-helpers";
|
||||
import {
|
||||
|
@ -278,6 +282,36 @@ export function completeVPSelection(
|
|||
};
|
||||
}
|
||||
|
||||
export function uncompleteVPSelection(
|
||||
vps: T.VPSelectionComplete
|
||||
): T.VPSelectionState {
|
||||
const tense = vps.verb.tense;
|
||||
const tenseCategory = isVerbTense(tense)
|
||||
? "basic"
|
||||
: isPerfectTense(tense)
|
||||
? "perfect"
|
||||
: isImperativeTense(tense)
|
||||
? "modal"
|
||||
: "imperative";
|
||||
return {
|
||||
...vps,
|
||||
verb: {
|
||||
...vps.verb,
|
||||
verbTense:
|
||||
tenseCategory === "basic" ? (tense as T.VerbTense) : "presentVerb",
|
||||
perfectTense:
|
||||
tenseCategory === "perfect"
|
||||
? (tense as T.PerfectTense)
|
||||
: "presentPerfect",
|
||||
imperativeTense:
|
||||
tenseCategory === "imperative"
|
||||
? (tense as T.ImperativeTense)
|
||||
: "imperfectiveImperative",
|
||||
tenseCategory,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function isThirdPerson(p: T.Person): boolean {
|
||||
return (
|
||||
p === T.Person.ThirdSingMale ||
|
||||
|
|
|
@ -3,6 +3,17 @@ import { pashtoConsonants } from "./pashto-consonants";
|
|||
import { endsWith } from "./p-text-helpers";
|
||||
import { countSyllables } from "./accent-helpers";
|
||||
|
||||
const verbTenses: T.VerbTense[] = [
|
||||
"presentVerb",
|
||||
"subjunctiveVerb",
|
||||
"perfectiveFuture",
|
||||
"imperfectiveFuture",
|
||||
"perfectivePast",
|
||||
"imperfectivePast",
|
||||
"habitualPerfectivePast",
|
||||
"habitualImperfectivePast",
|
||||
];
|
||||
|
||||
export function isTlulVerb(e: T.VerbEntry | T.VerbDictionaryEntry): boolean {
|
||||
const entry = "entry" in e ? e.entry : e;
|
||||
return (
|
||||
|
@ -276,16 +287,6 @@ export function isPerfectTense(tense: T.Tense): tense is T.PerfectTense {
|
|||
}
|
||||
|
||||
export function isVerbTense(tense: T.Tense): tense is T.VerbTense {
|
||||
const verbTenses: T.VerbTense[] = [
|
||||
"presentVerb",
|
||||
"subjunctiveVerb",
|
||||
"perfectiveFuture",
|
||||
"imperfectiveFuture",
|
||||
"perfectivePast",
|
||||
"imperfectivePast",
|
||||
"habitualPerfectivePast",
|
||||
"habitualImperfectivePast",
|
||||
];
|
||||
return verbTenses.some((x) => x === tense);
|
||||
}
|
||||
|
||||
|
|
|
@ -787,7 +787,7 @@ export type VerbFormName =
|
|||
|
||||
export type VerbSelectionComplete = Omit<
|
||||
VerbSelection,
|
||||
"object" | "verbTense" | "perfectTense" | "imperativeTense" | "tenseCategory"
|
||||
"verbTense" | "perfectTense" | "imperativeTense" | "tenseCategory"
|
||||
> & {
|
||||
tense: VerbFormName;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue