@borgar/fx 4.11.2 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fx.d.ts +3 -0
- package/dist/fx.js +2 -2
- package/docs/API.md +1 -0
- package/lib/parseSRange.js +4 -2
- package/lib/parseStructRef.spec.js +5 -1
- package/lib/parser.js +12 -8
- package/lib/parser.spec.js +12 -0
- package/package.json +1 -1
package/docs/API.md
CHANGED
|
@@ -383,6 +383,7 @@ The AST Abstract Syntax Tree's format is documented in [AST_format.md](./AST_for
|
|
|
383
383
|
| [options] | `object` | `{}` | Options |
|
|
384
384
|
| [options].allowNamed | `boolean` | `true` | Enable parsing names as well as ranges. |
|
|
385
385
|
| [options].allowTernary | `boolean` | `false` | Enables the recognition of ternary ranges in the style of `A1:A` or `A1:1`. These are supported by Google Sheets but not Excel. See: References.md. |
|
|
386
|
+
| [options].looseRefCalls | `boolean` | `false` | Permits any function call where otherwise only functions that return references would be permitted. |
|
|
386
387
|
| [options].negativeNumbers | `boolean` | `true` | Merges unary minuses with their immediately following number tokens (`-`,`1`) => `-1` (alternatively these will be unary operations in the tree). |
|
|
387
388
|
| [options].permitArrayCalls | `boolean` | `false` | Function calls are allowed as elements of arrays. This is a feature in Google Sheets while Excel does not allow it. |
|
|
388
389
|
| [options].permitArrayRanges | `boolean` | `false` | Ranges are allowed as elements of arrays. This is a feature in Google Sheets while Excel does not allow it. |
|
package/lib/parseSRange.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const re_SRcolumnB = /^\[('['#@[\]]|[^'#@[\]])
|
|
1
|
+
const re_SRcolumnB = /^\[('['#@[\]]|[^'#@[\]])*\]/i;
|
|
2
2
|
const re_SRcolumnN = /^([^#@[\]:]+)/i;
|
|
3
3
|
|
|
4
4
|
const keyTerms = {
|
|
@@ -68,7 +68,9 @@ export function parseSRange (raw) {
|
|
|
68
68
|
// [column]
|
|
69
69
|
else if ((m1 = matchColumn(s, false))) {
|
|
70
70
|
pos += m1[0].length;
|
|
71
|
-
|
|
71
|
+
if (m1[1]) {
|
|
72
|
+
columns.push(m1[1]);
|
|
73
|
+
}
|
|
72
74
|
}
|
|
73
75
|
// use the "normal" method
|
|
74
76
|
// [[#keyword]]
|
|
@@ -24,12 +24,16 @@ Test.prototype.isSREqual = function isSREqual (expr, expect, opts) {
|
|
|
24
24
|
this.deepEqual(parseStructRef(expr, opts), expect, expr);
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
test('parse structured references', t => {
|
|
27
|
+
test.only('parse structured references', t => {
|
|
28
28
|
t.isSREqual('table[col]', {
|
|
29
29
|
table: 'table',
|
|
30
30
|
columns: [ 'col' ]
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
+
t.isSREqual('table[]', {
|
|
34
|
+
table: 'table'
|
|
35
|
+
});
|
|
36
|
+
|
|
33
37
|
t.isSREqual('[#All]', {
|
|
34
38
|
sections: [ 'all' ]
|
|
35
39
|
});
|
package/lib/parser.js
CHANGED
|
@@ -63,8 +63,16 @@ const refFunctions = [
|
|
|
63
63
|
'XLOOKUP'
|
|
64
64
|
];
|
|
65
65
|
|
|
66
|
+
const symbolTable = {};
|
|
67
|
+
let currentNode;
|
|
68
|
+
let tokens;
|
|
69
|
+
let tokenIndex;
|
|
70
|
+
let permitArrayRanges = false;
|
|
71
|
+
let permitArrayCalls = false;
|
|
72
|
+
let looseRefCalls = false;
|
|
73
|
+
|
|
66
74
|
const isReferenceFunctionName = fnName => {
|
|
67
|
-
return refFunctions.includes(fnName.toUpperCase());
|
|
75
|
+
return looseRefCalls || refFunctions.includes(fnName.toUpperCase());
|
|
68
76
|
};
|
|
69
77
|
|
|
70
78
|
const isReferenceToken = (token, allowOperators = false) => {
|
|
@@ -98,13 +106,6 @@ const isReferenceNode = node => {
|
|
|
98
106
|
);
|
|
99
107
|
};
|
|
100
108
|
|
|
101
|
-
const symbolTable = {};
|
|
102
|
-
let currentNode;
|
|
103
|
-
let tokens;
|
|
104
|
-
let tokenIndex;
|
|
105
|
-
let permitArrayRanges = false;
|
|
106
|
-
let permitArrayCalls = false;
|
|
107
|
-
|
|
108
109
|
function halt (message, atIndex = null) {
|
|
109
110
|
const err = new Error(message);
|
|
110
111
|
err.source = tokens.map(d => d.value).join('');
|
|
@@ -688,6 +689,7 @@ prefix('{', function () {
|
|
|
688
689
|
* @param {boolean} [options.negativeNumbers=true] Merges unary minuses with their immediately following number tokens (`-`,`1`) => `-1` (alternatively these will be unary operations in the tree).
|
|
689
690
|
* @param {boolean} [options.permitArrayRanges=false] Ranges are allowed as elements of arrays. This is a feature in Google Sheets while Excel does not allow it.
|
|
690
691
|
* @param {boolean} [options.permitArrayCalls=false] Function calls are allowed as elements of arrays. This is a feature in Google Sheets while Excel does not allow it.
|
|
692
|
+
* @param {boolean} [options.looseRefCalls=false] Permits any function call where otherwise only functions that return references would be permitted.
|
|
691
693
|
* @param {boolean} [options.r1c1=false] Ranges are expected to be in the R1C1 style format rather than the more popular A1 style.
|
|
692
694
|
* @param {boolean} [options.withLocation=false] Nodes will include source position offsets to the tokens: `{ loc: [ start, end ] }`
|
|
693
695
|
* @param {boolean} [options.xlsx=false] Switches to the `[1]Sheet1!A1` or `[1]!name` prefix syntax form for external workbooks. See: [Prefixes.md](./Prefixes.md)
|
|
@@ -711,6 +713,8 @@ export function parse (formula, options) {
|
|
|
711
713
|
permitArrayRanges = options?.permitArrayRanges;
|
|
712
714
|
// allow calls in arrays "literals"?
|
|
713
715
|
permitArrayCalls = options?.permitArrayCalls;
|
|
716
|
+
// allow any function call in range operations?
|
|
717
|
+
looseRefCalls = options?.looseRefCalls;
|
|
714
718
|
// set index to start
|
|
715
719
|
tokenIndex = 0;
|
|
716
720
|
// discard redundant whitespace and = prefix
|
package/lib/parser.spec.js
CHANGED
|
@@ -1194,3 +1194,15 @@ test('parser whitespace handling', t => {
|
|
|
1194
1194
|
});
|
|
1195
1195
|
t.end();
|
|
1196
1196
|
});
|
|
1197
|
+
|
|
1198
|
+
test('looseRefCalls: true relaxes ref function restrictions', t => {
|
|
1199
|
+
t.isInvalidExpr('A1:TESTFN()');
|
|
1200
|
+
t.isParsed('A1:TESTFN()', {
|
|
1201
|
+
type: 'BinaryExpression', operator: ':',
|
|
1202
|
+
arguments: [
|
|
1203
|
+
{ type: 'ReferenceIdentifier', value: 'A1', kind: 'range' },
|
|
1204
|
+
{ type: 'CallExpression', callee: { type: 'Identifier', name: 'TESTFN' }, arguments: [] }
|
|
1205
|
+
]
|
|
1206
|
+
}, { looseRefCalls: true });
|
|
1207
|
+
t.end();
|
|
1208
|
+
});
|