diff --git a/src/components/equative-explorer/EquativeDisplay.tsx b/src/components/equative-explorer/EquativeDisplay.tsx
index b5383dc..7b546b2 100644
--- a/src/components/equative-explorer/EquativeDisplay.tsx
+++ b/src/components/equative-explorer/EquativeDisplay.tsx
@@ -10,18 +10,13 @@ import {
ExplorerState,
ExplorerReducerAction,
} from "./explorer-types";
-// import {
-// makeBlockWPronouns,
-// } from "./explorer-helpers";
import {
equativeMachine,
assembleEquativeOutput,
} from "../../lib/equative-machine";
import {
- isPluralNounEntry,
isUnisexNounEntry,
isAdjectiveEntry,
- isSingularEntry,
isVerbEntry,
isLocativeAdverbEntry,
isNounEntry,
@@ -47,6 +42,7 @@ function SingleItemDisplay({ state }: { state: ExplorerState }) {
subject,
predicate,
tense: state.tense,
+ negative: state.negative,
})
);
return
@@ -72,56 +68,27 @@ function makeNounPhrase(entry: NounEntry | UnisexNounEntry | VerbEntry, state: E
entry,
};
}
- const isUnisex = isUnisexNounEntry(entry);
- if (isUnisex && isSingularEntry(entry)) {
- return {
- type: "unisex noun",
- number: state[entity].info.number,
- gender: state[entity].info.gender,
- entry,
- };
- }
- if (isUnisex && isPluralNounEntry(entry)) {
- return {
- type: "unisex noun",
- number: state[entity].info.number,
- gender: state[entity].info.gender,
- entry,
- };
- }
- if (isUnisex) {
- throw new Error("improper unisex noun");
- }
- if (isPluralNounEntry(entry)) {
- const e = entry as PluralNounEntry
;
- return {
- type: "plural noun",
- entry: e,
- };
- }
- if (isSingularEntry(entry)) {
- const e = entry as SingularEntry;
- return {
- type: "singular noun",
- entry: e,
- number: state[entity].info.number,
- };
- }
- throw new Error("unable to make subject input from entry");
+ return {
+ type: "noun",
+ number: state[entity].info.number,
+ gender: state[entity].info.gender,
+ entry,
+ };
}
-export function makeBlockWPronouns(e: AdjectiveEntry | UnisexNounEntry | LocativeAdverbEntry, tense: EquativeTense, length?: "short" | "long"): T.SingleOrLengthOpts {
+export function makeBlockWPronouns(e: AdjectiveEntry | UnisexNounEntry | LocativeAdverbEntry, tense: EquativeTense, negative: boolean, length?: "short" | "long"): T.SingleOrLengthOpts {
// if the output's gonna have long / short forms (if it's past or wouldBe) then recursive call to make the long and short versions
if (!length && "long" in assembleEquativeOutput(equativeMachine({
subject: { type: "pronoun", pronounType: "near", person: 0 },
predicate: (isAdjectiveEntry(e) || isLocativeAdverbEntry(e))
? { type: "compliment", entry: e }
- : { type: "unisex noun", gender: "masc", number: "singular", entry: e },
+ : { type: "noun", gender: "masc", number: "singular", entry: e },
tense,
+ negative,
}))) {
return {
- short: makeBlockWPronouns(e, tense, "short") as T.VerbBlock,
- long: makeBlockWPronouns(e, tense, "long") as T.VerbBlock,
+ short: makeBlockWPronouns(e, tense, negative, "short") as T.VerbBlock,
+ long: makeBlockWPronouns(e, tense, negative, "long") as T.VerbBlock,
};
}
const makeP = (p: T.Person): T.ArrayOneOrMore => {
@@ -129,8 +96,9 @@ export function makeBlockWPronouns(e: AdjectiveEntry | UnisexNounEntry | Locativ
subject: { type: "pronoun", pronounType: "far", person: p },
predicate: (isAdjectiveEntry(e) || isLocativeAdverbEntry(e))
? { type: "compliment", entry: e }
- : { type: "unisex noun", gender: personGender(p), number: personIsPlural(p) ? "plural" : "singular", entry: e },
+ : { type: "noun", gender: personGender(p), number: personIsPlural(p) ? "plural" : "singular", entry: e },
tense,
+ negative,
}));
if ("long" in b) {
if (!length) throw new Error("bad length processing");
@@ -151,7 +119,7 @@ export function makeBlockWPronouns(e: AdjectiveEntry | UnisexNounEntry | Locativ
function PronounBlockDisplay({ state }: { state: ExplorerState }) {
const pred = state.predicate[state.predicate.type];
if (!isVerbEntry(pred) && (isAdjectiveEntry(pred) || isLocativeAdverbEntry(pred) || (isNounEntry(pred) && isUnisexNounEntry(pred)))) {
- const block = makeBlockWPronouns(pred, state.tense);
+ const block = makeBlockWPronouns(pred, state.tense, state.negative);
return o.value === state.tense)?.label}
{...zIndexProps}
/>
+
+ dispatch({ type: "setNegative", payload: p === "neg" })}
+ />
+
}
diff --git a/src/components/equative-explorer/explorer-types.ts b/src/components/equative-explorer/explorer-types.ts
index 0714190..23053eb 100644
--- a/src/components/equative-explorer/explorer-types.ts
+++ b/src/components/equative-explorer/explorer-types.ts
@@ -10,6 +10,7 @@ export type ExplorerState = {
length: "short" | "long",
subject: SubjectEntityInfo,
predicate: PredicateEntityInfo,
+ negative: boolean,
};
export type SubjectEntityInfo = EntitiyInfo & { type: SubjectType };
@@ -46,4 +47,6 @@ export type ExplorerReducerAction = {
type: "setTense", payload: EquativeTense,
} | {
type: "setLength", payload: "short" | "long",
+} | {
+ type: "setNegative", payload: boolean,
};
\ No newline at end of file
diff --git a/src/lib/equative-machine.ts b/src/lib/equative-machine.ts
index 039afd1..071e2ca 100644
--- a/src/lib/equative-machine.ts
+++ b/src/lib/equative-machine.ts
@@ -4,6 +4,7 @@ import {
getVerbBlockPosFromPerson,
getPersonFromVerbForm,
concatPsString,
+ removeAccents,
} from "@lingdocs/pashto-inflector";
import {
personFromNP,
@@ -12,6 +13,7 @@ import {
import {
evaluateCompliment,
} from "./compliment-tools";
+import { isPluralNounEntry } from "./type-predicates";
// Equative Rules
// - An equative equates a SUBJECT: Noun Phrase and a PREDICATE: Noun Phrase | Compliment
@@ -27,11 +29,13 @@ export function equativeMachine(e: EquativeClause): EquativeClauseOutput {
? evaluateCompliment(e.predicate, personFromNP(e.subject))
: evaluateNP(e.predicate);
const equative = makeEquative(e);
+ const negative = !!e?.negative;
return {
ba,
subject,
predicate,
equative,
+ negative,
};
}
@@ -47,10 +51,19 @@ export function assembleEquativeOutput(o: EquativeClauseOutput): T.SingleOrLengt
const equatives = o.equative.ps;
const predicates = o.predicate.ps;
const ba = o.ba ? { p: " به", f: " ba" } : "";
+ const neg = o.negative ? { p: "نه ", f: "nú " } : "";
const ps = o.subject.ps.flatMap(subj => (
predicates.flatMap(pred => (
equatives.map(eq => (
- concatPsString(subj, ba, " ", pred, " ", eq))
+ concatPsString(
+ subj,
+ ba,
+ " ",
+ pred,
+ " ",
+ neg,
+ o.negative ? removeAccents(eq) : eq,
+ ))
)
))
));
@@ -71,7 +84,7 @@ function makeEquative(e: EquativeClause) {
? "past"
: e.tense;
const subjP = personFromNP(e.subject);
- const englishPerson = (e.subject.type === "plural noun" || e.subject.type === "participle")
+ const englishPerson = (e.subject.type === "participle" || (e.subject.type === "noun" && isPluralNounEntry(e.subject.entry)))
? T.Person.ThirdSingMale
: subjP
const pashtoPerson = (e.subject.type === "pronoun")
diff --git a/src/lib/np-tools.test.ts b/src/lib/np-tools.test.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/lib/np-tools.ts b/src/lib/np-tools.ts
index a9e3462..9d75e1a 100644
--- a/src/lib/np-tools.ts
+++ b/src/lib/np-tools.ts
@@ -1,4 +1,4 @@
-import { isMascNounEntry } from "./type-predicates";
+import { isMascNounEntry, isPluralNounEntry, isUnisexNounEntry } from "./type-predicates";
import {
Types as T,
getEnglishWord,
@@ -18,14 +18,8 @@ export function personFromNP(np: NounPhrase): T.Person {
if (np.type === "pronoun") {
return np.person;
}
- const gender: T.Gender = "gender" in np
- ? np.gender
- : isMascNounEntry(np.entry)
- ? "masc"
- : "fem";
- const number: NounNumber = np.type === "plural noun"
- ? "plural"
- : np.number;
+ const gender = nounGender(np);
+ const number = nounNumber(np);
return number === "plural"
? (gender === "masc" ? T.Person.ThirdPlurMale : T.Person.ThirdPlurFemale)
: (gender === "masc" ? T.Person.ThirdSingMale : T.Person.ThirdSingFemale);
@@ -41,6 +35,30 @@ export function evaluateNP(np: NounPhrase): { ps: T.PsString[], e: string } {
return evaluateNoun(np);
}
+function nounGender(n: Noun): T.Gender {
+ const nGender = isUnisexNounEntry(n.entry)
+ ? "unisex"
+ : isMascNounEntry(n.entry)
+ ? "masc"
+ : "fem";
+ return (nGender === "unisex" && n.gender)
+ ? n.gender
+ : (nGender === "unisex")
+ ? "masc"
+ : nGender;
+}
+
+function nounNumber(n: Noun): NounNumber {
+ const nNumber = isPluralNounEntry(n.entry)
+ ? "plural"
+ : "singular";
+ return nNumber === "plural"
+ ? "plural"
+ : n.number
+ ? n.number
+ : nNumber;
+}
+
function evaluatePronoun(p: Pronoun): { ps: T.PsString[], e: string } {
// TODO: Will need to handle inflecting and inflecting english pronouns etc.
const [row, col] = getVerbBlockPosFromPerson(p.person);
@@ -51,12 +69,11 @@ function evaluatePronoun(p: Pronoun): { ps: T.PsString[], e: string } {
}
function evaluateNoun(n: Noun): { ps: T.PsString[], e: string } {
- const number: NounNumber = "number" in n ? n.number : "plural";
+ const number = nounNumber(n);
const english = getEnglishFromNoun(n.entry, number);
const pashto = ((): T.PsString[] => {
const infs = inflectWord(n.entry);
- const gender: T.Gender = "gender" in n ? n.gender :
- (isMascNounEntry(n.entry) ? "masc" : "fem");
+ const gender = nounGender(n);
const ps = number === "singular"
? getInf(infs, "inflections", gender, false)
: [
diff --git a/src/types/gramm-types.d.ts b/src/types/gramm-types.d.ts
index f04d1c6..ec4c62c 100644
--- a/src/types/gramm-types.d.ts
+++ b/src/types/gramm-types.d.ts
@@ -5,6 +5,7 @@ type EquativeClause = {
subject: NounPhrase,
predicate: NounPhrase | Compliment,
tense: EquativeTense,
+ negative?: boolean,
};
type EquativeClauseOutput = {
@@ -17,6 +18,7 @@ type EquativeClauseOutput = {
e: string,
},
ba: boolean,
+ negative: boolean,
equative: {
ps: import("@lingdocs/pashto-inflector").Types.SentenceForm,
e: string[],
@@ -25,23 +27,12 @@ type EquativeClauseOutput = {
type NounPhrase = Pronoun | Noun | Participle;
-// TODO: better, simpler type here
+// The gender and number can be added, if it conflicts with the noun it will be ignored
type Noun = {
- type: "unisex noun",
- number: NounNumber,
- gender: import("@lingdocs/pashto-inflector").Types.Gender,
- entry: UnisexNounEntry,
- possesor?: Noun,
- adjectives?: AdjectiveEntry[],
-} | {
- type: "plural noun",
- entry: PluralNounEntry,
- possesor?: Noun,
- adjectives?: AdjectiveEntry[],
-} | {
- type: "singular noun",
- number: NounNumber,
- entry: SingularEntry,
+ type: "noun",
+ entry: NounEntry,
+ number?: NounNumber,
+ gender?: import("@lingdocs/pashto-inflector").Types.Gender,
possesor?: Noun,
adjectives?: AdjectiveEntry[],
};