@rowsncolumns/fast-formula-parser 6.2.33 → 6.2.35
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/cjs/index.js +75 -5
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +75 -6
- package/dist/esm/index.js.map +1 -1
- package/index.d.ts +4 -1
- package/package.json +2 -2
package/dist/esm/index.js
CHANGED
|
@@ -3219,12 +3219,15 @@ const IndexedColors = Object.freeze([
|
|
|
3219
3219
|
|
|
3220
3220
|
const isSingleSectionElapsedTimePattern = (pattern) => !pattern.includes(";") &&
|
|
3221
3221
|
/\[(?:h+|m+|s+)\]/i.test(pattern.replace(/\[\$[^\]]+\]/g, ""));
|
|
3222
|
+
const localeForPattern = (pattern, locale) => {
|
|
3223
|
+
return locale;
|
|
3224
|
+
};
|
|
3222
3225
|
const ssfFormat = (pattern, value, locale) => {
|
|
3223
3226
|
try {
|
|
3224
3227
|
const isNegativeElapsedTime = typeof value === "number" &&
|
|
3225
3228
|
value < 0 &&
|
|
3226
3229
|
isSingleSectionElapsedTimePattern(pattern);
|
|
3227
|
-
const formatted = format(pattern, isNegativeElapsedTime ? Math.abs(value) : value, { locale });
|
|
3230
|
+
const formatted = format(pattern, isNegativeElapsedTime ? Math.abs(value) : value, { locale: localeForPattern(pattern, locale) });
|
|
3228
3231
|
return isNegativeElapsedTime ? `-${formatted}` : formatted;
|
|
3229
3232
|
}
|
|
3230
3233
|
catch (err) {
|
|
@@ -41820,7 +41823,19 @@ const allTokens = [
|
|
|
41820
41823
|
|
|
41821
41824
|
const SelectLexer = new Lexer(allTokens, { ensureOptimizations: true });
|
|
41822
41825
|
|
|
41823
|
-
|
|
41826
|
+
// Catch-all for characters no other token matches. Spelled out as a code-unit
|
|
41827
|
+
// range because Chevrotain's first-char optimisation mis-analyses `[\s\S]`
|
|
41828
|
+
// (it never matches) and refuses to optimise the complement set `[^]`.
|
|
41829
|
+
const UnknownChar = createToken({
|
|
41830
|
+
name: "UnknownChar",
|
|
41831
|
+
pattern: /[\u0000-\uFFFF]/,
|
|
41832
|
+
});
|
|
41833
|
+
|
|
41834
|
+
const tolerantTokens = [...allTokens, UnknownChar];
|
|
41835
|
+
|
|
41836
|
+
const TolerantLexer = new Lexer(tolerantTokens, { ensureOptimizations: true });
|
|
41837
|
+
|
|
41838
|
+
tolerantTokens.forEach((tokenType) => {
|
|
41824
41839
|
tokenVocabulary$1[tokenType.name] = tokenType;
|
|
41825
41840
|
});
|
|
41826
41841
|
|
|
@@ -41848,11 +41863,29 @@ function lex(inputText) {
|
|
|
41848
41863
|
/**
|
|
41849
41864
|
* Tolerant lexer that returns partial tokens even when errors occur.
|
|
41850
41865
|
* Useful for incomplete formulas (e.g., '=SUM(') without throwing.
|
|
41866
|
+
*
|
|
41867
|
+
* Every character the formula grammar has no token for (e.g. a bare `\`)
|
|
41868
|
+
* is lexed as an `UnknownChar` token instead of being dropped by Chevrotain's
|
|
41869
|
+
* error recovery, which never advances its column counter over the dropped
|
|
41870
|
+
* characters. Unknown characters stay in `tokens` as first-class tokens with
|
|
41871
|
+
* native positions and are additionally reported in `errors` (Chevrotain's
|
|
41872
|
+
* `ILexingError` shape) so callers can still detect them.
|
|
41851
41873
|
*/
|
|
41852
41874
|
function tolerantLex(inputText) {
|
|
41853
|
-
const lexingResult =
|
|
41854
|
-
|
|
41855
|
-
|
|
41875
|
+
const lexingResult = TolerantLexer.tokenize(inputText);
|
|
41876
|
+
const errors = [];
|
|
41877
|
+
for (const token of lexingResult.tokens) {
|
|
41878
|
+
if (token.tokenType === UnknownChar) {
|
|
41879
|
+
errors.push({
|
|
41880
|
+
offset: token.startOffset,
|
|
41881
|
+
line: token.startLine,
|
|
41882
|
+
column: token.startColumn,
|
|
41883
|
+
length: 1,
|
|
41884
|
+
message: `unexpected character: ->${token.image}<- at offset: ${token.startOffset}, skipped 1 characters.`,
|
|
41885
|
+
});
|
|
41886
|
+
}
|
|
41887
|
+
}
|
|
41888
|
+
return { tokens: lexingResult.tokens, groups: lexingResult.groups, errors };
|
|
41856
41889
|
}
|
|
41857
41890
|
|
|
41858
41891
|
const tokenVocabulary = tokenVocabulary$1;
|
|
@@ -45495,6 +45528,17 @@ class DepParser {
|
|
|
45495
45528
|
if (fnName === "OFFSET") {
|
|
45496
45529
|
return this.handleOffset(args);
|
|
45497
45530
|
}
|
|
45531
|
+
// ADDRESS is pure and is the idiomatic way to build INDIRECT's
|
|
45532
|
+
// target. Folding it here lets handleIndirect register the real
|
|
45533
|
+
// precedent edge (`INDIRECT(ADDRESS(1,3,1,1,"Source"))` →
|
|
45534
|
+
// Source!$C$1), so the calc engine orders the INDIRECT cell after
|
|
45535
|
+
// the chain it reads instead of evaluating it against stale values.
|
|
45536
|
+
if (fnName === "ADDRESS") {
|
|
45537
|
+
const folded = this.foldAddress(args);
|
|
45538
|
+
if (folded !== undefined) {
|
|
45539
|
+
return { value: folded };
|
|
45540
|
+
}
|
|
45541
|
+
}
|
|
45498
45542
|
// Phase 7 LAMBDA: __RNC_LAMBDA__("params", "body") is the
|
|
45499
45543
|
// preprocessor's runtime lambda constructor. The body is a string
|
|
45500
45544
|
// literal that may contain cell refs — recurse the dep parser on
|
|
@@ -45561,6 +45605,31 @@ class DepParser {
|
|
|
45561
45605
|
}
|
|
45562
45606
|
}
|
|
45563
45607
|
|
|
45608
|
+
/**
|
|
45609
|
+
* Evaluate ADDRESS(...) when every argument is a literal scalar.
|
|
45610
|
+
* Returns undefined when an argument is a reference or another
|
|
45611
|
+
* function's placeholder result (the dep parser does not evaluate
|
|
45612
|
+
* those), or when ADDRESS itself would error.
|
|
45613
|
+
*/
|
|
45614
|
+
foldAddress(args = []) {
|
|
45615
|
+
if (!args.length || args.length > 5) return undefined;
|
|
45616
|
+
const scalars = [];
|
|
45617
|
+
for (const arg of args) {
|
|
45618
|
+
if (arg == null) {
|
|
45619
|
+
scalars.push(undefined);
|
|
45620
|
+
continue;
|
|
45621
|
+
}
|
|
45622
|
+
if (typeof arg === "object") return undefined;
|
|
45623
|
+
scalars.push(arg);
|
|
45624
|
+
}
|
|
45625
|
+
try {
|
|
45626
|
+
const address = ReferenceFunctions.ADDRESS(...scalars);
|
|
45627
|
+
return typeof address === "string" ? address : undefined;
|
|
45628
|
+
} catch {
|
|
45629
|
+
return undefined;
|
|
45630
|
+
}
|
|
45631
|
+
}
|
|
45632
|
+
|
|
45564
45633
|
handleIndirect(args = []) {
|
|
45565
45634
|
const refText = this.extractScalar(args[0]);
|
|
45566
45635
|
if (typeof refText !== "string") {
|
|
@@ -45743,5 +45812,5 @@ class DepParser {
|
|
|
45743
45812
|
// Export a Set of implemented function names for O(1) lookup
|
|
45744
45813
|
const implementedFunctionNames = FormulaParser.getImplementedFunctionNames();
|
|
45745
45814
|
|
|
45746
|
-
export { Address, Criteria, DepParser, Factorials, FormulaError, FormulaHelpers, MAX_COLUMN, MAX_ROW, ReversedTypes, Types, WildCard, allTokens, FormulaParser as default, implementedFunctionNames, lex, noop, tokenVocabulary$1 as tokenVocabulary, tolerantLex };
|
|
45815
|
+
export { Address, Criteria, DepParser, Factorials, FormulaError, FormulaHelpers, MAX_COLUMN, MAX_ROW, ReversedTypes, Types, UnknownChar, WildCard, allTokens, FormulaParser as default, implementedFunctionNames, lex, noop, tokenVocabulary$1 as tokenVocabulary, tolerantLex };
|
|
45747
45816
|
//# sourceMappingURL=index.js.map
|