From ba06fdf14f38ea2a6522efea4865c1e411104798 Mon Sep 17 00:00:00 2001 From: adueck Date: Thu, 23 Jan 2025 16:52:36 -0500 Subject: [PATCH] mayo working on sandwiches --- package-lock.json | 4 +- package.json | 2 +- src/components/package.json | 2 +- src/components/src/vp-explorer/NPDisplay.tsx | 3 +- .../src/vp-explorer/chart-builder.tsx | 2 +- src/lib/package.json | 2 +- src/lib/src/phrase-building/mayo-utils.ts | 29 +++++ src/lib/src/phrase-building/render-adj.ts | 121 +++++++++++------- src/lib/src/phrase-building/render-ap.ts | 86 +++++++------ .../src/phrase-building/render-complement.ts | 75 ++++++----- src/lib/src/phrase-building/render-ep.ts | 6 +- src/lib/src/phrase-building/render-np.ts | 45 ++++--- .../src/phrase-building/render-sandwich.ts | 42 +++--- src/lib/src/phrase-building/render-vp.ts | 6 +- src/lib/src/sandwiches.ts | 101 ++++++++++++--- src/types.ts | 1 + 16 files changed, 343 insertions(+), 184 deletions(-) create mode 100644 src/lib/src/phrase-building/mayo-utils.ts diff --git a/package-lock.json b/package-lock.json index 3902de02..345e9588 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pashto-inflector-website", - "version": "7.7.9", + "version": "7.7.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pashto-inflector-website", - "version": "7.7.9", + "version": "7.7.10", "dependencies": { "@fortawesome/fontawesome-free": "^5.15.2", "bootstrap": "4.6.1", diff --git a/package.json b/package.json index f2c6e44a..152b3034 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pashto-inflector-website", - "version": "7.7.9", + "version": "7.7.10", "type": "module", "scripts": { "patch": "npm version patch --no-git-tag-version && cd src/lib && npm version patch --no-git-tag-version && cd ../components && npm version patch --no-git-tag-version", diff --git a/src/components/package.json b/src/components/package.json index 405dcc94..b69f48c4 100644 --- a/src/components/package.json +++ b/src/components/package.json @@ -1,6 +1,6 @@ { "name": "@lingdocs/ps-react", - "version": "7.7.9", + "version": "7.7.10", "description": "Pashto inflector library module with React components", "main": "dist/components/library-cjs.js", "module": "dist/components/library.js", diff --git a/src/components/src/vp-explorer/NPDisplay.tsx b/src/components/src/vp-explorer/NPDisplay.tsx index ceeec34f..1e3991e7 100644 --- a/src/components/src/vp-explorer/NPDisplay.tsx +++ b/src/components/src/vp-explorer/NPDisplay.tsx @@ -38,7 +38,8 @@ function NPDisplay({ false, "subject", "none", - false + false, + "no" ); const english = getEnglishFromRendered(rendered); const pashto = getPashtoFromRendered(rendered, false); diff --git a/src/components/src/vp-explorer/chart-builder.tsx b/src/components/src/vp-explorer/chart-builder.tsx index c3582562..7de0b812 100644 --- a/src/components/src/vp-explorer/chart-builder.tsx +++ b/src/components/src/vp-explorer/chart-builder.tsx @@ -34,7 +34,7 @@ export function buildVerbChart({ : ([...Array(12).keys()] as T.Person[]); const isPast = isPastTense(tense); const objNP: T.Rendered | undefined = objectNP - ? renderNPSelection(objectNP, false, false, "object", "none", false) + ? renderNPSelection(objectNP, false, false, "object", "none", false, "no") : undefined; function conjugateAllPers( p?: T.Person diff --git a/src/lib/package.json b/src/lib/package.json index 782dfba8..e162c0ff 100644 --- a/src/lib/package.json +++ b/src/lib/package.json @@ -1,6 +1,6 @@ { "name": "@lingdocs/inflect", - "version": "7.7.9", + "version": "7.7.10", "description": "Pashto inflector library", "main": "dist/lib/library.cjs", "module": "dist/lib/library.js", diff --git a/src/lib/src/phrase-building/mayo-utils.ts b/src/lib/src/phrase-building/mayo-utils.ts new file mode 100644 index 00000000..82764ec8 --- /dev/null +++ b/src/lib/src/phrase-building/mayo-utils.ts @@ -0,0 +1,29 @@ +import * as T from "../../../types"; +import { endsWith, psStringFromEntry } from "../p-text-helpers"; +import { isPattern1Entry } from "../type-predicates"; +import { accentOnNFromEnd, countSyllables } from "../accent-helpers"; +import { monoidPsString } from "../fp-ps"; +import { concatAll } from "fp-ts/lib/Monoid"; + +export function mayoOnWord( + isMayoSandwich: "req" | "opt" | "no" | undefined, + entry: T.InflectableEntry, + gender: T.Gender, + number: T.NounNumber +): "req" | "opt" | "no" { + return isMayoSandwich && + isMayoSandwich !== "no" && + isPattern1Entry(entry) && + number === "singular" && + gender === "masc" && + !endsWith(entry, { p: "ه", f: "u" }) + ? isMayoSandwich + : "no"; +} + +export function addMayo(entry: T.InflectableEntry, req: boolean): T.PsString[] { + const base = psStringFromEntry(entry); + const ps1 = concatAll(monoidPsString)([base, { p: "ه", f: "a" }]); + const ps = countSyllables(base) === 1 ? accentOnNFromEnd(ps1, 1) : ps1; + return [ps, ...(!req ? [base] : [])]; +} diff --git a/src/lib/src/phrase-building/render-adj.ts b/src/lib/src/phrase-building/render-adj.ts index ab2fe44b..d78b4b80 100644 --- a/src/lib/src/phrase-building/render-adj.ts +++ b/src/lib/src/phrase-building/render-adj.ts @@ -1,60 +1,85 @@ import * as T from "../../../types"; import { inflectWord } from "../pashto-inflector"; -import { - psStringFromEntry, - isUnisexSet, -} from "../p-text-helpers"; +import { psStringFromEntry, isUnisexSet } from "../p-text-helpers"; import { getEnglishWord } from "../get-english-word"; -import { - personGender, - personIsPlural, -} from "../misc-helpers"; +import { personGender, personIsPlural } from "../misc-helpers"; import { renderSandwich } from "./render-sandwich"; import { isPattern1Entry } from "../type-predicates"; +import { addMayo, mayoOnWord } from "./mayo-utils"; -function chooseInflection(inflections: T.UnisexSet, pers: T.Person, inflected?: boolean): T.ArrayOneOrMore { - const gender = personGender(pers); - const plural = personIsPlural(pers); - const infNumber = (plural ? 1 : 0) + (inflected ? 1 : 0); - return inflections[gender][infNumber]; +function chooseInflection( + inflections: T.UnisexSet, + pers: T.Person, + inflected?: boolean +): T.ArrayOneOrMore { + const gender = personGender(pers); + const plural = personIsPlural(pers); + const infNumber = (plural ? 1 : 0) + (inflected ? 1 : 0); + return inflections[gender][infNumber]; } -export function inflectAdvAdj(a: T.AdjectiveSelection | T.AdverbSelection, person: T.Person, inflected: boolean): T.ArrayOneOrMore { - const infs = inflectWord(a.entry); - if (!infs) { - return [psStringFromEntry(a.entry)]; - } - if (!infs.inflections || !isUnisexSet(infs.inflections)) { - throw new Error("error getting inflections for adjective, looks like a noun's inflections"); - } - return chooseInflection(infs.inflections, person, inflected); +export function inflectAdvAdj( + a: T.AdjectiveSelection | T.AdverbSelection, + person: T.Person, + inflected: boolean, + mayo: "req" | "opt" | "no" +): T.ArrayOneOrMore { + if (mayo !== "no") { + return addMayo(a.entry, mayo === "req") as T.ArrayOneOrMore; + } + const infs = inflectWord(a.entry); + if (!infs) { + return [psStringFromEntry(a.entry)]; + } + if (!infs.inflections || !isUnisexSet(infs.inflections)) { + throw new Error( + "error getting inflections for adjective, looks like a noun's inflections" + ); + } + return chooseInflection(infs.inflections, person, inflected); } -export function inflectAdjective(a: T.AdjectiveSelection, person: T.Person, inflected: boolean): T.ArrayOneOrMore { - return inflectAdvAdj(a, person, inflected) +export function inflectAdjective( + a: T.AdjectiveSelection, + person: T.Person, + inflected: boolean, + mayo: "req" | "opt" | "no" +): T.ArrayOneOrMore { + return inflectAdvAdj(a, person, inflected, mayo); } -export function renderAdjectiveSelection(a: T.AdjectiveSelection, person: T.Person, inflected: boolean, isLocationSingSandwich?: boolean): T.Rendered { - const eWord = getEnglishWord(a.entry); - const e = !eWord - ? undefined - : typeof eWord === "string" - ? eWord - : (eWord.singular || undefined); - const ps = inflectAdjective( - a, - person, - isLocationSingSandwich && isPattern1Entry(a.entry) - ? false - : inflected, - ); - return { - type: "adjective", - entry: a.entry, - ps, - e, - inflected, - person, - sandwich: a.sandwich ? renderSandwich(a.sandwich) : undefined, - }; -} \ No newline at end of file +export function renderAdjectiveSelection( + a: T.AdjectiveSelection, + person: T.Person, + inflected: boolean, + isLocationSingSandwich: boolean, + mayo: "req" | "opt" | "no" +): T.Rendered { + const eWord = getEnglishWord(a.entry); + const e = !eWord + ? undefined + : typeof eWord === "string" + ? eWord + : eWord.singular || undefined; + const toAddMayo = mayoOnWord( + mayo, + a.entry, + personGender(person), + personIsPlural(person) ? "plural" : "singular" + ); + const ps = inflectAdjective( + a, + person, + isLocationSingSandwich && isPattern1Entry(a.entry) ? false : inflected, + toAddMayo + ); + return { + type: "adjective", + entry: a.entry, + ps, + e, + inflected, + person, + sandwich: a.sandwich ? renderSandwich(a.sandwich) : undefined, + }; +} diff --git a/src/lib/src/phrase-building/render-ap.ts b/src/lib/src/phrase-building/render-ap.ts index 9ca8f042..d26d94e7 100644 --- a/src/lib/src/phrase-building/render-ap.ts +++ b/src/lib/src/phrase-building/render-ap.ts @@ -5,50 +5,54 @@ import { isAdjectiveEntry } from "../type-predicates"; import { inflectAdvAdj } from "./render-adj"; import { renderSandwich } from "./render-sandwich"; -export function renderAPSelection({ selection }: T.APSelection, person: T.Person): T.Rendered { - if (selection.type === "sandwich") { - return { - type: "AP", - selection: renderSandwich(selection), - }; - } +export function renderAPSelection( + { selection }: T.APSelection, + person: T.Person +): T.Rendered { + if (selection.type === "sandwich") { return { - type: "AP", - selection: renderAdverbSelection(selection, person), + type: "AP", + selection: renderSandwich(selection), }; + } + return { + type: "AP", + selection: renderAdverbSelection(selection, person), + }; } -export function renderLocativeAdverbSelection({ entry }: T.LocativeAdverbSelection): T.Rendered { - const e = getEnglishWord(entry); - if (!e || typeof e !== "string") { - throw new Error("error getting english for compliment"); - } - return { - type: "loc. adv.", - entry: entry, - ps: [psStringFromEntry(entry)], - e, - inflected: false, - // TODO: don't use persons for these - person: T.Person.FirstSingMale, - role: "none", - }; +export function renderLocativeAdverbSelection({ + entry, +}: T.LocativeAdverbSelection): T.Rendered { + const e = getEnglishWord(entry); + if (!e || typeof e !== "string") { + throw new Error("error getting english for compliment"); + } + return { + type: "loc. adv.", + entry: entry, + ps: [psStringFromEntry(entry)], + e, + inflected: false, + // TODO: don't use persons for these + person: T.Person.FirstSingMale, + role: "none", + }; } -export function renderAdverbSelection(a: T.AdverbSelection, person: T.Person): T.Rendered { - const ew = getEnglishWord(a.entry); - const e = typeof ew === "object" - ? (ew.singular || "") - : !ew - ? "" - : ew; - return { - type: "adverb", - entry: a.entry, - ps: isAdjectiveEntry(a.entry) - ? inflectAdvAdj(a, person, false) - : [psStringFromEntry(a.entry)], - person, - e, - }; -} \ No newline at end of file +export function renderAdverbSelection( + a: T.AdverbSelection, + person: T.Person +): T.Rendered { + const ew = getEnglishWord(a.entry); + const e = typeof ew === "object" ? ew.singular || "" : !ew ? "" : ew; + return { + type: "adverb", + entry: a.entry, + ps: isAdjectiveEntry(a.entry) + ? inflectAdvAdj(a, person, false, "no") + : [psStringFromEntry(a.entry)], + person, + e, + }; +} diff --git a/src/lib/src/phrase-building/render-complement.ts b/src/lib/src/phrase-building/render-complement.ts index f57412bf..ce220f74 100644 --- a/src/lib/src/phrase-building/render-complement.ts +++ b/src/lib/src/phrase-building/render-complement.ts @@ -4,38 +4,47 @@ import { renderAdjectiveSelection } from "./render-adj"; import { renderSandwich } from "./render-sandwich"; import { renderLocativeAdverbSelection } from "./render-ap"; -export function renderComplementSelection(s: T.ComplementSelection | T.UnselectedComplementSelection, person: T.Person): T.Rendered { - if (s.selection.type === "unselected") { - return { - type: "complement", - selection: { - type: "unselected", - ps: [{ p: "____", f: "____" }], - e: "____", - }, - }; - } - if (s.selection.type === "sandwich") { - return { - type: "complement", - selection: renderSandwich(s.selection), - }; - } - if (s.selection.type === "loc. adv.") { - return { - type: "complement", - selection: renderLocativeAdverbSelection(s.selection), - }; - } - if (s.selection.type === "adjective") { - return { - type: "complement", - selection: renderAdjectiveSelection(s.selection, person, false), - }; - } - // if (s.selection.type === "noun") { +export function renderComplementSelection( + s: T.ComplementSelection | T.UnselectedComplementSelection, + person: T.Person +): T.Rendered { + if (s.selection.type === "unselected") { return { - type: "complement", - selection: renderNounSelection(s.selection, false, "none", "noArticles"), + type: "complement", + selection: { + type: "unselected", + ps: [{ p: "____", f: "____" }], + e: "____", + }, }; -} \ No newline at end of file + } + if (s.selection.type === "sandwich") { + return { + type: "complement", + selection: renderSandwich(s.selection), + }; + } + if (s.selection.type === "loc. adv.") { + return { + type: "complement", + selection: renderLocativeAdverbSelection(s.selection), + }; + } + if (s.selection.type === "adjective") { + return { + type: "complement", + selection: renderAdjectiveSelection( + s.selection, + person, + false, + false, + "no" + ), + }; + } + // if (s.selection.type === "noun") { + return { + type: "complement", + selection: renderNounSelection(s.selection, false, "none", "noArticles"), + }; +} diff --git a/src/lib/src/phrase-building/render-ep.ts b/src/lib/src/phrase-building/render-ep.ts index c4468e2a..4ff3e992 100644 --- a/src/lib/src/phrase-building/render-ep.ts +++ b/src/lib/src/phrase-building/render-ep.ts @@ -61,7 +61,8 @@ function getEPSBlocksAndKids(EP: T.EPSelectionComplete): { false, "subject", "king", - false + false, + "no" ) : // we won't have an unselected complement in the EP - TODO: make safer? (renderComplementSelection( @@ -172,7 +173,8 @@ function renderEPSBlocks(blocks: T.EPSBlockComplete[]): T.Block[] { false, "subject", "none", - false + false, + "no" ), }); }); diff --git a/src/lib/src/phrase-building/render-np.ts b/src/lib/src/phrase-building/render-np.ts index b2262f72..6c3a54b1 100644 --- a/src/lib/src/phrase-building/render-np.ts +++ b/src/lib/src/phrase-building/render-np.ts @@ -16,6 +16,7 @@ import { removeL } from "../new-verb-engine/rs-helpers"; import { applySingleOrLengthOpts } from "../fp-ps"; import { accentOnNFromEnd } from "../accent-helpers"; import { getInfsAndVocative } from "../inflections-and-vocative"; +import { addMayo, mayoOnWord } from "./mayo-utils"; // TODO: can have subject and objects in possesors!! @@ -30,7 +31,8 @@ export function renderNPSelection( inflectEnglish: boolean, role: "subject", soRole: "servant" | "king" | "none", - isPuSandwich: boolean + isPuSandwich: boolean, + isMayoSandwich: "req" | "opt" | "no" ): T.Rendered; export function renderNPSelection( NP: T.NPSelection, @@ -38,7 +40,8 @@ export function renderNPSelection( inflectEnglish: boolean, role: "object", soRole: "servant" | "king" | "none", - isPuSandwich: boolean + isPuSandwich: boolean, + isMayoSandwich: "req" | "opt" | "no" ): T.Rendered; export function renderNPSelection( NP: T.NPSelection, @@ -46,7 +49,8 @@ export function renderNPSelection( inflectEnglish: boolean, role: "subject" | "object", soRole: "servant" | "king" | "none", - isPuSandwich: boolean + isPuSandwich: boolean, + isMayoSandwich: "req" | "opt" | "no" ): T.Rendered { if (typeof NP !== "object") { if (role !== "object") { @@ -62,7 +66,8 @@ export function renderNPSelection( inflected, soRole, undefined, - isPuSandwich + isPuSandwich, + isMayoSandwich ), }; } @@ -91,14 +96,20 @@ export function renderNounSelection( inflected: boolean, role: "servant" | "king" | "none", noArticles?: true | "noArticles", - isPuSandwich?: boolean + isPuSandwich?: boolean, + isMayoSandwich?: "req" | "opt" | "no" ): T.Rendered { const english = getEnglishFromNoun(n.entry, n.number, noArticles); + const isPattern1 = isPattern1Entry(n.entry); const nounInflects = - inflected && - !(isPuSandwich && isPattern1Entry(n.entry) && n.number === "singular"); + inflected && !(isPuSandwich && isPattern1 && n.number === "singular"); + const mayo = mayoOnWord(isMayoSandwich, n.entry, n.gender, n.number); const pashto = ((): T.PsString[] => { + if (mayo !== "no") { + return addMayo(n.entry, mayo === "req"); + } const infs = inflectWord(n.entry); + // TODO: get optional mayo const ps = n.number === "singular" ? getInf(infs, "inflections", n.gender, false, nounInflects) @@ -137,7 +148,11 @@ export function renderNounSelection( a, person, inflected, - isPuSandwich && n.number === "singular" + isPuSandwich && n.number === "singular" ? true : false, + // TODO: This is not the best because the variations of optional and inflecting adjectives in the + // sandwich aren't fully accurate - but to get the variations properly we need to think of a way + // for the adjective and noun rendering / compiling to talk to each other better + mayo === "opt" ? "no" : mayo ) ), person, @@ -334,7 +349,8 @@ function renderPossesor( possesorRole === "subj/obj" ? true : false, "subject", possesorRole === "subj/obj" ? "none" : possesorRole, - false + false, + "no" ), }; } @@ -347,7 +363,7 @@ function getBasicInf( ): T.PsString[] | false { const inflectionNumber = (inflected ? 1 : 0) + (number === "plural" ? 1 : 0); if (gender in infs) { - // @ts-ignore + // @ts-expect-error - bexpect-error - because return infs[gender][inflectionNumber]; } return false; @@ -361,18 +377,17 @@ function getInf( inflected: boolean ): T.PsString[] { // TODO: make this safe!! - // @ts-ignore if ( infs && t in infs && - // @ts-ignore + // @ts-expect-error - because infs[t] !== undefined && - // @ts-ignore + // @ts-expect-error - because gender in infs[t] && - // @ts-ignore + // @ts-expect-error - because infs[t][gender] !== undefined ) { - // @ts-ignore + // @ts-expect-error - because const iset = infs[t][gender] as T.InflectionSet; const inflectionNumber = (inflected ? 1 : 0) + (t === "inflections" && plural ? 1 : 0); diff --git a/src/lib/src/phrase-building/render-sandwich.ts b/src/lib/src/phrase-building/render-sandwich.ts index 9888ecb9..e1d11e20 100644 --- a/src/lib/src/phrase-building/render-sandwich.ts +++ b/src/lib/src/phrase-building/render-sandwich.ts @@ -2,23 +2,31 @@ import * as T from "../../../types"; import { isPattern5Entry, isAnimNounEntry } from "../type-predicates"; import { renderNPSelection } from "./render-np"; -export function renderSandwich(s: T.SandwichSelection): T.Rendered> { - const inflectInside: boolean | "locationSandwich" = (s.inside.selection.type === "noun" && isPattern5Entry(s.inside.selection.entry) && isAnimNounEntry(s.inside.selection.entry)) - ? false - : true; - return { - ...s, - inside: renderNPSelection( - s.inside, - true, - inflectInside, - "subject", - "none", - isPuLocationSandwich(s), - ), - }; +export function renderSandwich( + s: T.SandwichSelection +): T.Rendered> { + const inflectInside: boolean | "locationSandwich" = + s.inside.selection.type === "noun" && + isPattern5Entry(s.inside.selection.entry) && + isAnimNounEntry(s.inside.selection.entry) + ? false + : true; + return { + ...s, + inside: renderNPSelection( + s.inside, + true, + inflectInside, + "subject", + "none", + isPuLocationSandwich(s), + s.mayo ? (s.after ? "opt" : "req") : "no" + ), + }; } function isPuLocationSandwich(s: T.SandwichSelection): boolean { - return s.before?.p === "په" && !!["کې", "کښې", "باندې"].includes(s.after?.p || "") -} \ No newline at end of file + return ( + s.before?.p === "په" && !!["کې", "کښې", "باندې"].includes(s.after?.p || "") + ); +} diff --git a/src/lib/src/phrase-building/render-vp.ts b/src/lib/src/phrase-building/render-vp.ts index e8a96019..326405d2 100644 --- a/src/lib/src/phrase-building/render-vp.ts +++ b/src/lib/src/phrase-building/render-vp.ts @@ -242,7 +242,8 @@ function renderVPBlocks( false, "subject", config.king === "subject" ? "king" : "servant", - false + false, + "no" ), }), ]; @@ -264,7 +265,8 @@ function renderVPBlocks( true, "object", config.king === "object" ? "king" : "servant", - false + false, + "no" ); return [ ...blocks, diff --git a/src/lib/src/sandwiches.ts b/src/lib/src/sandwiches.ts index 9f72bb23..7473c2a1 100644 --- a/src/lib/src/sandwiches.ts +++ b/src/lib/src/sandwiches.ts @@ -1,138 +1,201 @@ import * as T from "../../types"; export const sandwiches: T.Sandwich[] = [ - { - type: "sandwich", - before: { p: "له", f: "la" }, - after: { p: "نه", f: "na" }, - e: "from", - }, - { - type: "sandwich", - before: { p: "له", f: "la" }, - after: { p: "څخه", f: "tsuxa" }, - e: "from", - }, - // TODO: Implement mayonaise - // { - // type: "sandwich", - // before: { p: "له", f: "la" }, - // after: "mayonaise", - // e: "from", - // }, { type: "sandwich", before: { p: "له", f: "la" }, after: { p: "سره", f: "sara" }, e: "with", + mayo: false, }, { type: "sandwich", before: undefined, after: { p: "ته", f: "ta" }, e: "to", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "لپاره", f: "lapaara" }, e: "for", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "دمخې", f: "dumúkhe" }, e: "before/in front of", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "په څانګ", f: "pu tsaang" }, e: "beside", + mayo: false, }, { type: "sandwich", before: { p: "پر", f: "pur" }, after: { p: "باندې", f: "baande" }, e: "on", + mayo: false, }, { type: "sandwich", before: { p: "په", f: "pu" }, after: { p: "کې", f: "ke" }, e: "in", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "دننه", f: "dununa" }, e: "inside", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "دباندې", f: "dubaande" }, e: "outside", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "مخې ته", f: "mukhe ta" }, e: "in front of", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "شا ته", f: "shaa ta" }, e: "behind", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "لاندې", f: "laande" }, e: "under", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "په شان", f: "pu shaan" }, e: "like", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "غوندې", f: "ghwunde" }, e: "like", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "په حیث", f: "pu hays" }, e: "as", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "په لور", f: "pu lor" }, e: "towards", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "په اړه", f: "pu aRa" }, e: "about", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "په باره کې", f: "pu baara ke" }, e: "about", + mayo: false, }, { type: "sandwich", before: { p: "د", f: "du" }, after: { p: "په اړوند", f: "pu aRwand" }, e: "concerning", + mayo: false, + }, + { + type: "sandwich", + before: { p: "له", f: "la" }, + after: { p: "نه", f: "na" }, + e: "from", + mayo: true, + }, + { + type: "sandwich", + before: { p: "له", f: "la" }, + after: undefined, + e: "from", + mayo: true, + }, + { + type: "sandwich", + before: { p: "له", f: "la" }, + after: { p: "څخه", f: "tsuxa" }, + e: "from", + mayo: true, + }, + { + type: "sandwich", + before: { p: "بې", f: "be" }, + after: undefined, + e: "without", + mayo: true, + }, + { + type: "sandwich", + before: { p: "بې له", f: "be la" }, + after: undefined, + e: "without", + mayo: true, + }, + { + type: "sandwich", + before: { p: "له", f: "la" }, + after: { p: "پرته", f: "práta" }, + e: "without", + mayo: true, + }, + { + type: "sandwich", + before: { p: "پرته له", f: "práta la" }, + after: undefined, + e: "without", + mayo: true, + }, + { + type: "sandwich", + before: { p: "تر", f: "tur" }, + after: undefined, + e: "until/up to", + mayo: true, + }, + { + type: "sandwich", + before: { p: "تر", f: "tur" }, + after: { p: "پورې", f: "póre" }, + e: "until/up to", + mayo: true, }, ]; diff --git a/src/types.ts b/src/types.ts index 0d39da33..0d65da64 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1187,6 +1187,7 @@ export type Sandwich = { type: "sandwich"; before: PsString | undefined; after: PsString | undefined; + mayo: boolean; e: string; };