UNPKG

n2words

Version:

n2words converts a numerical number into a written one, supports 28 languages and has zero dependencies.

138 lines (112 loc) 4.48 kB
import BaseLanguage from '../classes/base-language.js'; // TODO Adapt language to work with {@link BaseLanguage} better export class N2WordsIT extends BaseLanguage { cardinalWords = [ this.zero, 'uno', 'due', 'tre', 'quattro', 'cinque', 'sei', 'sette', 'otto', 'nove', 'dieci', 'undici', 'dodici', 'tredici', 'quattordici', 'quindici', 'sedici', 'diciassette', 'diciotto', 'diciannove', ]; strTens = { '2': 'venti', '3': 'trenta', '4': 'quaranta', '6': 'sessanta' }; exponentPrefixes = [this.zero, 'm', 'b', 'tr', 'quadr', 'quint', 'sest', 'sett', 'ott', 'nov', 'dec']; constructor(options) { options = Object.assign({ negativeWord: 'meno', separatorWord: 'virgola', zero: 'zero' }, options); super(options, []); } accentuate(string) { const splittedString = string.split(' '); const result = splittedString.map(word => { return word.slice(-3) == 'tre' && word.length > 3 ? word.replaceAll('tré', 'tre').slice(0, -3) + 'tré' : word.replaceAll('tré', 'tre'); }); return result.join(' '); } omitIfZero(numberToString) { return numberToString == this.zero ? '' : numberToString; } phoneticContraction(string) { return string.replaceAll('oo', 'o').replaceAll('ao', 'o').replaceAll('io', 'o').replaceAll('au', 'u').replaceAll('iu', 'u'); } tensToCardinal(number) { const tens = Math.floor(number / 10); const units = number % 10; let prefix; prefix = Object.prototype.hasOwnProperty.call(this.strTens, tens) ? this.strTens[tens] : this.cardinalWords[tens].slice(0, -1) + 'anta'; const postfix = this.omitIfZero(this.cardinalWords[units]); return this.phoneticContraction(prefix + postfix); } hundredsToCardinal(number) { const hundreds = Math.floor(number / 100); let prefix = 'cento'; if (hundreds != 1) { prefix = this.cardinalWords[hundreds] + prefix; } const postfix = this.omitIfZero(this.toCardinal(number % 100)); return this.phoneticContraction(prefix + postfix); } thousandsToCardinal(number) { const thousands = Math.floor(number / 1000); let prefix; prefix = thousands == 1 ? 'mille' : this.toCardinal(thousands) + 'mila'; const postfix = this.omitIfZero(this.toCardinal(number % 1000)); return prefix + postfix; } exponentLengthToString(exponentLength) { const prefix = this.exponentPrefixes[Math.floor(exponentLength / 6)]; return exponentLength % 6 == 0 ? prefix + 'ilione' : prefix + 'iliardo'; } bigNumberToCardinal(number) { const digits = [...number.toString()]; let preDigits = digits.length % 3; if (preDigits == 0) { preDigits = 3; } const multiplier = digits.slice(0, preDigits); // first `preDigits` elements const exponent = digits.slice(preDigits); // without the first `preDigits` elements let prefix, postfix; let infix = this.exponentLengthToString(exponent.length); if (multiplier == '1') { prefix = 'un '; } else { prefix = this.toCardinal(Math.trunc(Number(multiplier.join('')))); infix = ' ' + infix.slice(0, -1) + 'i'; // without last element } // TODO ESLint suggestion // eslint-disable-next-line unicorn/consistent-function-scoping const isSetsEqual = (a, b) => a.size == b.size && [...a].every(value => b.has(value)); if (isSetsEqual(new Set(exponent), new Set(['0']))) { postfix = ''; } else { postfix = this.toCardinal(Math.trunc(exponent.join(''))); infix += (postfix.includes(' e ') ? ', ' : ' e '); } return prefix + infix + postfix; } toCardinal(number) { let words = ''; if (number < 20) { words = this.cardinalWords[number]; } else if (number < 100) { words = this.tensToCardinal(Number(number)); } else if (number < 1000) { words = this.hundredsToCardinal(Number(number)); } else if (number < 1_000_000) { words = this.thousandsToCardinal(Number(number)); } else { words = this.bigNumberToCardinal(number); } return this.accentuate(words); } } /** * Converts a value to cardinal (written) form. * @param {number|string|bigint} value Number to be convert. * @param {object} [options] Options for class. * @returns {string} Value in cardinal (written) format. * @throws {Error} Value cannot be invalid. */ export default function floatToCardinal (value, options = {}) { return new N2WordsIT(options).floatToCardinal(value); }