@azure-tools/codegen
Version:
Autorest Code generator common and base classes
1,044 lines • 40 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnglishPluralizationService = void 0;
const text_manipulation_1 = require("./text-manipulation");
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/*
* PORTED FROM System.Data.Entity.Infrastructure.Pluralization.EnglishPluralizationService (EntityFramework.dll)
*/
class StringBidirectionalDictionary {
constructor(dict = {}) {
this.dictForward = new Map();
this.dictBackward = new Map();
for (const key of Object.keys(dict)) {
const value = dict[key];
this.addValue(key, value);
}
}
addValue(first, second) {
this.dictForward.set(first, second);
this.dictBackward.set(second, first);
}
existsInFirst(s) {
return this.dictForward.has(s);
}
existsInSecond(s) {
return this.dictBackward.has(s);
}
getFirstValue(s) {
return (this.dictBackward.get(s) ||
(() => {
throw new Error("Cannot find key.");
})());
}
getSecondValue(s) {
return (this.dictForward.get(s) ||
(() => {
throw new Error("Cannot find key.");
})());
}
}
function endsWithIgnoreCase(word, suffix) {
return word.toLowerCase().endsWith(suffix.toLowerCase());
}
class PluralizationServiceUtil {
static DoesWordContainSuffix(word, suffixes) {
return suffixes.some((s) => endsWithIgnoreCase(word, s));
}
static TryInflectOnSuffixInWord(word, suffixes, operationOnWord) {
if (PluralizationServiceUtil.DoesWordContainSuffix(word, suffixes)) {
return operationOnWord(word);
}
else {
return null;
}
}
}
class EnglishPluralizationService {
constructor() {
this.uninflectiveSuffixList = ["fish", "ois", "sheep", "deer", "pos", "itis", "ism"];
this.uninflectiveWordList = [
"bison",
"flounder",
"pliers",
"bream",
"gallows",
"proceedings",
"breeches",
"graffiti",
"rabies",
"britches",
"headquarters",
"salmon",
"carp",
"----",
"scissors",
"ch----is",
"high-jinks",
"sea-bass",
"clippers",
"homework",
"series",
"cod",
"innings",
"shears",
"contretemps",
"jackanapes",
"species",
"corps",
"mackerel",
"swine",
"debris",
"measles",
"trout",
"diabetes",
"mews",
"tuna",
"djinn",
"mumps",
"whiting",
"eland",
"news",
"wildebeest",
"elk",
"pincers",
"police",
"hair",
"ice",
"chaos",
"milk",
"cotton",
"pneumonoultramicroscopicsilicovolcanoconiosis",
"information",
"aircraft",
"scabies",
"traffic",
"corn",
"millet",
"rice",
"hay",
"----",
"tobacco",
"cabbage",
"okra",
"broccoli",
"asparagus",
"lettuce",
"beef",
"pork",
"venison",
"mutton",
"cattle",
"offspring",
"molasses",
"shambles",
"shingles",
"https",
"sas",
"statuses",
"as",
"statistics",
"alias",
"dns",
"ms",
"os",
"vmss",
"acls",
"rights",
"credentials",
"ddos",
"media",
"gbps",
"kbps",
"mbps",
"bps",
"fips",
];
this.irregularVerbList = {
am: "are",
are: "are",
is: "are",
was: "were",
were: "were",
has: "have",
have: "have",
};
this.pronounList = [
"I",
"we",
"you",
"he",
"she",
"they",
"it",
"me",
"us",
"him",
"her",
"them",
"myself",
"ourselves",
"yourself",
"himself",
"herself",
"itself",
"oneself",
"oneselves",
"my",
"our",
"your",
"his",
"their",
"its",
"mine",
"yours",
"hers",
"theirs",
"this",
"that",
"these",
"those",
"all",
"another",
"any",
"anybody",
"anyone",
"anything",
"both",
"each",
"other",
"either",
"everyone",
"everybody",
"everything",
"most",
"much",
"nothing",
"nobody",
"none",
"one",
"others",
"some",
"somebody",
"someone",
"something",
"what",
"whatever",
"which",
"whichever",
"who",
"whoever",
"whom",
"whomever",
"whose",
];
this.irregularPluralsDictionary = {
brother: "brothers",
child: "children",
cow: "cows",
ephemeris: "ephemerides",
genie: "genies",
money: "moneys",
mongoose: "mongooses",
mythos: "mythoi",
octopus: "octopuses",
ox: "oxen",
soliloquy: "soliloquies",
trilby: "trilbys",
crisis: "crises",
synopsis: "synopses",
rose: "roses",
gas: "gases",
bus: "buses",
axis: "axes",
memo: "memos",
casino: "casinos",
silo: "silos",
stereo: "stereos",
studio: "studios",
lens: "lenses",
alias: "aliases",
pie: "pies",
corpus: "corpora",
viscus: "viscera",
hippopotamus: "hippopotami",
trace: "traces",
person: "people",
chili: "chilies",
analysis: "analyses",
basis: "bases",
neurosis: "neuroses",
oasis: "oases",
synthesis: "syntheses",
thesis: "theses",
change: "changes",
lie: "lies",
calorie: "calories",
freebie: "freebies",
case: "cases",
house: "houses",
valve: "valves",
cloth: "clothes",
tie: "ties",
movie: "movies",
bonus: "bonuses",
specimen: "specimens",
};
this.assimilatedClassicalInflectionDictionary = {
alumna: "alumnae",
alga: "algae",
vertebra: "vertebrae",
codex: "codices",
murex: "murices",
silex: "silices",
aphelion: "aphelia",
hyperbaton: "hyperbata",
perihelion: "perihelia",
asyndeton: "asyndeta",
noumenon: "noumena",
phenomenon: "phenomena",
criterion: "criteria",
organon: "organa",
prolegomenon: "prolegomena",
agendum: "agenda",
extremum: "extrema",
bacterium: "bacteria",
desideratum: "desiderata",
stratum: "strata",
candelabrum: "candelabra",
erratum: "errata",
ovum: "ova",
forum: "fora",
addendum: "addenda",
stadium: "stadia",
automaton: "automata",
polyhedron: "polyhedra",
};
this.oSuffixDictionary = {
albino: "albinos",
generalissimo: "generalissimos",
manifesto: "manifestos",
archipelago: "archipelagos",
ghetto: "ghettos",
medico: "medicos",
armadillo: "armadillos",
guano: "guanos",
octavo: "octavos",
commando: "commandos",
inferno: "infernos",
photo: "photos",
ditto: "dittos",
jumbo: "jumbos",
pro: "pros",
dynamo: "dynamos",
lingo: "lingos",
quarto: "quartos",
embryo: "embryos",
lumbago: "lumbagos",
rhino: "rhinos",
fiasco: "fiascos",
magneto: "magnetos",
stylo: "stylos",
};
this.classicalInflectionDictionary = {
stamen: "stamina",
foramen: "foramina",
lumen: "lumina",
anathema: "anathemata",
"----": "----ta",
oedema: "oedemata",
bema: "bemata",
enigma: "enigmata",
sarcoma: "sarcomata",
carcinoma: "carcinomata",
gumma: "gummata",
schema: "schemata",
charisma: "charismata",
lemma: "lemmata",
soma: "somata",
diploma: "diplomata",
lymphoma: "lymphomata",
stigma: "stigmata",
dogma: "dogmata",
magma: "magmata",
stoma: "stomata",
drama: "dramata",
melisma: "melismata",
trauma: "traumata",
edema: "edemata",
miasma: "miasmata",
abscissa: "abscissae",
formula: "formulae",
medusa: "medusae",
amoeba: "amoebae",
hydra: "hydrae",
nebula: "nebulae",
antenna: "antennae",
hyperbola: "hyperbolae",
nova: "novae",
aurora: "aurorae",
lacuna: "lacunae",
parabola: "parabolae",
apex: "apices",
latex: "latices",
vertex: "vertices",
cortex: "cortices",
pontifex: "pontifices",
vortex: "vortices",
index: "indices",
simplex: "simplices",
iris: "irides",
"----oris": "----orides",
alto: "alti",
contralto: "contralti",
soprano: "soprani",
"b----o": "b----i",
crescendo: "crescendi",
tempo: "tempi",
canto: "canti",
solo: "soli",
aquarium: "aquaria",
interregnum: "interregna",
quantum: "quanta",
compendium: "compendia",
lustrum: "lustra",
rostrum: "rostra",
consortium: "consortia",
maximum: "maxima",
spectrum: "spectra",
cranium: "crania",
medium: "media",
speculum: "specula",
curriculum: "curricula",
memorandum: "memoranda",
stadium: "stadia",
dictum: "dicta",
millenium: "millenia",
"t----zium": "t----zia",
emporium: "emporia",
minimum: "minima",
ultimatum: "ultimata",
enconium: "enconia",
momentum: "momenta",
vacuum: "vacua",
gymnasium: "gymnasia",
optimum: "optima",
velum: "vela",
honorarium: "honoraria",
phylum: "phyla",
focus: "foci",
nimbus: "nimbi",
succubus: "succubi",
fungus: "fungi",
nucleolus: "nucleoli",
torus: "tori",
genius: "genii",
radius: "radii",
umbilicus: "umbilici",
incubus: "incubi",
stylus: "styli",
uterus: "uteri",
stimulus: "stimuli",
apparatus: "apparatus",
impetus: "impetus",
prospectus: "prospectus",
cantus: "cantus",
nexus: "nexus",
sinus: "sinus",
coitus: "coitus",
plexus: "plexus",
status: "status",
hiatus: "hiatus",
afreet: "afreeti",
afrit: "afriti",
efreet: "efreeti",
cherub: "cherubim",
goy: "goyim",
seraph: "seraphim",
alumnus: "alumni",
};
// this list contains all the plural words that being treated as singluar form, for example, "they" -> "they"
this.knownConflictingPluralList = ["they", "them", "their", "have", "were", "yourself", "are"];
// this list contains the words ending with "se" and we special case these words since
// we need to add a rule for "ses" singularize to "s"
this.wordsEndingWithSeDictionary = {
house: "houses",
case: "cases",
enterprise: "enterprises",
purchase: "purchases",
surprise: "surprises",
release: "releases",
disease: "diseases",
promise: "promises",
refuse: "refuses",
whose: "whoses",
phase: "phases",
noise: "noises",
nurse: "nurses",
rose: "roses",
franchise: "franchises",
supervise: "supervises",
farmhouse: "farmhouses",
suitcase: "suitcases",
recourse: "recourses",
impulse: "impulses",
license: "licenses",
diocese: "dioceses",
excise: "excises",
demise: "demises",
blouse: "blouses",
bruise: "bruises",
misuse: "misuses",
curse: "curses",
prose: "proses",
purse: "purses",
goose: "gooses",
tease: "teases",
poise: "poises",
vase: "vases",
fuse: "fuses",
muse: "muses",
slaughterhouse: "slaughterhouses",
clearinghouse: "clearinghouses",
endonuclease: "endonucleases",
steeplechase: "steeplechases",
metamorphose: "metamorphoses",
"----": "----s",
commonsense: "commonsenses",
intersperse: "intersperses",
merchandise: "merchandises",
phosphatase: "phosphatases",
summerhouse: "summerhouses",
watercourse: "watercourses",
catchphrase: "catchphrases",
compromise: "compromises",
greenhouse: "greenhouses",
lighthouse: "lighthouses",
paraphrase: "paraphrases",
mayonnaise: "mayonnaises",
"----course": "----courses",
apocalypse: "apocalypses",
courthouse: "courthouses",
powerhouse: "powerhouses",
storehouse: "storehouses",
glasshouse: "glasshouses",
hypotenuse: "hypotenuses",
peroxidase: "peroxidases",
pillowcase: "pillowcases",
roundhouse: "roundhouses",
streetwise: "streetwises",
expertise: "expertises",
discourse: "discourses",
warehouse: "warehouses",
staircase: "staircases",
workhouse: "workhouses",
briefcase: "briefcases",
clubhouse: "clubhouses",
clockwise: "clockwises",
concourse: "concourses",
playhouse: "playhouses",
turquoise: "turquoises",
boathouse: "boathouses",
cellulose: "celluloses",
epitomise: "epitomises",
gatehouse: "gatehouses",
grandiose: "grandioses",
menopause: "menopauses",
penthouse: "penthouses",
"----horse": "----horses",
transpose: "transposes",
almshouse: "almshouses",
customise: "customises",
footloose: "footlooses",
galvanise: "galvanises",
princesse: "princesses",
universe: "universes",
workhorse: "workhorses",
response: "responses",
phrase: "phrases",
};
this.wordsEndingWithSisDictionary = {
analysis: "analyses",
crisis: "crises",
basis: "bases",
atherosclerosis: "atheroscleroses",
electrophoresis: "electrophoreses",
psychoanalysis: "psychoanalyses",
photosynthesis: "photosyntheses",
amniocentesis: "amniocenteses",
metamorphosis: "metamorphoses",
toxoplasmosis: "toxoplasmoses",
endometriosis: "endometrioses",
tuberculosis: "tuberculoses",
pathogenesis: "pathogeneses",
osteoporosis: "osteoporoses",
parenthesis: "parentheses",
anastomosis: "anastomoses",
peristalsis: "peristalses",
hypothesis: "hypotheses",
antithesis: "antitheses",
apotheosis: "apotheoses",
thrombosis: "thromboses",
diagnosis: "diagnoses",
synthesis: "syntheses",
paralysis: "paralyses",
prognosis: "prognoses",
cirrhosis: "cirrhoses",
sclerosis: "scleroses",
psychosis: "psychoses",
apoptosis: "apoptoses",
symbiosis: "symbioses",
redis: "redis",
};
this.wordsEndingWithSusDictionary = {
consensus: "consensuses",
census: "censuses",
status: "statuses",
};
this.wordsEndingWithInxAnxYnxDictionary = {
sphinx: "sphinxes",
larynx: "larynges",
lynx: "lynxes",
pharynx: "pharynxes",
phalanx: "phalanxes",
};
// eslint-disable-next-line prefer-spread
const flatten = (l) => [].concat.apply([], l);
this.userDictionary = new StringBidirectionalDictionary();
this.irregularPluralsPluralizationService = new StringBidirectionalDictionary(this.irregularPluralsDictionary);
this.assimilatedClassicalInflectionPluralizationService = new StringBidirectionalDictionary(this.assimilatedClassicalInflectionDictionary);
this.oSuffixPluralizationService = new StringBidirectionalDictionary(this.oSuffixDictionary);
this.classicalInflectionPluralizationService = new StringBidirectionalDictionary(this.classicalInflectionDictionary);
this.wordsEndingWithSePluralizationService = new StringBidirectionalDictionary(this.wordsEndingWithSeDictionary);
this.wordsEndingWithSisPluralizationService = new StringBidirectionalDictionary(this.wordsEndingWithSisDictionary);
this.wordsEndingWithSusPluralizationService = new StringBidirectionalDictionary(this.wordsEndingWithSusDictionary);
this.wordsEndingWithInxAnxYnxPluralizationService = new StringBidirectionalDictionary(this.wordsEndingWithInxAnxYnxDictionary);
// verb
this.irregularVerbPluralizationService = new StringBidirectionalDictionary(this.irregularVerbList);
this.knownSingluarWords = flatten([
Object.keys(this.irregularPluralsDictionary),
Object.keys(this.assimilatedClassicalInflectionDictionary),
Object.keys(this.oSuffixDictionary),
Object.keys(this.classicalInflectionDictionary),
Object.keys(this.irregularVerbList),
Object.keys(this.irregularPluralsDictionary),
Object.keys(this.wordsEndingWithSeDictionary),
Object.keys(this.wordsEndingWithSisDictionary),
Object.keys(this.wordsEndingWithSusDictionary),
Object.keys(this.wordsEndingWithInxAnxYnxDictionary),
Object.keys(this.uninflectiveWordList),
]).filter((x) => !this.knownConflictingPluralList.includes(x)); // see the _knowConflictingPluralList comment above
this.knownPluralWords = flatten([
Object.values(this.irregularPluralsDictionary),
Object.values(this.assimilatedClassicalInflectionDictionary),
Object.values(this.oSuffixDictionary),
Object.values(this.classicalInflectionDictionary),
Object.values(this.irregularVerbList),
Object.values(this.irregularPluralsDictionary),
Object.values(this.wordsEndingWithSeDictionary),
Object.values(this.wordsEndingWithSisDictionary),
Object.values(this.wordsEndingWithSusDictionary),
Object.values(this.wordsEndingWithInxAnxYnxDictionary),
Object.values(this.uninflectiveWordList),
]);
}
isPlural(word) {
if (this.userDictionary.existsInSecond(word)) {
return true;
}
if (this.userDictionary.existsInFirst(word)) {
return false;
}
if (this.isUninflective(word) || this.knownPluralWords.includes(word.toLowerCase())) {
return true;
}
else if (this.singularize(word) === word) {
return false;
}
else {
return true;
}
}
isSingular(word) {
if (this.userDictionary.existsInFirst(word)) {
return true;
}
if (this.userDictionary.existsInSecond(word)) {
return false;
}
if (this.isUninflective(word) || this.knownSingluarWords.includes(word.toLowerCase())) {
return true;
}
else if (!this.isNoOpWord(word) && this.singularize(word) === word) {
return true;
}
else {
return false;
}
}
//
pluralize(word) {
return this.capitalize(word, (w) => this.internalPluralize(w));
}
internalPluralize(word) {
// words that we know of
if (this.userDictionary.existsInFirst(word)) {
return this.userDictionary.getSecondValue(word);
}
if (this.isNoOpWord(word)) {
return word;
}
const { prefixWord, suffixWord } = this.getSuffixWord(word);
// by me -> by me
if (this.isNoOpWord(suffixWord)) {
return prefixWord + suffixWord;
}
// handle the word that do not inflect in the plural form
if (this.isUninflective(suffixWord)) {
return prefixWord + suffixWord;
}
// if word is one of the known plural forms, then just return
if (this.knownPluralWords.includes(suffixWord.toLowerCase()) || this.isPlural(suffixWord)) {
return prefixWord + suffixWord;
}
// handle irregular plurals, e.g. "ox" -> "oxen"
if (this.irregularPluralsPluralizationService.existsInFirst(suffixWord)) {
return prefixWord + this.irregularPluralsPluralizationService.getSecondValue(suffixWord);
}
let newSuffixWord;
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["man"], (s) => `${s.slice(0, -2)}en`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
// handle irregular inflections for common suffixes, e.g. "mouse" -> "mice"
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["louse", "mouse"], (s) => `${s.slice(0, -4)}ice`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["tooth"], (s) => `${s.slice(0, -4)}eeth`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["goose"], (s) => `${s.slice(0, -4)}eese`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["foot"], (s) => `${s.slice(0, -3)}eet`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["zoon"], (s) => `${s.slice(0, -3)}oa`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["cis", "sis", "xis"], (s) => `${s.slice(0, -2)}es`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
// handle assimilated classical inflections, e.g. vertebra -> vertebrae
if (this.assimilatedClassicalInflectionPluralizationService.existsInFirst(suffixWord)) {
return prefixWord + this.assimilatedClassicalInflectionPluralizationService.getSecondValue(suffixWord);
}
// Handle the classical variants of modern inflections
//
if (this.classicalInflectionPluralizationService.existsInFirst(suffixWord)) {
return prefixWord + this.classicalInflectionPluralizationService.getSecondValue(suffixWord);
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["trix"], (s) => `${s.slice(0, -1)}ces`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["eau", "ieu"], (s) => `${s}x`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
if (this.wordsEndingWithInxAnxYnxPluralizationService.existsInFirst(suffixWord)) {
return prefixWord + this.wordsEndingWithInxAnxYnxPluralizationService.getSecondValue(suffixWord);
}
// [cs]h and ss that take es as plural form
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["ch", "sh", "ss"], (s) => `${s}es`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
// f, fe that take ves as plural form
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["alf", "elf", "olf", "eaf", "arf"], (s) => (endsWithIgnoreCase(s, "deaf") ? s : `${s.slice(0, -1)}ves`));
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["nife", "life", "wife"], (s) => `${s.slice(0, -2)}ves`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
// y takes ys as plural form if preceded by a vowel, but ies if preceded by a consonant, e.g. stays, skies
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["ay", "ey", "iy", "oy", "uy"], (s) => `${s}s`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
//
if (endsWithIgnoreCase(suffixWord, "y")) {
return prefixWord + suffixWord.slice(0, -1) + "ies";
}
// handle some of the words o -> os, and [vowel]o -> os, and the rest are o->oes
if (this.oSuffixPluralizationService.existsInFirst(suffixWord)) {
return prefixWord + this.oSuffixPluralizationService.getSecondValue(suffixWord);
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["ao", "eo", "io", "oo", "uo"], (s) => `${s}s`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
if (endsWithIgnoreCase(suffixWord, "o") || endsWithIgnoreCase(suffixWord, "s")) {
return `${prefixWord}${suffixWord}es`;
}
if (endsWithIgnoreCase(suffixWord, "x")) {
return `${prefixWord}${suffixWord}es`;
}
// cats, bags, hats, speakers
return `${prefixWord}${suffixWord}s`;
}
singularize(word) {
if (!word) {
return word;
}
// split it up.
const de = (0, text_manipulation_1.deconstruct)(word);
// singularize the last word only
de[de.length - 1] = this.capitalize(de[de.length - 1], (w) => this.internalSingularize(w));
// return the pascal cased whole thing.
return (0, text_manipulation_1.pascalCase)(de);
}
internalSingularize(word) {
// words that we know of
if (this.userDictionary.existsInSecond(word)) {
return this.userDictionary.getFirstValue(word);
}
if (this.isNoOpWord(word)) {
return word;
}
const { prefixWord, suffixWord } = this.getSuffixWord(word);
if (this.isNoOpWord(suffixWord)) {
return prefixWord + suffixWord;
}
// handle the word that is the same as the plural form
if (this.isUninflective(suffixWord)) {
return prefixWord + suffixWord;
}
// if word is one of the known singular words, then just return
if (this.knownSingluarWords.includes(suffixWord.toLowerCase())) {
return prefixWord + suffixWord;
}
// handle simple irregular verbs, e.g. was -> were
if (this.irregularVerbPluralizationService.existsInSecond(suffixWord)) {
return prefixWord + this.irregularVerbPluralizationService.getFirstValue(suffixWord);
}
// handle irregular plurals, e.g. "ox" -> "oxen"
if (this.irregularPluralsPluralizationService.existsInSecond(suffixWord)) {
return prefixWord + this.irregularPluralsPluralizationService.getFirstValue(suffixWord);
}
// handle singluarization for words ending with sis and pluralized to ses,
// e.g. "ses" -> "sis"
if (this.wordsEndingWithSisPluralizationService.existsInSecond(suffixWord)) {
return prefixWord + this.wordsEndingWithSisPluralizationService.getFirstValue(suffixWord);
}
// handle words ending with se, e.g. "ses" -> "se"
if (this.wordsEndingWithSePluralizationService.existsInSecond(suffixWord)) {
return prefixWord + this.wordsEndingWithSePluralizationService.getFirstValue(suffixWord);
}
// handle words ending with sus, e.g. "suses" -> "sus"
if (this.wordsEndingWithSusPluralizationService.existsInSecond(suffixWord)) {
return prefixWord + this.wordsEndingWithSusPluralizationService.getFirstValue(suffixWord);
}
let newSuffixWord;
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["men"], (s) => `${s.slice(0, -2)}an`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
// handle irregular inflections for common suffixes, e.g. "mouse" -> "mice"
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["lice", "mice"], (s) => `${s.slice(0, -3)}ouse`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["teeth"], (s) => `${s.slice(0, -4)}ooth`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["geese"], (s) => `${s.slice(0, -4)}oose`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["feet"], (s) => `${s.slice(0, -3)}oot`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["zoa"], (s) => `${s.slice(0, -2)}oon`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
// [cs]h and ss that take es as plural form, this is being moved up since the sses will be override by the ses
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["ches", "shes", "sses"], (s) => s.slice(0, -2));
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
// handle assimilated classical inflections, e.g. vertebra -> vertebrae
if (this.assimilatedClassicalInflectionPluralizationService.existsInSecond(suffixWord)) {
return prefixWord + this.assimilatedClassicalInflectionPluralizationService.getFirstValue(suffixWord);
}
// Handle the classical variants of modern inflections
//
if (this.classicalInflectionPluralizationService.existsInSecond(suffixWord)) {
return prefixWord + this.classicalInflectionPluralizationService.getFirstValue(suffixWord);
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["trices"], (s) => `${s.slice(0, -3)}x`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["eaux", "ieux"], (s) => s.slice(0, -1));
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
if (this.wordsEndingWithInxAnxYnxPluralizationService.existsInSecond(suffixWord)) {
return prefixWord + this.wordsEndingWithInxAnxYnxPluralizationService.getFirstValue(suffixWord);
}
// f, fe that take ves as plural form
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["alves", "elves", "olves", "eaves", "arves"], (s) => `${s.slice(0, -3)}f`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["nives", "lives", "wives"], (s) => `${s.slice(0, -3)}fe`);
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
// y takes ys as plural form if preceded by a vowel, but ies if preceded by a consonant, e.g. stays, skies
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["ays", "eys", "iys", "oys", "uys"], (s) => s.slice(0, -1));
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
//
if (endsWithIgnoreCase(suffixWord, "ies")) {
return prefixWord + suffixWord.slice(0, -3) + "y";
}
// handle some of the words o -> os, and [vowel]o -> os, and the rest are o->oes
if (this.oSuffixPluralizationService.existsInSecond(suffixWord)) {
return prefixWord + this.oSuffixPluralizationService.getFirstValue(suffixWord);
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["aos", "eos", "ios", "oos", "uos"], (s) => s.slice(0, -1));
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
//
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["ces"], (s) => s.slice(0, -1));
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
newSuffixWord = PluralizationServiceUtil.TryInflectOnSuffixInWord(suffixWord, ["ces", "ses", "xes"], (s) => s.slice(0, -2));
if (newSuffixWord !== null) {
return prefixWord + newSuffixWord;
}
if (endsWithIgnoreCase(suffixWord, "oes")) {
return prefixWord + suffixWord.slice(0, -2);
}
if (endsWithIgnoreCase(suffixWord, "ss")) {
return prefixWord + suffixWord;
}
if (endsWithIgnoreCase(suffixWord, "s")) {
return prefixWord + suffixWord.slice(0, -1);
}
// word is a singlar
return prefixWord + suffixWord;
}
/// <summary>
/// captalize the return word if the parameter is capitalized
/// if word is "Table", then return "Tables"
/// </summary>
/// <param name="word"></param>
/// <param name="action"></param>
/// <returns></returns>
capitalize(word, action) {
const result = action(word);
if (this.isCapitalized(word)) {
if (result.length === 0) {
return result;
}
return result.charAt(0).toUpperCase() + result.slice(1);
}
else {
return result;
}
}
/// <summary>
/// separate one combine word in to two parts, prefix word and the last word(suffix word)
/// </summary>
/// <param name="word"></param>
/// <param name="prefixWord"></param>
/// <returns></returns>
getSuffixWord(word) {
// use the last space to separate the words
const lastSpaceIndex = word.lastIndexOf(" ");
return {
prefixWord: word.slice(0, lastSpaceIndex + 1),
suffixWord: word.slice(lastSpaceIndex + 1),
};
//
}
isCapitalized(word) {
if (word === "") {
return false;
}
return word.charAt(0) == word.charAt(0).toUpperCase();
}
isAlphabets(word) {
// return false when the word is "[\s]*" or leading or tailing with spaces
// or contains non alphabetical characters
if (word === "" || word !== word.trim() || /[^a-zA-Z\\s]/.test(word)) {
return false;
}
else {
return true;
}
}
isUninflective(word) {
if (PluralizationServiceUtil.DoesWordContainSuffix(word, this.uninflectiveSuffixList) ||
(word.toLowerCase() !== word && word.endsWith("ese")) ||
this.uninflectiveWordList.includes(word.toLowerCase())) {
return true;
}
else {
return false;
}
}
/// <summary>
/// return true when the word is "[\s]*" or leading or tailing with spaces
/// or contains non alphabetical characters
/// </summary>
/// <param name="word"></param>
/// <returns></returns>
isNoOpWord(word) {
if (!this.isAlphabets(word) || word.length <= 1 || this.pronounList.includes(word.toLowerCase())) {
return true;
}
else {
return false;
}
}
/// <summary>
/// This method allow you to add word to internal PluralizationService of English.
/// If the singluar or the plural value was already added by this method, then an ArgumentException will be thrown.
/// </summary>
/// <param name="singular"></param>
/// <param name="plural"></param>
addWord(singular, plural) {
if (this.userDictionary.existsInSecond(plural)) {
throw new Error(`The plural value '${plural}' already exists in the user-defined dictionary.`);
}
else if (this.userDictionary.existsInFirst(singular)) {
throw new Error(`The singular value '${singular}' already exists in the user-defined dictionary.`);
}
else {
this.userDictionary.addValue(singular, plural);
}
}
}
exports.EnglishPluralizationService = EnglishPluralizationService;
//# sourceMappingURL=pluralization.js.map