diff --git a/diagrams/diagram-light.png b/diagrams/diagram-light.png index b5379ed..521ad06 100644 Binary files a/diagrams/diagram-light.png and b/diagrams/diagram-light.png differ diff --git a/package-lock.json b/package-lock.json index 7459f74..44acb00 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pashto-inflector", - "version": "6.0.6", + "version": "6.0.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "pashto-inflector", - "version": "6.0.6", + "version": "6.0.7", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 889c744..aca1526 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pashto-inflector", - "version": "6.0.6", + "version": "6.0.7", "author": "lingdocs.com", "description": "A Pashto inflection and verb conjugation engine, inculding React components for displaying Pashto text, inflections, and conjugations", "homepage": "https://verbs.lingdocs.com", @@ -77,4 +77,4 @@ ] }, "dependencies": {} -} \ No newline at end of file +} diff --git a/src/components/package-lock.json b/src/components/package-lock.json index ec926ff..5edb3a3 100644 --- a/src/components/package-lock.json +++ b/src/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@lingdocs/ps-react", - "version": "6.0.6", + "version": "6.0.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@lingdocs/ps-react", - "version": "6.0.6", + "version": "6.0.7", "license": "MIT", "dependencies": { "@formkit/auto-animate": "^1.0.0-beta.3", diff --git a/src/components/package.json b/src/components/package.json index cfcab22..47a8888 100644 --- a/src/components/package.json +++ b/src/components/package.json @@ -1,6 +1,6 @@ { "name": "@lingdocs/ps-react", - "version": "6.0.6", + "version": "6.0.7", "description": "Pashto inflector library module with React components", "main": "dist/components/library.js", "module": "dist/components/library.js", diff --git a/src/lib/package.json b/src/lib/package.json index fba22a0..d7365c7 100644 --- a/src/lib/package.json +++ b/src/lib/package.json @@ -1,6 +1,6 @@ { "name": "@lingdocs/inflect", - "version": "6.0.6", + "version": "6.0.7", "description": "Pashto inflector library", "main": "dist/index.js", "types": "dist/lib/library.d.ts", diff --git a/src/lib/src/new-verb-engine/render-verb.test.ts b/src/lib/src/new-verb-engine/render-verb.test.ts index d6c2ef3..e3ec282 100644 --- a/src/lib/src/new-verb-engine/render-verb.test.ts +++ b/src/lib/src/new-verb-engine/render-verb.test.ts @@ -97,6 +97,9 @@ const sturayKawul = wordQuery("ستړی کول", "verb"); const raawrul = wordQuery("راوړل", "verb"); const ooPh: T.PH = { type: "PH", ps: { p: "و", f: "óo" } }; +// TODO: test all cases of یوړ یوړه یووړ یووړه +// and then parsing of all those!! + const tests: { label: string; cases: { @@ -1115,6 +1118,7 @@ test("special endings", () => { { p: "خوت", f: "khot" }, // // TODO: is this even right? // { p: "خوته", f: "khotu" }, + // { p: "خته", f: "khatu" }, ??? // { p: "خوتو", f: "khoto" }, ], }, @@ -1142,8 +1146,7 @@ test("special endings", () => { short: [ { p: "لید", f: "léed" }, // // TODO: is this even right? - // { p: "خوته", f: "khotu" }, - // { p: "خوتو", f: "khoto" }, + { p: "لیده", f: "leedú" }, ], }, person: 4, @@ -1167,7 +1170,10 @@ test("special endings", () => { type: "VB", ps: { long: [{ p: "وړلو", f: "wRulo" }], - short: [{ p: "ووړ", f: "woR" }], + short: [ + { p: "ووړ", f: "woR" }, + { p: "وړه", f: "wRu" }, + ], }, person: 4, info: { @@ -1180,6 +1186,32 @@ test("special endings", () => { ], ], }, + { + verb: raawrul, + tense: "imperfectivePast", + result: [ + [], + [ + { + type: "VB", + ps: { + long: [{ p: "راوړلو", f: "raawRúlo" }], + short: [ + { p: "راووړ", f: "raawóR" }, + { p: "راوړه", f: "raawRú" }, + ], + }, + person: 4, + info: { + type: "verb", + aspect: "imperfective", + base: "root", + verb: raawrul, + }, + }, + ], + ], + }, // verbs ending in a dental ت or د { verb: rasedul, diff --git a/src/lib/src/new-verb-engine/render-verb.ts b/src/lib/src/new-verb-engine/render-verb.ts index d855e85..05308ef 100644 --- a/src/lib/src/new-verb-engine/render-verb.ts +++ b/src/lib/src/new-verb-engine/render-verb.ts @@ -8,7 +8,9 @@ import { import { applySingleOrLengthOpts, fmapSingleOrLengthOpts } from "../fp-ps"; import { concatPsString, + endsInConsonant, getLength, + lastVowelNotAorO, splitPsByVarients, } from "../p-text-helpers"; import { @@ -116,7 +118,8 @@ const formulas: Record< }, }; -// TODO: dynamic and stative compounds +// TODO: is وخوته masc ok ?? +// TODO: what to do with khatu, khot, khotu - bi-directional export function renderVerb({ verb, tense, @@ -375,17 +378,40 @@ function ensure3rdPast( const tpps = splitPsByVarients( makePsString(verb.entry.tppp, verb.entry.tppf) ); - return tpps.map(({ p, f }) => { - const tip = removeAccents( - verb.entry.separationAtP !== undefined + if (verb.entry.p === "وړل" && aspect === "perfective") { + return [ + { p: "ړ", f: "R" }, + { p: "ړ", f: "Ru" }, + { p: "وړ", f: "wuR" }, + { p: "وړه", f: "wRu" }, + ]; + } + return tpps + .flatMap(({ p, f }) => { + if (p.endsWith("ووړ")) { + return [ + { p, f }, + { p: p.slice(0, -2) + "ړه", f: f.slice(0, -2) + "Ru" }, + ]; + } + return [{ p, f }]; + }) + .map(({ p, f }) => + verb.entry.separationAtP !== undefined && aspect === "perfective" ? makePsString( p.slice(verb.entry.separationAtP), f.slice(verb.entry.separationAtF) ) : makePsString(p, f) + ) + .flatMap((ps) => + endsInConsonant(ps) && lastVowelNotAorO(ps.f) + ? [ps, concatPsString(ps, { p: "ه", f: "u" })] + : [ps] + ) + .map((ps) => + aspect === "imperfective" ? accentOnNFromEnd(ps, 0) : removeAccents(ps) ); - return aspect === "imperfective" ? accentOnNFromEnd(tip, 0) : tip; - }); // if it ends in a consonant, the special form will also have another // variation ending with a ه - u // const endsInAConsonant = (pashtoConsonants.includes(tip.p.slice(-1)) || tip.f.slice(-1) === "w"); diff --git a/src/lib/src/p-text-helpers.ts b/src/lib/src/p-text-helpers.ts index 6ced86e..109f831 100644 --- a/src/lib/src/p-text-helpers.ts +++ b/src/lib/src/p-text-helpers.ts @@ -1250,3 +1250,13 @@ export function lastVowelNotA(g: string): boolean { } return matches[matches.length - 1] !== "a"; } + +export function lastVowelNotAorO(g: string): boolean { + const matches = g.match(/ee|aa|i|u|o|oo|U|e|a/g); + if (!matches) { + return true; + } + return ( + matches[matches.length - 1] !== "a" && matches[matches.length - 1] !== "o" + ); +} diff --git a/src/lib/src/phrase-building/compile.ts b/src/lib/src/phrase-building/compile.ts index 3cd4b4f..722430c 100644 --- a/src/lib/src/phrase-building/compile.ts +++ b/src/lib/src/phrase-building/compile.ts @@ -6,7 +6,7 @@ import { } from "../p-text-helpers"; import { negativeParticle } from "../grammar-units"; import * as grammarUnits from "../grammar-units"; -import { removeDuplicates } from "./vp-tools"; +import { ensureNoHangingR, removeDuplicates } from "./vp-tools"; import { getEnglishFromRendered, getPashtoFromRendered } from "./np-tools"; import { completeEPSelection, renderEP } from "./render-ep"; import { completeVPSelection } from "./vp-tools"; @@ -391,7 +391,7 @@ function putKidsInKidsSection( return [ first, ...(enforceKidsSectionBlankout ? [kidsBlank] : kids), - ...rest, + ...ensureNoHangingR(rest), ]; } return blocksWVars.map(insert); diff --git a/src/lib/src/phrase-building/render-np.ts b/src/lib/src/phrase-building/render-np.ts index 2641a6d..177dc83 100644 --- a/src/lib/src/phrase-building/render-np.ts +++ b/src/lib/src/phrase-building/render-np.ts @@ -20,6 +20,8 @@ import { accentOnNFromEnd } from "../accent-helpers"; // like زما د ښځو لیدل // my seeing women... +// seeing my women... +// the women seeing me... export function renderNPSelection( NP: T.NPSelection, diff --git a/src/lib/src/phrase-building/render-vp.ts b/src/lib/src/phrase-building/render-vp.ts index ea85e04..e8a9601 100644 --- a/src/lib/src/phrase-building/render-vp.ts +++ b/src/lib/src/phrase-building/render-vp.ts @@ -1,7 +1,7 @@ import * as T from "../../../types"; import { mapVerbRenderedOutput } from "../fp-ps"; import { removeAccents } from "../accent-helpers"; -import { getPersonFromNP, isPastTense } from "./vp-tools"; +import { ensureNoHangingR, getPersonFromNP, isPastTense } from "./vp-tools"; import { isImperativeTense, isPattern4Entry } from "../type-predicates"; import { renderVerb } from "../new-verb-engine/render-verb"; import { renderEnglishVPBase } from "./english-vp-rendering"; @@ -21,6 +21,9 @@ import { import { renderComplementSelection } from "./render-complement"; import { statVerb } from "../new-verb-engine/roots-and-stems"; +// TODO: Issue with yo me R -- both in rendering (what to do - یوړ مې) +// and in parsing! + export function renderVP(VP: T.VPSelectionComplete): T.VPRendered { const subject = getSubjectSelection(VP.blocks).selection; const object = getObjectSelection(VP.blocks).selection; @@ -172,25 +175,6 @@ export function insertNegative( } } -function ensureNoHangingR(b: T.Block[]): T.Block[] { - return b.map((x) => - x.block.type === "VB" && - "short" in x.block.ps && - x.block.ps.short.find((x) => x.p === "ړ") - ? { - ...x, - block: { - ...x.block, - ps: { - ...x.block.ps, - short: x.block.ps.short.filter((ps) => ps.p !== "ړ"), - }, - }, - } - : x - ); -} - function swapEndingBlocks(arr: X[], n: number = 1): X[] { return [ ...arr.slice(0, arr.length - (n + 1)), diff --git a/src/lib/src/phrase-building/vp-tools.ts b/src/lib/src/phrase-building/vp-tools.ts index 85278b2..e7b355b 100644 --- a/src/lib/src/phrase-building/vp-tools.ts +++ b/src/lib/src/phrase-building/vp-tools.ts @@ -361,3 +361,22 @@ export function ensure2ndPersSubjPronounAndNoConflict( } throw new Error("error ensuring compatible VPSelection for imperative verb"); } + +export function ensureNoHangingR(b: T.Block[]): T.Block[] { + return b.map((x) => + x.block.type === "VB" && + "short" in x.block.ps && + x.block.ps.short.find((x) => x.p === "ړ") + ? { + ...x, + block: { + ...x.block, + ps: { + ...x.block.ps, + short: x.block.ps.short.filter((ps) => ps.p !== "ړ"), + }, + }, + } + : x + ); +}