@gridsheet/react-core 0.12.3 → 0.12.4-rc.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.
Files changed (190) hide show
  1. package/dist/components/Cell.js +197 -181
  2. package/dist/components/Cell.js.map +1 -1
  3. package/dist/components/ContextMenu.js +211 -194
  4. package/dist/components/ContextMenu.js.map +1 -1
  5. package/dist/components/Editor.js +280 -263
  6. package/dist/components/Editor.js.map +1 -1
  7. package/dist/components/Emitter.js +41 -24
  8. package/dist/components/Emitter.js.map +1 -1
  9. package/dist/components/GridSheet.js +142 -105
  10. package/dist/components/GridSheet.js.map +1 -1
  11. package/dist/components/HeaderLeftCell.js +76 -60
  12. package/dist/components/HeaderLeftCell.js.map +1 -1
  13. package/dist/components/HeaderTopCell.js +77 -61
  14. package/dist/components/HeaderTopCell.js.map +1 -1
  15. package/dist/components/Resizer.js +91 -75
  16. package/dist/components/Resizer.js.map +1 -1
  17. package/dist/components/SearchBox.js +66 -49
  18. package/dist/components/SearchBox.js.map +1 -1
  19. package/dist/components/StoreInitializer.js +83 -66
  20. package/dist/components/StoreInitializer.js.map +1 -1
  21. package/dist/components/Tabular.js +98 -80
  22. package/dist/components/Tabular.js.map +1 -1
  23. package/dist/constants.js +33 -19
  24. package/dist/constants.js.map +1 -1
  25. package/dist/formula/evaluator.js +500 -474
  26. package/dist/formula/evaluator.js.map +1 -1
  27. package/dist/formula/functions/__base.js +27 -13
  28. package/dist/formula/functions/__base.js.map +1 -1
  29. package/dist/formula/functions/__utils.js +113 -95
  30. package/dist/formula/functions/__utils.js.map +1 -1
  31. package/dist/formula/functions/abs.js +31 -17
  32. package/dist/formula/functions/abs.js.map +1 -1
  33. package/dist/formula/functions/abs.spec.js +35 -23
  34. package/dist/formula/functions/abs.spec.js.map +1 -1
  35. package/dist/formula/functions/acos.js +38 -24
  36. package/dist/formula/functions/acos.js.map +1 -1
  37. package/dist/formula/functions/add.js +57 -43
  38. package/dist/formula/functions/add.js.map +1 -1
  39. package/dist/formula/functions/and.js +38 -24
  40. package/dist/formula/functions/and.js.map +1 -1
  41. package/dist/formula/functions/asin.js +38 -24
  42. package/dist/formula/functions/asin.js.map +1 -1
  43. package/dist/formula/functions/atan.js +36 -22
  44. package/dist/formula/functions/atan.js.map +1 -1
  45. package/dist/formula/functions/atan2.js +42 -28
  46. package/dist/formula/functions/atan2.js.map +1 -1
  47. package/dist/formula/functions/average.js +50 -36
  48. package/dist/formula/functions/average.js.map +1 -1
  49. package/dist/formula/functions/col.js +38 -24
  50. package/dist/formula/functions/col.js.map +1 -1
  51. package/dist/formula/functions/concat.js +37 -23
  52. package/dist/formula/functions/concat.js.map +1 -1
  53. package/dist/formula/functions/concatenate.js +35 -21
  54. package/dist/formula/functions/concatenate.js.map +1 -1
  55. package/dist/formula/functions/cos.js +36 -22
  56. package/dist/formula/functions/cos.js.map +1 -1
  57. package/dist/formula/functions/count.js +45 -31
  58. package/dist/formula/functions/count.js.map +1 -1
  59. package/dist/formula/functions/counta.js +45 -31
  60. package/dist/formula/functions/counta.js.map +1 -1
  61. package/dist/formula/functions/countif.js +40 -26
  62. package/dist/formula/functions/countif.js.map +1 -1
  63. package/dist/formula/functions/divide.js +42 -28
  64. package/dist/formula/functions/divide.js.map +1 -1
  65. package/dist/formula/functions/eq.js +35 -21
  66. package/dist/formula/functions/eq.js.map +1 -1
  67. package/dist/formula/functions/exp.js +38 -24
  68. package/dist/formula/functions/exp.js.map +1 -1
  69. package/dist/formula/functions/gt.js +37 -23
  70. package/dist/formula/functions/gt.js.map +1 -1
  71. package/dist/formula/functions/gte.js +37 -23
  72. package/dist/formula/functions/gte.js.map +1 -1
  73. package/dist/formula/functions/hlookup.js +77 -63
  74. package/dist/formula/functions/hlookup.js.map +1 -1
  75. package/dist/formula/functions/if.js +46 -32
  76. package/dist/formula/functions/if.js.map +1 -1
  77. package/dist/formula/functions/iferror.js +48 -34
  78. package/dist/formula/functions/iferror.js.map +1 -1
  79. package/dist/formula/functions/iferror.spec.js +63 -51
  80. package/dist/formula/functions/iferror.spec.js.map +1 -1
  81. package/dist/formula/functions/len.js +36 -22
  82. package/dist/formula/functions/len.js.map +1 -1
  83. package/dist/formula/functions/lenb.js +36 -22
  84. package/dist/formula/functions/lenb.js.map +1 -1
  85. package/dist/formula/functions/ln.js +38 -24
  86. package/dist/formula/functions/ln.js.map +1 -1
  87. package/dist/formula/functions/log.js +43 -29
  88. package/dist/formula/functions/log.js.map +1 -1
  89. package/dist/formula/functions/log10.js +38 -24
  90. package/dist/formula/functions/log10.js.map +1 -1
  91. package/dist/formula/functions/lt.js +37 -23
  92. package/dist/formula/functions/lt.js.map +1 -1
  93. package/dist/formula/functions/lte.js +37 -23
  94. package/dist/formula/functions/lte.js.map +1 -1
  95. package/dist/formula/functions/max.js +52 -38
  96. package/dist/formula/functions/max.js.map +1 -1
  97. package/dist/formula/functions/min.js +52 -38
  98. package/dist/formula/functions/min.js.map +1 -1
  99. package/dist/formula/functions/minus.js +57 -43
  100. package/dist/formula/functions/minus.js.map +1 -1
  101. package/dist/formula/functions/mod.js +40 -26
  102. package/dist/formula/functions/mod.js.map +1 -1
  103. package/dist/formula/functions/mod.spec.js +58 -46
  104. package/dist/formula/functions/mod.spec.js.map +1 -1
  105. package/dist/formula/functions/multiply.js +37 -23
  106. package/dist/formula/functions/multiply.js.map +1 -1
  107. package/dist/formula/functions/ne.js +35 -21
  108. package/dist/formula/functions/ne.js.map +1 -1
  109. package/dist/formula/functions/not.js +40 -26
  110. package/dist/formula/functions/not.js.map +1 -1
  111. package/dist/formula/functions/now.js +31 -17
  112. package/dist/formula/functions/now.js.map +1 -1
  113. package/dist/formula/functions/or.js +38 -24
  114. package/dist/formula/functions/or.js.map +1 -1
  115. package/dist/formula/functions/pi.js +29 -15
  116. package/dist/formula/functions/pi.js.map +1 -1
  117. package/dist/formula/functions/power.js +34 -20
  118. package/dist/formula/functions/power.js.map +1 -1
  119. package/dist/formula/functions/product.js +47 -33
  120. package/dist/formula/functions/product.js.map +1 -1
  121. package/dist/formula/functions/radians.js +36 -22
  122. package/dist/formula/functions/radians.js.map +1 -1
  123. package/dist/formula/functions/rand.js +29 -15
  124. package/dist/formula/functions/rand.js.map +1 -1
  125. package/dist/formula/functions/round.js +44 -30
  126. package/dist/formula/functions/round.js.map +1 -1
  127. package/dist/formula/functions/rounddown.js +44 -30
  128. package/dist/formula/functions/rounddown.js.map +1 -1
  129. package/dist/formula/functions/roundup.js +44 -30
  130. package/dist/formula/functions/roundup.js.map +1 -1
  131. package/dist/formula/functions/row.js +38 -24
  132. package/dist/formula/functions/row.js.map +1 -1
  133. package/dist/formula/functions/sin.js +36 -22
  134. package/dist/formula/functions/sin.js.map +1 -1
  135. package/dist/formula/functions/sqrt.js +38 -24
  136. package/dist/formula/functions/sqrt.js.map +1 -1
  137. package/dist/formula/functions/sum.js +52 -38
  138. package/dist/formula/functions/sum.js.map +1 -1
  139. package/dist/formula/functions/sum.spec.js +45 -33
  140. package/dist/formula/functions/sum.spec.js.map +1 -1
  141. package/dist/formula/functions/sumif.js +66 -52
  142. package/dist/formula/functions/sumif.js.map +1 -1
  143. package/dist/formula/functions/tan.js +36 -22
  144. package/dist/formula/functions/tan.js.map +1 -1
  145. package/dist/formula/functions/uminus.js +33 -19
  146. package/dist/formula/functions/uminus.js.map +1 -1
  147. package/dist/formula/functions/vlookup.js +77 -63
  148. package/dist/formula/functions/vlookup.js.map +1 -1
  149. package/dist/formula/mapping.js +126 -113
  150. package/dist/formula/mapping.js.map +1 -1
  151. package/dist/formula/solver.js +71 -56
  152. package/dist/formula/solver.js.map +1 -1
  153. package/dist/index.js +41 -10
  154. package/dist/index.js.map +1 -1
  155. package/dist/lib/autofill.js +344 -330
  156. package/dist/lib/autofill.js.map +1 -1
  157. package/dist/lib/clipboard.js +55 -41
  158. package/dist/lib/clipboard.js.map +1 -1
  159. package/dist/lib/converters.js +140 -119
  160. package/dist/lib/converters.js.map +1 -1
  161. package/dist/lib/structs.js +266 -228
  162. package/dist/lib/structs.js.map +1 -1
  163. package/dist/lib/table.js +915 -900
  164. package/dist/lib/table.js.map +1 -1
  165. package/dist/lib/time.js +69 -55
  166. package/dist/lib/time.js.map +1 -1
  167. package/dist/lib/virtualization.js +121 -104
  168. package/dist/lib/virtualization.js.map +1 -1
  169. package/dist/parsers/core.js +119 -105
  170. package/dist/parsers/core.js.map +1 -1
  171. package/dist/renderers/checkbox.js +24 -8
  172. package/dist/renderers/checkbox.js.map +1 -1
  173. package/dist/renderers/core.js +139 -125
  174. package/dist/renderers/core.js.map +1 -1
  175. package/dist/renderers/thousand_separator.js +25 -12
  176. package/dist/renderers/thousand_separator.js.map +1 -1
  177. package/dist/store/actions.js +495 -480
  178. package/dist/store/actions.js.map +1 -1
  179. package/dist/store/helpers.js +88 -72
  180. package/dist/store/helpers.js.map +1 -1
  181. package/dist/store/index.js +38 -2
  182. package/dist/store/index.js.map +1 -1
  183. package/dist/styles/embedder.js +27 -13
  184. package/dist/styles/embedder.js.map +1 -1
  185. package/dist/styles/minified.js +16 -3
  186. package/dist/styles/minified.js.map +1 -1
  187. package/dist/types.js +12 -1
  188. package/dist/utils.js +19 -5
  189. package/dist/utils.js.map +1 -1
  190. package/package.json +1 -1
