diff --git a/gulpfile.js b/gulpfile.js
index b5f9a21..3e6c5ef 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -3,6 +3,7 @@ var gulp = require('gulp'),
rename = require('gulp-rename'),
notify = require('gulp-notify'),
concat = require('gulp-concat'),
+ webpack = require('webpack-stream'),
del = require('del'),
fs = require('fs.extra'),
paths = {
@@ -33,16 +34,34 @@ gulp.task('update_bs_fonts', function(){
gulp.task('libs', gulp.series('update_jquery', 'update_bs_js', 'update_bs_css', 'update_bs_fonts'));
-gulp.task('scripts', function() {
+gulp.task('script-concat', function() {
return gulp.src(paths.scripts)
- .pipe(concat('core.js'))
- .pipe(concat('excel-formula.js'))
- .pipe(gulp.dest('dist'))
- .pipe(rename({suffix: '.min'}))
- .pipe(uglify())
- .pipe(gulp.dest('dist'))
+ .pipe(webpack({
+ mode: 'production',
+ output: {
+ filename: 'excel-formula.js',
+ },
+ optimization: {
+ minimize: false
+ }
+ }))
+ .pipe(gulp.dest('dist'))
+});
+
+gulp.task('script-minify', function() {
+ return gulp.src(paths.scripts)
+ .pipe(webpack({
+ mode: 'production',
+ output: {
+ filename: 'excel-formula.js',
+ }
+ }))
+ .pipe(rename({suffix: '.min'}))
+ .pipe(gulp.dest('dist'))
});
+gulp.task('scripts', gulp.series(['script-concat', 'script-minify']))
+
gulp.task('site', function() {
return gulp.src(paths.siteScripts)
.pipe(concat('page.js'))
diff --git a/package.json b/package.json
index 3376d5d..6ad5b48 100644
--- a/package.json
+++ b/package.json
@@ -17,11 +17,7 @@
"repository": {
"url": "git://github.com/joshatjben/excelFormulaUtilitiesJS.git"
},
- "keyword": [
- "excel",
- "formula",
- "convert"
- ],
+ "keyword": ["excel", "formula", "convert"],
"scripts": {
"build": "gulp",
"test": "mocha & qunit -t ./test/browser/ExcelFormulaUtilities.test.js -d ./src/core.js -c ./src/ExcelFormulaUtilities.js & qunit -c ./dist/excel-formula.min.js -t ./test/browser/ExcelFormulaUtilities.test.js & qunit -c ./dist/excel-formula.js -t ./test/browser/ExcelFormulaUtilities.test.js"
@@ -41,10 +37,13 @@
"gulp-rename": "^1.2.2",
"gulp-uglify": "^1.4.1",
"mocha": "^9.1.3",
- "qunit": "~0.7.7"
+ "qunit": "~0.7.7",
+ "webpack": "^5.65.0",
+ "webpack-stream": "^7.0.0"
},
"dependencies": {
"bootstrap": "^4.1.3",
+ "excel-formula-tokenizer": "jlaramie/excel-formula-tokenizer#compatibility_updates",
"jquery": "^3.2.1"
}
}
diff --git a/src/ExcelFormulaUtilities.js b/src/ExcelFormulaUtilities.js
index a1558fa..ebdb51f 100644
--- a/src/ExcelFormulaUtilities.js
+++ b/src/ExcelFormulaUtilities.js
@@ -1,3 +1,9 @@
+var Tokenizer = require("excel-formula-tokenizer");
+var getTokens = Tokenizer.tokenize,
+ types = Tokenizer.TYPES,
+ F_tokens = Tokenizer.Tokens,
+ F_tokenStack = Tokenizer.TokenStack;
+
/*
* excelFormulaUtilitiesJS
* https://github.com/joshatjben/excelFormulaUtilitiesJS/
@@ -17,33 +23,7 @@
var excelFormulaUtilities = root.excelFormulaUtilities = root.excelFormulaUtilities || {},
core = root.excelFormulaUtilities.core,
formatStr = root.excelFormulaUtilities.string.formatStr,
- trim = root.excelFormulaUtilities.string.trim,
-
- types = {},
- TOK_TYPE_NOOP = types.TOK_TYPE_NOOP = "noop",
- TOK_TYPE_OPERAND = types.TOK_TYPE_OPERAND = "operand",
- TOK_TYPE_FUNCTION = types.TOK_TYPE_FUNCTION = "function",
- TOK_TYPE_SUBEXPR = types.TOK_TYPE_SUBEXPR = "subexpression",
- TOK_TYPE_ARGUMENT = types.TOK_TYPE_ARGUMENT = "argument",
- TOK_TYPE_OP_PRE = types.TOK_TYPE_OP_PRE = "operator-prefix",
- TOK_TYPE_OP_IN = types.TOK_TYPE_OP_IN = "operator-infix",
- TOK_TYPE_OP_POST = types.TOK_TYPE_OP_POST = "operator-postfix",
- TOK_TYPE_WHITE_SPACE = types.TOK_TYPE_WHITE_SPACE = "white-space",
- TOK_TYPE_UNKNOWN = types.TOK_TYPE_UNKNOWN = "unknown",
-
- TOK_SUBTYPE_START = types.TOK_SUBTYPE_START = "start",
- TOK_SUBTYPE_STOP = types.TOK_SUBTYPE_STOP = "stop",
-
- TOK_SUBTYPE_TEXT = types.TOK_SUBTYPE_TEXT = "text",
- TOK_SUBTYPE_NUMBER = types.TOK_SUBTYPE_NUMBER = "number",
- TOK_SUBTYPE_LOGICAL = types.TOK_SUBTYPE_LOGICAL = "logical",
- TOK_SUBTYPE_ERROR = types.TOK_SUBTYPE_ERROR = "error",
- TOK_SUBTYPE_RANGE = types.TOK_SUBTYPE_RANGE = "range",
-
- TOK_SUBTYPE_MATH = types.TOK_SUBTYPE_MATH = "math",
- TOK_SUBTYPE_CONCAT = types.TOK_SUBTYPE_CONCAT = "concatenate",
- TOK_SUBTYPE_INTERSECT = types.TOK_SUBTYPE_INTERSECT = "intersect",
- TOK_SUBTYPE_UNION = types.TOK_SUBTYPE_UNION = "union";
+ trim = root.excelFormulaUtilities.string.trim;
root.excelFormulaUtilities.isEu = typeof root.excelFormulaUtilities.isEu === 'boolean' ? root.excelFormulaUtilities.isEu : false;
@@ -58,529 +38,6 @@
this.subtype = subtype;
}
- /**
- * @class
- */
-
- function F_tokens() {
-
- this.items = [];
-
- this.add = function (value, type, subtype) {
- if (!subtype) {
- subtype = "";
- }
- var token = new F_token(value, type, subtype);
- this.addRef(token);
- return token;
- };
- this.addRef = function (token) {
- this.items.push(token);
- };
-
- this.index = -1;
- this.reset = function () {
- this.index = -1;
- };
- this.BOF = function () {
- return (this.index <= 0);
- };
- this.EOF = function () {
- return (this.index >= (this.items.length - 1));
- };
- this.moveNext = function () {
- if (this.EOF()) {
- return false;
- }
- this.index += 1;
- return true;
- };
- this.current = function () {
- if (this.index === -1) {
- return null;
- }
- return (this.items[this.index]);
- };
- this.next = function () {
- if (this.EOF()) {
- return null;
- }
- return (this.items[this.index + 1]);
- };
- this.previous = function () {
- if (this.index < 1) {
- return null;
- }
- return (this.items[this.index - 1]);
- };
-
- }
-
- function F_tokenStack() {
-
- this.items = [];
-
- this.push = function (token) {
- this.items.push(token);
- };
- this.pop = function (name) {
- var token = this.items.pop();
- return (new F_token(name || "", token.type, TOK_SUBTYPE_STOP));
- };
-
- this.token = function () {
- return ((this.items.length > 0) ? this.items[this.items.length - 1] : null);
- };
- this.value = function () {
- return ((this.token()) ? this.token().value.toString() : "");
- };
- this.type = function () {
- return ((this.token()) ? this.token().type.toString() : "");
- };
- this.subtype = function () {
- return ((this.token()) ? this.token().subtype.toString() : "");
- };
-
- }
-
- function getTokens(formula) {
-
- var tokens = new F_tokens(),
- tokenStack = new F_tokenStack(),
-
- offset = 0,
-
- currentChar = function () {
- return formula.substr(offset, 1);
- },
- doubleChar = function () {
- return formula.substr(offset, 2);
- },
- nextChar = function () {
- return formula.substr(offset + 1, 1);
- },
- EOF = function () {
- return (offset >= formula.length);
- },
-
- token = "",
-
- inString = false,
- inPath = false,
- inRange = false,
- inError = false,
- regexSN = /^[1-9]{1}(\.[0-9]+)?E{1}$/;
-
- while (formula.length > 0) {
- if (formula.substr(0, 1) === " ") {
- formula = formula.substr(1);
- } else {
- if (formula.substr(0, 1) === "=") {
- formula = formula.substr(1);
- }
- break;
- }
- }
-
-
-
- while (!EOF()) {
- // state-dependent character evaluation (order is important)
- // double-quoted strings
- // embeds are doubled
- // end marks token
- if (inString) {
- if (currentChar() === "\"") {
- if (nextChar() === "\"") {
- token += "\"";
- offset += 1;
- } else {
- inString = false;
- tokens.add(token, TOK_TYPE_OPERAND, TOK_SUBTYPE_TEXT);
- token = "";
- }
- } else {
- token += currentChar();
- }
- offset += 1;
- continue;
- }
-
- // single-quoted strings (links)
- // embeds are double
- // end does not mark a token
- if (inPath) {
- if (currentChar() === "'") {
-
- if (nextChar() === "'") {
- token += "'";
- offset += 1;
- } else {
- inPath = false;
- token += "'";
- }
- } else {
- token += currentChar();
- }
-
- offset += 1;
- continue;
- }
-
- // bracketed strings (range offset or linked workbook name)
- // no embeds (changed to "()" by Excel)
- // end does not mark a token
- if (inRange) {
- if (currentChar() === "]") {
- inRange = false;
- }
- token += currentChar();
- offset += 1;
- continue;
- }
-
- // error values
- // end marks a token, determined from absolute list of values
- if (inError) {
- token += currentChar();
- offset += 1;
- if ((",#NULL!,#DIV/0!,#VALUE!,#REF!,#NAME?,#NUM!,#N/A,").indexOf("," + token + ",") !== -1) {
- inError = false;
- tokens.add(token, TOK_TYPE_OPERAND, TOK_SUBTYPE_ERROR);
- token = "";
- }
- continue;
- }
-
- // scientific notation check
- if (("+-").indexOf(currentChar()) !== -1) {
- if (token.length > 1) {
- if (token.match(regexSN)) {
- token += currentChar();
- offset += 1;
- continue;
- }
- }
- }
-
- // independent character evaluation (order not important)
- // establish state-dependent character evaluations
- if (currentChar() === "\"") {
- if (token.length > 0) {
- // not expected
- tokens.add(token, TOK_TYPE_UNKNOWN);
- token = "";
- }
- inString = true;
- offset += 1;
- continue;
- }
-
- if (currentChar() === "'") {
- if (token.length > 0) {
- // not expected
- tokens.add(token, TOK_TYPE_UNKNOWN);
- token = "";
- }
- token = "'"
- inPath = true;
- offset += 1;
- continue;
- }
-
- if (currentChar() === "[") {
- inRange = true;
- token += currentChar();
- offset += 1;
- continue;
- }
-
- if (currentChar() === "#") {
- if (token.length > 0) {
- // not expected
- tokens.add(token, TOK_TYPE_UNKNOWN);
- token = "";
- }
- inError = true;
- token += currentChar();
- offset += 1;
- continue;
- }
-
- // mark start and end of arrays and array rows
- if (currentChar() === "{") {
- if (token.length > 0) {
- // not expected
- tokens.add(token, TOK_TYPE_UNKNOWN);
- token = "";
- }
- tokenStack.push(tokens.add("ARRAY", TOK_TYPE_FUNCTION, TOK_SUBTYPE_START));
- tokenStack.push(tokens.add("ARRAYROW", TOK_TYPE_FUNCTION, TOK_SUBTYPE_START));
- offset += 1;
- continue;
- }
-
- if (currentChar() === ";" ) {
- if(root.excelFormulaUtilities.isEu){
- // If is EU then handle ; as list separators
- if (token.length > 0) {
- tokens.add(token, TOK_TYPE_OPERAND);
- token = "";
- }
- if (tokenStack.type() !== TOK_TYPE_FUNCTION) {
- tokens.add(currentChar(), TOK_TYPE_OP_IN, TOK_SUBTYPE_UNION);
- } else {
- tokens.add(currentChar(), TOK_TYPE_ARGUMENT);
- }
- offset += 1;
- continue;
- } else {
- // Else if not Eu handle ; as array row separator
- if (token.length > 0) {
- tokens.add(token, TOK_TYPE_OPERAND);
- token = "";
- }
- tokens.addRef(tokenStack.pop());
- tokens.add(",", TOK_TYPE_ARGUMENT);
- tokenStack.push(tokens.add("ARRAYROW", TOK_TYPE_FUNCTION, TOK_SUBTYPE_START));
- offset += 1;
- continue;
- }
- }
-
- if (currentChar() === "}") {
- if (token.length > 0) {
- tokens.add(token, TOK_TYPE_OPERAND);
- token = "";
- }
- tokens.addRef(tokenStack.pop("ARRAYROWSTOP"));
- tokens.addRef(tokenStack.pop("ARRAYSTOP"));
- offset += 1;
- continue;
- }
-
- // trim white-space
- if (currentChar() === " ") {
- if (token.length > 0) {
- tokens.add(token, TOK_TYPE_OPERAND);
- token = "";
- }
- tokens.add("", TOK_TYPE_WHITE_SPACE);
- offset += 1;
- while ((currentChar() === " ") && (!EOF())) {
- offset += 1;
- }
- continue;
- }
-
- // multi-character comparators
- if ((",>=,<=,<>,").indexOf("," + doubleChar() + ",") !== -1) {
- if (token.length > 0) {
- tokens.add(token, TOK_TYPE_OPERAND);
- token = "";
- }
- tokens.add(doubleChar(), TOK_TYPE_OP_IN, TOK_SUBTYPE_LOGICAL);
- offset += 2;
- continue;
- }
-
- // standard infix operators
- if (("+-*/^&=><").indexOf(currentChar()) !== -1) {
- if (token.length > 0) {
- tokens.add(token, TOK_TYPE_OPERAND);
- token = "";
- }
- tokens.add(currentChar(), TOK_TYPE_OP_IN);
- offset += 1;
- continue;
- }
-
- // standard postfix operators
- if (("%").indexOf(currentChar()) !== -1) {
- if (token.length > 0) {
- tokens.add(token, TOK_TYPE_OPERAND);
- token = "";
- }
- tokens.add(currentChar(), TOK_TYPE_OP_POST);
- offset += 1;
- continue;
- }
-
- // start subexpression or function
- if (currentChar() === "(") {
- if (token.length > 0) {
- tokenStack.push(tokens.add(token, TOK_TYPE_FUNCTION, TOK_SUBTYPE_START));
- token = "";
- } else {
- tokenStack.push(tokens.add("", TOK_TYPE_SUBEXPR, TOK_SUBTYPE_START));
- }
- offset += 1;
- continue;
- }
-
- // function, subexpression, array parameters
- if (currentChar() === "," && !root.excelFormulaUtilities.isEu) {
- if (token.length > 0) {
- tokens.add(token, TOK_TYPE_OPERAND);
- token = "";
- }
- if (tokenStack.type() !== TOK_TYPE_FUNCTION) {
- tokens.add(currentChar(), TOK_TYPE_OP_IN, TOK_SUBTYPE_UNION);
- } else {
- tokens.add(currentChar(), TOK_TYPE_ARGUMENT);
- }
- offset += 1;
- continue;
- }
-
- // stop subexpression
- if (currentChar() === ")") {
- if (token.length > 0) {
- tokens.add(token, TOK_TYPE_OPERAND);
- token = "";
- }
- tokens.addRef(tokenStack.pop());
- offset += 1;
- continue;
- }
-
- // token accumulation
- token += currentChar();
- offset += 1;
-
- }
-
- // dump remaining accumulation
- if (token.length > 0 || inString || inPath || inRange || inError) {
- if (inString || inPath || inRange || inError) {
- if (inString) {
- token = "\"" + token;
- } else if (inPath) {
- token = "'" + token;
- } else if (inRange) {
- token = "[" + token;
- } else if (inError) {
- token = "#" + token;
- }
-
- tokens.add(token, TOK_TYPE_UNKNOWN);
- } else {
- tokens.add(token, TOK_TYPE_OPERAND);
- }
- }
-
- // move all tokens to a new collection, excluding all unnecessary white-space tokens
- var tokens2 = new F_tokens();
-
- while (tokens.moveNext()) {
-
- token = tokens.current();
-
- if (token.type.toString() === TOK_TYPE_WHITE_SPACE) {
- var doAddToken = (tokens.BOF()) || (tokens.EOF());
- //if ((tokens.BOF()) || (tokens.EOF())) {}
- doAddToken = doAddToken && (((tokens.previous().type.toString() === TOK_TYPE_FUNCTION) && (tokens.previous().subtype.toString() === TOK_SUBTYPE_STOP)) || ((tokens.previous().type.toString() === TOK_TYPE_SUBEXPR) && (tokens.previous().subtype.toString() === TOK_SUBTYPE_STOP)) || (tokens.previous().type.toString() === TOK_TYPE_OPERAND));
- //else if (!(
- // ((tokens.previous().type === TOK_TYPE_FUNCTION) && (tokens.previous().subtype == TOK_SUBTYPE_STOP))
- // || ((tokens.previous().type == TOK_TYPE_SUBEXPR) && (tokens.previous().subtype == TOK_SUBTYPE_STOP))
- // || (tokens.previous().type == TOK_TYPE_OPERAND)))
- // {}
- doAddToken = doAddToken && (((tokens.next().type.toString() === TOK_TYPE_FUNCTION) && (tokens.next().subtype.toString() === TOK_SUBTYPE_START)) || ((tokens.next().type.toString() === TOK_TYPE_SUBEXPR) && (tokens.next().subtype.toString() === TOK_SUBTYPE_START)) || (tokens.next().type.toString() === TOK_TYPE_OPERAND));
- //else if (!(
- // ((tokens.next().type == TOK_TYPE_FUNCTION) && (tokens.next().subtype == TOK_SUBTYPE_START))
- // || ((tokens.next().type == TOK_TYPE_SUBEXPR) && (tokens.next().subtype == TOK_SUBTYPE_START))
- // || (tokens.next().type == TOK_TYPE_OPERAND)))
- // {}
- //else { tokens2.add(token.value, TOK_TYPE_OP_IN, TOK_SUBTYPE_INTERSECT)};
- if (doAddToken) {
- tokens2.add(token.value.toString(), TOK_TYPE_OP_IN, TOK_SUBTYPE_INTERSECT);
- }
- continue;
- }
-
- tokens2.addRef(token);
-
- }
-
- // switch infix "-" operator to prefix when appropriate, switch infix "+" operator to noop when appropriate, identify operand
- // and infix-operator subtypes, pull "@" from in front of function names
- while (tokens2.moveNext()) {
-
- token = tokens2.current();
-
- if ((token.type.toString() === TOK_TYPE_OP_IN) && (token.value.toString() === "-")) {
- if (tokens2.BOF()) {
- token.type = TOK_TYPE_OP_PRE.toString();
- } else if (((tokens2.previous().type.toString() === TOK_TYPE_FUNCTION) && (tokens2.previous().subtype.toString() === TOK_SUBTYPE_STOP)) || ((tokens2.previous().type.toString() === TOK_TYPE_SUBEXPR) && (tokens2.previous().subtype.toString() === TOK_SUBTYPE_STOP)) || (tokens2.previous().type.toString() === TOK_TYPE_OP_POST) || (tokens2.previous().type.toString() === TOK_TYPE_OPERAND)) {
- token.subtype = TOK_SUBTYPE_MATH.toString();
- } else {
- token.type = TOK_TYPE_OP_PRE.toString();
- }
- continue;
- }
-
- if ((token.type.toString() === TOK_TYPE_OP_IN) && (token.value.toString() === "+")) {
- if (tokens2.BOF()) {
- token.type = TOK_TYPE_NOOP.toString();
- } else if (((tokens2.previous().type.toString() === TOK_TYPE_FUNCTION) && (tokens2.previous().subtype.toString() === TOK_SUBTYPE_STOP)) || ((tokens2.previous().type.toString() === TOK_TYPE_SUBEXPR) && (tokens2.previous().subtype.toString() === TOK_SUBTYPE_STOP)) || (tokens2.previous().type.toString() === TOK_TYPE_OP_POST) || (tokens2.previous().type.toString() === TOK_TYPE_OPERAND)) {
- token.subtype = TOK_SUBTYPE_MATH.toString();
- } else {
- token.type = TOK_TYPE_NOOP.toString();
- }
- continue;
- }
-
- if ((token.type.toString() === TOK_TYPE_OP_IN) && (token.subtype.length === 0)) {
- if (("<>=").indexOf(token.value.substr(0, 1)) !== -1) {
- token.subtype = TOK_SUBTYPE_LOGICAL.toString();
- } else if (token.value.toString() === "&") {
- token.subtype = TOK_SUBTYPE_CONCAT.toString();
- } else {
- token.subtype = TOK_SUBTYPE_MATH.toString();
- }
- continue;
- }
-
- if ((token.type.toString() === TOK_TYPE_OPERAND) && (token.subtype.length === 0)) {
- if (isNaN(parseFloat(token.value))) {
- if ((token.value.toString() === 'TRUE') || (token.value.toString() === 'FALSE')) {
- token.subtype = TOK_SUBTYPE_LOGICAL.toString();
- } else {
- token.subtype = TOK_SUBTYPE_RANGE.toString();
- }
- } else {
- token.subtype = TOK_SUBTYPE_NUMBER.toString();
- }
-
- continue;
- }
-
- if (token.type.toString() === TOK_TYPE_FUNCTION) {
- if (token.value.substr(0, 1) === "@") {
- token.value = token.value.substr(1).toString();
- }
- continue;
- }
-
- }
-
- tokens2.reset();
-
- // move all tokens to a new collection, excluding all no-ops
- tokens = new F_tokens();
-
- while (tokens2.moveNext()) {
- if (tokens2.current().type.toString() !== TOK_TYPE_NOOP) {
- tokens.addRef(tokens2.current());
- }
- }
-
- tokens.reset();
-
- return tokens;
- }
-
-
var parseFormula = excelFormulaUtilities.parseFormula = function (inputID, outputID) {
@@ -598,7 +55,11 @@
var formulaControl = document.getElementById(inputID);
var formula = formulaControl.value;
- var tokens = getTokens(formula);
+ var tokens = getTokens(formula, {
+ asClass: true,
+ language: root.excelFormulaUtilities.isEu ? "en-EU" : "en-US",
+ preserveLanguage: true
+ });
var tokensHtml = "";
@@ -614,7 +75,7 @@
var token = tokens.current();
- if (token.subtype === TOK_SUBTYPE_STOP) {
+ if (token.subtype === types.TOK_SUBTYPE_STOP) {
indentCount -= ((indentCount > 0) ? 1 : 0);
}
@@ -629,7 +90,7 @@
tokensHtml += "";
- if (token.subtype === TOK_SUBTYPE_START) {
+ if (token.subtype === types.TOK_SUBTYPE_START) {
indentCount += 1;
}
@@ -777,16 +238,18 @@
//-----------------FUNCTION------------------
switch (token.value) {
case "ARRAY":
- tokenString = formatStr(replaceTokenTmpl(options.tmplFunctionStartArray), tokenString, indent, lineBreak);
+ if (token.subtype.toString() === "start") {
+ tokenString = formatStr(replaceTokenTmpl(options.tmplFunctionStartArray), tokenString, indent, lineBreak);
+ } else {
+ tokenString = formatStr(replaceTokenTmpl(options.tmplFunctionStopArray), tokenString, indent, lineBreak);
+ }
break;
case "ARRAYROW":
- tokenString = formatStr(replaceTokenTmpl(options.tmplFunctionStartArrayRow), tokenString, indent, lineBreak);
- break;
- case "ARRAYSTOP":
- tokenString = formatStr(replaceTokenTmpl(options.tmplFunctionStopArray), tokenString, indent, lineBreak);
- break;
- case "ARRAYROWSTOP":
- tokenString = formatStr(replaceTokenTmpl(options.tmplFunctionStopArrayRow), tokenString, indent, lineBreak);
+ if (token.subtype.toString() === "start") {
+ tokenString = formatStr(replaceTokenTmpl(options.tmplFunctionStartArrayRow), tokenString, indent, lineBreak);
+ } else {
+ tokenString = formatStr(replaceTokenTmpl(options.tmplFunctionStopArrayRow), tokenString, indent, lineBreak);
+ }
break;
default:
if (token.subtype.toString() === "start") {
@@ -945,7 +408,11 @@
return s;
};
- var tokens = getTokens(formula);
+ var tokens = getTokens(formula, {
+ asClass: true,
+ language: root.excelFormulaUtilities.isEu ? "en-EU" : "en-US",
+ preserveLanguage: true
+ });
var outputFormula = "";
@@ -971,7 +438,7 @@
var token = tokens.current();
var nextToken = tokens.next();
- if (token.subtype.toString() === TOK_SUBTYPE_STOP) {
+ if (token.subtype.toString() === types.TOK_SUBTYPE_STOP) {
indentCount -= ((indentCount > 0) ? 1 : 0);
}
@@ -985,7 +452,7 @@
// TODO this strips out spaces which breaks part of issue 28. 'Data Sheet' gets changed to DataSheet
outputFormula += applyTokenTemplate(token, options, indent, lineBreak, options.customTokenRender, lastToken);
- if (token.subtype.toString() === TOK_SUBTYPE_START) {
+ if (token.subtype.toString() === types.TOK_SUBTYPE_START) {
indentCount += 1;
}
@@ -1012,8 +479,8 @@
var tokRender = function(tokenStr, token, indent, lineBreak){
var outStr = tokenStr;
switch (token.type.toString()) {
- case TOK_TYPE_OPERAND:
- if(token.subtype === TOK_SUBTYPE_TEXT){
+ case types.TOK_TYPE_OPERAND:
+ if(token.subtype === types.TOK_SUBTYPE_TEXT){
outStr = tokenStr.replace(//gi,">");
}
break;
@@ -1082,11 +549,11 @@
switch (token.type.toString()) {
- case TOK_TYPE_FUNCTION:
+ case types.TOK_TYPE_FUNCTION:
switch (token.subtype) {
- case TOK_SUBTYPE_START:
+ case types.TOK_SUBTYPE_START:
functionStack.push({
name: tokenString,
@@ -1097,7 +564,7 @@
break;
- case TOK_SUBTYPE_STOP:
+ case types.TOK_SUBTYPE_STOP:
useTemplate = true;
switch (currentFunctionOnStack.name.toLowerCase()) {
@@ -1115,7 +582,7 @@
break;
- case TOK_TYPE_ARGUMENT:
+ case types.TOK_TYPE_ARGUMENT:
switch (currentFunctionOnStack.name.toLowerCase()) {
case "if":
switch (currentFunctionOnStack.argumentNumber) {
@@ -1146,11 +613,11 @@
break;
- case TOK_TYPE_OPERAND:
+ case types.TOK_TYPE_OPERAND:
switch (token.subtype) {
- case TOK_SUBTYPE_RANGE:
+ case types.TOK_SUBTYPE_RANGE:
//Assume '=' sign
if(!currentFunctionOnStack){
break;
@@ -1296,11 +763,11 @@
switch (token.type.toString()) {
- case TOK_TYPE_FUNCTION:
+ case types.TOK_TYPE_FUNCTION:
switch (token.subtype) {
- case TOK_SUBTYPE_START:
+ case types.TOK_SUBTYPE_START:
functionStack.push({
name: tokenString,
@@ -1311,7 +778,7 @@
break;
- case TOK_SUBTYPE_STOP:
+ case types.TOK_SUBTYPE_STOP:
useTemplate = true;
switch (currentFunctionOnStack.name.toLowerCase()) {
@@ -1332,7 +799,7 @@
break;
- case TOK_TYPE_ARGUMENT:
+ case types.TOK_TYPE_ARGUMENT:
switch (currentFunctionOnStack.name.toLowerCase()) {
case "if":
switch (currentFunctionOnStack.argumentNumber) {
@@ -1363,11 +830,11 @@
break;
- case TOK_TYPE_OPERAND:
+ case types.TOK_TYPE_OPERAND:
switch (token.subtype) {
- case TOK_SUBTYPE_RANGE:
+ case types.TOK_SUBTYPE_RANGE:
//Assume '=' sign
if(!currentFunctionOnStack){
break;
diff --git a/test/ExcelFormulaUtilities.test.js b/test/ExcelFormulaUtilities.test.js
index 2fc0761..22db96f 100644
--- a/test/ExcelFormulaUtilities.test.js
+++ b/test/ExcelFormulaUtilities.test.js
@@ -60,6 +60,15 @@ describe("ExcelFormulaUtilities", () => {
let actual = formula.formatFormulaHTML(inputFormula);
assert.equal(actual, expected);
})
+ })
+
+ describe("#arrayliterals", () => {
+ it("Test parsing a formula that contains array literals. From Issue #83", () => {
+ let inputFormula='=SORT($B$3:$F$20,{2,1},{-1,1})';
+ let expected = '={ A1:C2,
B2:C3}';
+ let actual = formula.formatFormulaHTML(inputFormula);
+ assert.equal(actual, expected);
+ })
})
})