function formatNumberCustom()

in src/formattingService/formattingService.ts [698:801]


    function formatNumberCustom(
        value: number,
        format: string,
        culture: Culture,
        nonScientificOverrideFormat?: string): string {
        let result: string;
        let numberFormatInfo = culture.numberFormat;
        if (isFinite(value)) {
            // Split format by positive[;negative;zero] pattern
            let formatComponents = getComponents(format);
            // Pick a format based on the sign of value
            if (value > 0) {
                format = formatComponents.positive;
            } else if (value === 0) {
                format = formatComponents.zero;
            } else {
                format = formatComponents.negative;
            }

            // Normalize value if we have an explicit negative format
            if (formatComponents.hasNegative)
                value = Math.abs(value);

            // Get format metadata
            let formatMeta = getCustomFormatMetadata(format, true /*calculatePrecision*/);
            // Preserve literals and escaped chars
            let literals: string[] = [];
            if (formatMeta.hasLiterals) {
                format = formattingEncoder.preserveLiterals(format, literals);
            }

            // Scientific format
            if (formatMeta.hasE && !nonScientificOverrideFormat) {
                let scientificMatch = RegExpExtensions.run(ScientificFormatRegex, format);
                if (scientificMatch) {
                    // Case 2.1. Scientific custom format
                    let formatM = format.substr(0, scientificMatch.index);
                    let formatE = format.substr(scientificMatch.index + 2); // E(+|-)
                    let precision = getCustomFormatPrecision(formatM, formatMeta);
                    let scale = getCustomFormatScale(formatM, formatMeta);
                    if (scale !== 1) {
                        value = value * scale;
                    }
                    // Assert that value is a number and fall back on returning value if it is not
                    if (typeof (value) !== "number")
                        return String(value);
                    let s = value.toExponential(precision);
                    let indexOfE = s.indexOf("e");
                    let mantissa = s.substr(0, indexOfE);
                    let exp = s.substr(indexOfE + 1);
                    let resultM = fuseNumberWithCustomFormat(mantissa, formatM, numberFormatInfo);
                    let resultE = fuseNumberWithCustomFormat(exp, formatE, numberFormatInfo);
                    if (resultE.charAt(0) === "+" && scientificMatch[0].charAt(1) !== "+") {
                        resultE = resultE.substr(1);
                    }
                    let e = scientificMatch[0].charAt(0);
                    result = resultM + e + resultE;
                }
            }

            // Non scientific format
            if (result === undefined) {
                let valueFormatted: string;
                let isValueGlobalized: boolean = false;
                let precision = getCustomFormatPrecision(format, formatMeta);
                let scale = getCustomFormatScale(format, formatMeta);

                if (scale !== 1)
                    value = value * scale;

                // Rounding
                value = parseFloat(toNonScientific(value, precision));

                if (!isFinite(value)) {
                    // very large and small finite values can become infinite by parseFloat(toNonScientific())
                    return Globalize.format(value, undefined);
                }

                if (nonScientificOverrideFormat) {
                    // Get numeric format from format string
                    let numericFormat = numberFormat.getNumericFormat(value, format);

                    // Add separators and decimalFormat to nonScientificFormat
                    nonScientificOverrideFormat = getNonScientificFormatWithPrecision(nonScientificOverrideFormat, numericFormat);

                    // Format the value
                    valueFormatted = formattingService.format(nonScientificOverrideFormat, [value], culture.name);
                    isValueGlobalized = true;
                }
                else
                    valueFormatted = toNonScientific(value, precision);

                result = fuseNumberWithCustomFormat(valueFormatted, format, <any>numberFormatInfo, nonScientificOverrideFormat, isValueGlobalized);
            }
            if (formatMeta.hasLiterals) {
                result = formattingEncoder.restoreLiterals(result, literals, false);
            }

            _lastCustomFormatMeta = formatMeta;
        } else {
            return Globalize.format(value, undefined);
        }
        return result;
    }