pashto-inflector/src/types.ts

1136 lines
32 KiB
TypeScript
Raw Normal View History

2021-03-09 12:39:13 +00:00
/**
* Copyright (c) 2021 lingdocs.com
*
2022-11-05 11:29:31 +00:00
* This source code is licensed under the GPL3 license found in the
2021-03-09 12:39:13 +00:00
* LICENSE file in the root directory of this source tree.
*
*/
export type PsStringField = "p" | "f";
export type PsString = {
[k in PsStringField]: string;
} & {
e?: string;
};
2021-09-04 12:20:46 +00:00
export type PsJSX = { p: JSX.Element, f: JSX.Element, e?: JSX.Element | string };
2021-03-09 12:39:13 +00:00
2023-01-26 08:33:48 +00:00
export type PsWord = PsString & {
hyphen?: HyphenPsContent[],
};
export type HyphenPsContent = {
type: "unwritten",
f: string,
} & Omit<PsString, "p"> | ({
type: "written",
} & PsString);
2021-03-09 12:39:13 +00:00
export type DictionaryInfo = {
title: string;
license: string;
release: number;
numberOfEntries: number;
url: string;
infoUrl: string;
}
export type Dictionary = {
info: DictionaryInfo;
entries: DictionaryEntry[];
}
2023-01-22 15:55:00 +00:00
export type AllWordsWithInflections = {
2023-01-22 15:40:34 +00:00
info: DictionaryInfo,
words: PsString[],
};
2022-08-23 12:11:32 +00:00
// TODO: MAKE THIS A RECORD TYPE
// Record<RequiredNumberFields, number> && Record<RequiredStringFields, string> &&
// Partial<Record<StringFields, string>> && Partial<Record<NumberFields, number>>
2021-03-09 12:39:13 +00:00
export type DictionaryEntry = {
// BASE REQUIRED INFO
2021-03-16 13:35:41 +00:00
/** timestamp - used for word id */
ts: number;
/** Pashto alphabetical index */
i: number;
2022-11-25 14:19:22 +00:00
/**
* commonality rank
* 0 - wrong
* 1 - historical/not in use
* 2 - rarely used
* 3 - used but there are more common alternatives
* 4 - common
*/
r?: number;
2021-03-16 13:35:41 +00:00
/** entry in Pashto */
p: string;
/** entry in Phonetics */
f: string;
/** entry in simplified phonetics */
g: string;
/** entry in English */
e: string;
2021-03-09 12:39:13 +00:00
// PART OF SPEECH AND LINK INFO
2021-03-16 13:35:41 +00:00
/** part of speech info */
c?: string;
/** link - timestamp of related word */
l?: number;
2021-03-09 12:39:13 +00:00
// INFLECTION INFO
2021-03-16 13:35:41 +00:00
/** first masculine irregular inflection in Pashto */
infap?: string;
/** first masculine irregular inflection in Phonetics */
2021-03-09 12:39:13 +00:00
infaf?: string;
2021-03-16 13:35:41 +00:00
/** base for second masculine / feminine irregular inflection in Pashto */
2021-03-09 12:39:13 +00:00
infbp?: string;
2021-03-16 13:35:41 +00:00
/** base for second masculine / feminine irregular inflection in Phonetics */
2021-03-09 12:39:13 +00:00
infbf?: string;
2021-03-16 13:35:41 +00:00
/** entry does not inflect? */
noInf?: boolean;
2021-03-09 12:39:13 +00:00
// PLURAL INFO
2021-03-16 13:35:41 +00:00
/** Arabic plural in Pashto */
app?: string;
/** Arabic plural in Phonetics */
apf?: string;
/** Pashto irregular plural in Pashto */
ppp?: string;
/** Pashto irregular plural in phonetics */
ppf?: string;
2021-03-09 12:39:13 +00:00
// VERB INFO
2021-03-16 13:35:41 +00:00
/** imperfective (present) stem in Pashto */
psp?: string;
/** imperfective (present) stem in Phonetics */
psf?: string;
/** perfective (subjunctive) stem in Pashto */
2021-03-09 12:39:13 +00:00
ssp?: string;
2021-03-16 13:35:41 +00:00
/** perfective (subjunctive) stem in Phonetics */
2021-03-09 12:39:13 +00:00
ssf?: string;
2021-03-16 13:35:41 +00:00
/** perfective root in Pashto */
prp?: string;
/** perfective root in Phonetics */
prf?: string;
/** past participle in Pashto */
2021-03-09 12:39:13 +00:00
pprtp?: string;
2021-03-16 13:35:41 +00:00
/** past participle in Phonetics */
2021-03-09 12:39:13 +00:00
pprtf?: string;
/** The idiosyncratic third person singular masc. short past in Pashto */
tppp?: string;
/** The idiosyncratic third person singular masc. short past in Phonetics */
tppf?: string;
2021-03-16 13:35:41 +00:00
/** intransitive short version is available like ګرځېږي and ګرځي */
shortIntrans?: boolean;
/** does not take a و - oo perfective verb prefix? */
noOo?: boolean;
/** takes a seperate و - oo perfective verb prefix? */
sepOo?: boolean;
/** Pashto separation point for seperable verbs */
separationAtP?: number;
/** Phonetics separation point for seperable verbs */
separationAtF?: number;
2021-03-09 12:39:13 +00:00
// PHONETICS - PASHTO - DIACRITICS INFO
2021-03-16 13:35:41 +00:00
/** Is an exception to the rules of diacritics for Pashto/Phonetics */
diacExcept?: boolean;
2021-10-07 18:39:29 +00:00
/** the English conjugations of a verb comma seperated set of 5 ie. "see,sees,seeing,saw,seen" or single word ie. "walk" if regular - or the english singular version of a noun */
ec?: string;
2021-10-07 18:39:29 +00:00
/** the English partical of a English phrasal verb - or the english irregular plural of a noun */
ep?: string;
2021-03-09 12:39:13 +00:00
}
2021-09-07 11:49:57 +00:00
export type DictionaryEntryNoFVars = DictionaryEntry & { __brand: "name for a dictionary entry with all the phonetics variations removed" };
export type VerbDictionaryEntryNoFVars = VerbDictionaryEntry & { __brand2: "name for a verb dictionary entry with all the phonetics variations removed" };
export type VerbEntryNoFVars = {
entry: VerbDictionaryEntryNoFVars,
complement?: DictionaryEntryNoFVars,
} & { __brand: "name for a verb entry with all the phonetics variations removed" };
2021-09-07 11:49:57 +00:00
export type PsStringNoFVars = PsString & { __brand: "name for a ps string with all the phonetics variations removed" };
export type FStringNoFVars = string & { __brand: "name for a phonetics string with all the phonetics variations removed" };
2023-03-16 08:05:37 +00:00
export const dictionaryEntryTextFields = [
"p",
"f",
"e",
"c",
"infap",
"infaf",
"infbp",
"infbf",
"app",
"apf",
"ppp",
"ppf",
"psp",
"psf",
"ssp",
"ssf",
"prp",
"prf",
"pprtp",
"pprtf",
"tppp",
"tppf",
"ec",
"ep",
] as const;
export type DictionaryEntryTextField = typeof dictionaryEntryTextFields[number];
export const dictionaryEntryBooleanFields = [
"noInf", "shortIntrans", "noOo", "sepOo", "diacExcept",
] as const;
export const dictionaryEntryNumberFields = [
"ts", "r", "i", "l", "separationAtP", "separationAtF",
] as const;
export type DictionaryEntryBooleanField = typeof dictionaryEntryBooleanFields[number];
export type DictionaryEntryNumberField = typeof dictionaryEntryNumberFields[number];
2021-03-09 12:39:13 +00:00
export type DictionaryEntryField = DictionaryEntryTextField | DictionaryEntryBooleanField | DictionaryEntryNumberField;
2022-08-23 12:11:32 +00:00
// TODO: make
2021-03-09 12:39:13 +00:00
export type DictionaryEntryError = {
errors: string[],
p: string,
f: string,
e: string,
ts: number,
erroneousFields: DictionaryEntryField[],
}
2021-07-24 15:43:53 +00:00
export type Spelling = "Afghan" | "Pakistani ی" | "Pakistani ي";
2021-03-09 12:39:13 +00:00
export type TextOptions = {
pTextSize: "normal" | "larger" | "largest";
phonetics: "lingdocs" | "ipa" | "alalc" | "none";
dialect: "standard" | "peshawer" | "southern";
2021-07-24 15:43:53 +00:00
spelling: Spelling;
2021-03-09 12:39:13 +00:00
diacritics: boolean;
}
export enum Person {
FirstSingMale = 0,
FirstSingFemale,
SecondSingMale,
SecondSingFemale,
ThirdSingMale,
ThirdSingFemale,
FirstPlurMale,
FirstPlurFemale,
SecondPlurMale,
SecondPlurFemale,
ThirdPlurMale,
ThirdPlurFemale,
}
// INPUT
// all information to be passed to conjugating functions
export type VerbInfoBase = {
2022-04-14 08:12:10 +00:00
entry: VerbEntry,
2021-03-09 12:39:13 +00:00
transitivity: Transitivity;
yulEnding: boolean | null;
stem: VerbStemSet;
root: VerbRootSet;
participle: ParticipleSet;
idiosyncraticThirdMascSing?: ShortThirdPersFormSet;
}
export type PassiveRootsAndStems = {
stem: VerbStemSet,
root: VerbRootSet,
participle: {
past: FullForm<PsString>,
},
}
export type AbilityRootsAndStems = Omit<PassiveRootsAndStems, "participle">;
2021-03-09 12:39:13 +00:00
export type SimpleVerbInfo = VerbInfoBase & {
type: "simple";
}
export type StativeCompoundVerbInfo = VerbInfoBase & {
type: "stative compound"
complement: UnisexInflections;
}
export type GenerativeStativeCompoundVerbInfo = VerbInfoBase & {
type: "generative stative compound"
objComplement: ObjComplement,
singularForm?: GenerativeStativeCompoundVerbInfo,
// TODO: Could add intransitive form 🤪
}
export type DynamicCompoundVerbInfo = VerbInfoBase & {
type: "dynamic compound";
objComplement: ObjComplement;
auxVerb: DictionaryEntry;
auxVerbComplement?: DictionaryEntry;
singularForm?: DynamicCompoundVerbInfo;
intransitiveForm?: DynamicCompoundVerbInfo;
}
export type ObjComplement = {
entry: DictionaryEntry;
plural?: PsString;
person: Person;
}
export type NonComboVerbInfo = SimpleVerbInfo |
StativeCompoundVerbInfo | DynamicCompoundVerbInfo | GenerativeStativeCompoundVerbInfo;
export type VerbInfo = NonComboVerbInfo | {
type: "transitive or grammatically transitive simple";
transitive: SimpleVerbInfo;
grammaticallyTransitive: SimpleVerbInfo;
} | {
type: "dynamic or stative compound";
transitivity: Transitivity;
stative: StativeCompoundVerbInfo;
dynamic: DynamicCompoundVerbInfo;
} | {
type: "dynamic or generative stative compound";
transitivity: Transitivity;
stative: GenerativeStativeCompoundVerbInfo;
dynamic: DynamicCompoundVerbInfo;
}
export type Transitivity = "transitive" | "intransitive" | "grammatically transitive";
export type SplitInfo = FullForm<[PsString, PsString]>;
export type VerbStemSet = {
perfective: FullForm<PsString>;
imperfective: FullForm<PsString>;
perfectiveSplit?: SplitInfo;
}
export type VerbRootSet = {
perfective: OptionalPersonInflections<LengthOptions<PsString>>;
imperfective: OptionalPersonInflections<LengthOptions<PsString>>;
perfectiveSplit?: SplitInfo;
}
export type ParticipleSet = {
present: FullForm<PsString>,
past: FullForm<PsString>,
}
export type ShortThirdPersFormSet = {
[K in Aspect]: PsString;
}
export type Aspect = "perfective" | "imperfective";
export type Length = "short" | "long" | "mini";
export type LengthOptions<T> = {
long: T;
short: T;
mini?: T;
}
export type PersonInflectionsField = "mascSing" | "mascPlur" | "femSing" | "femPlur";
export type OptionalPersonInflections<T> = {
[K in PersonInflectionsField]: T;
} | T;
export type SingleOrLengthOpts<T> = T | LengthOptions<T>;
export type VerbConjugation = {
info: NonComboVerbInfo,
// INFINITIVE = info.root.imperfective.long
imperfective: AspectContent; // --╖ ASPECT = "imperfective"
perfective: AspectContent; // --╜ ASPECT = "perfective"
hypothetical: VerbForm; // INFINITIVE - ul + aay
participle: ParticipleContent;
perfect: PerfectContent; // PPART = PAST PARTICIPLE (plus spectial short forms)
passive?: PassiveContent; // only on transitive verbs
singularForm?: VerbConjugation;
}
export type VerbOutput = VerbConjugation | {
info: VerbInfo,
stative: VerbConjugation,
dynamic: VerbConjugation,
} | {
info: VerbInfo,
transitive: VerbConjugation,
grammaticallyTransitive: VerbConjugation,
};
export type PassiveContent = {
imperfective: AspectContentPassive // --╖ ASPECT = "imperfective"
perfective: AspectContentPassive // --╜ ASPECT = "perfective"
perfect: PerfectContent; // PPART INFINITIVE + kedulStat perfect.pastParticiple
// TODO: ADD PARTICIPLE
}
// ASPECT -> AspectContent
export type AspectContent = {
// STEM = info.stem[ASPECT]
// ROOT = info.root[ASPECT]
nonImperative: VerbForm; // STEM + pres ending
future: VerbForm; // به + this.nonImperative
2022-04-20 14:05:15 +00:00
imperative: ImperativeForm; // STEM + imperative ending
2021-03-09 12:39:13 +00:00
past: VerbForm; // ROOT + past ending
2022-03-29 09:28:02 +00:00
habitualPast: VerbForm; // ba + past
2021-03-09 12:39:13 +00:00
modal: ModalContent;
}
2022-04-20 14:05:15 +00:00
// ASPECT -> AspectContentPssive
export type AspectContentPassive = Omit<AspectContent, "imperative"> & {
imperative: undefined,
};
2021-03-09 12:39:13 +00:00
export type ModalContent = {
nonImperative: VerbForm; // ROOT + ey + kedulStat.perfective.nonImperative
future: VerbForm; // به + this.nonImperative
past: VerbForm; // ROOT + ey + kedulStat.perfective.past
2022-03-29 10:47:06 +00:00
habitualPast: VerbForm; // ba + past
2021-03-09 12:39:13 +00:00
hypotheticalPast: VerbForm; // ROOT + ey + shw + ey
}
export type ParticipleForm = SingleOrLengthOpts<UnisexInflections> | SingleOrLengthOpts<PsString>;
export type ParticipleContent = {
past: SingleOrLengthOpts<UnisexInflections> | SingleOrLengthOpts<PsString>,
// TODO: Should this ever have an object matrix??
present: SingleOrLengthOpts<UnisexInflections>,
}
// PPART -> PerfectContent
export type PerfectContent = {
halfPerfect: VerbForm; // PPART
past: VerbForm; // PPART + equative.past
present: VerbForm; // PPART + equative.prest
habitual: VerbForm; // PPART + equative.habit
2021-03-09 12:39:13 +00:00
subjunctive: VerbForm; // PPART + equative.subj
future: VerbForm; // ba + PPART + equative.subj
2022-06-27 18:33:31 +00:00
wouldBe: VerbForm; // ba + PPART + equative.past
pastSubjunctive: VerbForm; // PPART + waay
wouldHaveBeen: VerbForm; // PPART + ba + waay
2021-03-09 12:39:13 +00:00
}
2021-07-13 22:10:58 +00:00
// Plain, 1st, and 2nd Inflection
export type InflectionSet = ArrayFixed<ArrayOneOrMore<PsString>, 3>;
2021-09-07 11:49:57 +00:00
// Plural and Second Inflection
export type PluralInflectionSet = ArrayFixed<ArrayOneOrMore<PsString>, 2>
2021-09-02 11:44:07 +00:00
export type Gender = "masc" | "fem";
2021-09-07 11:49:57 +00:00
export type UnisexSet<T> = Record<Gender, T>;
export type GenderedSet<T> = UnisexSet<T> | Omit<UnisexSet<T>, "fem"> | Omit<UnisexSet<T>, "masc">;
export type UnisexInflections = UnisexSet<InflectionSet>;
export type Inflections = GenderedSet<InflectionSet>;
2021-03-09 12:39:13 +00:00
2021-09-07 11:49:57 +00:00
export type PluralInflections = GenderedSet<PluralInflectionSet>;
export type InflectorOutput = {
2021-09-14 14:25:04 +00:00
arabicPlural: PluralInflections,
plural?: PluralInflections,
2022-12-02 04:15:37 +00:00
bundledPlural?: PluralInflections,
2021-09-14 14:25:04 +00:00
inflections?: Inflections,
} | {
2021-09-07 11:49:57 +00:00
plural: PluralInflections,
2021-09-14 14:25:04 +00:00
arabicPlural?: PluralInflections,
2022-12-02 04:15:37 +00:00
bundledPlural?: PluralInflections,
2021-09-07 11:49:57 +00:00
inflections?: Inflections,
} | {
inflections: Inflections,
} | false;
2021-03-09 12:39:13 +00:00
export type PersonLine = [
/** singular form of person */
ArrayOneOrMore<PsString>,
/** plural form of person */
ArrayOneOrMore<PsString>,
];
/**
* The basic form of a verb conjugation
* Each line representing one person (singular and plural)
* 1st Person Male, 1st Person Female, 2nd Person Male etc...
*/
export type VerbBlock = [
PersonLine, // 1st Person Male
PersonLine, // 1st Person Female
PersonLine, // 2nd Person Male
PersonLine, // 2nd Person Female
PersonLine, // 3rd Person Male
PersonLine, // 3rd Person Female
];
export type EnglishBlock = [
[string, string],
[string, string],
[string, string],
[string, string],
[string, string],
[string, string],
];
export type ImperativeBlock = [
PersonLine, // 2nd Person Male
PersonLine, // 2nd Person Female
];
export type FullForm<T> = OptionalPersonInflections<SingleOrLengthOpts<T>>;
export type VerbForm = FullForm<VerbBlock>;
export type ImperativeForm = FullForm<ImperativeBlock>;
export type SentenceForm = SingleOrLengthOpts<ArrayOneOrMore<PsString>>;
export interface ArrayFixed<T, L extends number> extends Array<T> {
0: T;
length: L;
}
export type Wrapper<T> = T & { __brand: "wrapped" };
2021-03-09 12:39:13 +00:00
export type ArrayOneOrMore<T> = {
0: T
2022-12-02 04:15:37 +00:00
} & T[];
2021-03-09 12:39:13 +00:00
export type RootsOrStemsToHighlight = ("imperfective root" | "perfective root" | "imperfective stem" | "perfective stem" | "past participle")[];
2021-07-05 08:21:57 +00:00
/* i.e. ec: ["take", "takes", "taking", "took", "taken"], ep: out */
export type EnglishVerbConjugationEc = [string, string, string, string, string];
export type EnglishVerbConjugation = {
ec: EnglishVerbConjugationEc,
ep: string | undefined,
};
2021-03-09 12:39:13 +00:00
export type DisplayFormItem = DisplayForm | DisplayFormSubgroup | DisplayFormForSentence;
2021-07-05 11:39:52 +00:00
export type EnglishBuilder = (subject: Person, ec: EnglishVerbConjugationEc, neg: boolean) => string[];
2021-03-09 12:39:13 +00:00
export type DisplayForm = {
label: string,
aspect?: Aspect,
form: VerbForm | ImperativeForm | ParticipleForm | SentenceForm,
advanced?: boolean,
2021-07-05 11:39:52 +00:00
englishBuilder?: EnglishBuilder,
2021-03-09 12:39:13 +00:00
formula: React.ReactNode,
explanation: React.ReactNode,
sentence?: boolean,
passive?: boolean,
past?: boolean,
reorderWithNegative?: boolean,
}
2021-07-05 11:39:52 +00:00
export type DisplayFormForSentence = Omit<DisplayForm, "form"> & {
2021-03-09 12:39:13 +00:00
form: VerbForm,
secondPronounNeeded?: boolean,
2021-07-05 11:39:52 +00:00
}
// {
// label: string,
// aspect?: Aspect,
// form: VerbForm,
// advanced?: boolean,
// englishBuilder?: EnglishBuilder,
// formula: React.ReactNode,
// secondPronounNeeded?: boolean,
// explanation: React.ReactNode,
// sentence?: boolean,
// passive?: boolean,
// past?: boolean,
// reorderWithNegative?: boolean,
// }
2021-03-09 12:39:13 +00:00
export type DisplayFormSubgroup = {
label: string,
subgroup: string,
advanced?: boolean,
content: DisplayFormItem[],
}
2021-03-20 04:35:48 +00:00
export type AayTail = "ey" | "aay";
export type NounEntry = DictionaryEntry & { c: string } & { __brand: "a noun entry" };
export type MascNounEntry = NounEntry & { __brand2: "a masc noun entry" };
export type FemNounEntry = NounEntry & { __brand2: "a fem noun entry" };
2022-05-20 23:17:03 +00:00
export type AnimNounEntry = NounEntry & { __brand3: "a anim noun entry" };
export type UnisexNounEntry = MascNounEntry & { __brand3: "a unisex noun entry" };
2022-05-05 18:42:52 +00:00
export type UnisexAnimNounEntry = UnisexNounEntry & { __brand4: "an anim unisex noun entry" };
export type AdverbEntry = DictionaryEntry & { c: string } & { __brand: "an adverb entry" };
export type LocativeAdverbEntry = AdverbEntry & { __brand2: "a locative adverb entry" };
export type AdjectiveEntry = DictionaryEntry & { c: string } & { __brand: "an adjective entry" };
2022-04-09 11:08:57 +00:00
export type VerbDictionaryEntry = DictionaryEntry & { __brand: "a verb entry" };
export type VerbEntry = {
2022-04-09 11:08:57 +00:00
entry: VerbDictionaryEntry,
// TODO: the compliment could also be typed? Maybe?
complement?: DictionaryEntry,
};
/** A dictionary entry that will include the complement / verb entry structure if it's a verb */
export type FullEntry = VerbEntry | DictionaryEntry;
2022-09-12 15:13:59 +00:00
export enum InflectionPattern {
2022-09-12 14:56:37 +00:00
None = 0,
Basic = 1,
UnstressedEy = 2,
StressedEy = 3,
Pashtun = 4,
Squish = 5,
FemInanEe = 6,
};
export type SingularEntry<T extends NounEntry> = T & { __brand7: "a singular noun - as opposed to an always plural noun" };
export type PluralNounEntry<T extends NounEntry> = T & { __brand7: "a noun that is always plural" };
export type Pattern1Entry<T> = T & { __brand3: "basic inflection pattern" };
export type Pattern2Entry<T> = T & { __brand3: "ending in unstressed ی pattern" };
export type Pattern3Entry<T> = T & { __brand3: "ending in stressed ی pattern" };
export type Pattern4Entry<T> = T & { __brand3: "Pashtoon pattern" };
export type Pattern5Entry<T> = T & { __brand3: "short squish pattern" };
export type Pattern6FemEntry<T extends FemNounEntry> = T & { __brand3: "non anim. ending in ي" };
export type NonInflecting<T> = T & { __brand3: "non-inflecting" };
export type Entry = NounEntry | AdjectiveEntry | AdverbEntry | VerbEntry;
// TODO: make this Rendered<VPSelectionComplete> with recursive Rendered<>
export type VPRendered = {
type: "VPRendered",
king: "subject" | "object",
servant: "subject" | "object" | undefined,
isPast: boolean,
isTransitive: boolean,
isCompound: "stative" | "dynamic" | false,
2022-06-20 22:45:40 +00:00
blocks: Block[][],
kids: Kid[],
englishBase?: string[],
2022-05-03 15:23:33 +00:00
form: FormVersion,
2022-05-05 18:42:52 +00:00
whatsAdjustable: "both" | "king" | "servant",
}
export type VerbTense = "presentVerb"
| "subjunctiveVerb"
| "perfectiveFuture"
| "imperfectiveFuture"
| "perfectivePast"
| "imperfectivePast"
| "habitualPerfectivePast"
| "habitualImperfectivePast";
export type NounNumber = "singular" | "plural";
2022-06-27 18:33:31 +00:00
export type EquativeTense = "present" | "subjunctive" | "habitual" | "past" | "future" | "wouldBe" | "pastSubjunctive" | "wouldHaveBeen";
export type PerfectTense = `${EquativeTense}Perfect`;
export type AbilityTense = `${VerbTense}Modal`;
2022-04-20 14:05:15 +00:00
export type ImperativeTense = `${Aspect}Imperative`;
export type Tense = EquativeTense | VerbTense | PerfectTense | AbilityTense | ImperativeTense;
2022-05-20 23:17:03 +00:00
export type SubjectSelection = {
type: "subjectSelection",
selection: NPSelection | undefined,
};
export type ObjectSelection = {
type: "objectSelection",
selection: NPSelection | ObjectNP | undefined,
};
export type SubjectSelectionComplete = {
type: "subjectSelection",
2022-05-20 23:17:03 +00:00
selection: NPSelection,
};
2022-06-04 22:32:54 +00:00
export type PredicateSelectionComplete = {
type: "predicateSelection",
selection: ComplementSelection | NPSelection,
2022-06-04 22:32:54 +00:00
};
2022-05-20 23:17:03 +00:00
export type ObjectSelectionComplete = {
type: "objectSelection",
selection: NPSelection | ObjectNP,
};
export type VPSelectionState = {
blocks: VPSBlock[]
2022-04-11 12:16:30 +00:00
verb: VerbSelection,
externalComplement: undefined | UnselectedComplementSelection | ComplementSelection,
2022-05-03 15:23:33 +00:00
form: FormVersion,
2022-04-11 12:16:30 +00:00
};
export type VPSelectionComplete = {
blocks: VPSBlockComplete[]
2022-04-13 08:08:44 +00:00
verb: VerbSelectionComplete,
externalComplement: VPSelectionState["externalComplement"],
2022-05-03 15:23:33 +00:00
form: FormVersion,
2022-04-13 08:08:44 +00:00
};
export type VerbFormName = VerbTense | PerfectTense | AbilityTense | ImperativeTense;
2022-08-29 13:55:58 +00:00
export type VerbSelectionComplete = Omit<VerbSelection, "object" | "verbTense" | "perfectTense" | "imperativeTense" | "tenseCategory"> & {
2022-08-29 13:55:58 +00:00
tense: VerbFormName,
}
2022-04-11 12:16:30 +00:00
export type Voice = "active" | "passive";
export type VerbSelection = {
type: "verb",
verb: VerbEntry,
dynAuxVerb?: VerbEntry,
transitivity: Transitivity,
2022-05-03 00:38:45 +00:00
canChangeTransitivity: boolean,
canChangeStatDyn: boolean,
isCompound: "stative" | "dynamic" | false,
voice: Voice,
2022-05-03 00:38:45 +00:00
canChangeVoice: boolean,
negative: boolean,
verbTense: VerbTense,
perfectTense: PerfectTense,
2022-04-20 14:05:15 +00:00
imperativeTense: ImperativeTense,
tenseCategory: "basic" | "modal" | "perfect" | "imperative",
};
export type VerbRendered = Omit<VerbSelectionComplete, "object"> & {
ps: {
head: PsString | undefined,
rest: SingleOrLengthOpts<
PsString[]
>,
},
hasBa: boolean,
person: Person,
};
export type VerbObject =
// transitive verb - object not selected yet
undefined |
// transitive verb - obect selected
NPSelection |
// grammatically transitive verb with unspoken 3rd pers masc plur entity
// or intransitive "none"
ObjectNP;
export type NPSelection = {
type: "NP",
selection: NounSelection | PronounSelection | ParticipleSelection,
};
export type APSelection = {
type: "AP",
selection: AdverbSelection | SandwichSelection<Sandwich>,
};
2022-05-20 23:17:03 +00:00
export type NPType = "noun" | "pronoun" | "participle";
export type ObjectNP = "none" | Person.ThirdPlurMale;
export type PossesorSelection = {
2022-05-05 18:42:52 +00:00
shrunken: boolean,
np: NPSelection,
}
// TODO require/import Person and PsString
export type NounSelection = {
type: "noun",
entry: NounEntry,
gender: Gender,
genderCanChange: boolean,
number: NounNumber,
numberCanChange: boolean,
dynamicComplement?: boolean,
adjectives: AdjectiveSelection[],
possesor: undefined | PossesorSelection,
2022-08-02 18:27:19 +00:00
demonstrative: undefined | DemonstrativeSelection,
};
export type DemonstrativeSelection = {
type: "demonstrative",
demonstrative: "daa" | "hagha" | "dagha",
hideNoun: boolean,
};
2022-05-20 23:17:03 +00:00
export type AdverbSelection = {
type: "adverb",
entry: AdverbEntry,
}
export type AdjectiveSelection = {
type: "adjective",
entry: AdjectiveEntry,
sandwich: SandwichSelection<Sandwich> | undefined,
}
export type LocativeAdverbSelection = {
type: "loc. adv.",
entry: LocativeAdverbEntry,
}
// take an argument for subject/object in rendering English
export type PronounSelection = {
type: "pronoun",
person: Person,
distance: "near" | "far",
};
export type ParticipleSelection = {
type: "participle",
verb: VerbEntry,
possesor: undefined | PossesorSelection,
};
// not object
// type Primitive = string | Function | number | boolean | Symbol | undefined | null;
// If T has key K ("user"), replace it
export type ReplaceKey<T, K extends string, R> = T extends Record<K, unknown> ? (Omit<T, K> & Record<K, R>) : T;
export type FormVersion = { removeKing: boolean, shrinkServant: boolean };
2022-05-05 18:42:52 +00:00
// TODO: rendered should would for rendering T.PossesorSelection etc
// look recursively down on something
export type RenderedPossesorSelection = {
np: Rendered<NPSelection>,
shrunken: boolean,
};
export type UnselectedComplementSelection = { type: "complement", selection: { type: "unselected" }};
export type Rendered<
T extends
| NPSelection
| NPSelection["selection"]
| APSelection
| APSelection["selection"]
| SubjectSelectionComplete
| ObjectSelectionComplete
2022-06-04 22:32:54 +00:00
| PredicateSelectionComplete
| AdjectiveSelection
| SandwichSelection<Sandwich>
| ComplementSelection
2022-08-02 18:27:19 +00:00
| DemonstrativeSelection
| ComplementSelection["selection"]
| UnselectedComplementSelection
| undefined
> =
T extends NPSelection
? {
type: "NP",
selection: Rendered<NPSelection["selection"]>
}
: T extends APSelection
? {
type: "AP",
2022-11-01 14:30:05 +00:00
selection: Rendered<APSelection["selection"]>,
}
: T extends ComplementSelection
? {
type: "complement",
selection: Rendered<ComplementSelection["selection"]>
}
: T extends UnselectedComplementSelection
? {
type: "complement",
selection: {
type: "unselected",
ps: PsString[],
e: string,
},
}
: T extends SandwichSelection<Sandwich>
2022-05-20 23:17:03 +00:00
? Omit<SandwichSelection<Sandwich>, "inside"> & {
inside: Rendered<NPSelection>,
}
: T extends AdverbSelection
? {
type: "adverb",
entry: AdverbEntry,
2022-11-01 14:30:05 +00:00
person: Person,
ps: PsString[],
e?: string,
}
: T extends AdjectiveSelection
? {
type: "adjective",
entry: AdjectiveEntry,
ps: PsString[],
e?: string,
sandwich: Rendered<SandwichSelection<Sandwich>> | undefined,
inflected: boolean,
person: Person,
}
2022-08-02 18:27:19 +00:00
: T extends DemonstrativeSelection
? {
type: "demonstrative",
demonstrative: DemonstrativeSelection["demonstrative"],
hideNoun: boolean,
ps: PsString,
}
: T extends ComplementSelection
? {
type: "complement",
selection: Rendered<ComplementSelection["selection"]>,
}
: T extends SubjectSelectionComplete
? {
type: "subjectSelection",
selection: Rendered<NPSelection>,
}
: T extends ObjectSelectionComplete
? {
type: "objectSelection",
selection: Rendered<NPSelection> | Person.ThirdPlurMale | "none",
}
2022-06-04 22:32:54 +00:00
: T extends PredicateSelectionComplete
? {
type: "predicateSelection",
selection: Rendered<ComplementSelection> | Rendered<NPSelection>,
} : T extends undefined
? {
type: "undefined",
ps: PsString,
}
: ReplaceKey<
2022-05-20 23:17:03 +00:00
Omit<T, "changeGender" | "changeNumber" | "changeDistance" | "adjectives" | "possesor">,
"e",
string
> & {
ps: PsString[],
e?: string,
inflected: boolean,
person: Person,
role: "king" | "servant" | "none",
// TODO: better recursive thing
adjectives?: Rendered<AdjectiveSelection>[],
possesor?: {
shrunken: boolean,
np: Rendered<NPSelection>,
},
2022-08-02 18:27:19 +00:00
demonstrative?: Rendered<DemonstrativeSelection>,
2022-05-20 23:17:03 +00:00
};
export type EPSelectionState = {
blocks: EPSBlock[],
predicate: {
type: "NP" | "Complement",
NP: NPSelection | undefined,
Complement: ComplementSelection | undefined,
},
equative: EquativeSelection,
omitSubject: boolean,
};
export type EPSBlock = {
key: number,
block: SubjectSelection | APSelection | undefined,
};
export type EPSBlockComplete = {
key: number,
block: SubjectSelectionComplete | APSelection,
};
export type VPSBlock = {
key: number,
// TODO: confusing use of APSelection / should be like APSelection s APSelection complete like the others
block: SubjectSelection | ObjectSelection | (APSelection | undefined) | ComplementSelection,
};
export type VPSBlockComplete = {
key: number,
block: SubjectSelectionComplete | ObjectSelectionComplete | APSelection | ComplementSelection,
};
export type EPSelectionComplete = Omit<EPSelectionState, "predicate" | "blocks"> & {
blocks: EPSBlockComplete[],
2022-06-04 22:32:54 +00:00
predicate: PredicateSelectionComplete,
omitSubject: boolean,
};
export type ComplementType = "adjective" | "loc. adv." | "sandwich" | "comp. noun";
2022-05-20 23:17:03 +00:00
export type SandwichSelection<S extends Sandwich> = S & {
inside: NPSelection,
};
export type ComplementSelection = {
type: "complement",
selection: AdjectiveSelection
| LocativeAdverbSelection
| SandwichSelection<Sandwich>
| NounSelection,
};
2022-05-20 23:17:03 +00:00
export type Sandwich = {
type: "sandwich",
before: PsString | undefined,
after: PsString | undefined,
e: string,
};
export type EquativeSelection = {
tense: EquativeTense,
negative: boolean,
};
export type EquativeRendered = EquativeSelection & {
ps: SingleOrLengthOpts<PsString[]>,
person: Person,
hasBa: boolean,
}
export type EPRendered = {
type: "EPRendered",
2022-06-20 22:45:40 +00:00
blocks: Block[][],
2022-06-04 22:32:54 +00:00
kids: Kid[],
englishBase?: string[],
omitSubject: boolean,
}
export type EntryFeeder = {
nouns: EntryLookupPortal<NounEntry>,
verbs: EntryLookupPortal<VerbEntry>,
adjectives: EntryLookupPortal<AdjectiveEntry>,
locativeAdverbs: EntryLookupPortal<LocativeAdverbEntry>,
adverbs: EntryLookupPortal<AdverbEntry>,
} | {
nouns: NounEntry[],
verbs: VerbEntry[],
adjectives: AdjectiveEntry[],
locativeAdverbs: LocativeAdverbEntry[],
adverbs: AdverbEntry[],
}
export type EntryFeederSingleType<X extends VerbEntry | DictionaryEntry> = X[] | EntryLookupPortal<X>;
export type EntryLookupPortal<X extends VerbEntry | DictionaryEntry> = {
search: (s: string) => X[],
2022-04-26 07:44:25 +00:00
getByTs: (ts: number) => (X | undefined),
}
2022-06-04 22:32:54 +00:00
export type EquativeBlock = { type: "equative", equative: EquativeRendered };
2022-07-20 01:17:50 +00:00
2022-06-20 22:45:40 +00:00
export type PerfectParticipleBlock = {
type: "perfectParticipleBlock",
ps: SingleOrLengthOpts<PsString[]>,
verb: VerbRenderedBlock,
person: Person,
2022-07-20 01:17:50 +00:00
complementWelded: undefined | Rendered<ComplementSelection> | Rendered<UnselectedComplementSelection>,
2022-06-20 22:45:40 +00:00
};
export type PerfectEquativeBlock = {
type: "perfectEquativeBlock",
ps: PsString[],
person: Person,
};
export type ModalVerbBlock = {
type: "modalVerbBlock",
ps: SingleOrLengthOpts<PsString[]>,
verb: VerbRenderedBlock,
2022-07-20 01:17:50 +00:00
complementWelded: undefined | Rendered<ComplementSelection> | Rendered<UnselectedComplementSelection>,
2022-06-20 22:45:40 +00:00
};
export type ModalVerbKedulPart = {
type: "modalVerbKedulPart",
ps: PsString[],
verb: VerbRenderedBlock,
};
export type PerfectiveHeadBlock = { type: "perfectiveHead", ps: PsString };
export type VerbRenderedBlock = {
type: "verb",
block: Omit<VerbSelectionComplete, "object"> & {
hasBa: boolean,
ps: SingleOrLengthOpts<PsString[]>,
person: Person,
2022-07-20 01:17:50 +00:00
complementWelded: undefined | Rendered<ComplementSelection> | Rendered<UnselectedComplementSelection>,
2022-06-20 22:45:40 +00:00
},
};
2022-06-04 22:32:54 +00:00
export type Block = {
key: number,
block: | Rendered<SubjectSelectionComplete>
| Rendered<ObjectSelectionComplete>
| Rendered<APSelection>
| Rendered<PredicateSelectionComplete>
| Rendered<ComplementSelection>
| Rendered<UnselectedComplementSelection>
| PerfectParticipleBlock
| PerfectEquativeBlock
| ModalVerbBlock
| ModalVerbKedulPart
| { type: "negative", imperative: boolean }
| PerfectiveHeadBlock
| VerbRenderedBlock
| EquativeBlock;
}
2022-08-23 13:25:31 +00:00
export type RenderedVerbB = VerbRenderedBlock
| PerfectiveHeadBlock
| ModalVerbBlock
| ModalVerbKedulPart
| PerfectEquativeBlock
| PerfectParticipleBlock;
export type Kid = {
key: number,
kid: | { type: "ba" }
| MiniPronoun,
}
2022-06-04 22:32:54 +00:00
export type MiniPronoun = {
type: "mini-pronoun",
person: Person,
ps: PsString,
source: "servant" | "possesive",
np: NPSelection,
};
2023-04-07 11:48:33 +00:00
export type VerbRenderedOutput = [[VHead] | [], [VB, VBE] | [VBE]];
export type RootsStemsOutput = [[VHead] | [], [VB, VBA] | [VBA]]; // or perfect / equative
2023-04-07 11:48:33 +00:00
export type VB = VBBasic | VBGenNum | Welded;
export type VBA = Exclude<VB, VBGenNum>;
2023-04-07 11:48:33 +00:00
export type VBE = (VBBasic | Welded) & {
person: Person,
2023-04-07 11:48:33 +00:00
}; // or equative
2023-04-07 11:48:33 +00:00
export type VBBasic = {
type: "VB",
ps: SingleOrLengthOpts<PsString[]>,
};
2023-04-07 11:48:33 +00:00
export type VBGenNum = VBBasic & GenderNumber;
export type GenderNumber = {
gender: Gender,
number: NounNumber,
};
2023-04-07 11:48:33 +00:00
export type Welded = {
type: "welded",
left: NComp | VBBasic | Welded,
right: VBBasic,
};
export type VHead = PH | NComp;
/** perfective head block */
export type PH = {
type: "PH",
ps: PsString,
};
export type NComp = {
type: "NComp",
comp: Comp,
};
// Complement can be one of
// - adjective
// - locative adv
// - sandwich (TODO)
// - noun
/** complement block */
export type Comp = {
type: "AdjComp",
ps: PsString,
gender: Gender,
number: NounNumber,
} | {
type: "LocAdvComp",
ps: PsString,
} | {
type: "NounComp",
ps: PsString,
};