Refactor for use of keys in the blocks so that we can autoAnimate the blocks diagrams, but it still doesn't work because we need a way to persist the keys in the blocks on re-renders - could be tricky
This commit is contained in:
parent
7275fbd73c
commit
4062cedd48
|
@ -1,4 +1,5 @@
|
|||
import { useState } from "react";
|
||||
// import autoAnimate from "@formkit/auto-animate";
|
||||
import { filterForVisibleBlocksEP, filterForVisibleBlocksVP } from "../lib/phrase-building/compile";
|
||||
import * as T from "../types";
|
||||
import Block from "./blocks/Block";
|
||||
|
@ -11,6 +12,11 @@ function RenderedBlocksDisplay({ opts, rendered, justify, script }: {
|
|||
justify?: "left" | "right" | "center",
|
||||
}) {
|
||||
const [variation, setVariation] = useState<number>(0);
|
||||
// not using autoAnimate here because we need a way to persist the keys in the blocks first
|
||||
// const parent = useRef(null);
|
||||
// useEffect(() => {
|
||||
// parent.current && autoAnimate(parent.current)
|
||||
// }, [parent]);
|
||||
const blocksWVars = ("omitSubject" in rendered)
|
||||
? filterForVisibleBlocksEP(rendered.blocks, rendered.omitSubject)
|
||||
: filterForVisibleBlocksVP(rendered.blocks, rendered.form, rendered.king);
|
||||
|
@ -19,14 +25,14 @@ function RenderedBlocksDisplay({ opts, rendered, justify, script }: {
|
|||
function handleVariationChange() {
|
||||
setVariation(ov => ((ov + 1) % blocksWVars.length));
|
||||
}
|
||||
return <div className={`d-flex flex-row justify-content-${justify ? justify : "center"}`} style={{}}>
|
||||
return <div className={`d-flex flex-row justify-content-${justify ? justify : "center"}`}>
|
||||
<div className={`d-flex flex-row${script === "p" ? "-reverse" : ""} justify-content-left align-items-end mt-3 pb-2`} style={{ overflowX: "auto" }}>
|
||||
<div key={Math.random()} className="mr-2">
|
||||
<div key={blocks[0].key} className="mr-2">
|
||||
<Block opts={opts} block={blocks[0]} king={king} script={script} />
|
||||
</div>
|
||||
<KidsSection opts={opts} kids={rendered.kids} script={script} />
|
||||
<KidsSection key="kidsSection" opts={opts} kids={rendered.kids} script={script} />
|
||||
{blocks.slice(1).map((block) => (
|
||||
<div key={Math.random()} className="mr-2">
|
||||
<div key={block.key} className="mr-2">
|
||||
<Block opts={opts} block={block} king={king} script={script} />
|
||||
</div>
|
||||
))}
|
||||
|
@ -42,10 +48,15 @@ function KidsSection({ opts, kids, script }: {
|
|||
kids: T.Kid[],
|
||||
script: "p" | "f",
|
||||
}) {
|
||||
// not using autoAnimate here because we need a way to persist the keys in the blocks first
|
||||
// const parent = useRef(null);
|
||||
// useEffect(() => {
|
||||
// parent.current && autoAnimate(parent.current)
|
||||
// }, [parent]);
|
||||
return kids.length > 0 ? <div className="text-center mx-1 mr-3" style={{ paddingBottom: "1rem"}}>
|
||||
<div className={`d-flex flex-row${script === "p" ? "-reverse" : ""} mb-3 justify-content-center`}>
|
||||
{kids.map(kid => (
|
||||
<KidDisplay key={Math.random()} opts={opts} kid={kid} script={script} />
|
||||
<KidDisplay key={kid.key} opts={opts} kid={kid} script={script} />
|
||||
))}
|
||||
</div>
|
||||
<div><strong>kids</strong></div>
|
||||
|
|
|
@ -15,53 +15,53 @@ function Block({ opts, block, king, script }: {
|
|||
king?: "subject" | "object" | undefined,
|
||||
script: "p" | "f";
|
||||
}) {
|
||||
if ("equative" in block) {
|
||||
return <EquativeBlock opts={opts} eq={block.equative} script={script} />;
|
||||
if ("equative" in block.block) {
|
||||
return <EquativeBlock opts={opts} eq={block.block.equative} script={script} />;
|
||||
}
|
||||
if (block.type === "AP") {
|
||||
const english = getEnglishFromRendered(block);
|
||||
return <APBlock opts={opts} english={english} script={script}>{block}</APBlock>
|
||||
if (block.block.type === "AP") {
|
||||
const english = getEnglishFromRendered(block.block);
|
||||
return <APBlock opts={opts} english={english} script={script}>{block.block}</APBlock>
|
||||
}
|
||||
if (block.type === "subjectSelection") {
|
||||
if (block.block.type === "subjectSelection") {
|
||||
const role = king === "subject" ? "king" : king === "object" ? "servant" : undefined;
|
||||
return <SubjectBlock opts={opts} np={block.selection} role={role} script={script} />
|
||||
return <SubjectBlock opts={opts} np={block.block.selection} role={role} script={script} />
|
||||
}
|
||||
if (block.type === "predicateSelection") {
|
||||
const english = getEnglishFromRendered(block.selection);
|
||||
if (block.block.type === "predicateSelection") {
|
||||
const english = getEnglishFromRendered(block.block.selection);
|
||||
return <div className="text-center">
|
||||
<div><strong>Predicate</strong></div>
|
||||
{block.selection.type === "EQComp"
|
||||
? <EqCompBlock opts={opts} comp={block.selection.selection} script={script} />
|
||||
: <NPBlock opts={opts} english={english} script={script}>{block.selection}</NPBlock>}
|
||||
{block.block.selection.type === "EQComp"
|
||||
? <EqCompBlock opts={opts} comp={block.block.selection.selection} script={script} />
|
||||
: <NPBlock opts={opts} english={english} script={script}>{block.block.selection}</NPBlock>}
|
||||
</div>
|
||||
}
|
||||
if (block.type === "negative") {
|
||||
return <NegBlock opts={opts} imperative={block.imperative} script={script} />
|
||||
if (block.block.type === "negative") {
|
||||
return <NegBlock opts={opts} imperative={block.block.imperative} script={script} />
|
||||
}
|
||||
if (block.type === "perfectiveHead") {
|
||||
return <PerfHeadBlock opts={opts} ps={block.ps} script={script} />
|
||||
if (block.block.type === "perfectiveHead") {
|
||||
return <PerfHeadBlock opts={opts} ps={block.block.ps} script={script} />
|
||||
}
|
||||
if (block.type === "verbComplement") {
|
||||
return <VCompBlock opts={opts} comp={block.complement} script={script} />;
|
||||
if (block.block.type === "verbComplement") {
|
||||
return <VCompBlock opts={opts} comp={block.block.complement} script={script} />;
|
||||
}
|
||||
if (block.type === "verb") {
|
||||
if (block.block.type === "verb") {
|
||||
return <VerbSBlock opts={opts} v={block.block.block} script={script} />;
|
||||
}
|
||||
if (block.block.type === "objectSelection") {
|
||||
const role = king === "object" ? "king" : king === "subject" ? "servant" : undefined;
|
||||
return <ObjectBlock opts={opts} obj={block.block.selection} role={role} script={script} />;
|
||||
}
|
||||
if (block.block.type === "perfectParticipleBlock") {
|
||||
return <VerbSBlock opts={opts} v={block.block} script={script} />;
|
||||
}
|
||||
if (block.type === "objectSelection") {
|
||||
const role = king === "object" ? "king" : king === "subject" ? "servant" : undefined;
|
||||
return <ObjectBlock opts={opts} obj={block.selection} role={role} script={script} />;
|
||||
if (block.block.type === "perfectEquativeBlock") {
|
||||
return <EquativeBlock opts={opts} eq={block.block} script={script} />;
|
||||
}
|
||||
if (block.type === "perfectParticipleBlock") {
|
||||
return <VerbSBlock opts={opts} v={block} script={script} />;
|
||||
if (block.block.type === "modalVerbBlock") {
|
||||
return <ModalVerbBlock opts={opts} v={block.block} script={script} />;
|
||||
}
|
||||
if (block.type === "perfectEquativeBlock") {
|
||||
return <EquativeBlock opts={opts} eq={block} script={script} />;
|
||||
}
|
||||
if (block.type === "modalVerbBlock") {
|
||||
return <ModalVerbBlock opts={opts} v={block} script={script} />;
|
||||
}
|
||||
if (block.type === "modalVerbKedulPart") {
|
||||
return <ModalAuxBlock opts={opts} aux={block} script={script} />
|
||||
if (block.block.type === "modalVerbKedulPart") {
|
||||
return <ModalAuxBlock opts={opts} aux={block.block} script={script} />
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@ function KidDisplay({ opts, kid, script }: {
|
|||
kid: T.Kid,
|
||||
script: "p" | "f",
|
||||
}) {
|
||||
const ps = kid.type === "ba"
|
||||
const ps = kid.kid.type === "ba"
|
||||
? baParticle
|
||||
: kid.ps;
|
||||
return <div className="mx-1">
|
||||
: kid.kid.ps;
|
||||
return <div className="mx-1" key={kid.key}>
|
||||
{script === "p"
|
||||
? <Pashto opts={opts}>{ps}</Pashto>
|
||||
: <Phonetics opts={opts}>{ps}</Phonetics>}
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
import * as T from "../../types";
|
||||
import { getLength } from "../p-text-helpers";
|
||||
|
||||
export function makeBlock(block: T.Block["block"], key?: number): T.Block {
|
||||
return {
|
||||
key: key === undefined ? Math.random() : key,
|
||||
block,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeKid(kid: T.Kid["kid"], key?: number): T.Kid {
|
||||
return {
|
||||
key: key === undefined ? Math.random() : key,
|
||||
kid,
|
||||
};
|
||||
}
|
||||
|
||||
export function getSubjectSelection(blocks: T.EPSBlockComplete[] | T.VPSBlockComplete[]): T.SubjectSelectionComplete;
|
||||
export function getSubjectSelection(blocks: T.EPSBlock[] | T.VPSBlock[]): T.SubjectSelection;
|
||||
export function getSubjectSelection(blocks: T.EPSBlock[] | T.EPSBlockComplete[] | T.VPSBlockComplete[] | T.VPSBlock[]): T.SubjectSelection | T.SubjectSelectionComplete {
|
||||
|
@ -12,31 +26,31 @@ export function getSubjectSelection(blocks: T.EPSBlock[] | T.EPSBlockComplete[]
|
|||
}
|
||||
|
||||
export function getSubjectSelectionFromBlocks(blocks: T.Block[][]): T.Rendered<T.SubjectSelectionComplete> {
|
||||
const b = blocks[0].find(f => f.type === "subjectSelection");
|
||||
if (!b || b.type !== "subjectSelection") {
|
||||
const b = blocks[0].find(f => f.block.type === "subjectSelection");
|
||||
if (!b || b.block.type !== "subjectSelection") {
|
||||
throw new Error("subjectSelection not found in blocks");
|
||||
}
|
||||
return b;
|
||||
return b.block;
|
||||
}
|
||||
|
||||
export function getObjectSelectionFromBlocks(blocks: T.Block[][]): T.Rendered<T.ObjectSelectionComplete> {
|
||||
const b = blocks[0].find(f => f.type === "objectSelection");
|
||||
if (!b || b.type !== "objectSelection") {
|
||||
const b = blocks[0].find(f => f.block.type === "objectSelection");
|
||||
if (!b || b.block.type !== "objectSelection") {
|
||||
throw new Error("objectSelection not found in blocks");
|
||||
}
|
||||
return b;
|
||||
return b.block;
|
||||
}
|
||||
|
||||
export function getVerbFromBlocks(blocks: T.Block[][]): T.VerbRenderedBlock {
|
||||
const b = blocks[0].find(f => f.type === "verb");
|
||||
const p = blocks[0].find(f => f.type === "perfectParticipleBlock");
|
||||
const m = blocks[0].find(f => f.type === "modalVerbBlock");
|
||||
const v = (b && b.type === "verb")
|
||||
? b
|
||||
: (p && p.type === "perfectParticipleBlock")
|
||||
? p.verb
|
||||
: (m && m.type === "modalVerbBlock")
|
||||
? m.verb
|
||||
const b = blocks[0].find(f => f.block.type === "verb");
|
||||
const p = blocks[0].find(f => f.block.type === "perfectParticipleBlock");
|
||||
const m = blocks[0].find(f => f.block.type === "modalVerbBlock");
|
||||
const v = (b && b.block.type === "verb")
|
||||
? b.block
|
||||
: (p && p.block.type === "perfectParticipleBlock")
|
||||
? p.block.verb
|
||||
: (m && m.block.type === "modalVerbBlock")
|
||||
? m.block.verb
|
||||
: undefined;
|
||||
if (!v) {
|
||||
throw new Error("verbSelection not found in blocks");
|
||||
|
@ -46,8 +60,8 @@ export function getVerbFromBlocks(blocks: T.Block[][]): T.VerbRenderedBlock {
|
|||
|
||||
export function getVerbAndHeadFromBlocks(blocks: T.Block[][]): { verb: T.VerbRenderedBlock, perfectiveHead: T.PerfectiveHeadBlock | undefined } {
|
||||
const verb = getVerbFromBlocks(blocks);
|
||||
const perfectiveHead = blocks[0].find(f => f.type === "perfectiveHead");
|
||||
if (!perfectiveHead || perfectiveHead.type !== "perfectiveHead") {
|
||||
const perfectiveHead = blocks[0].find(f => f.block.type === "perfectiveHead");
|
||||
if (!perfectiveHead || perfectiveHead.block.type !== "perfectiveHead") {
|
||||
return {
|
||||
verb,
|
||||
perfectiveHead: undefined,
|
||||
|
@ -55,27 +69,27 @@ export function getVerbAndHeadFromBlocks(blocks: T.Block[][]): { verb: T.VerbRen
|
|||
}
|
||||
return {
|
||||
verb,
|
||||
perfectiveHead,
|
||||
perfectiveHead: perfectiveHead.block,
|
||||
};
|
||||
}
|
||||
|
||||
export function includesShrunkenServant(kids?: T.Kid[]): boolean {
|
||||
if (!kids) return false;
|
||||
return kids.some(k => (
|
||||
k.type === "mini-pronoun" && k.source === "servant"
|
||||
k.kid.type === "mini-pronoun" && k.kid.source === "servant"
|
||||
));
|
||||
}
|
||||
|
||||
export function getPredicateSelectionFromBlocks(blocks: T.Block[][]): T.Rendered<T.PredicateSelectionComplete> {
|
||||
const b = blocks[0].find(f => f.type === "predicateSelection");
|
||||
if (!b || b.type !== "predicateSelection") {
|
||||
const b = blocks[0].find(f => f.block.type === "predicateSelection");
|
||||
if (!b || b.block.type !== "predicateSelection") {
|
||||
throw new Error("predicateSelection not found in blocks");
|
||||
}
|
||||
return b;
|
||||
return b.block;
|
||||
}
|
||||
|
||||
export function getAPsFromBlocks(blocks: T.Block[][]): T.Rendered<T.APSelection>[] {
|
||||
return blocks[0].filter(b => b.type === "AP") as T.Rendered<T.APSelection>[];
|
||||
return blocks[0].filter(b => b.block.type === "AP").map(b => b.block) as T.Rendered<T.APSelection>[];
|
||||
}
|
||||
|
||||
export function getObjectSelection(blocks: T.VPSBlockComplete[]): T.ObjectSelectionComplete;
|
||||
|
@ -238,16 +252,19 @@ export function isNoObject(b: T.VPSBlock["block"] | T.EPSBlock["block"]): b is {
|
|||
|
||||
export function specifyEquativeLength(blocksWVars: T.Block[][], length: "long" | "short"): T.Block[][] {
|
||||
function specify(blocks: T.Block[]): T.Block[] {
|
||||
const i = blocks.findIndex(b => b.type === "equative");
|
||||
const i = blocks.findIndex(b => b.block.type === "equative");
|
||||
if (i === -1) throw new Error("equative block not found in EPRendered");
|
||||
const eq = blocks[i];
|
||||
if (eq.type !== "equative") throw new Error("error searching for equative block");
|
||||
if (eq.block.type !== "equative") throw new Error("error searching for equative block");
|
||||
const adjusted = [...blocks];
|
||||
adjusted[i] = {
|
||||
...eq,
|
||||
equative: {
|
||||
...eq.equative,
|
||||
ps: getLength(eq.equative.ps, length),
|
||||
block: {
|
||||
...eq.block,
|
||||
equative: {
|
||||
...eq.block.equative,
|
||||
ps: getLength(eq.block.equative.ps, length),
|
||||
},
|
||||
},
|
||||
};
|
||||
return adjusted;
|
||||
|
@ -257,28 +274,37 @@ export function specifyEquativeLength(blocksWVars: T.Block[][], length: "long" |
|
|||
|
||||
export function specifyVerbLength(blocksWVars: T.Block[][], length: "long" | "short" | "mini"): T.Block[][] {
|
||||
function specify(blocks: T.Block[]): T.Block[] {
|
||||
return blocks.map((block) => {
|
||||
if (block.type === "verb") {
|
||||
const v: T.VerbRenderedBlock = {
|
||||
return blocks.map((block): T.Block => {
|
||||
if (block.block.type === "verb") {
|
||||
const v: T.Block = {
|
||||
...block,
|
||||
block: {
|
||||
...block.block,
|
||||
block: {
|
||||
...block.block.block,
|
||||
ps: getLength(block.block.block.ps, length),
|
||||
},
|
||||
},
|
||||
};
|
||||
return v;
|
||||
}
|
||||
if (block.block.type === "perfectParticipleBlock") {
|
||||
const p: T.Block = {
|
||||
...block,
|
||||
block: {
|
||||
...block.block,
|
||||
ps: getLength(block.block.ps, length),
|
||||
},
|
||||
};
|
||||
return v;
|
||||
}
|
||||
if (block.type === "perfectParticipleBlock") {
|
||||
const p: T.PerfectParticipleBlock = {
|
||||
...block,
|
||||
ps: getLength(block.ps, length),
|
||||
};
|
||||
return p;
|
||||
}
|
||||
if (block.type === "modalVerbBlock") {
|
||||
const m: T.ModalVerbBlock = {
|
||||
if (block.block.type === "modalVerbBlock") {
|
||||
const m: T.Block = {
|
||||
...block,
|
||||
ps: getLength(block.ps, length),
|
||||
block: {
|
||||
...block.block,
|
||||
ps: getLength(block.block.ps, length),
|
||||
},
|
||||
};
|
||||
return m;
|
||||
}
|
||||
|
@ -289,21 +315,21 @@ export function specifyVerbLength(blocksWVars: T.Block[][], length: "long" | "sh
|
|||
}
|
||||
|
||||
export function hasEquativeWithLengths(blocks: T.Block[][]): boolean {
|
||||
const equative = blocks[0].find(x => x.type === "equative");
|
||||
const equative = blocks[0].find(x => x.block.type === "equative");
|
||||
if (!equative) throw new Error("equative not found in blocks");
|
||||
if (equative.type !== "equative") throw new Error("error finding equative in blocks");
|
||||
return "long" in equative.equative.ps;
|
||||
if (equative.block.type !== "equative") throw new Error("error finding equative in blocks");
|
||||
return "long" in equative.block.equative.ps;
|
||||
}
|
||||
|
||||
export function hasVerbWithLengths(blocks: T.Block[][]): boolean {
|
||||
// TODO: handle length options with perfect verb equative as well?
|
||||
const verb = blocks[0].find(x => (x.type === "verb" || x.type === "perfectParticipleBlock" || x.type === "modalVerbBlock"));
|
||||
const verb = blocks[0].find(x => (x.block.type === "verb" || x.block.type === "perfectParticipleBlock" || x.block.type === "modalVerbBlock"));
|
||||
if (!verb) throw new Error("verb not found in blocks");
|
||||
if (verb.type !== "verb" && verb.type !== "perfectParticipleBlock" && verb.type !== "modalVerbBlock") throw new Error("error finding verb in blocks");
|
||||
if (verb.block.type !== "verb" && verb.block.type !== "perfectParticipleBlock" && verb.block.type !== "modalVerbBlock") throw new Error("error finding verb in blocks");
|
||||
return (
|
||||
(verb.type === "verb" && "long" in verb.block.ps)
|
||||
|| (verb.type === "perfectParticipleBlock" && "long" in verb.ps)
|
||||
|| (verb.type === "modalVerbBlock" && "long" in verb.ps)
|
||||
(verb.block.type === "verb" && "long" in verb.block.block.ps)
|
||||
|| (verb.block.type === "perfectParticipleBlock" && "long" in verb.block.ps)
|
||||
|| (verb.block.type === "modalVerbBlock" && "long" in verb.block.ps)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ function compileEPPs(blocks: T.Block[][], kids: T.Kid[], omitSubject: boolean, b
|
|||
const subjectPerson = getSubjectSelectionFromBlocks(blocks)
|
||||
.selection.selection.person;
|
||||
const blocksWKids = putKidsInKidsSection(
|
||||
omitSubject ? blocks.map(blks => blks.filter(b => b.type !== "subjectSelection")) : blocks,
|
||||
omitSubject ? blocks.map(blks => blks.filter(b => b.block.type !== "subjectSelection")) : blocks,
|
||||
kids,
|
||||
!!blankOut?.kidsSection
|
||||
);
|
||||
|
@ -119,19 +119,19 @@ export function filterForVisibleBlocksVP(blocks: T.Block[][], form: T.FormVersio
|
|||
return blocks.map(blks => blks.filter((block) => {
|
||||
if (form.removeKing) {
|
||||
if (
|
||||
(king === "subject" && block.type === "subjectSelection")
|
||||
(king === "subject" && block.block.type === "subjectSelection")
|
||||
||
|
||||
(king === "object" && block.type === "objectSelection")
|
||||
(king === "object" && block.block.type === "objectSelection")
|
||||
) return false;
|
||||
}
|
||||
if (form.shrinkServant) {
|
||||
if (
|
||||
(servant === "subject" && block.type === "subjectSelection")
|
||||
(servant === "subject" && block.block.type === "subjectSelection")
|
||||
||
|
||||
(servant === "object" && block.type === "objectSelection")
|
||||
(servant === "object" && block.block.type === "objectSelection")
|
||||
) return false;
|
||||
}
|
||||
if (block.type === "objectSelection" && typeof block.selection !== "object") {
|
||||
if (block.block.type === "objectSelection" && typeof block.block.selection !== "object") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -140,7 +140,7 @@ export function filterForVisibleBlocksVP(blocks: T.Block[][], form: T.FormVersio
|
|||
|
||||
export function filterForVisibleBlocksEP(blocks: T.Block[][], omitSubject: boolean): T.Block[][] {
|
||||
if (!omitSubject) return blocks;
|
||||
return blocks.map(blks => blks.filter((block) => {
|
||||
return blocks.map(blks => blks.filter(({ block }) => {
|
||||
if (block.type === "subjectSelection") {
|
||||
return false;
|
||||
}
|
||||
|
@ -155,9 +155,9 @@ function combineIntoText(piecesWVars: (T.Block | T.Kid | T.PsString)[][], subjec
|
|||
const rest = pieces.slice(1);
|
||||
const firstPs = ("p" in first)
|
||||
? [first]
|
||||
: (blankOut?.equative && first.type === "equative")
|
||||
: (blankOut?.equative && "block" in first && first.block.type === "equative")
|
||||
? [blank]
|
||||
: ((blankOut?.ba) && first.type === "ba")
|
||||
: ((blankOut?.ba) && "kid" in first && first.kid.type === "ba")
|
||||
? [kidsBlank]
|
||||
: getPsFromPiece(first, subjectPerson);
|
||||
if (!rest.length) {
|
||||
|
@ -166,8 +166,8 @@ function combineIntoText(piecesWVars: (T.Block | T.Kid | T.PsString)[][], subjec
|
|||
return combine(rest).flatMap(r => (
|
||||
firstPs.map(fPs => concatPsString(
|
||||
fPs,
|
||||
(!("p" in first) && first.type === "perfectiveHead" && !("p" in next) && (next.type === "verb" || next.type === "negative" || next.type === "mini-pronoun"))
|
||||
? ((next.type === "negative" || next.type === "mini-pronoun") ? { p: "", f: "-" } : "")
|
||||
(!("p" in first) && "block" in first && first.block.type === "perfectiveHead" && !("p" in next) && (("block" in next && (next.block.type === "verb" || next.block.type === "negative")) || ("kid" in next && next.kid.type === "mini-pronoun")))
|
||||
? ((("block" in next && next.block.type === "negative") || ("kid" in next && next.kid.type === "mini-pronoun")) ? { p: "", f: "-" } : "")
|
||||
: " ",
|
||||
r,
|
||||
))
|
||||
|
@ -178,59 +178,64 @@ function combineIntoText(piecesWVars: (T.Block | T.Kid | T.PsString)[][], subjec
|
|||
}
|
||||
|
||||
function getPsFromPiece(piece: T.Block | T.Kid, subjectPerson: T.Person): T.PsString[] {
|
||||
if (piece.type === "ba") {
|
||||
return [grammarUnits.baParticle];
|
||||
}
|
||||
if (piece.type === "mini-pronoun") {
|
||||
return [piece.ps];
|
||||
}
|
||||
if (piece.type === "negative") {
|
||||
return [
|
||||
negativeParticle[piece.imperative ? "imperative" : "nonImperative"],
|
||||
];
|
||||
}
|
||||
if (piece.type === "equative") {
|
||||
// length will already be specified in compileEPPs - this is just for type safety
|
||||
return getLong(piece.equative.ps);
|
||||
}
|
||||
if (piece.type === "subjectSelection" || piece.type === "predicateSelection") {
|
||||
return getPashtoFromRendered(piece.selection, subjectPerson);
|
||||
}
|
||||
if (piece.type === "AP") {
|
||||
return getPashtoFromRendered(piece, subjectPerson);
|
||||
}
|
||||
if (piece.type === "perfectiveHead") {
|
||||
return [piece.ps];
|
||||
}
|
||||
if (piece.type === "verbComplement") {
|
||||
return [{ p: "---", f: "---"}]; //getPashtoFromRendered(piece.complement);
|
||||
}
|
||||
if (piece.type === "objectSelection") {
|
||||
if (typeof piece.selection !== "object") {
|
||||
return [{ p: "", f: "" }];
|
||||
if ("block" in piece) {
|
||||
if (piece.block.type === "negative") {
|
||||
return [
|
||||
negativeParticle[piece.block.imperative ? "imperative" : "nonImperative"],
|
||||
];
|
||||
}
|
||||
if (piece.block.type === "equative") {
|
||||
// length will already be specified in compileEPPs - this is just for type safety
|
||||
return getLong(piece.block.equative.ps);
|
||||
}
|
||||
if (piece.block.type === "subjectSelection" || piece.block.type === "predicateSelection") {
|
||||
return getPashtoFromRendered(piece.block.selection, subjectPerson);
|
||||
}
|
||||
if (piece.block.type === "AP") {
|
||||
return getPashtoFromRendered(piece.block, subjectPerson);
|
||||
}
|
||||
if (piece.block.type === "perfectiveHead") {
|
||||
return [piece.block.ps];
|
||||
}
|
||||
if (piece.block.type === "verbComplement") {
|
||||
return [{ p: "---", f: "---"}]; //getPashtoFromRendered(piece.block.complement);
|
||||
}
|
||||
if (piece.block.type === "objectSelection") {
|
||||
if (typeof piece.block.selection !== "object") {
|
||||
return [{ p: "", f: "" }];
|
||||
}
|
||||
return getPashtoFromRendered(piece.block.selection, subjectPerson);
|
||||
}
|
||||
if (piece.block.type === "verb") {
|
||||
// getLong is just for type safety - we will have split up the length options earlier in compileVPPs
|
||||
return getLong(piece.block.block.ps);
|
||||
}
|
||||
if (piece.block.type === "perfectParticipleBlock") {
|
||||
// getLong is just for type safety - we will have split up the length options earlier in compileVPPs
|
||||
return getLong(piece.block.ps);
|
||||
}
|
||||
if (piece.block.type === "perfectEquativeBlock") {
|
||||
// just using the short one for now - it will only be short anyways
|
||||
return getShort(piece.block.ps);
|
||||
}
|
||||
if (piece.block.type === "modalVerbBlock") {
|
||||
// getLong is just for type safety - we will have split up the length options earlier in compileVPPs
|
||||
return getLong(piece.block.ps);
|
||||
}
|
||||
if (piece.block.type === "modalVerbKedulPart") {
|
||||
// just using the short one for now - it will only be short anyways
|
||||
return getShort(piece.block.ps);
|
||||
}
|
||||
return getPashtoFromRendered(piece.selection, subjectPerson);
|
||||
}
|
||||
if (piece.type === "verb") {
|
||||
// getLong is just for type safety - we will have split up the length options earlier in compileVPPs
|
||||
return getLong(piece.block.ps);
|
||||
}
|
||||
if (piece.type === "perfectParticipleBlock") {
|
||||
// getLong is just for type safety - we will have split up the length options earlier in compileVPPs
|
||||
return getLong(piece.ps);
|
||||
}
|
||||
if (piece.type === "perfectEquativeBlock") {
|
||||
// just using the short one for now - it will only be short anyways
|
||||
return getShort(piece.ps);
|
||||
}
|
||||
if (piece.type === "modalVerbBlock") {
|
||||
// getLong is just for type safety - we will have split up the length options earlier in compileVPPs
|
||||
return getLong(piece.ps);
|
||||
}
|
||||
if (piece.type === "modalVerbKedulPart") {
|
||||
// just using the short one for now - it will only be short anyways
|
||||
return getShort(piece.ps);
|
||||
if ("kid" in piece) {
|
||||
if (piece.kid.type === "ba") {
|
||||
return [grammarUnits.baParticle];
|
||||
}
|
||||
if (piece.kid.type === "mini-pronoun") {
|
||||
return [piece.kid.ps];
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error("unrecognized piece type");
|
||||
}
|
||||
|
||||
|
@ -317,7 +322,7 @@ export function checkForMiniPronounsError(s: T.EPSelectionState | T.VPSelectionS
|
|||
return renderVP(VPS).kids;
|
||||
})();
|
||||
if (!kids) return undefined;
|
||||
const miniPronouns = kids.filter(x => x.type === "mini-pronoun") as T.MiniPronoun[];
|
||||
const miniPronouns = kids.filter(x => x.kid.type === "mini-pronoun").map(m => m.kid) as T.MiniPronoun[];
|
||||
if (miniPronouns.length > 2) {
|
||||
return "can't add another mini-pronoun, there are alread two";
|
||||
}
|
||||
|
|
|
@ -88,11 +88,11 @@ export function getMiniPronounPs(person: T.Person): T.PsString {
|
|||
export function orderKids(kids: T.Kid[]): T.Kid[] {
|
||||
const sorted = [...kids].sort((a, b) => {
|
||||
// ba first
|
||||
if (a.type === "ba") return -1;
|
||||
if (a.kid.type === "ba") return -1;
|
||||
// kinds lined up 1st 2nd 3rd person
|
||||
if (a.type === "mini-pronoun" && b.type === "mini-pronoun") {
|
||||
const aPers = getFirstSecThird(a.person);
|
||||
const bPers = getFirstSecThird(b.person);
|
||||
if (a.kid.type === "mini-pronoun" && b.kid.type === "mini-pronoun") {
|
||||
const aPers = getFirstSecThird(a.kid.person);
|
||||
const bPers = getFirstSecThird(b.kid.person);
|
||||
if (aPers < bPers) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import { psStringFromEntry } from "../p-text-helpers";
|
|||
import { isLocativeAdverbEntry } from "../type-predicates";
|
||||
import { renderAdjectiveSelection } from "./render-adj";
|
||||
import { renderSandwich } from "./render-sandwich";
|
||||
import { EPSBlocksAreComplete, getSubjectSelection } from "./blocks-utils";
|
||||
import { EPSBlocksAreComplete, getSubjectSelection, makeBlock, makeKid } from "./blocks-utils";
|
||||
import { removeAccentsWLength } from "../accent-helpers";
|
||||
import { findPossesivesToShrink, orderKids } from "./render-common";
|
||||
|
||||
|
@ -41,18 +41,18 @@ function getEPSBlocksAndKids(EP: T.EPSelectionComplete): { kids: T.Kid[], blocks
|
|||
const equative: T.EquativeBlock = { type: "equative", equative: renderEquative(EP.equative, commandingPerson) };
|
||||
const blocks: T.Block[][] = insertNegative([
|
||||
...renderEPSBlocks(EP.blocks),
|
||||
{
|
||||
makeBlock({
|
||||
type: "predicateSelection",
|
||||
selection: EP.predicate.selection.type === "NP"
|
||||
? renderNPSelection(EP.predicate.selection, false, false, "subject", "king")
|
||||
: renderEqCompSelection(EP.predicate.selection, commandingPerson),
|
||||
},
|
||||
equative,
|
||||
selection: EP.predicate.selection.type === "NP"
|
||||
? renderNPSelection(EP.predicate.selection, false, false, "subject", "king")
|
||||
: renderEqCompSelection(EP.predicate.selection, commandingPerson),
|
||||
}),
|
||||
makeBlock(equative),
|
||||
], EP.equative.negative);
|
||||
const miniPronouns = findPossesivesToShrink(removeOrKeepSubject([...EP.blocks, EP.predicate], EP.omitSubject));
|
||||
const kids: T.Kid[] = orderKids([
|
||||
...equative.equative.hasBa ? [{ type: "ba" } as T.Kid] : [],
|
||||
...miniPronouns,
|
||||
...equative.equative.hasBa ? [makeKid({ type: "ba" })] : [],
|
||||
...miniPronouns.map(makeKid),
|
||||
]);
|
||||
return {
|
||||
blocks,
|
||||
|
@ -69,12 +69,12 @@ function insertNegative(blocks: T.Block[], negative: boolean): T.Block[][] {
|
|||
return [
|
||||
[
|
||||
...blocksA.slice(0, blocks.length - 1),
|
||||
{ type: "negative", imperative: false },
|
||||
makeBlock({ type: "negative", imperative: false }),
|
||||
...blocksA.slice(-1), // last (equative)
|
||||
],
|
||||
[
|
||||
...blocksA.slice(0, blocks.length - 2),
|
||||
{ type: "negative", imperative: false },
|
||||
makeBlock({ type: "negative", imperative: false }),
|
||||
...blocksA.slice(-1), // last (equative)
|
||||
...blocksA.slice(-2, -1), // second last (predicate)
|
||||
],
|
||||
|
@ -100,25 +100,25 @@ export function getEquativeForm(tense: T.EquativeTense): { hasBa: boolean, form:
|
|||
}
|
||||
|
||||
function renderEPSBlocks(blocks: T.EPSBlockComplete[]): T.Block[] {
|
||||
return blocks.map(({ block }): (T.Rendered<T.SubjectSelectionComplete> | T.Rendered<T.APSelection>) => {
|
||||
return blocks.map(({ block }): T.Block => {
|
||||
if (block.type === "AP") {
|
||||
if (block.selection.type === "adverb") {
|
||||
return {
|
||||
return makeBlock({
|
||||
type: "AP",
|
||||
selection: renderAdverbSelection(block.selection),
|
||||
};
|
||||
});
|
||||
}
|
||||
// if (block.selection.type === "sandwich") {
|
||||
return {
|
||||
return makeBlock({
|
||||
type: "AP",
|
||||
selection: renderSandwich(block.selection),
|
||||
};
|
||||
});
|
||||
// }
|
||||
}
|
||||
return {
|
||||
return makeBlock({
|
||||
type: "subjectSelection",
|
||||
selection: renderNPSelection(block.selection, false, false, "subject", "none")
|
||||
};
|
||||
selection: renderNPSelection(block.selection, false, false, "subject", "none"),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -279,15 +279,17 @@ export function completeEPSelection(eps: T.EPSelectionState): T.EPSelectionCompl
|
|||
|
||||
function removeAccentsFromEq(blocks: T.Block[]): T.Block[] {
|
||||
return blocks.map((block) => {
|
||||
if (block.type === "equative") {
|
||||
const e: T.EquativeBlock = {
|
||||
if (block.block.type === "equative") {
|
||||
return {
|
||||
...block,
|
||||
equative: {
|
||||
...block.equative,
|
||||
ps: removeAccentsWLength(block.equative.ps),
|
||||
},
|
||||
};
|
||||
return e;
|
||||
block: {
|
||||
...block.block,
|
||||
equative: {
|
||||
...block.block.equative,
|
||||
ps: removeAccentsWLength(block.block.equative.ps),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return block;
|
||||
});
|
||||
|
|
|
@ -26,7 +26,7 @@ import {
|
|||
import { renderEnglishVPBase } from "./english-vp-rendering";
|
||||
import { personGender } from "../../lib/misc-helpers";
|
||||
import { renderNPSelection } from "./render-np";
|
||||
import { getObjectSelection, getSubjectSelection } from "./blocks-utils";
|
||||
import { getObjectSelection, getSubjectSelection, makeBlock, makeKid } from "./blocks-utils";
|
||||
import { renderAPSelection } from "./render-ap";
|
||||
import { findPossesivesToShrink, orderKids, getMiniPronounPs } from "./render-common";
|
||||
|
||||
|
@ -67,7 +67,7 @@ export function renderVP(VP: T.VPSelectionComplete): T.VPRendered {
|
|||
isCompound: VP.verb.isCompound,
|
||||
blocks: insertNegative([
|
||||
...firstBlocks,
|
||||
...verbBlocks,
|
||||
...verbBlocks.map(makeBlock),
|
||||
], VP.verb.negative, isImperativeTense(VP.verb.tense)),
|
||||
kids: getVPKids(hasBa, VP.blocks, VP.form, king),
|
||||
englishBase: renderEnglishVPBase({
|
||||
|
@ -200,11 +200,11 @@ function getVPKids(hasBa: boolean, blocks: T.VPSBlockComplete[], form: T.FormVer
|
|||
const object = typeof objectS === "object" ? objectS : undefined;
|
||||
const servantNP = king === "subject" ? object : subject;
|
||||
const shrunkenServant = (form.shrinkServant && servantNP)
|
||||
? shrinkServant(servantNP)
|
||||
? makeKid(shrinkServant(servantNP))
|
||||
: undefined;
|
||||
const shrunkenPossesives = findPossesivesToShrink(removeAbbreviated(blocks, form, king));
|
||||
const shrunkenPossesives = findPossesivesToShrink(removeAbbreviated(blocks, form, king)).map(makeKid);
|
||||
return orderKids([
|
||||
...hasBa ? [{ type: "ba" } as T.Kid] : [],
|
||||
...hasBa ? [makeKid({ type: "ba" })] : [],
|
||||
...shrunkenServant ? [shrunkenServant] : [],
|
||||
...shrunkenPossesives ? shrunkenPossesives : [],
|
||||
]);
|
||||
|
@ -231,10 +231,10 @@ function insertNegative(blocks: T.Block[], negative: boolean, imperative: boolea
|
|||
const blocksA = removeVerbAccent(blocks);
|
||||
const basic: T.Block[] = [
|
||||
...blocksA.slice(0, blocks.length - 1),
|
||||
{
|
||||
makeBlock({
|
||||
type: "negative",
|
||||
imperative,
|
||||
},
|
||||
}),
|
||||
...blocksA.slice(-1),
|
||||
];
|
||||
if (hasNonStandardPerfectiveSplit(blocks)) {
|
||||
|
@ -242,7 +242,7 @@ function insertNegative(blocks: T.Block[], negative: boolean, imperative: boolea
|
|||
basic,
|
||||
[
|
||||
...blocksA.slice(0, blocks.length - 2),
|
||||
{ type: "negative", imperative },
|
||||
makeBlock({ type: "negative", imperative }),
|
||||
...blocksA.slice(-2, -1), // second last (perfective split)
|
||||
...blocksA.slice(-1), // last (verb)
|
||||
],
|
||||
|
@ -252,7 +252,7 @@ function insertNegative(blocks: T.Block[], negative: boolean, imperative: boolea
|
|||
return [
|
||||
[
|
||||
...blocksA.slice(0, blocks.length - 2),
|
||||
{ type: "negative", imperative },
|
||||
makeBlock({ type: "negative", imperative }),
|
||||
...blocksA.slice(-1), // last
|
||||
...blocksA.slice(-2, -1), // second last
|
||||
],
|
||||
|
@ -263,31 +263,34 @@ function insertNegative(blocks: T.Block[], negative: boolean, imperative: boolea
|
|||
}
|
||||
|
||||
function hasLeapFroggable(blocks: T.Block[]): boolean {
|
||||
return blocks.some(b => b.type === "perfectEquativeBlock" || b.type === "modalVerbBlock");
|
||||
return blocks.some(b => b.block.type === "perfectEquativeBlock" || b.block.type === "modalVerbBlock");
|
||||
}
|
||||
|
||||
function hasNonStandardPerfectiveSplit(blocks: T.Block[]): boolean {
|
||||
const perfS = blocks.find(b => b.type === "perfectiveHead");
|
||||
if (!perfS || perfS.type !== "perfectiveHead") {
|
||||
const perfS = blocks.find(b => b.block.type === "perfectiveHead");
|
||||
if (!perfS || perfS.block.type !== "perfectiveHead") {
|
||||
return false;
|
||||
}
|
||||
return !["و", "وا"].includes(perfS.ps.p);
|
||||
return !["و", "وا"].includes(perfS.block.ps.p);
|
||||
}
|
||||
|
||||
function removeVerbAccent(blocks: T.Block[]): T.Block[] {
|
||||
return blocks.map((block) => {
|
||||
if (block.type === "perfectiveHead") {
|
||||
return {
|
||||
...block,
|
||||
ps: removeAccents(block.ps),
|
||||
};
|
||||
}
|
||||
if (block.type === "verb") {
|
||||
if (block.block.type === "perfectiveHead") {
|
||||
return {
|
||||
...block,
|
||||
block: {
|
||||
...block.block,
|
||||
ps: removeAccentsWLength(block.block.ps),
|
||||
ps: removeAccents(block.block.ps),
|
||||
},
|
||||
};
|
||||
}
|
||||
if (block.block.type === "verb") {
|
||||
return {
|
||||
...block,
|
||||
block: {
|
||||
...block.block,
|
||||
ps: removeAccentsWLength(block.block.block.ps),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -315,10 +318,10 @@ function renderVPBlocks(blocks: T.VPSBlockComplete[], config: {
|
|||
if (block.type === "subjectSelection") {
|
||||
return [
|
||||
...blocks,
|
||||
{
|
||||
makeBlock({
|
||||
type: "subjectSelection",
|
||||
selection: renderNPSelection(block.selection, config.inflectSubject, false, "subject", config.king === "subject" ? "king" : "servant"),
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
if (block.type === "objectSelection") {
|
||||
|
@ -326,24 +329,24 @@ function renderVPBlocks(blocks: T.VPSBlockComplete[], config: {
|
|||
if (typeof object !== "object") {
|
||||
return [
|
||||
...blocks,
|
||||
{
|
||||
makeBlock({
|
||||
type: "objectSelection",
|
||||
selection: object,
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
const selection = renderNPSelection(object, config.inflectObject, true, "object", config.king === "object" ? "king" : "servant");
|
||||
return [
|
||||
...blocks,
|
||||
{
|
||||
makeBlock({
|
||||
type: "objectSelection",
|
||||
selection,
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
return [
|
||||
...blocks,
|
||||
renderAPSelection(block),
|
||||
makeBlock(renderAPSelection(block)),
|
||||
];
|
||||
}, [] as T.Block[]);
|
||||
}
|
||||
|
@ -362,7 +365,8 @@ function whatsAdjustable(VP: T.VPSelectionComplete): "both" | "king" | "servant"
|
|||
: "king";
|
||||
}
|
||||
|
||||
type VerbBlocks = | [T.PerfectiveHeadBlock, T.VerbRenderedBlock] // verb w perfective split
|
||||
type VerbBlocks =
|
||||
| [T.PerfectiveHeadBlock, T.VerbRenderedBlock] // verb w perfective split
|
||||
| [T.VerbRenderedBlock] // verb w/out perfective split
|
||||
| [T.PerfectParticipleBlock, T.PerfectEquativeBlock] // perfect verb
|
||||
| [T.ModalVerbBlock, T.ModalVerbKedulPart] // modal verb
|
||||
|
|
38
src/types.ts
38
src/types.ts
|
@ -900,24 +900,28 @@ export type VerbRenderedBlock = {
|
|||
},
|
||||
};
|
||||
|
||||
export type Block =
|
||||
| Rendered<SubjectSelectionComplete>
|
||||
| Rendered<ObjectSelectionComplete>
|
||||
| Rendered<APSelection>
|
||||
| Rendered<PredicateSelectionComplete>
|
||||
| PerfectParticipleBlock
|
||||
| PerfectEquativeBlock
|
||||
| ModalVerbBlock
|
||||
| ModalVerbKedulPart
|
||||
| { type: "negative", imperative: boolean }
|
||||
| PerfectiveHeadBlock
|
||||
| VerbRenderedBlock
|
||||
| VerbComplementBlock
|
||||
| EquativeBlock;
|
||||
export type Block = {
|
||||
key: number,
|
||||
block: | Rendered<SubjectSelectionComplete>
|
||||
| Rendered<ObjectSelectionComplete>
|
||||
| Rendered<APSelection>
|
||||
| Rendered<PredicateSelectionComplete>
|
||||
| PerfectParticipleBlock
|
||||
| PerfectEquativeBlock
|
||||
| ModalVerbBlock
|
||||
| ModalVerbKedulPart
|
||||
| { type: "negative", imperative: boolean }
|
||||
| PerfectiveHeadBlock
|
||||
| VerbRenderedBlock
|
||||
| VerbComplementBlock
|
||||
| EquativeBlock;
|
||||
}
|
||||
|
||||
export type Kid =
|
||||
| { type: "ba" }
|
||||
| MiniPronoun;
|
||||
export type Kid = {
|
||||
key: number,
|
||||
kid: | { type: "ba" }
|
||||
| MiniPronoun,
|
||||
}
|
||||
|
||||
export type MiniPronoun = {
|
||||
type: "mini-pronoun",
|
||||
|
|
Loading…
Reference in New Issue