@technobuddha/library
Version:
A large library of useful functions
431 lines (430 loc) • 10.3 kB
JavaScript
import isUndefined from 'lodash/isUndefined';
import { empty, space } from '../constants';
import matchCase from '../matchCase';
/**
* Return the plural version of the input string
*
* @param input The word to pluralize
* @param quantity The quantity to prepend to the word. If omitted nothing is prepended. If quantity is one the singular form is returned.
* @returns The plural form of the input, or if a quantity is supplied - the quantity and the singular/plural form of the input (whichever is appropriate)
*/
export function plural(input, quantity) {
if (quantity === 1 || quantity === -1)
return quantity.toString() + space + input;
let lc = input.toLowerCase();
let suffix = empty;
let prefix = empty;
let result = null;
for (const p of database.prefixes) {
if (lc.startsWith(p)) {
prefix = p;
lc = lc.slice(p.length);
break;
}
}
for (const s of database.suffixes) {
if (lc.endsWith(s)) {
suffix = s;
lc = lc.slice(0, Math.max(0, lc.length - s.length));
break;
}
}
if (database.uncountableWords.includes(lc))
result = matchCase(prefix + lc + suffix, input);
if (!result && lc in database.irregulars)
result = matchCase(prefix + database.irregulars[lc] + suffix, input);
if (!result) {
for (const v of database.uncountableRules) {
if (v.test(lc)) {
result = matchCase(prefix + lc + suffix, input);
break;
}
}
}
if (!result) {
for (const v of database.rules) {
if (v[0].test(lc)) {
result = matchCase(prefix + lc.replace(v[0], v[1]) + suffix, input);
break;
}
}
}
if (!result)
result = matchCase(`${prefix}${lc}s${suffix}`, input);
return isUndefined(quantity) ? result : (quantity.toString() + space + result);
}
const database = {
/* cspell:disable */
'rules': [
[/(stig|sto|dog|sche|anathe)ma$/ui, '$1mata'],
[/(alumn|alg|antenn|ecclesi|faun|formul|larv|nebul|vertebr)a$/ui, '$1ae'],
[/child$/ui, 'children'],
[/(giraf|sa)fe$/ui, '$1fes'],
[/fe$/ui, 'ves'],
[/(l|m)ouse$/ui, '$1ice'],
[/goose$/ui, 'geese'],
[/zampone$/ui, 'zamponi'],
[/ff$/ui, 'ffs'],
[/(belie|brie|che|chie|cle|gul|i|proo|roo)f$/ui, '$1fs'],
[/(its|her|him|them)self$/ui, 'themselves'],
[/f$/ui, 'ves'],
[/tooth$/ui, 'teeth'],
[/(epo|matriar|patriar|stoma)ch$/ui, '$1chs'],
[/([sc])h$/ui, '$1hes'],
[/(aqua)rium$/ui, '$1ira'],
[/(seraph|cherub)im$/ui, '$1im'],
[/(memorand|millenni|ov|quor|strat|symposi)um$/ui, '$1a'],
[/(addend|agend|automat|bacteri|curricul|dat|desiderat|endotheli|errat|extrem|fusari|medi)um$/ui, '$1a'],
[/(m|wom)an/ui, '$1en'],
[/(criteri|hedr|heli|phenomen|prolegomen|organ)on$/ui, '$1a'],
[/person$/ui, 'people'],
[/(alt|armadill|boler|bong|bronc|cell|dynam|embarg|hal|hell|gazeb|gyr|jumb|kil|lim)o$/ui, '$1os'],
[/(maestr|metr|mosquit|octav|pian|piccol|pint|phot|ponch|sil|sombrer|sopran|stere|stilett)o$/ui, '$1os'],
[/(temp|tornad|tors|tw|volcan)o$/ui, '$1os'],
[/([^aeiou])o$/ui, '$1oes'],
[/(gen|visc)us$/ui, '$1era'],
[/(alumn|bacill|cirr|cact|foc|fung|hippopotam|loc|nucle|octop|radi|pegas|stimul|strat|syllab|termin|uter)us$/ui, '$1i'],
[/(ax|analys|antithes|bas|cris|diagnos|ellips|emphas|hypothes|neuros|oas|paralys|synthes|synops|test|thes)is$/ui, '$1es'],
[/(ephemer)is$/ui, '$1ides'],
[/(bu|ga)s$/ui, '$1sses'],
[/(corp)us$/ui, '$1ora'],
[/s$/ui, 'ses'],
[/foot$/ui, 'feet'],
[/(b|bur|chat|tabl)eau$/ui, '$1eaux'],
[/(whisk)ey$/ui, '$1ies'],
[/([^aeiou]|qu)y$/ui, '$1ies'],
[/(append|matr)ix$/ui, '$1ices'],
[/(cod|ind|mur|vert)ex$/ui, '$1ices'],
[/(ap)ex$/ui, '$1ices'],
[/x$/ui, 'xes'],
[/(fez|qui)z$/ui, '$1zzes'],
[/z$/ui, 'zes'],
],
'uncountableRules': [
/(adult|child)hood$/ui,
/craft$/ui,
/deer$/ui,
/fish$/ui,
/measles$/ui,
/pox$/ui,
/sheep$/ui,
/wood$/ui,
/ographuy$/ui,
/itis$/ui,
/ology$/ui,
/[hw]ealth$/ui,
/bage$/ui,
/llows$/ui,
/ment$/ui,
/friut$/ui,
/tion$/ui,
/work$/ui,
/ing$/ui,
/ism$/ui,
/tics$/ui,
/moose$/ui,
/trout$/ui,
],
/* cspell: enable */
'uncountableWords': [
'abroad',
'acoustics',
'advice',
'aid',
'air',
'alcohol',
'alms',
'alpenglow',
'aluminum',
'ammo',
'anger',
'anime',
'applause',
'arithmetic',
'art',
'athletics',
'audio',
'awareness',
'barracks',
'bad',
'bakeware',
'beyond',
'bifocals',
'binoculars',
'bison',
'blood',
'bloomers',
'blouse',
'boots',
'bourgeois',
'bowling',
'bricklaying',
'butter',
'calculus',
'cappuccino',
'caribou',
'carp',
'cash',
'casino',
'castanets',
'cattle',
'celeriac',
'chafe',
'chalk',
'chaos',
'chassis',
'chess',
'children',
'chino',
'clippers',
'cod',
'commerce',
'concrete',
'corps',
'courage',
'deadness',
'debris',
'deer',
'diabetes',
'dirt',
'disco',
'doldrums',
'dungarees',
'economics',
'egg',
'electricity',
'elk',
'energy',
'ethics',
'expertise',
'fauna',
'faux pas',
'fedelini',
'fibre',
'fiberglass',
'flesh',
'flounder',
'forestry',
'fun',
'furniture',
'gain',
'glass',
'glasses',
'golf',
'graffiti',
'gratitude',
'grief',
'grouse',
'guidance',
'guilt',
'haddock',
'happiness',
'hardware',
'hair',
'halibut',
'headquarters',
'helium',
'helo',
'help',
'herpes',
'high jinks',
'homework',
'housework',
'humidity',
'humour',
'hypochondria',
'hypothermia',
'ides',
'ikebana',
'importance',
'impudence',
'incandescence',
'indigence',
'innocence',
'insignia',
'jeans',
'jodhpur',
'judo',
'justice',
'karate',
'kendo',
'knickers',
'knowledge',
'kudos',
'labour',
'laughter',
'leisure',
'legal',
'literature',
'livestock',
'loneliness',
'lycra',
'lye',
'macaroni',
'machinery',
'mackerel',
'macrame',
'magic',
'mail',
'manga',
'mambo',
'mankind',
'math',
'means',
'media',
'methane',
'mews',
'might',
'most',
'mud',
'mullet',
'multimedia',
'music',
'neon',
'news',
'nitrogen',
'normal',
'oatmeal',
'obedience',
'opium',
'osmosis',
'outback',
'oxygen',
'pants',
'pantology',
'pantyhose',
'passion',
'patience',
'peace',
'penicillin',
'permafrost',
'physics',
'pike',
'plankton',
'platinum',
'plenty',
'pliers',
'police',
'polo',
'premises',
'propane',
'prose',
'pseudoscience',
'pyjamas',
'quicksand',
'radio',
'random',
'rain',
'rendezvous',
'reinscription',
'relief',
'research',
'rice',
'salmon',
'septicaemia',
'school',
'schoolchild',
'scissors',
'series',
'sewage',
'shambles',
'shorts',
'shrimp',
'sick',
'smithereens',
'smog',
'soccer',
'software',
'soot',
'soy',
'species',
'squid',
'staff',
'stamina',
'stupid',
'subconscious',
'subsidence',
'sugar',
'sunglasses',
'sunshine',
'sushi',
'suspenders',
'sweats',
'sweet',
'sweets',
'swine',
'temporariness',
'terracotta',
'tennis',
'thanks',
'them',
'tights',
'timpani',
'titanium',
'tongs',
'tonight',
'tortellini',
'traffic',
'trigonometry',
'trousers',
'tuna',
'tweezers',
'underclothes',
'underneath',
'underpants',
'underwear',
'veal',
'vermicelli',
'video',
'vinyl',
'virus',
'violence',
'viscose',
'warmth',
'weedkiller',
'welfare',
'wheat',
'whitebait',
'wildebeest',
'wildlife',
'worth',
'yoga',
'you',
'young',
],
'irregulars': {
'i': 'we',
'me': 'us',
'he': 'they',
'she': 'they',
'is': 'are',
'was': 'were',
'has': 'have',
'this': 'these',
'that': 'those',
'die': 'dice',
'ox': 'oxen',
},
/* cspell: disable */
'suffixes': [
'-up',
'-out',
'-in-law',
'-in-trade',
],
'prefixes': [
'anti-',
'bi-',
'co-',
'semi-',
'mal-',
'ex-',
'sub-',
'dis-',
'non-',
'un-',
'over-',
],
/* cspell: enable */
};
export default plural;