UNPKG

@universis/number-format

Version:

Universis library for converting number to text

165 lines 6.49 kB
"use strict"; exports.__esModule = true; exports.NumberFormatter = void 0; var locales_1 = require("./locales"); var registeredLocales = { el: locales_1.LOCALES.el, en: locales_1.LOCALES.en }; var NumberFormatter = /** @class */ (function () { function NumberFormatter() { } /** * Registers the given local configuration * @param locale * @param configuration */ NumberFormatter.registerLocale = function (locale, configuration) { Object.defineProperty(registeredLocales, locale, { configurable: true, enumerable: true, writable: true, value: configuration }); }; /** * Creates a new instance of NumberFormatter class */ NumberFormatter.create = function () { return new NumberFormatter(); }; NumberFormatter.prototype.formatIntegerPart = function (number, locale) { // format number var currentLocale = registeredLocales[locale]; var result = ''; var nextValue = number; var keys = currentLocale.values.map(function (key) { return key[0]; }); // if nextValue is zero return zero string if (nextValue === 0) { var findZero = currentLocale.values.find(function (key) { return key[0] === '0'; }); if (findZero) { result = findZero[1]; } return result; } // enumerate formatter keys for (var index = 0; index < keys.length; index++) { var key = keys[index]; // convert property value to number var divider = parseFloat(key); // divide object var nextResult = Math.floor(nextValue / divider); if (nextResult >= 1) { if (nextResult > 1) { result += " "; result += this.formatIntegerPart(nextResult, locale); } var value = currentLocale.values[index][1]; if (typeof value === 'string') { result += " "; result += value; } else if (typeof value === 'object') { result += " "; if (nextResult === 1 && nextValue > divider && Object.prototype.hasOwnProperty.call(value, 'more')) { result += value.more; } else { result += nextResult === 1 ? value.one : value.many; } } else { throw new Error('Invalid number formatter provider value.'); } } // get next value nextValue = nextValue % divider; // if value is zero break and exit if (nextValue === 0) { break; } // otherwise continue } // trim result return result.trim(); }; NumberFormatter.prototype.formatFractionalPart = function (number, locale, fractionDigits) { if (number < 0) { throw new Error('Fractional part of a number cannot be less than zero'); } // if number is zero if (number === 0) { // do nothing return ''; } var currentLocale = registeredLocales[locale]; // get values lower than 1 var values = currentLocale.values.map(function (key) { return parseFloat(key[0]); }); var result; // enumerate locale values for (var i = 0; i < values.length; i++) { var value = values[i]; // test value that it is lower than 1 e.g. 0.01 if (value > 0 && value < 1) { var valueText = currentLocale.values[i][0]; // if result is greater or equal to 1 if (valueText.length - 2 === fractionDigits) { // get key value var keyValue = currentLocale.values[i]; // format number e.g. 45 => a cardinal number result = this.formatIntegerPart(number, locale); result += " "; // and get key value description if (typeof keyValue === 'string') { result += keyValue[1]; } else if (typeof keyValue === 'object') { result += number === 1 ? keyValue[1].one : keyValue[1].many; } else { throw new Error('Invalid number formatter provider value.'); } break; } } } return result; }; NumberFormatter.prototype.format = function (number, locale, fractionDigits) { if (Object.prototype.hasOwnProperty.call(registeredLocales, locale) === false) { throw new Error("The specified locale is missing for registered locales."); } // format number var currentLocale = registeredLocales[locale]; // get integer part var numberString = fractionDigits ? number.toFixed(fractionDigits) : number.toString(); var integerPart = parseInt(/^(\d+)\.?/.exec(numberString)[0]); var result = this.formatIntegerPart(integerPart, locale); var fractionalMatch = /\.(\d+)$/.exec(numberString); if (fractionalMatch) { var fractionalPart = Math.round(Number((parseFloat(fractionalMatch[0]) * Math.pow(10, fractionalMatch[1].length)).toFixed(0))); var fractionalResult = this.formatFractionalPart(fractionalPart, locale, fractionDigits ? fractionDigits : fractionalMatch[1].length); if (fractionalResult && fractionalResult.length) { result += " "; if (currentLocale.decimalSeparator && currentLocale.decimalSeparator.length) { result += currentLocale.decimalSeparator; result += " "; } result += fractionalResult; } } if (typeof currentLocale.spellcheck === 'function') { result = currentLocale.spellcheck(result); } return result; }; return NumberFormatter; }()); exports.NumberFormatter = NumberFormatter; //# sourceMappingURL=NumberFormatter.js.map