@trebco/treb 29.6.2 → 29.8.1

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.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- /*! API v29.6. Copyright 2018-2024 trebco, llc. All rights reserved. LGPL: https://treb.app/license */
1
+ /*! API v29.8. Copyright 2018-2024 trebco, llc. All rights reserved. LGPL: https://treb.app/license */
2
2
 
3
3
  /**
4
4
  * add our tag to the map
@@ -389,7 +389,7 @@ export declare class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
389
389
  * grid stops broadcasting events for the duration of the function call,
390
390
  * and collects them instead. After the function call we update as necessary.
391
391
  */
392
- Batch(func: () => void, paint?: boolean): Promise<void>;
392
+ Batch(func: () => void, paint?: boolean): void;
393
393
 
394
394
  /** set freeze area */
395
395
  Freeze(rows?: number, columns?: number): void;
@@ -781,7 +781,7 @@ export declare class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
781
781
  *
782
782
  * @public
783
783
  */
784
- Recalculate(): Promise<void>;
784
+ Recalculate(): void;
785
785
 
786
786
  /**
787
787
  * Save document to local storage.
@@ -963,19 +963,18 @@ export declare class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
963
963
  Select(range?: RangeReference): void;
964
964
 
965
965
  /**
966
+ * override for paste method omits the data parameter.
967
+ */
968
+ Paste(target?: RangeReference, options?: PasteOptions): void;
969
+
970
+ /**
971
+ * standard paste method accepts data argument
966
972
  *
967
- * @param target - the target to paste data into. this can be larger
968
- * than the clipboard data, in which case values will be recycled in
969
- * blocks. if the target is smaller than the source data, we will expand
970
- * it.
971
- *
972
- * @param data - clipboard data to paste.
973
- *
974
- * @param style - optional paste style. default is to paste formulas and
975
- * source formatting. paste options can be usef to paste values, values
976
- * and number formats, or retain the target formatting.
973
+ * @param target
974
+ * @param data
975
+ * @param options
977
976
  */
978
- Paste(target?: RangeReference, data?: ClipboardData | undefined, options?: PasteOptions): Promise<void>;
977
+ Paste(target?: RangeReference, data?: ClipboardData, options?: PasteOptions): void;
979
978
 
980
979
  /**
981
980
  * copy data. this method returns the copied data. it does not put it on
@@ -1034,50 +1033,6 @@ export declare class EmbeddedSpreadsheet<USER_DATA_TYPE = unknown> {
1034
1033
  Cancel(token: number): void;
1035
1034
  }
1036
1035
 
1037
- /**
1038
- * this is a structure for copy/paste data. clipboard data may include
1039
- * relative formauls and resolved styles, so it's suitable for pasting into
1040
- * other areas of the spreadsheet.
1041
- */
1042
- export interface ClipboardDataElement {
1043
-
1044
- /** calculated cell value */
1045
- calculated: CellValue;
1046
-
1047
- /** the actual cell value or formula */
1048
- value: CellValue;
1049
-
1050
- /** cell style. this may include row/column styles from the copy source */
1051
- style?: CellStyle;
1052
- }
1053
-
1054
- /** clipboard data is a 2d array */
1055
- export type ClipboardData = ClipboardDataElement[][];
1056
-
1057
- /**
1058
- * optional paste options. we can paste formulas or values, and we
1059
- * can use the source style, target style, or just use the source
1060
- * number formats.
1061
- */
1062
- export interface PasteOptions {
1063
-
1064
- /**
1065
- * when clipboard data includes formulas, optionally paste calculated
1066
- * values instead of the original formulas. defaults to false.
1067
- */
1068
- values?: boolean;
1069
-
1070
- /**
1071
- * when pasting data from the clipboard, we can copy formatting/style
1072
- * from the original data, or we can retain the target range formatting
1073
- * and just paste data. a third option allows pasting source number
1074
- * formats but dropping other style information.
1075
- *
1076
- * defaults to "source", meaning paste source styles.
1077
- */
1078
- formatting?: 'source' | 'target' | 'number-formats';
1079
- }
1080
-
1081
1036
  /**
1082
1037
  * options for saving files. we add the option for JSON formatting.
1083
1038
  */
