spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← All files
name: dist/Utilities/MoreUtils.js
-rw-r--r--
9588
  1"use strict";
  2exports.__esModule = true;
  3/**
  4 * If the value is UNDEFINED, return true.
  5 * @param value - Value to check if undefined.
  6 * @returns {boolean}
  7 */
  8function isUndefined(value) {
  9    return value === undefined;
 10}
 11exports.isUndefined = isUndefined;
 12/**
 13 * If the value is DEFINED, return true.
 14 * @param value - Value to check if is defined.
 15 * @returns {boolean}
 16 */
 17function isDefined(value) {
 18    return value !== undefined;
 19}
 20exports.isDefined = isDefined;
 21/**
 22 * Returns true if value is an instance of a Array.
 23 * @param value
 24 * @returns {boolean}
 25 */
 26function isArray(value) {
 27    return value instanceof Array;
 28}
 29exports.isArray = isArray;
 30/**
 31 * Alphabetical character to number.
 32 * @param chr
 33 * @returns {number}
 34 */
 35function characterToNumber(chr) {
 36    chr = chr.replace(/\$/g, '');
 37    var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', i, j, result = 0;
 38    for (i = 0, j = chr.length - 1; i < chr.length; i += 1, j -= 1) {
 39        result += Math.pow(base.length, j) * (base.indexOf(chr[i]) + 1);
 40    }
 41    if (result) {
 42        --result;
 43    }
 44    return result;
 45}
 46exports.characterToNumber = characterToNumber;
 47/**
 48 * Converts a number to an alphabetical character.
 49 * @param num
 50 * @returns {string}
 51 */
 52function numberToCharacter(num) {
 53    var s = '';
 54    while (num >= 0) {
 55        s = String.fromCharCode(num % 26 + 97) + s;
 56        num = Math.floor(num / 26) - 1;
 57    }
 58    return s.toUpperCase();
 59}
 60exports.numberToCharacter = numberToCharacter;
 61/**
 62 * Converts a quoted string to an un-quoted string: `"hey"` to `hey`
 63 * @param str
 64 * @returns {string}
 65 */
 66function string(str) {
 67    return str.substring(1, str.length - 1);
 68}
 69exports.string = string;
 70/**
 71 * Converts XY coordinates (eg {0, 0}) to A1 coordinates (eg {A1}).
 72 * @param x
 73 * @param y
 74 * @returns {string}
 75 */
 76function convertXYtoA1Coordinates(x, y) {
 77    function numberToLetters(num) {
 78        var mod = num % 26, pow = num / 26 | 0, out = mod ? String.fromCharCode(64 + mod) : (--pow, 'Z');
 79        return pow ? numberToLetters(pow) + out : out;
 80    }
 81    return numberToLetters(x + 1) + (y + 1).toString();
 82}
 83exports.convertXYtoA1Coordinates = convertXYtoA1Coordinates;
 84/**
 85 * Returns RowCol coordinates of an A1 cellId
 86 * @param cellId
 87 * @returns {Object}
 88 */
 89function A1toRowColCoordinates(cellId) {
 90    var num = cellId.match(/\d+$/), alpha = cellId.replace(num, '');
 91    return {
 92        row: parseInt(num[0], 10) - 1,
 93        col: characterToNumber(alpha)
 94    };
 95}
 96exports.A1toRowColCoordinates = A1toRowColCoordinates;
 97/**
 98 * Class for building formatted strings with commas, forced number of leading and trailing zeros, and arbitrary leading
 99 * and trailing strings.
100 */
101var NumberStringBuilder = /** @class */ (function () {
102    function NumberStringBuilder() {
103        this.shouldUseComma = false;
104        this.integerZeroCount = 1; // e.g. default to "0.1"
105        this.decimalZeroCount = 0; // e.g. default to "1"
106        this.headString = "";
107        this.tailString = "";
108    }
109    /**
110     * Static builder, easier than `new`.
111     * @returns {NumberStringBuilder}
112     */
113    NumberStringBuilder.start = function () {
114        return new NumberStringBuilder();
115    };
116    /**
117     * Pads a given string with "0" on the right or left side until it is a certain width.
118     * @param {string} str - String to pad.
119     * @param {number} width - Width to pad to. If this is less than the strings length, will do nothing.
120     * @param {string} type - "right" or "left" side to append zeroes.
121     * @returns {string}
122     */
123    NumberStringBuilder.pad = function (str, width, type) {
124        var z = '0';
125        str = str + '';
126        if (type === "left") {
127            return str.length >= width ? str : new Array(width - str.length + 1).join(z) + str;
128        }
129        else {
130            return str.length >= width ? str : str + (new Array(width - str.length + 1).join(z));
131        }
132    };
133    /**
134     * Rounds a number n to a certain number of digits.
135     * @param n - Number to round.
136     * @param digits - Digits to round to.
137     * @returns {number}
138     */
139    NumberStringBuilder.round = function (n, digits) {
140        return Math.round(n * Math.pow(10, digits)) / Math.pow(10, digits);
141    };
142    /**
143     * Set the number that we'll be formatting.
144     * @param {number} n - Number.
145     * @returns {NumberStringBuilder}
146     */
147    NumberStringBuilder.prototype.number = function (n) {
148        this.n = n;
149        return this;
150    };
151    /**
152     * The number of zeros to force on the left side of the decimal.
153     * @param {number} zeros
154     * @returns {NumberStringBuilder}
155     */
156    NumberStringBuilder.prototype.integerZeros = function (zeros) {
157        this.integerZeroCount = zeros;
158        return this;
159    };
160    /**
161     * The number of zeros to force on the right side of the decimal.
162     * @param {number} zeros
163     * @returns {NumberStringBuilder}
164     */
165    NumberStringBuilder.prototype.decimalZeros = function (zeros) {
166        this.decimalZeroCount = zeros;
167        return this;
168    };
169    /**
170     * If you would like to force the maximum number of decimal places, without padding with zeros, set this.
171     * WARNING: Should not be used in conjunction with decimalZeros().
172     * @param {number} maxDecimalPlaces
173     * @returns {NumberStringBuilder}
174     */
175    NumberStringBuilder.prototype.maximumDecimalPlaces = function (maxDecimalPlaces) {
176        this.maxDecimalPlaces = maxDecimalPlaces;
177        return this;
178    };
179    /**
180     * Should digits to the left side of the decimal use comma-notation?
181     * @param {boolean} shouldUseComma
182     * @returns {NumberStringBuilder}
183     */
184    NumberStringBuilder.prototype.commafy = function (shouldUseComma) {
185        this.shouldUseComma = shouldUseComma;
186        return this;
187    };
188    /**
189     * String to append to the beginning of the final formatted number.
190     * @param {string} head
191     * @returns {NumberStringBuilder}
192     */
193    NumberStringBuilder.prototype.head = function (head) {
194        this.headString = head;
195        return this;
196    };
197    /**
198     * String to append to the end of the final formatted number.
199     * @param {string} tail
200     * @returns {NumberStringBuilder}
201     */
202    NumberStringBuilder.prototype.tail = function (tail) {
203        this.tailString = tail;
204        return this;
205    };
206    /**
207     * Building the string using the rules set in this builder.
208     * @returns {string}
209     */
210    NumberStringBuilder.prototype.build = function () {
211        var nStr = this.n.toString();
212        var isInt = this.n % 1 === 0;
213        var integerPart = isInt ? nStr : nStr.split(".")[0];
214        integerPart = integerPart.replace("-", "");
215        var decimalPart = isInt ? "" : nStr.split(".")[1];
216        // Building integer part
217        if (this.integerZeroCount > 1) {
218            integerPart = NumberStringBuilder.pad(integerPart, this.integerZeroCount, "left");
219        }
220        // Building decimal part
221        // If the decimal part is greater than the number of zeros we allow, then we have to round the number.
222        if (isDefined(this.maxDecimalPlaces)) {
223            var decimalAsFloat = NumberStringBuilder.round(parseFloat("0." + decimalPart), this.maxDecimalPlaces);
224            if (decimalAsFloat % 1 === 0) {
225                integerPart = Math.floor((parseInt(integerPart) + decimalAsFloat)).toString();
226                integerPart = NumberStringBuilder.pad(integerPart, this.integerZeroCount, "left");
227                decimalPart = "";
228            }
229            else {
230                decimalPart = decimalAsFloat.toString().split(".")[1];
231            }
232        }
233        else {
234            if (decimalPart.length > this.decimalZeroCount) {
235                var decimalAsFloat = NumberStringBuilder.round(parseFloat("0." + decimalPart), this.decimalZeroCount);
236                var roundedDecimalPart = void 0;
237                if (decimalAsFloat % 1 === 0) {
238                    integerPart = Math.floor((parseInt(integerPart) + decimalAsFloat)).toString();
239                    integerPart = NumberStringBuilder.pad(integerPart, this.integerZeroCount, "left");
240                    roundedDecimalPart = "";
241                }
242                else {
243                    roundedDecimalPart = decimalAsFloat.toString().split(".")[1];
244                }
245                decimalPart = NumberStringBuilder.pad(roundedDecimalPart, this.decimalZeroCount, "right");
246            }
247            else {
248                decimalPart = NumberStringBuilder.pad(decimalPart, this.decimalZeroCount, "right");
249            }
250        }
251        // Inserting commas if necessary.
252        if (this.shouldUseComma) {
253            integerPart = integerPart.split("").reverse().map(function (digit, index) {
254                if (index % 3 === 0 && index !== 0) {
255                    return digit + ",";
256                }
257                return digit;
258            }).reverse().join("");
259        }
260        if (this.integerZeroCount === 0 && integerPart === "0") {
261            integerPart = "";
262        }
263        if (this.n === 0) {
264            return this.headString + "." + this.tailString;
265        }
266        var trueSign = this.n < 0 ? "-" : "";
267        if ((this.decimalZeroCount === 0 && isUndefined(this.maxDecimalPlaces)) || isDefined(this.maxDecimalPlaces) && decimalPart === "") {
268            return trueSign + this.headString + integerPart + this.tailString;
269        }
270        return trueSign + this.headString + integerPart + "." + decimalPart + this.tailString;
271    };
272    return NumberStringBuilder;
273}());
274exports.NumberStringBuilder = NumberStringBuilder;