UNPKG

@phensley/cldr-core

Version:
259 lines 14.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var context_1 = require("./context"); var number_1 = require("../../parsing/patterns/number"); var cache_1 = require("../../utils/cache"); var util_1 = require("./util"); var render_1 = require("./render"); /** * Number internal engine singleton, shared across all locales. */ var NumberInternalsImpl = /** @class */ (function () { function NumberInternalsImpl(internals, cacheSize) { if (cacheSize === void 0) { cacheSize = 50; } this.internals = internals; var schema = internals.schema; this.currencies = schema.Currencies; this.numbers = schema.Numbers; this.numberPatternCache = new cache_1.Cache(number_1.parseNumberPattern, cacheSize); } NumberInternalsImpl.prototype.stringRenderer = function (params) { return new render_1.StringNumberFormatter(params); }; NumberInternalsImpl.prototype.partsRenderer = function (params) { return new render_1.PartsNumberFormatter(params); }; NumberInternalsImpl.prototype.getCurrencySymbol = function (bundle, code, width) { var alt = width === 'narrow' ? 'narrow' : 'none'; return this.currencies.symbol.get(bundle, alt, code) || this.currencies.symbol.get(bundle, 'none', code); }; NumberInternalsImpl.prototype.getCurrencyDisplayName = function (bundle, code) { return this.currencies.displayName.get(bundle, code); }; NumberInternalsImpl.prototype.getCurrencyPluralName = function (bundle, code, plural) { return this.currencies.pluralName.get(bundle, plural, code); }; NumberInternalsImpl.prototype.getNumberPattern = function (raw, negative) { return this.numberPatternCache.get(raw)[negative ? 1 : 0]; }; NumberInternalsImpl.prototype.formatDecimal = function (bundle, renderer, n, options, params) { // TODO: abstract away pattern selection defaulting var style = options.style === undefined ? 'decimal' : options.style; var result; var plural = 'other'; var latnInfo = this.numbers.numberSystem.get('latn'); var info = this.numbers.numberSystem.get(params.numberSystemName) || latnInfo; var decimalFormats = info.decimalFormats; var latnDecimalFormats = this.numbers.numberSystem.get('latn').decimalFormats; var standardRaw = decimalFormats.standard.get(bundle) || latnDecimalFormats.standard.get(bundle); switch (style) { case 'long': case 'short': { var isShort = style === 'short'; var useLatn = decimalFormats.short.get(bundle, 'other', 4); var patternImpl = isShort ? (useLatn ? latnInfo.decimalFormats.short : decimalFormats.short) : (useLatn ? latnInfo.decimalFormats.long : decimalFormats.long); var ctx = new context_1.NumberContext(options, true); // Adjust the number using the compact pattern and divisor. var _a = this.setupCompact(bundle, n, ctx, standardRaw, patternImpl), q2 = _a[0], ndigits = _a[1]; // Compute the plural category for the final q2. var operands = q2.operands(); plural = this.internals.plurals.cardinal(bundle.language(), operands); // Select the final pluralized compact pattern based on the integer // digits of n and the plural category of the rounded / shifted number q2. var raw = patternImpl.get(bundle, plural, ndigits)[0] || standardRaw; if (raw === '0') { raw = standardRaw; } // Re-select pattern as number may have changed sign due to rounding. var pattern = this.getNumberPattern(raw, q2.isNegative()); result = renderer.render(q2, pattern, '', '', ctx.minInt, options.group); break; } case 'percent': case 'percent-scaled': case 'permille': case 'permille-scaled': { // Get percent pattern. var raw = info.percentFormat.get(bundle) || latnInfo.percentFormat.get(bundle); var pattern = this.getNumberPattern(raw, n.isNegative()); // Scale the number to a percent or permille form as needed. if (style === 'percent') { n = n.movePoint(2); } else if (style === 'permille') { n = n.movePoint(3); } // Select percent or permille symbol. var symbol = (style === 'percent' || style === 'percent-scaled') ? params.symbols.percentSign : params.symbols.perMille; // Adjust number using pattern and options, then render. var ctx = new context_1.NumberContext(options, false, -1); ctx.setPattern(pattern); n = ctx.adjust(n); var operands = n.operands(); plural = this.internals.plurals.cardinal(bundle.language(), operands); // Re-select pattern as number may have changed sign due to rounding. pattern = this.getNumberPattern(raw, n.isNegative()); result = renderer.render(n, pattern, '', symbol, ctx.minInt, options.group); break; } case 'decimal': { // Get decimal pattern. var pattern = this.getNumberPattern(standardRaw, n.isNegative()); // Adjust number using pattern and options, then render. var ctx = new context_1.NumberContext(options, false, -1); ctx.setPattern(pattern); n = ctx.adjust(n); var operands = n.operands(); plural = this.internals.plurals.cardinal(bundle.language(), operands); // Re-select pattern as number may have changed sign due to rounding. pattern = this.getNumberPattern(standardRaw, n.isNegative()); result = renderer.render(n, pattern, '', '', ctx.minInt, options.group); break; } default: result = renderer.empty(); break; } // No valid style matched return [result, plural]; }; NumberInternalsImpl.prototype.formatCurrency = function (bundle, renderer, n, code, options, params) { var fractions = util_1.getCurrencyFractions(code); // TODO: display context support // const width = options.symbolWidth === 'narrow' ? Alt.NARROW : Alt.NONE; var width = options.symbolWidth === 'narrow' ? 'narrow' : 'none'; var style = options.style === undefined ? 'symbol' : options.style; var latnInfo = this.numbers.numberSystem.get('latn'); var info = this.numbers.numberSystem.get(params.numberSystemName) || latnInfo; var currencyFormats = info.currencyFormats; var latnDecimalFormats = this.numbers.numberSystem.get('latn').decimalFormats; var standardRaw = currencyFormats.standard.get(bundle) || latnDecimalFormats.standard.get(bundle); switch (style) { case 'code': case 'name': { var raw = info.decimalFormats.standard.get(bundle) || latnInfo.decimalFormats.standard.get(bundle); var pattern = this.getNumberPattern(raw, n.isNegative()); // Adjust number using pattern and options, then render. var ctx = new context_1.NumberContext(options, false, fractions.digits); ctx.setPattern(pattern); n = ctx.adjust(n); // Re-select pattern as number may have changed sign due to rounding. pattern = this.getNumberPattern(raw, n.isNegative()); var num = renderer.render(n, pattern, '', '', ctx.minInt, options.group); // Compute plural category and select pluralized unit. var operands = n.operands(); var plural = this.internals.plurals.cardinal(bundle.language(), operands); var unit = style === 'code' ? code : this.getCurrencyPluralName(bundle, code, plural); // Wrap number and unit together. var unitWrapper = currencyFormats.unitPattern.get(bundle, plural) || latnInfo.currencyFormats.unitPattern.get(bundle, plural); return renderer.wrap(this.internals.wrapper, unitWrapper, num, renderer.make('unit', unit)); } case 'short': { // The extra complexity here is to deal with rounding up and selecting the // correct pluralized pattern for the final rounded form. var patternImpl = currencyFormats.short; var ctx = new context_1.NumberContext(options, true, fractions.digits); var symbol = this.currencies.symbol.get(bundle, width, code); // Adjust the number using the compact pattern and divisor. var _a = this.setupCompact(bundle, n, ctx, standardRaw, patternImpl), q2 = _a[0], ndigits = _a[1]; // Compute the plural category for the final q2. var operands = q2.operands(); var plural = this.internals.plurals.cardinal(bundle.language(), operands); // Select the final pluralized compact pattern based on the integer // digits of n and the plural category of the rounded / shifted number q2. var raw = patternImpl.get(bundle, plural, ndigits)[0] || standardRaw; if (raw === '0') { raw = standardRaw; } var pattern = this.getNumberPattern(raw, q2.isNegative()); return renderer.render(q2, pattern, symbol, '', ctx.minInt, options.group); } case 'accounting': case 'symbol': { // Select standard or accounting pattern based on style. var styleArrow = style === 'symbol' ? currencyFormats.standard : currencyFormats.accounting; var raw = styleArrow.get(bundle); if (!raw) { styleArrow = style === 'symbol' ? latnInfo.currencyFormats.standard : latnInfo.currencyFormats.accounting; raw = styleArrow.get(bundle); } var pattern = this.getNumberPattern(raw, n.isNegative()); // Adjust number using pattern and options, then render. var ctx = new context_1.NumberContext(options, false, fractions.digits); ctx.setPattern(pattern); n = ctx.adjust(n); // Re-select pattern as number may have changed sign due to rounding. pattern = this.getNumberPattern(raw, n.isNegative()); var symbol = this.currencies.symbol.get(bundle, width, code); return renderer.render(n, pattern, symbol, '', ctx.minInt, options.group); } } // No valid style matched return renderer.empty(); }; /** * Setup for a compact pattern. Returns the adjusted number and digits for * selecting the pluralized pattern. * * The extra complexity here is to deal with rounding up and selecting the * correct pluralized pattern for the final rounded form. */ NumberInternalsImpl.prototype.setupCompact = function (bundle, n, ctx, standardRaw, patternImpl) { // Select the correct divisor based on the number of integer digits in n. var negative = n.isNegative(); var ndigits = n.integerDigits(); // Select the initial compact pattern based on the integer digits of n. // The plural category doesn't matter until the final pattern is selected. var raw; var ndivisor = 0; _a = patternImpl.get(bundle, 'other', ndigits), raw = _a[0], ndivisor = _a[1]; var pattern = this.getNumberPattern(raw || standardRaw, negative); var fracDigits = ctx.useSignificant ? -1 : 0; // Move the decimal point of n, producing q1. We always strip trailing // zeros on compact patterns. var q1 = n; if (ndivisor > 0) { q1 = q1.movePoint(-ndivisor); } // Adjust q1 using the compact pattern's parameters, to produce q2. var q1digits = q1.integerDigits(); ctx.setCompact(pattern, q1digits, ndivisor, fracDigits); var q2 = ctx.adjust(q1); var q2digits = q2.integerDigits(); // Check if the number rounded up, adding another integer digit. if (q2digits > q1digits) { // Select a new divisor and pattern. ndigits++; var divisor = 0; _b = patternImpl.get(bundle, 'other', ndigits), raw = _b[0], divisor = _b[1]; pattern = this.getNumberPattern(raw || standardRaw, negative); // If divisor changed we need to divide and adjust again. We don't divide, // we just move the decimal point, since our Decimal type uses a radix that // is a power of 10. Otherwise q2 is ready for formatting. if (divisor > ndivisor) { // We shift right before we move the decimal point. This triggers rounding // of the number at its correct scale. Otherwise we would end up with // 999,999 becoming 0.999999 and half-even rounding truncating the // number to '0M' instead of '1M'. q1 = n.shiftright(divisor); q1 = q1.movePoint(-divisor); ctx.setCompact(pattern, q1.integerDigits(), divisor, fracDigits); q2 = ctx.adjust(q1); } } return [q2, ndigits]; var _a, _b; }; return NumberInternalsImpl; }()); exports.NumberInternalsImpl = NumberInternalsImpl; //# sourceMappingURL=internal.js.map