@trebco/treb 28.11.1 → 28.15.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/treb-spreadsheet-light.mjs +11 -11
- package/dist/treb-spreadsheet.mjs +11 -11
- package/dist/treb.d.ts +27 -3
- package/package.json +1 -1
- package/treb-base-types/src/style.ts +3 -0
- package/treb-calculator/src/calculator.ts +235 -68
- package/treb-calculator/src/descriptors.ts +5 -0
- package/treb-calculator/src/expression-calculator.ts +9 -5
- package/treb-calculator/src/functions/base-functions.ts +410 -21
- package/treb-calculator/src/functions/text-functions.ts +45 -55
- package/treb-calculator/src/primitives.ts +11 -0
- package/treb-calculator/src/utilities.ts +55 -0
- package/treb-embed/markup/layout.html +15 -10
- package/treb-embed/markup/toolbar.html +5 -5
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +38 -2
- package/treb-embed/src/embedded-spreadsheet.ts +227 -29
- package/treb-embed/src/options.ts +5 -0
- package/treb-embed/style/dark-theme.scss +1 -0
- package/treb-embed/style/formula-bar.scss +20 -7
- package/treb-embed/style/theme-defaults.scss +20 -0
- package/treb-export/src/export-worker/export-worker.ts +1 -0
- package/treb-export/src/export2.ts +6 -1
- package/treb-export/src/import2.ts +76 -6
- package/treb-export/src/shared-strings2.ts +1 -1
- package/treb-export/src/workbook-style2.ts +89 -52
- package/treb-export/src/workbook2.ts +119 -1
- package/treb-grid/src/editors/editor.ts +7 -0
- package/treb-grid/src/editors/formula_bar.ts +23 -1
- package/treb-grid/src/render/tile_renderer.ts +46 -3
- package/treb-grid/src/types/annotation.ts +17 -3
- package/treb-grid/src/types/grid.ts +28 -9
- package/treb-grid/src/types/grid_base.ts +10 -105
- package/treb-grid/src/types/grid_options.ts +3 -2
- package/treb-grid/src/types/named_range.ts +8 -1
- package/treb-grid/src/types/serialize_options.ts +5 -0
- package/treb-parser/src/parser-types.ts +27 -4
- package/treb-parser/src/parser.ts +74 -36
|
@@ -34,10 +34,11 @@ import type {
|
|
|
34
34
|
ParserFlags,
|
|
35
35
|
UnitStructuredReference,
|
|
36
36
|
RenderOptions,
|
|
37
|
-
|
|
37
|
+
} from './parser-types';
|
|
38
38
|
import {
|
|
39
39
|
ArgumentSeparatorType,
|
|
40
|
-
DecimalMarkType
|
|
40
|
+
DecimalMarkType,
|
|
41
|
+
DefaultParserConfig
|
|
41
42
|
} from './parser-types';
|
|
42
43
|
|
|
43
44
|
interface PrecedenceList {
|
|
@@ -152,31 +153,47 @@ const unary_operators: PrecedenceList = { '-': 100, '+': 100 };
|
|
|
152
153
|
* which runs synchronously). one benefit of using a singleton would be
|
|
153
154
|
* consistency in decimal mark, we'd only have to set once.
|
|
154
155
|
*
|
|
156
|
+
* FIXME: the internal state is starting to grate. there's no reason for
|
|
157
|
+
* it and it just confuses things because parsing is stateless (except for
|
|
158
|
+
* configuration). internal state just keeps results from the last parse
|
|
159
|
+
* operation. we should refactor so parsing is clean and returns all
|
|
160
|
+
* results directly, caller can store if necessary.
|
|
161
|
+
*
|
|
155
162
|
* FIXME: split rendering into a separate class? would be a little cleaner.
|
|
163
|
+
*
|
|
164
|
+
* FIXME: we don't currently handle full-width punctuation. it would be
|
|
165
|
+
* simple to parse, a little more complicated to keep track of if we wanted
|
|
166
|
+
* to be able to rewrite. TODO/FIXME.
|
|
167
|
+
*
|
|
156
168
|
*/
|
|
157
169
|
export class Parser {
|
|
158
170
|
|
|
159
|
-
/**
|
|
160
|
-
*
|
|
161
|
-
*
|
|
171
|
+
/**
|
|
172
|
+
* accessor replacing old field. the actual value is moved to flags,
|
|
173
|
+
* and should be set via the SetLocaleSettings method.
|
|
162
174
|
*/
|
|
163
|
-
public argument_separator
|
|
175
|
+
public get argument_separator(): ArgumentSeparatorType {
|
|
176
|
+
return this.flags.argument_separator;
|
|
177
|
+
}
|
|
164
178
|
|
|
165
|
-
/**
|
|
166
|
-
*
|
|
167
|
-
*
|
|
179
|
+
/**
|
|
180
|
+
* accessor replacing old field. the actual value is moved to flags,
|
|
181
|
+
* and should be set via the SetLocaleSettings method.
|
|
168
182
|
*/
|
|
169
|
-
public decimal_mark
|
|
183
|
+
public get decimal_mark(): DecimalMarkType {
|
|
184
|
+
return this.flags.decimal_mark;
|
|
185
|
+
}
|
|
170
186
|
|
|
171
187
|
/**
|
|
172
188
|
* unifying flags
|
|
173
189
|
*/
|
|
174
|
-
public flags:
|
|
175
|
-
|
|
176
|
-
dimensioned_quantities: false,
|
|
177
|
-
fractions: true,
|
|
190
|
+
public flags: ParserFlags = {
|
|
191
|
+
...DefaultParserConfig,
|
|
178
192
|
};
|
|
179
193
|
|
|
194
|
+
/**
|
|
195
|
+
* FIXME: why is this a class member? at a minimum it could be static
|
|
196
|
+
*/
|
|
180
197
|
protected r1c1_regex = /[rR]((?:\[[-+]{0,1}\d+\]|\d+))[cC]((?:\[[-+]{0,1}\d+\]|\d+))$/;
|
|
181
198
|
|
|
182
199
|
/**
|
|
@@ -249,7 +266,36 @@ export class Parser {
|
|
|
249
266
|
*/
|
|
250
267
|
protected full_reference_list: Array<UnitAddress | UnitRange | UnitIdentifier | UnitStructuredReference> = [];
|
|
251
268
|
|
|
252
|
-
|
|
269
|
+
/**
|
|
270
|
+
* cache for storing/restoring parser state, if we toggle it
|
|
271
|
+
*/
|
|
272
|
+
protected parser_state_cache: string[] = [];
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* step towards protecting these values and setting them in one
|
|
276
|
+
* operation.
|
|
277
|
+
*
|
|
278
|
+
* UPDATE: switch order. argument separator is optional and implied.
|
|
279
|
+
*/
|
|
280
|
+
public SetLocaleSettings(decimal_mark: DecimalMarkType, argument_separator?: ArgumentSeparatorType) {
|
|
281
|
+
|
|
282
|
+
if (typeof argument_separator === 'undefined') {
|
|
283
|
+
argument_separator = (decimal_mark === DecimalMarkType.Comma) ?
|
|
284
|
+
ArgumentSeparatorType.Semicolon :
|
|
285
|
+
ArgumentSeparatorType.Comma ;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// I suppose semicolon and period is allowable, although no one
|
|
289
|
+
// uses it. this test only works because we know the internal type
|
|
290
|
+
// representation, but that's fragile and not a good idea. FIXME
|
|
291
|
+
|
|
292
|
+
if ((argument_separator as any) === (decimal_mark as any)) {
|
|
293
|
+
throw new Error('invalid locale setting');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
this.flags.argument_separator = argument_separator;
|
|
297
|
+
this.flags.decimal_mark = decimal_mark;
|
|
298
|
+
}
|
|
253
299
|
|
|
254
300
|
/**
|
|
255
301
|
* save local configuration to a buffer, so it can be restored. we're doing
|
|
@@ -265,12 +311,7 @@ export class Parser {
|
|
|
265
311
|
*
|
|
266
312
|
*/
|
|
267
313
|
public Save() {
|
|
268
|
-
|
|
269
|
-
flags: this.flags,
|
|
270
|
-
argument_separator: this.argument_separator,
|
|
271
|
-
decimal_mark: this.decimal_mark,
|
|
272
|
-
}
|
|
273
|
-
this.parser_state.push(JSON.stringify(config));
|
|
314
|
+
this.parser_state_cache.push(JSON.stringify(this.flags));
|
|
274
315
|
}
|
|
275
316
|
|
|
276
317
|
/**
|
|
@@ -278,13 +319,10 @@ export class Parser {
|
|
|
278
319
|
* @see Save
|
|
279
320
|
*/
|
|
280
321
|
public Restore() {
|
|
281
|
-
const json = this.
|
|
322
|
+
const json = this.parser_state_cache.shift();
|
|
282
323
|
if (json) {
|
|
283
324
|
try {
|
|
284
|
-
|
|
285
|
-
this.flags = config.flags;
|
|
286
|
-
this.argument_separator = config.argument_separator;
|
|
287
|
-
this.decimal_mark = config.decimal_mark;
|
|
325
|
+
this.flags = JSON.parse(json) as ParserFlags;
|
|
288
326
|
}
|
|
289
327
|
catch (err) {
|
|
290
328
|
console.error(err);
|
|
@@ -421,7 +459,7 @@ export class Parser {
|
|
|
421
459
|
|
|
422
460
|
// use default separator, unless we're explicitly converting.
|
|
423
461
|
|
|
424
|
-
let separator = this.argument_separator + ' ';
|
|
462
|
+
let separator = this.flags.argument_separator + ' ';
|
|
425
463
|
if (convert_argument_separator === ArgumentSeparatorType.Comma) {
|
|
426
464
|
separator = ', ';
|
|
427
465
|
}
|
|
@@ -438,13 +476,13 @@ export class Parser {
|
|
|
438
476
|
|
|
439
477
|
const decimal = convert_decimal === DecimalMarkType.Comma ? ',' : '.';
|
|
440
478
|
const decimal_rex =
|
|
441
|
-
this.decimal_mark === DecimalMarkType.Comma ? /,/ : /\./;
|
|
479
|
+
this.flags.decimal_mark === DecimalMarkType.Comma ? /,/ : /\./;
|
|
442
480
|
|
|
443
481
|
// we need this for complex numbers, but I don't want to change the
|
|
444
482
|
// original at the moment, just in case. we can run through that later.
|
|
445
483
|
|
|
446
484
|
const decimal_rex_g =
|
|
447
|
-
this.decimal_mark === DecimalMarkType.Comma ? /,/g : /\./g;
|
|
485
|
+
this.flags.decimal_mark === DecimalMarkType.Comma ? /,/g : /\./g;
|
|
448
486
|
|
|
449
487
|
switch (unit.type) {
|
|
450
488
|
case 'address':
|
|
@@ -517,13 +555,13 @@ export class Parser {
|
|
|
517
555
|
// and convert if necessary.
|
|
518
556
|
|
|
519
557
|
let imaginary_text = Math.abs(unit.imaginary).toString();
|
|
520
|
-
if (convert_decimal === DecimalMarkType.Comma || this.decimal_mark === DecimalMarkType.Comma) {
|
|
558
|
+
if (convert_decimal === DecimalMarkType.Comma || this.flags.decimal_mark === DecimalMarkType.Comma) {
|
|
521
559
|
imaginary_text = imaginary_text.replace(/\./, ',');
|
|
522
560
|
}
|
|
523
561
|
|
|
524
562
|
if (unit.real) {
|
|
525
563
|
let real_text = unit.real.toString();
|
|
526
|
-
if (convert_decimal === DecimalMarkType.Comma || this.decimal_mark === DecimalMarkType.Comma) {
|
|
564
|
+
if (convert_decimal === DecimalMarkType.Comma || this.flags.decimal_mark === DecimalMarkType.Comma) {
|
|
527
565
|
real_text = real_text.replace(/\./, ',');
|
|
528
566
|
}
|
|
529
567
|
|
|
@@ -568,7 +606,7 @@ export class Parser {
|
|
|
568
606
|
let text = unit.text;
|
|
569
607
|
if (
|
|
570
608
|
convert_decimal === DecimalMarkType.Comma &&
|
|
571
|
-
this.decimal_mark === DecimalMarkType.Period
|
|
609
|
+
this.flags.decimal_mark === DecimalMarkType.Period
|
|
572
610
|
) {
|
|
573
611
|
text = text.replace(/,/g, ''); // remove grouping
|
|
574
612
|
}
|
|
@@ -699,7 +737,7 @@ export class Parser {
|
|
|
699
737
|
this.id_counter = 0;
|
|
700
738
|
|
|
701
739
|
// set separator
|
|
702
|
-
switch (this.argument_separator) {
|
|
740
|
+
switch (this.flags.argument_separator) {
|
|
703
741
|
case ArgumentSeparatorType.Semicolon:
|
|
704
742
|
this.argument_separator_char = SEMICOLON;
|
|
705
743
|
break;
|
|
@@ -709,7 +747,7 @@ export class Parser {
|
|
|
709
747
|
}
|
|
710
748
|
|
|
711
749
|
// and decimal mark
|
|
712
|
-
switch (this.decimal_mark) {
|
|
750
|
+
switch (this.flags.decimal_mark) {
|
|
713
751
|
case DecimalMarkType.Comma:
|
|
714
752
|
this.decimal_mark_char = COMMA;
|
|
715
753
|
break;
|
|
@@ -765,8 +803,8 @@ export class Parser {
|
|
|
765
803
|
error: this.error,
|
|
766
804
|
error_position: this.error_position,
|
|
767
805
|
dependencies: this.dependencies,
|
|
768
|
-
separator: this.argument_separator,
|
|
769
|
-
decimal_mark: this.decimal_mark,
|
|
806
|
+
separator: this.flags.argument_separator,
|
|
807
|
+
decimal_mark: this.flags.decimal_mark,
|
|
770
808
|
full_reference_list: this.full_reference_list.slice(0),
|
|
771
809
|
};
|
|
772
810
|
}
|