@trebco/treb 30.2.4 → 30.2.10
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/package.json +1 -1
- package/treb-calculator/src/calculator.ts +41 -0
- package/treb-calculator/src/functions/base-functions.ts +164 -1
- package/treb-calculator/src/functions/statistics-functions.ts +134 -0
- package/treb-calculator/src/functions/text-functions.ts +45 -0
- package/treb-calculator/src/utilities.ts +5 -1
- package/treb-data-model/src/data_model.ts +227 -2
- package/treb-data-model/src/index.ts +1 -0
- package/{treb-embed → treb-data-model}/src/language-model.ts +3 -0
- package/treb-data-model/src/sheet.ts +0 -13
- package/treb-embed/src/embedded-spreadsheet.ts +12 -36
- package/treb-grid/src/render/tile_renderer.ts +14 -0
- package/treb-grid/src/types/grid.ts +25 -139
- package/treb-parser/src/parser-types.ts +12 -0
- package/treb-parser/src/parser.ts +43 -2
- package/tsproject.json +1 -1
|
@@ -807,19 +807,6 @@ export class Sheet {
|
|
|
807
807
|
}
|
|
808
808
|
}
|
|
809
809
|
|
|
810
|
-
/* *
|
|
811
|
-
* factory method creates a sheet from a 2D array.
|
|
812
|
-
*
|
|
813
|
-
* /
|
|
814
|
-
public static FromArray(data: any[] = [], transpose = false): Sheet {
|
|
815
|
-
const sheet = new Sheet();
|
|
816
|
-
sheet.cells.FromArray(data, transpose);
|
|
817
|
-
|
|
818
|
-
return sheet;
|
|
819
|
-
}
|
|
820
|
-
*/
|
|
821
|
-
|
|
822
|
-
|
|
823
810
|
// --- public methods -------------------------------------------------------
|
|
824
811
|
|
|
825
812
|
public MergeCells(area: Area): void {
|
|
@@ -49,7 +49,10 @@ import type {
|
|
|
49
49
|
CondifionalFormatExpressionOptions,
|
|
50
50
|
ConditionalFormatCellMatchOptions,
|
|
51
51
|
ConditionalFormatCellMatch,
|
|
52
|
-
|
|
52
|
+
|
|
53
|
+
LanguageModel,
|
|
54
|
+
TranslatedFunctionDescriptor,
|
|
55
|
+
|
|
53
56
|
} from 'treb-data-model';
|
|
54
57
|
|
|
55
58
|
|
|
@@ -88,7 +91,6 @@ import { Spinner } from './spinner';
|
|
|
88
91
|
import { type EmbeddedSpreadsheetOptions, DefaultOptions, type ExportOptions } from './options';
|
|
89
92
|
import { type TREBDocument, SaveFileType, LoadSource, type EmbeddedSheetEvent, type InsertTableOptions } from './types';
|
|
90
93
|
|
|
91
|
-
import type { LanguageModel, TranslatedFunctionDescriptor } from './language-model';
|
|
92
94
|
import type { SelectionState } from './selection-state';
|
|
93
95
|
import type { BorderToolbarMessage, ToolbarMessage } from './toolbar-message';
|
|
94
96
|
|
|
@@ -341,8 +343,9 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
341
343
|
return Localization;
|
|
342
344
|
}
|
|
343
345
|
|
|
344
|
-
|
|
346
|
+
/* * loaded language model, if any (moved to data model) * /
|
|
345
347
|
protected language_model?: LanguageModel;
|
|
348
|
+
*/
|
|
346
349
|
|
|
347
350
|
/** FIXME: fix type (needs to be extensible) */
|
|
348
351
|
protected events = new EventSource<{ type: string }>();
|
|
@@ -1204,10 +1207,10 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
1204
1207
|
|
|
1205
1208
|
let list: FunctionDescriptor[] = this.calculator.SupportedFunctions();
|
|
1206
1209
|
|
|
1207
|
-
if (this.language_model?.functions) {
|
|
1210
|
+
if (this.model.language_model?.functions) {
|
|
1208
1211
|
|
|
1209
1212
|
const map: Record<string, TranslatedFunctionDescriptor> = {};
|
|
1210
|
-
for (const entry of this.language_model.functions || []) {
|
|
1213
|
+
for (const entry of this.model.language_model.functions || []) {
|
|
1211
1214
|
map[entry.base.toUpperCase()] = entry;
|
|
1212
1215
|
}
|
|
1213
1216
|
|
|
@@ -2002,8 +2005,6 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
2002
2005
|
language = parts[0];
|
|
2003
2006
|
}
|
|
2004
2007
|
|
|
2005
|
-
this.SetLanguage(); // clear
|
|
2006
|
-
|
|
2007
2008
|
language = language.toLowerCase();
|
|
2008
2009
|
|
|
2009
2010
|
let mod: { LanguageMap: LanguageModel } | undefined;
|
|
@@ -2029,39 +2030,14 @@ export class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
|
|
|
2029
2030
|
}
|
|
2030
2031
|
|
|
2031
2032
|
if (mod) {
|
|
2032
|
-
this.SetLanguage(mod.LanguageMap);
|
|
2033
|
-
}
|
|
2034
|
-
|
|
2035
|
-
}
|
|
2036
|
-
|
|
2037
|
-
/**
|
|
2038
|
-
* this is not public _yet_
|
|
2039
|
-
*
|
|
2040
|
-
* @internal
|
|
2041
|
-
*/
|
|
2042
|
-
public SetLanguage(model?: LanguageModel): void {
|
|
2043
|
-
|
|
2044
|
-
this.language_model = model;
|
|
2045
|
-
|
|
2046
|
-
if (!model) {
|
|
2047
|
-
this.grid.SetLanguageMap(); // clear
|
|
2033
|
+
this.model.SetLanguage(mod.LanguageMap);
|
|
2048
2034
|
}
|
|
2049
2035
|
else {
|
|
2050
|
-
|
|
2051
|
-
// create a name map for grid
|
|
2052
|
-
|
|
2053
|
-
const map: Record< string, string > = {};
|
|
2054
|
-
|
|
2055
|
-
if (model.functions) {
|
|
2056
|
-
for (const entry of model.functions || []) {
|
|
2057
|
-
map[entry.base] = entry.name;
|
|
2058
|
-
}
|
|
2059
|
-
}
|
|
2060
|
-
|
|
2061
|
-
this.grid.SetLanguageMap(map);
|
|
2062
|
-
|
|
2036
|
+
this.model.SetLanguage();
|
|
2063
2037
|
}
|
|
2064
2038
|
|
|
2039
|
+
this.grid.Reselect();
|
|
2040
|
+
this.grid.Update(true);
|
|
2065
2041
|
this.UpdateAC();
|
|
2066
2042
|
|
|
2067
2043
|
}
|
|
@@ -727,6 +727,20 @@ export class TileRenderer {
|
|
|
727
727
|
let pad_entry: RenderTextPart | undefined;
|
|
728
728
|
let composite_width = 0;
|
|
729
729
|
|
|
730
|
+
// -------------------------------------------------------------------------
|
|
731
|
+
|
|
732
|
+
// moved translated boolean formatting here. I don't like this. it
|
|
733
|
+
// should be in sheet (at least that's where the rest of formatting
|
|
734
|
+
// is), but sheet doesn't have a reference to data model (and because
|
|
735
|
+
// sheets are owned by data model, I don't want to add a circular ref).
|
|
736
|
+
|
|
737
|
+
if (cell.rendered_type === ValueType.boolean) {
|
|
738
|
+
const value = cell.calculated_type ? cell.calculated : cell.value;
|
|
739
|
+
cell.formatted = value ? (this.model.language_model?.boolean_true || 'TRUE') : (this.model.language_model?.boolean_false || 'FALSE');
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// -------------------------------------------------------------------------
|
|
743
|
+
|
|
730
744
|
let override_formatting: string | undefined;
|
|
731
745
|
let formatted = cell.editing ? '' : cell.formatted; // <-- empty on editing, to remove overflows
|
|
732
746
|
|
|
@@ -175,18 +175,6 @@ export class Grid extends GridBase {
|
|
|
175
175
|
|
|
176
176
|
// --- private members -------------------------------------------------------
|
|
177
177
|
|
|
178
|
-
/**
|
|
179
|
-
* maps common language (english) -> local language. this should
|
|
180
|
-
* be passed in (actually set via a function).
|
|
181
|
-
*/
|
|
182
|
-
private language_map?: Record<string, string>;
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* maps local language -> common (english). this should be constructed
|
|
186
|
-
* when the forward function is passed in, so there's a 1-1 correspondence.
|
|
187
|
-
*/
|
|
188
|
-
private reverse_language_map?: Record<string, string>;
|
|
189
|
-
|
|
190
178
|
// testing
|
|
191
179
|
private hover_data: {
|
|
192
180
|
note?: boolean;
|
|
@@ -648,33 +636,10 @@ export class Grid extends GridBase {
|
|
|
648
636
|
// --- public methods --------------------------------------------------------
|
|
649
637
|
|
|
650
638
|
/**
|
|
651
|
-
*
|
|
652
|
-
*
|
|
653
|
-
* as that will be used when we translate one way or the other.
|
|
639
|
+
* re-select the current selection, for side effects. used when switching
|
|
640
|
+
* languages to update the function view (if any)
|
|
654
641
|
*/
|
|
655
|
-
public
|
|
656
|
-
|
|
657
|
-
if (!language_map) {
|
|
658
|
-
this.language_map = this.reverse_language_map = undefined;
|
|
659
|
-
}
|
|
660
|
-
else {
|
|
661
|
-
|
|
662
|
-
const keys = Object.keys(language_map);
|
|
663
|
-
|
|
664
|
-
// normalize forward
|
|
665
|
-
this.language_map = {};
|
|
666
|
-
for (const key of keys) {
|
|
667
|
-
this.language_map[key.toUpperCase()] = language_map[key];
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
// normalize backward
|
|
671
|
-
this.reverse_language_map = {};
|
|
672
|
-
for (const key of keys) {
|
|
673
|
-
const value = language_map[key];
|
|
674
|
-
this.reverse_language_map[value.toUpperCase()] = key;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
}
|
|
642
|
+
public Reselect() {
|
|
678
643
|
|
|
679
644
|
// we might need to update the current displayed selection. depends
|
|
680
645
|
// on when we expect languages to be set.
|
|
@@ -2171,7 +2136,7 @@ export class Grid extends GridBase {
|
|
|
2171
2136
|
|
|
2172
2137
|
|
|
2173
2138
|
// this is public so we need to (un)translate.
|
|
2174
|
-
data = this.UntranslateData(data);
|
|
2139
|
+
data = this.model.UntranslateData(data);
|
|
2175
2140
|
|
|
2176
2141
|
// single value, easiest
|
|
2177
2142
|
if (!Array.isArray(data)) {
|
|
@@ -2481,105 +2446,12 @@ export class Grid extends GridBase {
|
|
|
2481
2446
|
|
|
2482
2447
|
// --- private methods -------------------------------------------------------
|
|
2483
2448
|
|
|
2484
|
-
/**
|
|
2485
|
-
* translation back and forth is the same operation, with a different
|
|
2486
|
-
* (inverted) map. although it still might be worth inlining depending
|
|
2487
|
-
* on cost.
|
|
2488
|
-
*
|
|
2489
|
-
* FIXME: it's about time we started using proper maps, we dropped
|
|
2490
|
-
* support for IE11 some time ago.
|
|
2491
|
-
*/
|
|
2492
|
-
private TranslateInternal(value: string, map: Record<string, string>): string {
|
|
2493
|
-
|
|
2494
|
-
const parse_result = this.parser.Parse(value);
|
|
2495
|
-
|
|
2496
|
-
if (parse_result.expression) {
|
|
2497
|
-
|
|
2498
|
-
let modified = false;
|
|
2499
|
-
this.parser.Walk(parse_result.expression, unit => {
|
|
2500
|
-
if (unit.type === 'call') {
|
|
2501
|
-
const replacement = map[unit.name.toUpperCase()];
|
|
2502
|
-
if (replacement) {
|
|
2503
|
-
modified = true;
|
|
2504
|
-
unit.name = replacement;
|
|
2505
|
-
}
|
|
2506
|
-
}
|
|
2507
|
-
return true;
|
|
2508
|
-
});
|
|
2509
|
-
|
|
2510
|
-
if (modified) {
|
|
2511
|
-
return '=' + this.parser.Render(parse_result.expression, { missing: '' });
|
|
2512
|
-
}
|
|
2513
|
-
}
|
|
2514
|
-
|
|
2515
|
-
return value;
|
|
2516
|
-
|
|
2517
|
-
}
|
|
2518
|
-
|
|
2519
2449
|
protected RenameSheetInternal(target: Sheet, name: string) {
|
|
2520
2450
|
super.RenameSheetInternal(target, name);
|
|
2521
2451
|
this.tab_bar?.Update();
|
|
2522
2452
|
|
|
2523
2453
|
}
|
|
2524
2454
|
|
|
2525
|
-
/**
|
|
2526
|
-
* translate function from common (english) -> local language. this could
|
|
2527
|
-
* be inlined (assuming it's only called in one place), but we are breaking
|
|
2528
|
-
* it out so we can develop/test/manage it.
|
|
2529
|
-
*/
|
|
2530
|
-
protected TranslateFunction(value: string): string {
|
|
2531
|
-
if (this.language_map) {
|
|
2532
|
-
return this.TranslateInternal(value, this.language_map);
|
|
2533
|
-
}
|
|
2534
|
-
return value;
|
|
2535
|
-
}
|
|
2536
|
-
|
|
2537
|
-
/**
|
|
2538
|
-
* translate from local language -> common (english).
|
|
2539
|
-
* @see TranslateFunction
|
|
2540
|
-
*/
|
|
2541
|
-
protected UntranslateFunction(value: string): string {
|
|
2542
|
-
if (this.reverse_language_map) {
|
|
2543
|
-
return this.TranslateInternal(value, this.reverse_language_map);
|
|
2544
|
-
}
|
|
2545
|
-
return value;
|
|
2546
|
-
}
|
|
2547
|
-
|
|
2548
|
-
protected UntranslateData(value: CellValue|CellValue[]|CellValue[][]): CellValue|CellValue[]|CellValue[][] {
|
|
2549
|
-
|
|
2550
|
-
if (Array.isArray(value)) {
|
|
2551
|
-
|
|
2552
|
-
// could be 1d or 2d. typescript is complaining, not sure why...
|
|
2553
|
-
|
|
2554
|
-
if (Is2DArray(value)) {
|
|
2555
|
-
return value.map(row => row.map(entry => {
|
|
2556
|
-
if (entry && typeof entry === 'string' && entry[0] === '=') {
|
|
2557
|
-
return this.UntranslateFunction(entry);
|
|
2558
|
-
}
|
|
2559
|
-
return entry;
|
|
2560
|
-
}));
|
|
2561
|
-
}
|
|
2562
|
-
else {
|
|
2563
|
-
return value.map(entry => {
|
|
2564
|
-
if (entry && typeof entry === 'string' && entry[0] === '=') {
|
|
2565
|
-
return this.UntranslateFunction(entry);
|
|
2566
|
-
}
|
|
2567
|
-
return entry;
|
|
2568
|
-
});
|
|
2569
|
-
}
|
|
2570
|
-
|
|
2571
|
-
}
|
|
2572
|
-
else if (value && typeof value === 'string' && value[0] === '=') {
|
|
2573
|
-
|
|
2574
|
-
// single value
|
|
2575
|
-
value = this.UntranslateFunction(value);
|
|
2576
|
-
|
|
2577
|
-
}
|
|
2578
|
-
|
|
2579
|
-
return value;
|
|
2580
|
-
|
|
2581
|
-
}
|
|
2582
|
-
|
|
2583
2455
|
private StyleDefaultFromTheme() {
|
|
2584
2456
|
this.model.theme_style_properties.font_face = this.theme.grid_cell?.font_face || '';
|
|
2585
2457
|
this.model.theme_style_properties.font_size =
|
|
@@ -5520,15 +5392,26 @@ export class Grid extends GridBase {
|
|
|
5520
5392
|
|
|
5521
5393
|
}
|
|
5522
5394
|
|
|
5523
|
-
|
|
5524
|
-
|
|
5395
|
+
let parse_result: ParseResult2|undefined;
|
|
5396
|
+
|
|
5397
|
+
if (expression?.type === 'complex') {
|
|
5398
|
+
parse_result = {
|
|
5525
5399
|
type: ValueType.complex,
|
|
5526
5400
|
value: {
|
|
5527
5401
|
real: expression.real,
|
|
5528
5402
|
imaginary: expression.imaginary
|
|
5529
5403
|
},
|
|
5530
|
-
}
|
|
5531
|
-
|
|
5404
|
+
};
|
|
5405
|
+
}
|
|
5406
|
+
else if (expression?.type === 'literal' && typeof expression.value === 'boolean') {
|
|
5407
|
+
parse_result = {
|
|
5408
|
+
type: ValueType.boolean,
|
|
5409
|
+
value: expression.value,
|
|
5410
|
+
};
|
|
5411
|
+
}
|
|
5412
|
+
else {
|
|
5413
|
+
parse_result = ValueParser.TryParse(value);
|
|
5414
|
+
}
|
|
5532
5415
|
|
|
5533
5416
|
if (!is_function && parse_result.type === ValueType.number) {
|
|
5534
5417
|
|
|
@@ -5593,7 +5476,7 @@ export class Grid extends GridBase {
|
|
|
5593
5476
|
key: CommandKey.SetRange,
|
|
5594
5477
|
area: array ? selection.area : target,
|
|
5595
5478
|
array,
|
|
5596
|
-
value: is_function ? this.UntranslateFunction(value || '') : parse_result.value,
|
|
5479
|
+
value: is_function ? this.model.UntranslateFunction(value || '') : parse_result.value,
|
|
5597
5480
|
});
|
|
5598
5481
|
|
|
5599
5482
|
if (exec) {
|
|
@@ -5778,7 +5661,10 @@ export class Grid extends GridBase {
|
|
|
5778
5661
|
}
|
|
5779
5662
|
}
|
|
5780
5663
|
else if (cell.ValueIsBoolean()) {
|
|
5781
|
-
|
|
5664
|
+
|
|
5665
|
+
// TRANSLATION: FIXME/CENTRALIZE
|
|
5666
|
+
return cell.value ? (this.model.language_model?.boolean_true || 'TRUE') : (this.model.language_model?.boolean_false || 'FALSE');
|
|
5667
|
+
|
|
5782
5668
|
}
|
|
5783
5669
|
else if (cell.ValueIsNumber()) { // no style: I think this is no longer possible
|
|
5784
5670
|
if (cell_value && Localization.decimal_separator === ',') {
|
|
@@ -5821,7 +5707,7 @@ export class Grid extends GridBase {
|
|
|
5821
5707
|
// this is where we _render_ translation. so names in function
|
|
5822
5708
|
// calls shoule be translated before returning.
|
|
5823
5709
|
|
|
5824
|
-
cell_value = this.TranslateFunction(cell.value);
|
|
5710
|
+
cell_value = this.model.TranslateFunction(cell.value);
|
|
5825
5711
|
|
|
5826
5712
|
}
|
|
5827
5713
|
|
|
@@ -398,6 +398,12 @@ export interface OptionalParserFlags {
|
|
|
398
398
|
*/
|
|
399
399
|
// complex_numbers: true,
|
|
400
400
|
|
|
401
|
+
/** string representing boolean true, for parsing/rendering */
|
|
402
|
+
boolean_true?: string;
|
|
403
|
+
|
|
404
|
+
/** string representing boolean false, for parsing/rendering */
|
|
405
|
+
boolean_false?: string;
|
|
406
|
+
|
|
401
407
|
}
|
|
402
408
|
|
|
403
409
|
export type ParserFlags = Partial<OptionalParserFlags> & RequiredParserFlags;
|
|
@@ -423,6 +429,10 @@ export interface RenderOptions {
|
|
|
423
429
|
convert_imaginary_number: 'i'|'j';
|
|
424
430
|
long_structured_references: boolean;
|
|
425
431
|
table_name: string;
|
|
432
|
+
|
|
433
|
+
boolean_true?: string;
|
|
434
|
+
boolean_false?: string;
|
|
435
|
+
|
|
426
436
|
}
|
|
427
437
|
|
|
428
438
|
/*
|
|
@@ -439,5 +449,7 @@ export const DefaultParserConfig: ParserFlags = {
|
|
|
439
449
|
fractions: true,
|
|
440
450
|
decimal_mark: DecimalMarkType.Period,
|
|
441
451
|
argument_separator: ArgumentSeparatorType.Comma,
|
|
452
|
+
boolean_true: 'TRUE',
|
|
453
|
+
boolean_false: 'FALSE',
|
|
442
454
|
};
|
|
443
455
|
|
|
@@ -108,8 +108,12 @@ const LC_Z = 0x7a;
|
|
|
108
108
|
const LC_I = 0x69;
|
|
109
109
|
// const LC_J = 0x6a;
|
|
110
110
|
|
|
111
|
+
// there are a couple of characters we don't want in this
|
|
112
|
+
// range; we should split into separate ranges. also we
|
|
113
|
+
// probably have characters we don't need (atm)
|
|
114
|
+
|
|
111
115
|
const ACCENTED_RANGE_START = 192;
|
|
112
|
-
const ACCENTED_RANGE_END = 312;
|
|
116
|
+
const ACCENTED_RANGE_END = 382; // bumping up for polish // 312;
|
|
113
117
|
|
|
114
118
|
/**
|
|
115
119
|
* precedence map
|
|
@@ -533,7 +537,7 @@ export class Parser {
|
|
|
533
537
|
convert_argument_separator,
|
|
534
538
|
// convert_imaginary_number,
|
|
535
539
|
long_structured_references,
|
|
536
|
-
table_name
|
|
540
|
+
table_name,
|
|
537
541
|
} = options;
|
|
538
542
|
|
|
539
543
|
// use default separator, unless we're explicitly converting.
|
|
@@ -673,6 +677,18 @@ export class Parser {
|
|
|
673
677
|
// escape any quotation marks in string
|
|
674
678
|
return '"' + unit.value.replace(/"/g, '""') + '"';
|
|
675
679
|
}
|
|
680
|
+
else if (typeof unit.value === 'boolean') {
|
|
681
|
+
|
|
682
|
+
// use render option (replacement) value; then flags value; then a default
|
|
683
|
+
|
|
684
|
+
if (unit.value) {
|
|
685
|
+
return options.boolean_true || this.flags.boolean_true || 'true' ; // default
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
return options.boolean_false || this.flags.boolean_false || 'false' ; // default
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
}
|
|
676
692
|
else if (convert_decimal && typeof unit.value === 'number') {
|
|
677
693
|
if (unit.text) {
|
|
678
694
|
// here we want to translate the literal typed-in value.
|
|
@@ -2290,6 +2306,8 @@ export class Parser {
|
|
|
2290
2306
|
|
|
2291
2307
|
}
|
|
2292
2308
|
|
|
2309
|
+
/* remove special handling
|
|
2310
|
+
|
|
2293
2311
|
// special handling
|
|
2294
2312
|
|
|
2295
2313
|
if (str.toLowerCase() === 'true') {
|
|
@@ -2309,6 +2327,8 @@ export class Parser {
|
|
|
2309
2327
|
};
|
|
2310
2328
|
}
|
|
2311
2329
|
|
|
2330
|
+
*/
|
|
2331
|
+
|
|
2312
2332
|
// function takes precendence over address? I guess so
|
|
2313
2333
|
|
|
2314
2334
|
this.ConsumeWhiteSpace();
|
|
@@ -2345,8 +2365,29 @@ export class Parser {
|
|
|
2345
2365
|
|
|
2346
2366
|
}
|
|
2347
2367
|
|
|
2368
|
+
// move true/false handling here
|
|
2369
|
+
// should we accept english even if it's not the active language? (...)
|
|
2370
|
+
|
|
2371
|
+
const lc = str.toLowerCase();
|
|
2348
2372
|
|
|
2373
|
+
if (lc === 'true' || (this.flags.boolean_true && lc === this.flags.boolean_true.toLowerCase())) {
|
|
2374
|
+
return {
|
|
2375
|
+
type: 'literal',
|
|
2376
|
+
id: this.id_counter++,
|
|
2377
|
+
value: true,
|
|
2378
|
+
position,
|
|
2379
|
+
};
|
|
2380
|
+
}
|
|
2349
2381
|
|
|
2382
|
+
if (lc === 'false' || (this.flags.boolean_false && lc === this.flags.boolean_false.toLowerCase())) {
|
|
2383
|
+
return {
|
|
2384
|
+
type: 'literal',
|
|
2385
|
+
id: this.id_counter++,
|
|
2386
|
+
value: false,
|
|
2387
|
+
position,
|
|
2388
|
+
};
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2350
2391
|
const identifier: UnitIdentifier = {
|
|
2351
2392
|
type: 'identifier',
|
|
2352
2393
|
id: this.id_counter++,
|