@@ -1161,6 +1116,46 @@ export interface SheetScrollOptions {
1161
1116
  * function type used for filtering tables
1162
1117
  */
1163
1118
  export type TableFilterFunction = (value: CellValue, calculated_value: CellValue, style: CellStyle) => boolean;
1119
+ export interface FreezePane {
1120
+ rows: number;
1121
+ columns: number;
1122
+ }
1123
+
1124
+ /**
1125
+ * options for serializing data
1126
+ */
1127
+ export interface SerializeOptions {
1128
+
1129
+ /** optimize for size */
1130
+ optimize?: 'size' | 'speed';
1131
+
1132
+ /** include the rendered/calculated value in export */
1133
+ rendered_values?: boolean;
1134
+
1135
+ /** translate colors to xlsx-friendly values */
1136
+ export_colors?: boolean;
1137
+
1138
+ /** export cells that have no value, but have a border or background color */
1139
+ decorated_cells?: boolean;
1140
+
1141
+ /** prune unused rows/columns */
1142
+ shrink?: boolean;
1143
+
1144
+ /**
1145
+ * include tables. tables will be serialized in the model, so we can
1146
+ * drop them from cells. but you can leave them in if that's useful.
1147
+ */
1148
+ tables?: boolean;
1149
+
1150
+ /** share resources (images, for now) to prevent writing data URIs more than once */
1151
+ share_resources?: boolean;
1152
+
1153
+ /**
1154
+ * if a function has an export() handler, call that
1155
+ */
1156
+ export_functions?: boolean;
1157
+ }
1158
+ export type AnnotationType = 'treb-chart' | 'image' | 'textbox' | 'external';
1164
1159
 
1165
1160
  /**
1166
1161
  * Structure represents a 2d range of cells.
@@ -1302,6 +1297,10 @@ export interface Complex {
1302
1297
  real: number;
1303
1298
  imaginary: number;
1304
1299
  }
1300
+
1301
+ /**
1302
+ * dimensioned quantity: 3.2 m/s, 2kg, 5m, &c.
1303
+ */
1305
1304
  export interface DimensionedQuantity {
1306
1305
  value: number;
1307
1306
  unit: string;
@@ -1384,46 +1383,53 @@ export interface EvaluateOptions {
1384
1383
  */
1385
1384
  r1c1?: boolean;
1386
1385
  }
1387
- export interface FreezePane {
1388
- rows: number;
1389
- columns: number;
1390
- }
1386
+
1387
+ /** clipboard data is a 2d array */
1388
+ export type ClipboardData = ClipboardDataElement[][];
1391
1389
 
1392
1390
  /**
1393
- * options for serializing data
1391
+ * optional paste options. we can paste formulas or values, and we
1392
+ * can use the source style, target style, or just use the source
1393
+ * number formats.
1394
1394
  */
1395
- export interface SerializeOptions {
1396
-
1397
- /** optimize for size */
1398
- optimize?: 'size' | 'speed';
1395
+ export interface PasteOptions {
1399
1396
 
1400
- /** include the rendered/calculated value in export */
1401
- rendered_values?: boolean;
1397
+ /**
1398
+ * when clipboard data includes formulas, optionally paste calculated
1399
+ * values instead of the original formulas. defaults to false.
1400
+ */
1401
+ values?: boolean;
1402
1402
 
1403
- /** translate colors to xlsx-friendly values */
1404
- export_colors?: boolean;
1403
+ /**
1404
+ * when pasting data from the clipboard, we can copy formatting/style
1405
+ * from the original data, or we can retain the target range formatting
1406
+ * and just paste data. a third option allows pasting source number
1407
+ * formats but dropping other style information.
1408
+ *
1409
+ * defaults to "source", meaning paste source styles.
1410
+ */
1411
+ formatting?: 'source' | 'target' | 'number-formats';
1412
+ }
1405
1413
 
1406
- /** export cells that have no value, but have a border or background color */
1407
- decorated_cells?: boolean;
1414
+ /**
1415
+ * this is a structure for copy/paste data. clipboard data may include
1416
+ * relative formauls and resolved styles, so it's suitable for pasting into
1417
+ * other areas of the spreadsheet.
1418
+ */
1419
+ export interface ClipboardDataElement {
1408
1420
 
1409
- /** prune unused rows/columns */
1410
- shrink?: boolean;
1421
+ /** calculated cell value */
1422
+ calculated: CellValue;
1411
1423
 
1412
- /**
1413
- * include tables. tables will be serialized in the model, so we can
1414
- * drop them from cells. but you can leave them in if that's useful.
1415
- */
1416
- tables?: boolean;
1424
+ /** the actual cell value or formula */
1425
+ value: CellValue;
1417
1426
 
1418
- /** share resources (images, for now) to prevent writing data URIs more than once */
1419
- share_resources?: boolean;
1427
+ /** cell style. this may include row/column styles from the copy source */
1428
+ style?: CellStyle;
1420
1429
 
1421
- /**
1422
- * if a function has an export() handler, call that
1423
- */
1424
- export_functions?: boolean;
1430
+ /** area. if this cell is part of an array, this is the array range */
1431
+ area?: IArea;
1425
1432
  }
1426
- export type AnnotationType = 'treb-chart' | 'image' | 'textbox' | 'external';
1427
1433
  export declare type BorderConstants = "none" | "all" | "outside" | "top" | "bottom" | "left" | "right";
1428
1434
 
1429
1435
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trebco/treb",
3
- "version": "29.6.2",
3
+ "version": "29.8.1",
4
4
  "license": "LGPL-3.0-or-later",
5
5
  "homepage": "https://treb.app",
6
6
  "repository": {
@@ -1210,6 +1210,40 @@ export class Cells {
1210
1210
 
1211
1211
  }
1212
1212
 
1213
+ /**
1214
+ * yet another iterator, this one returns cell and address.
1215
+ * iterates all cells; does not create missing cells.
1216
+ *
1217
+ * UPDATE: adding area parameter; not shrinking it (don't call w/ infinities)
1218
+ */
1219
+ public *IterateRC(area?: IArea) {
1220
+
1221
+ if (area) {
1222
+ for (let row = area.start.row; row <= area.end.row; row++) {
1223
+ const block = this.data[row];
1224
+ if (block) {
1225
+ for (let column = area.start.column; column <= area.end.column; column++) {
1226
+ const cell = block[column];
1227
+ if (cell) {
1228
+ yield { cell, row, column };
1229
+ }
1230
+ }
1231
+ }
1232
+ }
1233
+ }
1234
+ else {
1235
+ for (const [row, r] of this.data.entries()) {
1236
+ if (r) {
1237
+ for (const [column, cell] of r.entries()) {
1238
+ if (cell) {
1239
+ yield { cell, row, column };
1240
+ }
1241
+ }
1242
+ }
1243
+ }
1244
+ }
1245
+ }
1246
+
1213
1247
  /**
1214
1248
  * replacement for old callback iterator. this is a composite
1215
1249
  * of iterating all and iterating an area. I want to remove the
@@ -1,4 +1,7 @@
1
1
 
2
+ import type { ExpressionUnit } from 'treb-parser';
3
+ import type { ICellAddress } from './area';
4
+
2
5
  /**
3
6
  * options for the evaluate function
4
7
  */
@@ -17,5 +20,23 @@ export interface EvaluateOptions {
17
20
  * so we optionally support that behind this flag.
18
21
  */
19
22
  r1c1?: boolean;
20
-
23
+
24
+ /**
25
+ * @internal
26
+ *
27
+ * @privateRemarks
28
+ * in some cases we may call this method after parsing an expression.
29
+ * we don't need the evaluate method to parse it again.
30
+ */
31
+ preparsed?: ExpressionUnit;
32
+
33
+ /**
34
+ * @internal
35
+ *
36
+ * @privateRemarks
37
+ * we also might want to pass the address of the expression, if (or as if)
38
+ * it was originally in the spreadsheet.
39
+ */
40
+ address?: ICellAddress;
41
+
21
42
  }
@@ -105,15 +105,6 @@ export type UnionValue
105
105
  | ErrorUnion
106
106
  ;
107
107
 
108
- // common types
109
-
110
- /**
111
- * this is a factory instead of a constant value to prevent any accidental pollution
112
- */
113
- // export const CreateUndefinedUnion = (): UnionValue => {
114
- // return { type: ValueType.undefined, value: undefined };
115
- //};
116
-
117
108
  /**
118
109
  * shortcut, although this is wasteful
119
110
  *
@@ -136,8 +127,6 @@ export const Box = (value: unknown, type?: ValueType): UnionValue => {
136
127
 
137
128
  };
138
129
 
139
- // export type UnionOrArray = UnionValue|UnionValue[][];
140
-
141
130
  /**
142
131
  * box a complex value in a union, potentially switching to a real if
143
132
  * there's no imaginary component.
@@ -19,9 +19,6 @@
19
19
  *
20
20
  */
21
21
 
22
- // split from cell for separate import,
23
- // @see format-index.ts
24
-
25
22
  /**
26
23
  * Complex number type
27
24
  */
@@ -67,6 +64,9 @@ export const ComplexToString = (value: Complex): string => {
67
64
  }
68
65
  };
69
66
 
67
+ /**
68
+ * dimensioned quantity: 3.2 m/s, 2kg, 5m, &c.
69
+ */
70
70
  export interface DimensionedQuantity {
71
71
  value: number;
72
72
  unit: string;
@@ -43,6 +43,7 @@ import { InformationFunctionLibrary } from './functions/information-functions';
43
43
  import { StatisticsFunctionLibrary, StatisticsFunctionAliases } from './functions/statistics-functions';
44
44
  import { ComplexFunctionLibrary } from './functions/complex-functions';
45
45
  import { MatrixFunctionLibrary } from './functions/matrix-functions';
46
+ import { RegexFunctionLibrary } from './functions/regex-functions';
46
47
 
47
48
  import { Variance } from './functions/statistics-functions';
48
49
 
@@ -222,7 +223,7 @@ export class Calculator extends Graph {
222
223
  InformationFunctionLibrary, // etc
223
224
  ComplexFunctionLibrary,
224
225
  MatrixFunctionLibrary,
225
-
226
+ RegexFunctionLibrary,
226
227
  );
227
228
 
228
229
  // aliases
@@ -1589,45 +1590,54 @@ export class Calculator extends Graph {
1589
1590
  /** moved from embedded sheet */
1590
1591
  public Evaluate(expression: string, active_sheet?: Sheet, options: EvaluateOptions = {}, raw_result = false) {
1591
1592
 
1592
- // const current = this.parser.argument_separator;
1593
- // const r1c1_state = this.parser.flags.r1c1;
1593
+ let parse_expression = options?.preparsed;
1594
+
1595
+ if (!parse_expression) {
1594
1596
 
1595
- this.parser.Save();
1597
+ this.parser.Save();
1596
1598
 
1597
- if (options.argument_separator) {
1598
- if (options.argument_separator === ',') {
1599
- this.parser.SetLocaleSettings(DecimalMarkType.Period);
1599
+ if (options.argument_separator) {
1600
+ if (options.argument_separator === ',') {
1601
+ this.parser.SetLocaleSettings(DecimalMarkType.Period);
1602
+
1603
+ // this.parser.argument_separator = ArgumentSeparatorType.Comma;
1604
+ // this.parser.decimal_mark = DecimalMarkType.Period;
1605
+ }
1606
+ else {
1607
+ this.parser.SetLocaleSettings(DecimalMarkType.Comma);
1600
1608
 
1601
- // this.parser.argument_separator = ArgumentSeparatorType.Comma;
1602
- // this.parser.decimal_mark = DecimalMarkType.Period;
1609
+ // this.parser.argument_separator = ArgumentSeparatorType.Semicolon;
1610
+ // this.parser.decimal_mark = DecimalMarkType.Comma;
1611
+ }
1603
1612
  }
1604
- else {
1605
- this.parser.SetLocaleSettings(DecimalMarkType.Comma);
1606
1613
 
1607
- // this.parser.argument_separator = ArgumentSeparatorType.Semicolon;
1608
- // this.parser.decimal_mark = DecimalMarkType.Comma;
1614
+ if (options.r1c1) {
1615
+ this.parser.flags.r1c1 = options.r1c1;
1609
1616
  }
1610
- }
1611
1617
 
1612
- if (options.r1c1) {
1613
- this.parser.flags.r1c1 = options.r1c1;
1614
- }
1618
+ const parse_result = this.parser.Parse(expression);
1619
+
1620
+ // reset
1615
1621
 
1616
- const parse_result = this.parser.Parse(expression);
1622
+ // this.parser.argument_separator = current;
1623
+ // this.parser.decimal_mark = (current === ArgumentSeparatorType.Comma) ? DecimalMarkType.Period : DecimalMarkType.Comma;
1624
+ // this.parser.flags.r1c1 = r1c1_state;
1617
1625
 
1618
- // reset
1626
+ this.parser.Restore();
1619
1627
 
1620
- // this.parser.argument_separator = current;
1621
- // this.parser.decimal_mark = (current === ArgumentSeparatorType.Comma) ? DecimalMarkType.Period : DecimalMarkType.Comma;
1622
- // this.parser.flags.r1c1 = r1c1_state;
1628
+ parse_expression = parse_result.expression;
1623
1629
 
1624
- this.parser.Restore();
1630
+ if (parse_result.error) {
1631
+ throw new Error(parse_result.error);
1632
+ }
1633
+
1634
+ }
1625
1635
 
1626
1636
  // OK
1627
1637
 
1628
- if (parse_result && parse_result.expression ){
1638
+ if (parse_expression ){
1629
1639
 
1630
- this.parser.Walk(parse_result.expression, (unit) => {
1640
+ this.parser.Walk(parse_expression, (unit) => {
1631
1641
  if (unit.type === 'address' || unit.type === 'range') {
1632
1642
 
1633
1643
  // don't allow offset references, even in R1C1
@@ -1648,7 +1658,7 @@ export class Calculator extends Graph {
1648
1658
  });
1649
1659
 
1650
1660
  // console.info({expression: parse_result.expression})
1651
- const result = this.CalculateExpression(parse_result.expression);
1661
+ const result = this.CalculateExpression(parse_expression, options.address);
1652
1662
  if (raw_result) {
1653
1663
  return result;
1654
1664
  }
@@ -1664,10 +1674,6 @@ export class Calculator extends Graph {
1664
1674
 
1665
1675
  // or? (...)
1666
1676
 
1667
- if (parse_result.error) {
1668
- throw new Error(parse_result.error);
1669
- }
1670
-
1671
1677
  throw new Error('invalid expression');
1672
1678
 
1673
1679
  }
@@ -76,6 +76,8 @@ export interface ArgumentDescriptor {
76
76
  *
77
77
  * if this flag is set in any argument descriptor in a function, we'll
78
78
  * apply arrays. that's done when the function is installed.
79
+ *
80
+ * FIXME: this should maybe be the default, and we have an !unroll flag
79
81
  */
80
82
  unroll?: boolean;
81
83