UNPKG

@technobuddha/library

Version:
294 lines (288 loc) 6.22 kB
const TESTS: [string, RegExp][] = [ [ 'an', /^[aefhilmnirsx]([-.]|$|th$)/ui ], [ 'a', /^[bcdgjkpqtuvwyz]([-.]|$|th$)/ui ], [ 'an', /^(euler|hour(?!i)|heir|honest|hono)/ui ], [ 'an', /^(?!FJO|[HLMNS]Y.|RY[EO]|SQU|(F[LR]?|[HL]|MN?|N|RH?|S[CHKLMNPTVW]?|X(YL)?)[AEIOU])[FHLMNRSX][A-Z]/u ], [ 'a', /^[^aeiouy]/ui ], [ 'a', /^e[uw]/ui ], [ 'a', /^onc?e\b/u ], [ 'a', /^uni([^nmd]|mo)/ui ], [ 'an', /^ut[th]/ui ], [ 'a', /^u[bcfhjkqrst][aeiou]/ui ], [ 'a', /^U[NK][AIEO]?/u ], [ 'an', /^[aeiou]/ui ], [ 'an', /^y(b[lor]|cl[ea]|fere|gg|p[ios]|rou|tt)/ui ], ]; type Options = { /** only return the indefinite article, do not combine with the input */ only?: boolean; }; /** * Determine the appropriate indefinite article to use with a word. * * @remarks The answer is derived from a simple rules engine, it attempts to cover most exceptions * to the rules, but the English language has lots of quirks, and this rules engine can not cover them * all * * @param word The word * @param __namedParameters see {@link Options} * @default only false * @returns The appropriate indefinite article ("a" or "an") combined with the input word. If the only * option is used, only the indefinite article is returned. */ export function indefiniteArticle(word: string, { only = false }: Options = {}): string { let result = 'a'; for(const [ article, rule ] of TESTS) { if(rule.test(word)) { result = article; break; } } return only ? result : `${result} ${word}`; } export default indefiniteArticle; /* for(const [a, w] of [ ['an', 'Ath'], ['a', 'Bth'], ['a', 'Cth'], ['a', 'Dth'], ['an', 'Eth'], ['an', 'Fth'], ['a', 'Gth'], ['an', 'Hth'], ['an', 'Ith'], ['a', 'Jth'], ['a', 'Kth'], ['an', 'Lth'], ['an', 'Mth'], ['an', 'Nth'], ['an', 'Oth'], ['a', 'Pth'], ['a', 'Qth'], ['an', 'Rth'], ['an', 'Sth'], ['a', 'Tth'], ['a', 'Uth'], ['a', 'Vth'], ['a', 'Wth'], ['an', 'Xth'], ['a', 'Yth'], ['a', 'Zth'], ['an', 'a-th'], ['a', 'b-th'], ['a', 'c-th'], ['a', 'd-th'], ['an', 'e-th'], ['an', 'f-th'], ['a', 'g-th'], ['an', 'h-th'], ['an', 'i-th'], ['a', 'j-th'], ['a', 'k-th'], ['an', 'l-th'], ['an', 'm-th'], ['an', 'n-th'], ['an', 'o-th'], ['a', 'p-th'], ['a', 'q-th'], ['an', 'r-th'], ['an', 's-th'], ['a', 't-th'], ['a', 'u-th'], ['a', 'v-th'], ['a', 'w-th'], ['an', 'x-th'], ['a', 'y-th'], ['a', 'z-th'], ['an', 'A.B.C'], ['an', 'AI'], ['an', 'AGE'], ['an', 'agendum'], ['an', 'aide-de-camp'], ['an', 'albino'], ['a', 'B.L.T. sandwich'], ['a', 'BMW'], ['a', 'BLANK'], ['a', 'bacterium'], ['a', 'Burmese restaurant'], ['a', 'C.O.'], ['a', 'CCD'], ['a', 'COLON'], ['a', 'cameo'], ['a', 'CAPITAL'], ['a', 'D.S.M.'], ['a', 'DNR'], ['a', 'DINNER'], ['a', 'dynamo'], ['an', 'E.K.G.'], ['an', 'ECG'], ['an', 'EGG'], ['an', 'embryo'], ['an', 'erratum'], ['a', 'eucalyptus'], ['an', 'Euler number'], ['a', 'eulogy'], ['a', 'euphemism'], ['a', 'euphoria'], ['a', 'ewe'], ['a', 'ewer'], ['an', 'extremum'], ['an', 'eye'], ['an', 'F.B.I. agent'], ['an', 'FSM'], ['a', 'FACT'], ['a', 'FAQ'], ['an', 'F.A.Q.'], ['a', 'fish'], ['a', 'G-string'], ['a', 'GSM phone'], ['a', 'GOD'], ['a', 'genus'], ['a', 'Governor General'], ['an', 'H-Bomb'], ['an', 'H.M.S Ark Royal'], ['an', 'HSL colour space'], ['a', 'HAL 9000'], ['an', 'H.A.L. 9000'], ['a', 'has-been'], ['a', 'height'], ['an', 'heir'], ['a', 'honed blade'], ['an', 'honest man'], ['a', 'honeymoon'], ['an', 'honorarium'], ['an', 'honorary degree'], ['an', 'honoree'], ['an', 'honorific'], ['a', 'Hough transform'], ['a', 'hound'], ['an', 'hour'], ['an', 'hourglass'], ['a', 'houri'], ['a', 'house'], ['an', 'I.O.U.'], ['an', 'IQ'], ['an', 'IDEA'], ['an', 'inferno'], ['an', 'Inspector General'], ['a', 'jumbo'], ['a', 'knife'], ['an', 'L.E.D.'], ['a', 'LED'], ['an', 'LCD'], ['a', 'lady in waiting'], ['a', 'leaf'], ['an', 'M.I.A.'], ['a', 'MIASMA'], ['an', 'MTV channel'], ['a', 'Major General'], ['an', 'N.C.O.'], ['an', 'NCO'], ['a', 'NATO country'], ['a', 'note'], ['an', 'O.K.'], ['an', 'OK'], ['an', 'OLE'], ['an', 'octavo'], ['an', 'octopus'], ['an', 'okay'], ['a', 'once-and-future-king'], ['an', 'oncologist'], ['a', 'one night stand'], ['an', 'onerous task'], ['an', 'opera'], ['an', 'optimum'], ['an', 'opus'], ['an', 'ox'], ['a', 'Ph.D.'], ['a', 'PET'], ['a', 'P.E.T. scan'], ['a', 'plateau'], ['a', 'quantum'], ['an', 'R.S.V.P.'], ['an', 'RSVP'], ['a', 'REST'], ['a', 'reindeer'], ['an', 'S.O.S.'], ['a', 'SUM'], ['an', 'SST'], ['a', 'salmon'], ['a', 'T.N.T. bomb'], ['a', 'TNT bomb'], ['a', 'TENT'], ['a', 'thought'], ['a', 'tomato'], ['a', 'U-boat'], ['a', 'UNESCO representative'], ['a', 'U.F.O.'], ['a', 'UFO'], ['a', 'UK citizen'], ['a', 'ubiquity'], ['a', 'unicorn'], ['an', 'unidentified flying object'], ['a', 'uniform'], ['a', 'unimodal system'], ['an', 'unimpressive record'], ['an', 'uninformed opinion'], ['an', 'uninvited guest'], ['a', 'union'], ['a', 'uniplex'], ['a', 'uniprocessor'], ['a', 'unique opportunity'], ['a', 'unisex hairdresser'], ['a', 'unison'], ['a', 'unit'], ['a', 'unitarian'], ['a', 'united front'], ['a', 'unity'], ['a', 'univalent bond'], ['a', 'univariate statistic'], ['a', 'universe'], ['an', 'unordered meal'], ['a', 'uranium atom'], ['an', 'urban myth'], ['an', 'urbane miss'], ['an', 'urchin'], ['a', 'urea detector'], ['a', 'urethane monomer'], ['an', 'urge'], ['an', 'urgency'], ['a', 'urinal'], ['an', 'urn'], ['a', 'usage'], ['a', 'use'], ['an', 'usher'], ['a', 'usual suspect'], ['a', 'usurer'], ['a', 'usurper'], ['a', 'utensil'], ['a', 'utility'], ['an', 'utmost urgency'], ['a', 'utopia'], ['an', 'utterance'], ['a', 'V.I.P.'], ['a', 'VIPER'], ['a', 'viper'], ['an', 'X-ray'], ['an', 'X.O.'], ['a', 'XYLOPHONE'], ['an', 'XY chromosome'], ['a', 'xenophobe'], ['a', 'Y-shaped pipe'], ['a', 'Y.Z. plane'], ['a', 'YMCA'], ['an', 'YBLENT eye'], ['an', 'yblent eye'], ['an', 'yclad body'], ['a', 'yellowing'], ['a', 'yield'], ['a', 'youth'], ['a', 'youth'], ['an', 'ypsiliform junction'], ['an', 'yttrium atom'], ['a', 'zoo'], ]) { const ia = indefiniteArticle(w); } */