@@ -1,541 +1,567 @@
1
- import { rangeToArea } from "../lib/structs";
2
- import { a2p, x2c } from "../lib/converters";
3
- // strip sharp and dollars
4
- const getId = (idString, stripAbsolute = true) => {
5
- let id = idString.slice(1);
6
- if (stripAbsolute && id.startsWith("$")) {
7
- id = id.slice(1);
8
- }
9
- if (stripAbsolute && id.endsWith("$")) {
10
- id = id.slice(0, -1);
11
- }
12
- return id;
13
- };
14
- export class FormulaError {
15
- constructor(code, message, error) {
16
- this.code = code;
17
- this.message = message;
18
- this.error = error;
19
- }
20
- }
21
- class Entity {
22
- constructor(value) {
23
- this.value = value;
24
- }
25
- }
26
- export class Value extends Entity {
27
- evaluate({}) {
28
- return this.value;
29
- }
30
- }
31
- export class Unreferenced extends Entity {
32
- evaluate({}) {
33
- throw new FormulaError("#REF!", `Reference does not exist.`);
34
- }
35
- }
36
- export class InvalidRef extends Entity {
37
- evaluate({}) {
38
- throw new FormulaError("#NAME?", `Invalid ref: ${this.value}`);
39
- }
40
- }
41
- export class Ref extends Entity {
42
- constructor(value) {
43
- super(value.toUpperCase());
44
- }
45
- evaluate({ table }) {
46
- const { y, x } = a2p(this.value);
47
- return table.trim({ top: y, left: x, bottom: y, right: x });
48
- }
49
- id(table) {
50
- const id = table.getIdByAddress(this.value);
51
- if (id) {
52
- return id;
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports", "../lib/structs", "../lib/converters"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.convertFormulaAbsolute = exports.Parser = exports.Lexer = exports.Token = exports.Function = exports.IdRange = exports.Id = exports.Range = exports.Ref = exports.InvalidRef = exports.Unreferenced = exports.Value = exports.FormulaError = void 0;
13
+ const structs_1 = require("../lib/structs");
14
+ const converters_1 = require("../lib/converters");
15
+ // strip sharp and dollars
16
+ const getId = (idString, stripAbsolute = true) => {
17
+ let id = idString.slice(1);
18
+ if (stripAbsolute && id.startsWith("$")) {
19
+ id = id.slice(1);
20
+ }
21
+ if (stripAbsolute && id.endsWith("$")) {
22
+ id = id.slice(0, -1);
23
+ }
24
+ return id;
25
+ };
26
+ class FormulaError {
27
+ constructor(code, message, error) {
28
+ this.code = code;
29
+ this.message = message;
30
+ this.error = error;
53
31
  }
54
- return this.value;
55
32
  }
56
- }
57
- export class Range extends Entity {
58
- constructor(value) {
59
- super(value.toUpperCase());
33
+ exports.FormulaError = FormulaError;
34
+ class Entity {
35
+ constructor(value) {
36
+ this.value = value;
37
+ }
60
38
  }
61
- evaluate({ table }) {
62
- const area = rangeToArea(this.complementRange(table));
63
- return table.trim(area);
39
+ class Value extends Entity {
40
+ evaluate({}) {
41
+ return this.value;
42
+ }
64
43
  }
65
- idRange(table) {
66
- return this.value
67
- .split(":")
68
- .map((ref) => table.getIdByAddress(ref))
69
- .join(":");
44
+ exports.Value = Value;
45
+ class Unreferenced extends Entity {
46
+ evaluate({}) {
47
+ throw new FormulaError("#REF!", `Reference does not exist.`);
48
+ }
70
49
  }
71
- complementRange(table) {
72
- const cells = this.value.split(":");
73
- let [start = "", end = ""] = cells;
74
- if (!start.match(/[1-9]\d*/)) {
75
- start += "1";
50
+ exports.Unreferenced = Unreferenced;
51
+ class InvalidRef extends Entity {
52
+ evaluate({}) {
53
+ throw new FormulaError("#NAME?", `Invalid ref: ${this.value}`);
76
54
  }
77
- if (!start.match(/[a-zA-Z]/)) {
78
- start = "A" + start;
55
+ }
56
+ exports.InvalidRef = InvalidRef;
57
+ class Ref extends Entity {
58
+ constructor(value) {
59
+ super(value.toUpperCase());
79
60
  }
80
- if (!end.match(/[1-9]\d*/)) {
81
- end += table.getNumRows();
61
+ evaluate({ table }) {
62
+ const { y, x } = (0, converters_1.a2p)(this.value);
63
+ return table.trim({ top: y, left: x, bottom: y, right: x });
82
64
  }
83
- if (!end.match(/[a-zA-Z]/)) {
84
- end = x2c(table.getNumCols() + 1) + end;
65
+ id(table) {
66
+ const id = table.getIdByAddress(this.value);
67
+ if (id) {
68
+ return id;
69
+ }
70
+ return this.value;
85
71
  }
86
- return `${start}:${end}`;
87
- }
88
- }
89
- export class Id extends Entity {
90
- evaluate({ table }) {
91
- const id = getId(this.value);
92
- const { y, x } = table.getPointById(id);
93
- return table.trim({ top: y, left: x, bottom: y, right: x });
94
- }
95
- ref(table, slideY = 0, slideX = 0) {
96
- return table.getAddressById(getId(this.value, false), slideY, slideX);
97
72
  }
98
- slide(table, slideY = 0, slideX = 0) {
99
- const address = this.ref(table, slideY, slideX);
100
- if (address == null || address.length < 2) {
101
- return "#REF!";
73
+ exports.Ref = Ref;
74
+ class Range extends Entity {
75
+ constructor(value) {
76
+ super(value.toUpperCase());
102
77
  }
103
- return table.getIdByAddress(address);
104
- }
105
- }
106
- export class IdRange extends Entity {
107
- evaluate({ table }) {
108
- const ids = this.value.split(":");
109
- const [p1, p2] = ids
110
- .map((id) => getId(id))
111
- .map((id) => table.getPointById(id));
112
- return table.trim({ top: p1.y, left: p1.x, bottom: p2.y, right: p2.x });
113
- }
114
- range(table, slideY = 0, slideX = 0) {
115
- return this.value
116
- .split(":")
117
- .map((id) => getId(id, false))
118
- .map((id) => table.getAddressById(id, slideY, slideX))
119
- .join(":");
120
- }
121
- slide(table, slideY = 0, slideX = 0) {
122
- const range = this.range(table, slideY, slideX);
123
- return new Range(range).idRange(table);
124
- }
125
- }
126
- export class Function {
127
- constructor(name, precedence = 0, args = []) {
128
- this.name = name;
129
- this.precedence = precedence;
130
- this.args = args;
131
- }
132
- evaluate({ table }) {
133
- const name = this.name.toLowerCase();
134
- const Func = table.getFunction(name);
135
- if (Func == null) {
136
- throw new FormulaError("#NAME?", `Unknown function: ${name}`);
137
- }
138
- const func = new Func({ args: this.args, table });
139
- return func.call();
140
- }
141
- }
142
- const ZERO = new Value(0);
143
- const INFIX_FUNCTION_NAME_MAP = {
144
- "+": "add",
145
- "-": "minus",
146
- "/": "divide",
147
- "*": "multiply",
148
- "^": "power",
149
- "&": "concat",
150
- "=": "eq",
151
- "<>": "ne",
152
- ">": "gt",
153
- ">=": "gte",
154
- "<": "lt",
155
- "<=": "lte",
156
- };
157
- const PREFIX_FUNCTION_NAME_MAP = {
158
- "-": "uminus",
159
- };
160
- export class Token {
161
- constructor(type, entity, precedence = 0) {
162
- this.type = type;
163
- this.entity = entity;
164
- this.precedence = precedence;
165
- }
166
- convert() {
167
- switch (this.type) {
168
- case "VALUE":
169
- return new Value(this.entity);
170
- case "ID":
171
- return new Id(this.entity);
172
- case "ID_RANGE":
173
- return new IdRange(this.entity);
174
- case "REF":
175
- return new Ref(this.entity);
176
- case "RANGE":
177
- return new Range(this.entity);
178
- case "INFIX_OPERATOR": {
179
- const name = INFIX_FUNCTION_NAME_MAP[this.entity];
180
- return new Function(name, this.precedence);
78
+ evaluate({ table }) {
79
+ const area = (0, structs_1.rangeToArea)(this.complementRange(table));
80
+ return table.trim(area);
81
+ }
82
+ idRange(table) {
83
+ return this.value
84
+ .split(":")
85
+ .map((ref) => table.getIdByAddress(ref))
86
+ .join(":");
87
+ }
88
+ complementRange(table) {
89
+ const cells = this.value.split(":");
90
+ let [start = "", end = ""] = cells;
91
+ if (!start.match(/[1-9]\d*/)) {
92
+ start += "1";
93
+ }
94
+ if (!start.match(/[a-zA-Z]/)) {
95
+ start = "A" + start;
96
+ }
97
+ if (!end.match(/[1-9]\d*/)) {
98
+ end += table.getNumRows();
181
99
  }
182
- case "PREFIX_OPERATOR": {
183
- const name = PREFIX_FUNCTION_NAME_MAP[this.entity];
184
- return new Function(name, this.precedence);
100
+ if (!end.match(/[a-zA-Z]/)) {
101
+ end = (0, converters_1.x2c)(table.getNumCols() + 1) + end;
185
102
  }
186
- case "FUNCTION":
187
- return new Function(this.entity);
188
- case "UNREFERENCED":
189
- return new Unreferenced(this.entity);
190
- case "INVALID_REF":
191
- return new InvalidRef(this.entity);
103
+ return `${start}:${end}`;
192
104
  }
193
105
  }
194
- }
195
- const isWhiteSpace = (char) => {
196
- return char === " " || char === "\n" || char === "\t";
197
- };
198
- const TOKEN_OPEN = new Token("OPEN", "("), TOKEN_CLOSE = new Token("CLOSE", ")"), TOKEN_COMMA = new Token("COMMA", ","), TOKEN_ADD = new Token("INFIX_OPERATOR", "+", 3), TOKEN_MINUS = new Token("INFIX_OPERATOR", "-", 3), TOKEN_UMINUS = new Token("PREFIX_OPERATOR", "-", 6), TOKEN_DIVIDE = new Token("INFIX_OPERATOR", "/", 4), TOKEN_MULTIPLY = new Token("INFIX_OPERATOR", "*", 4), TOKEN_POWER = new Token("INFIX_OPERATOR", "^", 5), TOKEN_CONCAT = new Token("INFIX_OPERATOR", "&", 4), TOKEN_GTE = new Token("INFIX_OPERATOR", ">=", 2), TOKEN_GT = new Token("INFIX_OPERATOR", ">", 2), TOKEN_LTE = new Token("INFIX_OPERATOR", "<=", 2), TOKEN_LT = new Token("INFIX_OPERATOR", "<", 2), TOKEN_NE = new Token("INFIX_OPERATOR", "<>", 1), TOKEN_EQ = new Token("INFIX_OPERATOR", "=", 1);
199
- const BOOLS = { ["true"]: true, ["false"]: false };
200
- export class Lexer {
201
- constructor(formula) {
202
- this.tokens = [];
203
- this.formula = formula;
204
- this.index = 0;
205
- this.tokens = [];
206
- }
207
- isWhiteSpace() {
208
- return isWhiteSpace(this.formula[this.index]);
209
- }
210
- next(base = 1) {
211
- this.index += base;
106
+ exports.Range = Range;
107
+ class Id extends Entity {
108
+ evaluate({ table }) {
109
+ const id = getId(this.value);
110
+ const { y, x } = table.getPointById(id);
111
+ return table.trim({ top: y, left: x, bottom: y, right: x });
112
+ }
113
+ ref(table, slideY = 0, slideX = 0) {
114
+ return table.getAddressById(getId(this.value, false), slideY, slideX);
115
+ }
116
+ slide(table, slideY = 0, slideX = 0) {
117
+ const address = this.ref(table, slideY, slideX);
118
+ if (address == null || address.length < 2) {
119
+ return "#REF!";
120
+ }
121
+ return table.getIdByAddress(address);
122
+ }
212
123
  }
213
- get(base = 0) {
214
- const c = this.formula[this.index + base];
215
- return c;
124
+ exports.Id = Id;
125
+ class IdRange extends Entity {
126
+ evaluate({ table }) {
127
+ const ids = this.value.split(":");
128
+ const [p1, p2] = ids
129
+ .map((id) => getId(id))
130
+ .map((id) => table.getPointById(id));
131
+ return table.trim({ top: p1.y, left: p1.x, bottom: p2.y, right: p2.x });
132
+ }
133
+ range(table, slideY = 0, slideX = 0) {
134
+ return this.value
135
+ .split(":")
136
+ .map((id) => getId(id, false))
137
+ .map((id) => table.getAddressById(id, slideY, slideX))
138
+ .join(":");
139
+ }
140
+ slide(table, slideY = 0, slideX = 0) {
141
+ const range = this.range(table, slideY, slideX);
142
+ return new Range(range).idRange(table);
143
+ }
216
144
  }
217
- getToken(base = 0) {
218
- return this.tokens[this.tokens.length + base];
145
+ exports.IdRange = IdRange;
146
+ class Function {
147
+ constructor(name, precedence = 0, args = []) {
148
+ this.name = name;
149
+ this.precedence = precedence;
150
+ this.args = args;
151
+ }
152
+ evaluate({ table }) {
153
+ const name = this.name.toLowerCase();
154
+ const Func = table.getFunction(name);
155
+ if (Func == null) {
156
+ throw new FormulaError("#NAME?", `Unknown function: ${name}`);
157
+ }
158
+ const func = new Func({ args: this.args, table });
159
+ return func.call();
160
+ }
219
161
  }
220
- stringifyToId(table, slideY = 0, slideX = 0) {
221
- return this.tokens
222
- .map((t) => {
223
- switch (t.type) {
162
+ exports.Function = Function;
163
+ const ZERO = new Value(0);
164
+ const INFIX_FUNCTION_NAME_MAP = {
165
+ "+": "add",
166
+ "-": "minus",
167
+ "/": "divide",
168
+ "*": "multiply",
169
+ "^": "power",
170
+ "&": "concat",
171
+ "=": "eq",
172
+ "<>": "ne",
173
+ ">": "gt",
174
+ ">=": "gte",
175
+ "<": "lt",
176
+ "<=": "lte",
177
+ };
178
+ const PREFIX_FUNCTION_NAME_MAP = {
179
+ "-": "uminus",
180
+ };
181
+ class Token {
182
+ constructor(type, entity, precedence = 0) {
183
+ this.type = type;
184
+ this.entity = entity;
185
+ this.precedence = precedence;
186
+ }
187
+ convert() {
188
+ switch (this.type) {
224
189
  case "VALUE":
225
- if (typeof t.entity === "number" || typeof t.entity === "boolean") {
226
- return t.entity;
227
- }
228
- return `"${t.entity}"`;
190
+ return new Value(this.entity);
229
191
  case "ID":
230
- return new Id(t.entity).slide(table, slideY, slideX);
192
+ return new Id(this.entity);
231
193
  case "ID_RANGE":
232
- return new IdRange(t.entity).slide(table, slideY, slideX);
194
+ return new IdRange(this.entity);
233
195
  case "REF":
234
- return new Ref(t.entity).id(table);
196
+ return new Ref(this.entity);
235
197
  case "RANGE":
236
- return new Range(t.entity).idRange(table);
237
- }
238
- return t.entity;
239
- })
240
- .join("");
241
- }
242
- stringifyToRef(table) {
243
- return this.tokens
244
- .map((t) => {
245
- switch (t.type) {
246
- case "VALUE":
247
- if (typeof t.entity === "number" || typeof t.entity === "boolean") {
248
- return t.entity;
249
- }
250
- return `"${t.entity}"`;
251
- case "ID":
252
- return new Id(t.entity).ref(table);
253
- case "ID_RANGE":
254
- return new IdRange(t.entity).range(table);
198
+ return new Range(this.entity);
199
+ case "INFIX_OPERATOR": {
200
+ const name = INFIX_FUNCTION_NAME_MAP[this.entity];
201
+ return new Function(name, this.precedence);
202
+ }
203
+ case "PREFIX_OPERATOR": {
204
+ const name = PREFIX_FUNCTION_NAME_MAP[this.entity];
205
+ return new Function(name, this.precedence);
206
+ }
207
+ case "FUNCTION":
208
+ return new Function(this.entity);
209
+ case "UNREFERENCED":
210
+ return new Unreferenced(this.entity);
211
+ case "INVALID_REF":
212
+ return new InvalidRef(this.entity);
255
213
  }
256
- return t.entity;
257
- })
258
- .join("");
214
+ }
259
215
  }
260
- tokenize() {
261
- var _a, _b;
262
- while (this.index <= this.formula.length) {
263
- this.skipSpaces();
264
- const char = this.get();
265
- this.next();
266
- switch (char) {
267
- case undefined:
268
- return;
269
- case "(":
270
- this.tokens.push(TOKEN_OPEN);
271
- continue;
272
- case ")":
273
- this.tokens.push(TOKEN_CLOSE);
274
- continue;
275
- case ",":
276
- this.tokens.push(TOKEN_COMMA);
277
- continue;
278
- case "+":
279
- this.tokens.push(TOKEN_ADD);
280
- continue;
281
- case "-": {
282
- const prev1 = (_a = this.getToken(-1)) === null || _a === void 0 ? void 0 : _a.type;
283
- const prev2 = (_b = this.getToken(-2)) === null || _b === void 0 ? void 0 : _b.type;
284
- if (prev1 === "INFIX_OPERATOR" ||
285
- (prev1 === "SPACE" && prev2 === "INFIX_OPERATOR")) {
286
- this.tokens.push(TOKEN_UMINUS);
287
- }
288
- else {
289
- this.tokens.push(TOKEN_MINUS);
290
- }
291
- continue;
216
+ exports.Token = Token;
217
+ const isWhiteSpace = (char) => {
218
+ return char === " " || char === "\n" || char === "\t";
219
+ };
220
+ const TOKEN_OPEN = new Token("OPEN", "("), TOKEN_CLOSE = new Token("CLOSE", ")"), TOKEN_COMMA = new Token("COMMA", ","), TOKEN_ADD = new Token("INFIX_OPERATOR", "+", 3), TOKEN_MINUS = new Token("INFIX_OPERATOR", "-", 3), TOKEN_UMINUS = new Token("PREFIX_OPERATOR", "-", 6), TOKEN_DIVIDE = new Token("INFIX_OPERATOR", "/", 4), TOKEN_MULTIPLY = new Token("INFIX_OPERATOR", "*", 4), TOKEN_POWER = new Token("INFIX_OPERATOR", "^", 5), TOKEN_CONCAT = new Token("INFIX_OPERATOR", "&", 4), TOKEN_GTE = new Token("INFIX_OPERATOR", ">=", 2), TOKEN_GT = new Token("INFIX_OPERATOR", ">", 2), TOKEN_LTE = new Token("INFIX_OPERATOR", "<=", 2), TOKEN_LT = new Token("INFIX_OPERATOR", "<", 2), TOKEN_NE = new Token("INFIX_OPERATOR", "<>", 1), TOKEN_EQ = new Token("INFIX_OPERATOR", "=", 1);
221
+ const BOOLS = { ["true"]: true, ["false"]: false };
222
+ class Lexer {
223
+ constructor(formula) {
224
+ this.tokens = [];
225
+ this.formula = formula;
226
+ this.index = 0;
227
+ this.tokens = [];
228
+ }
229
+ isWhiteSpace() {
230
+ return isWhiteSpace(this.formula[this.index]);
231
+ }
232
+ next(base = 1) {
233
+ this.index += base;
234
+ }
235
+ get(base = 0) {
236
+ const c = this.formula[this.index + base];
237
+ return c;
238
+ }
239
+ getToken(base = 0) {
240
+ return this.tokens[this.tokens.length + base];
241
+ }
242
+ stringifyToId(table, slideY = 0, slideX = 0) {
243
+ return this.tokens
244
+ .map((t) => {
245
+ switch (t.type) {
246
+ case "VALUE":
247
+ if (typeof t.entity === "number" || typeof t.entity === "boolean") {
248
+ return t.entity;
249
+ }
250
+ return `"${t.entity}"`;
251
+ case "ID":
252
+ return new Id(t.entity).slide(table, slideY, slideX);
253
+ case "ID_RANGE":
254
+ return new IdRange(t.entity).slide(table, slideY, slideX);
255
+ case "REF":
256
+ return new Ref(t.entity).id(table);
257
+ case "RANGE":
258
+ return new Range(t.entity).idRange(table);
292
259
  }
293
- case "/":
294
- this.tokens.push(TOKEN_DIVIDE);
295
- continue;
296
- case "*":
297
- this.tokens.push(TOKEN_MULTIPLY);
298
- continue;
299
- case "^":
300
- this.tokens.push(TOKEN_POWER);
301
- continue;
302
- case "&":
303
- this.tokens.push(TOKEN_CONCAT);
304
- continue;
305
- case "=":
306
- this.tokens.push(TOKEN_EQ);
307
- continue;
308
- case ">":
309
- if (this.get() === "=") {
310
- this.next();
311
- this.tokens.push(TOKEN_GTE);
260
+ return t.entity;
261
+ })
262
+ .join("");
263
+ }
264
+ stringifyToRef(table) {
265
+ return this.tokens
266
+ .map((t) => {
267
+ switch (t.type) {
268
+ case "VALUE":
269
+ if (typeof t.entity === "number" || typeof t.entity === "boolean") {
270
+ return t.entity;
271
+ }
272
+ return `"${t.entity}"`;
273
+ case "ID":
274
+ return new Id(t.entity).ref(table);
275
+ case "ID_RANGE":
276
+ return new IdRange(t.entity).range(table);
277
+ }
278
+ return t.entity;
279
+ })
280
+ .join("");
281
+ }
282
+ tokenize() {
283
+ var _a, _b;
284
+ while (this.index <= this.formula.length) {
285
+ this.skipSpaces();
286
+ const char = this.get();
287
+ this.next();
288
+ switch (char) {
289
+ case undefined:
290
+ return;
291
+ case "(":
292
+ this.tokens.push(TOKEN_OPEN);
312
293
  continue;
313
- }
314
- this.tokens.push(TOKEN_GT);
315
- continue;
316
- case "<":
317
- if (this.get() === "=") {
318
- this.next();
319
- this.tokens.push(TOKEN_LTE);
294
+ case ")":
295
+ this.tokens.push(TOKEN_CLOSE);
296
+ continue;
297
+ case ",":
298
+ this.tokens.push(TOKEN_COMMA);
299
+ continue;
300
+ case "+":
301
+ this.tokens.push(TOKEN_ADD);
302
+ continue;
303
+ case "-": {
304
+ const prev1 = (_a = this.getToken(-1)) === null || _a === void 0 ? void 0 : _a.type;
305
+ const prev2 = (_b = this.getToken(-2)) === null || _b === void 0 ? void 0 : _b.type;
306
+ if (prev1 === "INFIX_OPERATOR" ||
307
+ (prev1 === "SPACE" && prev2 === "INFIX_OPERATOR")) {
308
+ this.tokens.push(TOKEN_UMINUS);
309
+ }
310
+ else {
311
+ this.tokens.push(TOKEN_MINUS);
312
+ }
320
313
  continue;
321
314
  }
322
- if (this.get() === ">") {
323
- this.next();
324
- this.tokens.push(TOKEN_NE);
315
+ case "/":
316
+ this.tokens.push(TOKEN_DIVIDE);
317
+ continue;
318
+ case "*":
319
+ this.tokens.push(TOKEN_MULTIPLY);
320
+ continue;
321
+ case "^":
322
+ this.tokens.push(TOKEN_POWER);
323
+ continue;
324
+ case "&":
325
+ this.tokens.push(TOKEN_CONCAT);
326
+ continue;
327
+ case "=":
328
+ this.tokens.push(TOKEN_EQ);
329
+ continue;
330
+ case ">":
331
+ if (this.get() === "=") {
332
+ this.next();
333
+ this.tokens.push(TOKEN_GTE);
334
+ continue;
335
+ }
336
+ this.tokens.push(TOKEN_GT);
337
+ continue;
338
+ case "<":
339
+ if (this.get() === "=") {
340
+ this.next();
341
+ this.tokens.push(TOKEN_LTE);
342
+ continue;
343
+ }
344
+ if (this.get() === ">") {
345
+ this.next();
346
+ this.tokens.push(TOKEN_NE);
347
+ continue;
348
+ }
349
+ this.tokens.push(TOKEN_LT);
350
+ continue;
351
+ case '"': {
352
+ const buf = this.getString();
353
+ this.tokens.push(new Token("VALUE", buf));
325
354
  continue;
326
355
  }
327
- this.tokens.push(TOKEN_LT);
328
- continue;
329
- case '"': {
330
- const buf = this.getString();
331
- this.tokens.push(new Token("VALUE", buf));
332
- continue;
333
- }
334
- } // switch end
335
- let buf = char;
336
- while (true) {
337
- const c = this.get();
338
- if (c === "(") {
339
- this.tokens.push(new Token("FUNCTION", buf), TOKEN_OPEN);
340
- this.next();
341
- break;
342
- }
343
- if (c == null || c.match(/[ +\-/*^&=<>),]/)) {
344
- if (buf.length === 0) {
356
+ } // switch end
357
+ let buf = char;
358
+ while (true) {
359
+ const c = this.get();
360
+ if (c === "(") {
361
+ this.tokens.push(new Token("FUNCTION", buf), TOKEN_OPEN);
362
+ this.next();
345
363
  break;
346
364
  }
347
- if (buf.match(/^[+-]?(\d*[.])?\d+$/)) {
348
- this.tokens.push(new Token("VALUE", parseFloat(buf)));
349
- }
350
- else {
351
- // @ts-ignore
352
- const bool = BOOLS[buf.toLowerCase()];
353
- if (bool != null) {
354
- this.tokens.push(new Token("VALUE", bool));
355
- }
356
- else if (buf.startsWith("#")) {
357
- if (buf === "#REF!") {
358
- this.tokens.push(new Token("UNREFERENCED", buf));
359
- }
360
- else if (buf.indexOf(":") !== -1) {
361
- this.tokens.push(new Token("ID_RANGE", buf));
362
- }
363
- else {
364
- this.tokens.push(new Token("ID", buf));
365
- }
365
+ if (c == null || c.match(/[ +\-/*^&=<>),]/)) {
366
+ if (buf.length === 0) {
367
+ break;
366
368
  }
367
- else if (buf.indexOf(":") !== -1) {
368
- this.tokens.push(new Token("RANGE", buf));
369
+ if (buf.match(/^[+-]?(\d*[.])?\d+$/)) {
370
+ this.tokens.push(new Token("VALUE", parseFloat(buf)));
369
371
  }
370
372
  else {
371
373
  // @ts-ignore
372
- if (isNaN(buf[buf.length - 1])) {
373
- this.tokens.push(new Token("INVALID_REF", buf));
374
+ const bool = BOOLS[buf.toLowerCase()];
375
+ if (bool != null) {
376
+ this.tokens.push(new Token("VALUE", bool));
377
+ }
378
+ else if (buf.startsWith("#")) {
379
+ if (buf === "#REF!") {
380
+ this.tokens.push(new Token("UNREFERENCED", buf));
381
+ }
382
+ else if (buf.indexOf(":") !== -1) {
383
+ this.tokens.push(new Token("ID_RANGE", buf));
384
+ }
385
+ else {
386
+ this.tokens.push(new Token("ID", buf));
387
+ }
388
+ }
389
+ else if (buf.indexOf(":") !== -1) {
390
+ this.tokens.push(new Token("RANGE", buf));
374
391
  }
375
392
  else {
376
- this.tokens.push(new Token("REF", buf));
393
+ // @ts-ignore
394
+ if (isNaN(buf[buf.length - 1])) {
395
+ this.tokens.push(new Token("INVALID_REF", buf));
396
+ }
397
+ else {
398
+ this.tokens.push(new Token("REF", buf));
399
+ }
377
400
  }
378
401
  }
402
+ break;
379
403
  }
380
- break;
381
- }
382
- buf += c;
383
- this.next();
384
- }
385
- }
386
- }
387
- skipSpaces() {
388
- let space = "";
389
- while (this.isWhiteSpace()) {
390
- space += this.formula[this.index++];
391
- }
392
- if (space !== "") {
393
- this.tokens.push(new Token("SPACE", space));
394
- }
395
- }
396
- getString() {
397
- let buf = "";
398
- while (true) {
399
- const c = this.get();
400
- this.next();
401
- if (c == null) {
402
- break;
403
- }
404
- if (c === '"') {
405
- if (this.get() === '"') {
406
- // escape
407
- buf += '"';
404
+ buf += c;
408
405
  this.next();
409
- continue;
410
- }
411
- else {
412
- break;
413
406
  }
414
407
  }
415
- else {
416
- buf += c;
417
- }
418
408
  }
419
- return buf;
420
- }
421
- }
422
- export class Parser {
423
- constructor(tokens) {
424
- this.index = 0;
425
- this.depth = 0;
426
- this.tokens = tokens;
427
- }
428
- build() {
429
- const { expr } = this.parse(false);
430
- return expr;
431
- }
432
- parse(underFunction) {
433
- const stack = [];
434
- let lastOperator;
435
- const complement = (hasNext = false) => {
436
- if (lastOperator) {
437
- const outer = stack.pop();
438
- lastOperator.args.push(outer);
409
+ skipSpaces() {
410
+ let space = "";
411
+ while (this.isWhiteSpace()) {
412
+ space += this.formula[this.index++];
439
413
  }
440
- return { hasNext, expr: stack.shift() };
441
- };
442
- while (this.tokens.length > this.index) {
443
- const token = this.tokens[this.index++];
444
- if (token.type === "SPACE") {
445
- continue;
414
+ if (space !== "") {
415
+ this.tokens.push(new Token("SPACE", space));
446
416
  }
447
- if (token.type === "COMMA") {
448
- if (!underFunction) {
449
- throw new FormulaError("#ERROR!", "Invalid comma");
417
+ }
418
+ getString() {
419
+ let buf = "";
420
+ while (true) {
421
+ const c = this.get();
422
+ this.next();
423
+ if (c == null) {
424
+ break;
450
425
  }
451
- return complement(true);
452
- }
453
- else if (token.type === "VALUE" ||
454
- token.type === "ID" ||
455
- token.type === "ID_RANGE" ||
456
- token.type === "REF" ||
457
- token.type === "RANGE" ||
458
- token.type === "UNREFERENCED" ||
459
- token.type === "INVALID_REF") {
460
- const expr = token.convert();
461
- stack.push(expr);
462
- }
463
- else if (token.type === "FUNCTION") {
464
- this.index++;
465
- this.depth++;
466
- const func = token.convert();
467
- stack.push(func);
468
- while (true) {
469
- const { expr, hasNext } = this.parse(true);
470
- if (expr) {
471
- func.args.push(expr);
426
+ if (c === '"') {
427
+ if (this.get() === '"') {
428
+ // escape
429
+ buf += '"';
430
+ this.next();
431
+ continue;
472
432
  }
473
- if (!hasNext) {
433
+ else {
474
434
  break;
475
435
  }
476
436
  }
477
- }
478
- else if (token.type === "OPEN") {
479
- this.depth++;
480
- const { expr } = this.parse(false);
481
- stack.push(expr);
482
- }
483
- else if (token.type === "CLOSE") {
484
- if (this.depth-- === 0) {
485
- throw new FormulaError("#ERROR!", "Unexpected end paren");
437
+ else {
438
+ buf += c;
486
439
  }
487
- return complement();
488
440
  }
489
- else if (token.type === "INFIX_OPERATOR") {
490
- const operator = token.convert();
491
- let left = stack.pop();
492
- if (left == null) {
493
- if (operator.name === "minus" || operator.name === "add") {
494
- left = ZERO;
495
- }
496
- else {
497
- throw new FormulaError("#ERROR!", "Missing left expression");
441
+ return buf;
442
+ }
443
+ }
444
+ exports.Lexer = Lexer;
445
+ class Parser {
446
+ constructor(tokens) {
447
+ this.index = 0;
448
+ this.depth = 0;
449
+ this.tokens = tokens;
450
+ }
451
+ build() {
452
+ const { expr } = this.parse(false);
453
+ return expr;
454
+ }
455
+ parse(underFunction) {
456
+ const stack = [];
457
+ let lastOperator;
458
+ const complement = (hasNext = false) => {
459
+ if (lastOperator) {
460
+ const outer = stack.pop();
461
+ lastOperator.args.push(outer);
462
+ }
463
+ return { hasNext, expr: stack.shift() };
464
+ };
465
+ while (this.tokens.length > this.index) {
466
+ const token = this.tokens[this.index++];
467
+ if (token.type === "SPACE") {
468
+ continue;
469
+ }
470
+ if (token.type === "COMMA") {
471
+ if (!underFunction) {
472
+ throw new FormulaError("#ERROR!", "Invalid comma");
498
473
  }
474
+ return complement(true);
499
475
  }
500
- if (lastOperator == null) {
501
- operator.args.push(left);
502
- stack.unshift(operator);
476
+ else if (token.type === "VALUE" ||
477
+ token.type === "ID" ||
478
+ token.type === "ID_RANGE" ||
479
+ token.type === "REF" ||
480
+ token.type === "RANGE" ||
481
+ token.type === "UNREFERENCED" ||
482
+ token.type === "INVALID_REF") {
483
+ const expr = token.convert();
484
+ stack.push(expr);
503
485
  }
504
- else if (operator.precedence > lastOperator.precedence) {
505
- operator.args.push(left);
506
- lastOperator.args.push(operator);
507
- stack.unshift(lastOperator);
486
+ else if (token.type === "FUNCTION") {
487
+ this.index++;
488
+ this.depth++;
489
+ const func = token.convert();
490
+ stack.push(func);
491
+ while (true) {
492
+ const { expr, hasNext } = this.parse(true);
493
+ if (expr) {
494
+ func.args.push(expr);
495
+ }
496
+ if (!hasNext) {
497
+ break;
498
+ }
499
+ }
508
500
  }
509
- else {
510
- const outer = stack.shift();
511
- operator.args.push(outer);
512
- lastOperator.args.push(left);
513
- stack.unshift(operator);
501
+ else if (token.type === "OPEN") {
502
+ this.depth++;
503
+ const { expr } = this.parse(false);
504
+ stack.push(expr);
514
505
  }
515
- lastOperator = operator;
516
- }
517
- else if (token.type === "PREFIX_OPERATOR") {
518
- const operator = token.convert();
519
- if (lastOperator) {
520
- lastOperator.args.push(operator);
506
+ else if (token.type === "CLOSE") {
507
+ if (this.depth-- === 0) {
508
+ throw new FormulaError("#ERROR!", "Unexpected end paren");
509
+ }
510
+ return complement();
521
511
  }
522
- else {
523
- stack.unshift(operator);
512
+ else if (token.type === "INFIX_OPERATOR") {
513
+ const operator = token.convert();
514
+ let left = stack.pop();
515
+ if (left == null) {
516
+ if (operator.name === "minus" || operator.name === "add") {
517
+ left = ZERO;
518
+ }
519
+ else {
520
+ throw new FormulaError("#ERROR!", "Missing left expression");
521
+ }
522
+ }
523
+ if (lastOperator == null) {
524
+ operator.args.push(left);
525
+ stack.unshift(operator);
526
+ }
527
+ else if (operator.precedence > lastOperator.precedence) {
528
+ operator.args.push(left);
529
+ lastOperator.args.push(operator);
530
+ stack.unshift(lastOperator);
531
+ }
532
+ else {
533
+ const outer = stack.shift();
534
+ operator.args.push(outer);
535
+ lastOperator.args.push(left);
536
+ stack.unshift(operator);
537
+ }
538
+ lastOperator = operator;
539
+ }
540
+ else if (token.type === "PREFIX_OPERATOR") {
541
+ const operator = token.convert();
542
+ if (lastOperator) {
543
+ lastOperator.args.push(operator);
544
+ }
545
+ else {
546
+ stack.unshift(operator);
547
+ }
548
+ lastOperator = operator;
524
549
  }
525
- lastOperator = operator;
526
550
  }
551
+ return complement();
527
552
  }
528
- return complement();
529
553
  }
530
- }
531
- export const convertFormulaAbsolute = ({ value, table, slideY = 0, slideX = 0, }) => {
532
- if (typeof value === "string" || value instanceof String) {
533
- if (value.charAt(0) === "=") {
534
- const lexer = new Lexer(value.substring(1));
535
- lexer.tokenize();
536
- return "=" + lexer.stringifyToId(table, slideY, slideX);
554
+ exports.Parser = Parser;
555
+ const convertFormulaAbsolute = ({ value, table, slideY = 0, slideX = 0, }) => {
556
+ if (typeof value === "string" || value instanceof String) {
557
+ if (value.charAt(0) === "=") {
558
+ const lexer = new Lexer(value.substring(1));
559
+ lexer.tokenize();
560
+ return "=" + lexer.stringifyToId(table, slideY, slideX);
561
+ }
537
562
  }
538
- }
539
- return value;
540
- };
563
+ return value;
564
+ };
565
+ exports.convertFormulaAbsolute = convertFormulaAbsolute;
566
+ });
541
567
  //# sourceMappingURL=evaluator.js.map