@trebco/treb 28.10.5 → 28.13.2

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.
@@ -305,9 +305,19 @@ export interface ParseResult {
305
305
  full_reference_list?: Array<UnitRange | UnitAddress | UnitIdentifier | UnitStructuredReference>;
306
306
  }
307
307
 
308
+ /**
309
+ * moving these settings into flags, but we want to ensure that
310
+ * they're available so we'll have some required flags
311
+ *
312
+ */
313
+ export interface RequiredParserFlags {
314
+ decimal_mark: DecimalMarkType;
315
+ argument_separator: ArgumentSeparatorType;
316
+ }
317
+
308
318
  //
309
319
 
310
- export interface ParserFlags {
320
+ export interface OptionalParserFlags {
311
321
 
312
322
  /**
313
323
  * flag: support spreadsheet addresses (e.g. "A1"). this is the default,
@@ -386,6 +396,8 @@ export interface ParserFlags {
386
396
 
387
397
  }
388
398
 
399
+ export type ParserFlags = Partial<OptionalParserFlags> & RequiredParserFlags;
400
+
389
401
  export interface RenderOptions {
390
402
  offset: { rows: number; columns: number };
391
403
  missing: string;
@@ -396,8 +408,19 @@ export interface RenderOptions {
396
408
  table_name: string;
397
409
  }
398
410
 
411
+ /*
399
412
  export interface PersistedParserConfig {
400
- flags: Partial<ParserFlags>;
401
- argument_separator: ArgumentSeparatorType;
402
- decimal_mark: DecimalMarkType;
413
+ flags: Partial<ParserFlags> & RequiredParserFlags;
414
+ // argument_separator: ArgumentSeparatorType;
415
+ // decimal_mark: DecimalMarkType;
403
416
  }
417
+ */
418
+
419
+ export const DefaultParserConfig: ParserFlags = {
420
+ spreadsheet_semantics: true,
421
+ dimensioned_quantities: false,
422
+ fractions: true,
423
+ decimal_mark: DecimalMarkType.Period,
424
+ argument_separator: ArgumentSeparatorType.Comma,
425
+ };
426
+
@@ -34,10 +34,11 @@ import type {
34
34
  ParserFlags,
35
35
  UnitStructuredReference,
36
36
  RenderOptions,
37
- PersistedParserConfig} from './parser-types';
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
- * argument separator. this can be changed prior to parsing/rendering.
161
- * FIXME: use an accessor to ensure type, outside of ts?
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 = ArgumentSeparatorType.Comma;
175
+ public get argument_separator(): ArgumentSeparatorType {
176
+ return this.flags.argument_separator;
177
+ }
164
178
 
165
- /**
166
- * decimal mark. this can be changed prior to parsing/rendering.
167
- * FIXME: use an accessor to ensure type, outside of ts?
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 = DecimalMarkType.Period;
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: Partial<ParserFlags> = {
175
- spreadsheet_semantics: true,
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
- protected parser_state: string[] = [];
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
- const config: PersistedParserConfig = {
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.parser_state.shift();
322
+ const json = this.parser_state_cache.shift();
282
323
  if (json) {
283
324
  try {
284
- const config = JSON.parse(json) as PersistedParserConfig;
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
  }