better spacing around splits

This commit is contained in:
lingdocs 2022-03-25 16:50:17 +05:00
parent 75b6560625
commit 9afe378660
4 changed files with 111 additions and 93 deletions

View File

@ -5,7 +5,7 @@
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^5.15.4", "@fortawesome/fontawesome-free": "^5.15.4",
"@lingdocs/lingdocs-main": "^0.2.0", "@lingdocs/lingdocs-main": "^0.2.0",
"@lingdocs/pashto-inflector": "^1.5.4", "@lingdocs/pashto-inflector": "^1.5.5",
"@testing-library/jest-dom": "^5.11.4", "@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0", "@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10", "@testing-library/user-event": "^12.1.10",

View File

@ -5,64 +5,90 @@ import {
grammarUnits, grammarUnits,
getVerbBlockPosFromPerson, getVerbBlockPosFromPerson,
} from "@lingdocs/pashto-inflector"; } from "@lingdocs/pashto-inflector";
import { isMiniPronoun, removeBa } from "./vp-tools"; import { removeBa } from "./vp-tools";
type ListOfSegments = (T.PsString & { isVerbPrefix?: boolean, prefixFollowedByMiniPronoun?: boolean })[][]; type Segment = {
isVerbHead?: boolean,
isOoHead?: boolean,
isVerbRest?: boolean,
isMiniPronoun?: boolean,
isNu?: boolean,
isBa?: boolean,
ps: T.PsString[],
};
export function compileVP(VP: VPRendered, form: FormVersion): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] } { export function compileVP(VP: VPRendered, form: FormVersion): { ps: T.SingleOrLengthOpts<T.PsString[]>, e?: string [] } {
const { head, rest } = VP.verb.ps; const { head, rest } = VP.verb.ps;
const { kids, NPs } = shrinkSegmentsAndGatherKids(VP, form); const { kids, NPs } = shrinkSegmentsAndGatherKids(VP, form);
return { return {
ps: compilePs(NPs, head, rest, VP.verb.negative, kids), ps: compilePs({
NPs,
kids,
head,
rest,
negative: VP.verb.negative,
}),
e: compileEnglish(VP), e: compileEnglish(VP),
}; };
} }
// TODO: ISSUE off prefix-nu in the phonetics type CompilePsInput = {
NPs: Segment[],
function compilePs( kids: Segment[],
nps: ListOfSegments,
head: T.PsString | undefined,
rest: T.PsString[],
negative: boolean,
kids: ListOfSegments,
): T.PsString[];
function compilePs(
nps: ListOfSegments,
head: T.PsString | undefined, head: T.PsString | undefined,
rest: T.SingleOrLengthOpts<T.PsString[]>, rest: T.SingleOrLengthOpts<T.PsString[]>,
negative: boolean, negative: boolean,
kids: ListOfSegments, }
): T.SingleOrLengthOpts<T.PsString[]>; function compilePs({ NPs, kids, head, rest, negative }: CompilePsInput): T.SingleOrLengthOpts<T.PsString[]> {
function compilePs(
nps: ListOfSegments,
head: T.PsString | undefined,
rest: T.SingleOrLengthOpts<T.PsString[]>,
negative: boolean,
kids: ListOfSegments,
): T.SingleOrLengthOpts<T.PsString[]> {
if ("long" in rest) { if ("long" in rest) {
return { return {
long: compilePs(nps, head, rest.long, negative, kids), long: compilePs({ NPs, head, rest: rest.long, negative, kids }) as T.PsString[],
short: compilePs(nps, head, rest.short, negative, kids), short: compilePs({ NPs, head, rest: rest.short, negative, kids }) as T.PsString[],
...rest.mini ? { ...rest.mini ? {
mini: compilePs(nps, head, rest.mini, negative, kids), mini: compilePs({ NPs, head, rest: rest.mini, negative, kids }) as T.PsString[],
} : {}, } : {},
}; };
} }
const verbSegments = compileVerbWNegative(head, rest, negative) const verbSegments = compileVerbWNegative(head, rest, negative)
const segments: ListOfSegments = [ const segments: Segment[] = [
...nps, ...NPs,
...verbSegments, ...verbSegments,
]; ];
const segmentsWKids = putKidsInKidsSection( const segmentsWKids = putKidsInKidsSection(
segments, segments,
kids, kids,
); );
return combineSegments(segmentsWKids); // have all these pieces labelled
// add spaces
const segmentsWithSpaces = addSpacesBetweenSegments(segmentsWKids);
return combineSegments(segmentsWithSpaces);
} }
function shrinkSegmentsAndGatherKids(VP: VPRendered, form: FormVersion): { kids: ListOfSegments, NPs: ListOfSegments } { function addSpacesBetweenSegments(segments: Segment[]): (Segment | " " | "" | "-")[] {
const o: (Segment | " " | "" | "-")[] = [];
for (let i = 0; i < segments.length; i++) {
const current = segments[i];
const next = segments[i+1];
o.push(current);
if (!next) break;
if (current.isVerbHead &&
(
(next.isMiniPronoun || next.isNu)
||
(current.isOoHead && next.isBa)
)
) {
o.push("-");
} else if (current.isVerbHead && next.isVerbRest) {
o.push("");
} else {
o.push(" ");
}
}
return o;
}
function shrinkSegmentsAndGatherKids(VP: VPRendered, form: FormVersion): { kids: Segment[], NPs: Segment[] } {
const main = { const main = {
subject: VP.subject.ps, subject: VP.subject.ps,
object: typeof VP.object === "object" ? VP.object.ps : undefined, object: typeof VP.object === "object" ? VP.object.ps : undefined,
@ -83,13 +109,13 @@ function shrinkSegmentsAndGatherKids(VP: VPRendered, form: FormVersion): { kids:
return { return {
kids: [ kids: [
...VP.verb.hasBa ...VP.verb.hasBa
? [[grammarUnits.baParticle]] : [], ? [{ isBa: true, ps: [grammarUnits.baParticle] }] : [],
...toShrink ...toShrink
? [shrink(toShrink)] : [], ? [{ isMiniPronoun: true, ps: shrink(toShrink) }] : [],
], ],
NPs: [ NPs: [
...showSubject ? [main.subject] : [], ...showSubject ? [{ ps: main.subject }] : [],
...(showObject && main.object) ? [main.object] : [], ...(showObject && main.object) ? [{ ps: main.object }] : [],
], ],
} }
} }
@ -99,66 +125,74 @@ function shrink(np: Rendered<NPSelection>): T.PsString[] {
return grammarUnits.pronouns.mini[row][col]; return grammarUnits.pronouns.mini[row][col];
} }
function putKidsInKidsSection(segments: ListOfSegments, kids: ListOfSegments): ListOfSegments { function putKidsInKidsSection(segments: Segment[], kids: Segment[]): Segment[] {
const first = segments[0]; const first = segments[0];
const rest = segments.slice(1); const rest = segments.slice(1);
console.log({ kids }, kids.length);
return [ return [
first.map(x => ( first,
(x.isVerbPrefix && isMiniPronoun(kids[0][0]))
? { ...x, prefixFollowedByMiniPronoun: true }
: x
)),
...kids, ...kids,
...rest, ...rest,
]; ];
} }
function combineSegments(loe: ListOfSegments): T.PsString[] { function compileVerbWNegative(headRaw: T.PsString | undefined, restRaw: T.PsString[], negative: boolean): Segment[] {
function isLast(index: number, arr: any[]): boolean { const rest: Segment = {
return index === (arr.length - 1); isVerbRest: true,
} ps: restRaw.map(removeBa),
const first = loe[0]; };
const rest = loe.slice(1); const head: Segment | undefined = !headRaw
if (!rest.length) return first; ? headRaw
return combineSegments(rest).flatMap((r, restIndex, arr) => ( : {
first.map(ps => concatPsString( ps: [headRaw],
ps, isVerbHead: true,
(ps.isVerbPrefix && isLast(restIndex, arr) isOoHead: headRaw.p === "و"
? "" };
: ps.prefixFollowedByMiniPronoun
? { p: "", f: "-" }
: ps.isVerbPrefix ? " " : " "),
r,
))
));
}
function compileVerbWNegative(head: T.PsString | undefined, restRaw: T.PsString[], negative: boolean): ListOfSegments {
const rest = restRaw.map(removeBa);
if (!negative) { if (!negative) {
return [ return [
...head ? [[{...head, isVerbPrefix: true}]] : [], ...head ? [head] : [],
rest, rest,
]; ];
} }
const nu: T.PsString = { p: "نه", f: "nú" }; const nu: T.PsString = { p: "نه", f: "nú" };
if (!head) { if (!head) {
return [ return [
[nu], { ps: [nu], isNu: true },
rest.map(r => removeAccents(r)), {
...rest,
ps: rest.ps.map(p => removeAccents(p)),
},
]; ];
} }
// const regularPrefix = head.p === "و" || head.p === "وا";
// if (regularPrefix) {
// dashes for oo-nu etc
return [ return [
[{ ...removeAccents(head), isVerbPrefix: true }], ...head ? [{ ...head, ps: head.ps.map(h =>removeAccents(h)) }] : [],
rest.map(r => concatPsString(nu, " ", removeAccents(r))), {
...rest,
isNu: true,
ps: rest.ps.map(r => concatPsString(nu, " ", removeAccents(r))),
},
]; ];
} }
function combineSegments(loe: (Segment | " " | "" | "-")[]): T.PsString[] {
const first = loe[0];
const rest = loe.slice(1);
if (!rest.length) {
if (typeof first === "string") {
throw new Error("can't end with a spacer");
}
return first.ps;
}
function spaceOrDash(s: "" | " " | "-"): "" | " " | T.PsString {
return s === "-" ? { p: "", f: "-" } : s;
}
return combineSegments(rest).flatMap((r) => (
typeof first === "string"
? [concatPsString(spaceOrDash(first), r)]
: first.ps.map(f => concatPsString(f, r)
)
));
}
function compileEnglish(VP: VPRendered): string[] | undefined { function compileEnglish(VP: VPRendered): string[] | undefined {
function insertEWords(e: string, { subject, object }: { subject: string, object?: string }): string { function insertEWords(e: string, { subject, object }: { subject: string, object?: string }): string {
return e.replace("$SUBJ", subject).replace("$OBJ", object || ""); return e.replace("$SUBJ", subject).replace("$OBJ", object || "");

View File

@ -26,19 +26,3 @@ export function getPersonFromNP(np: NPSelection | ObjectNP): T.Person | undefine
export function removeBa(ps: T.PsString): T.PsString { export function removeBa(ps: T.PsString): T.PsString {
return psRemove(ps, concatPsString(grammarUnits.baParticle, " ")); return psRemove(ps, concatPsString(grammarUnits.baParticle, " "));
} }
export function isMiniPronoun(ps: T.PsString | undefined): boolean {
if (!ps) return false;
return isInVerbBlock(ps.p, grammarUnits.pronouns.mini);
}
/**
* returns true if the pashto text matches any item in a verb block
*
* @param vb
*/
function isInVerbBlock(p: string, vb: T.VerbBlock): boolean {
return vb.some((r) => (
r.some(x => x.some(y => y.p === p)
)));
}

View File

@ -1684,10 +1684,10 @@
pbf "^3.2.1" pbf "^3.2.1"
rambda "^6.7.0" rambda "^6.7.0"
"@lingdocs/pashto-inflector@^1.5.4": "@lingdocs/pashto-inflector@^1.5.5":
version "1.5.4" version "1.5.5"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.5.4.tgz#2ef3ebce061e62493f79b0b0862d1d9fb7954b40" resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.5.5.tgz#166e0181711cf019aef2e637bc798c3f41e8df8d"
integrity sha512-rvQuhld+Ioz5P1SsMKDoeT27RLSZN/r2qy4qm8JCpfPs3y/pFXmoTWhgnfXtbcZ8n2dy7UNiO3jTd4eCQXPsFA== integrity sha512-NK5slwLJrMTdS/whYoSjvtRQgN9vdy+PFJxecih7HgcaSEwfFVy+wxWXLwufznpGI4VCoDgIo4+gWNkNxvAt3Q==
dependencies: dependencies:
classnames "^2.2.6" classnames "^2.2.6"
pbf "^3.2.1" pbf "^3.2.1"