@rowsncolumns/utils 9.2.43 → 9.3.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/cjs/formula-locale/formula-locale-data.generated.d.ts +44 -0
- package/dist/cjs/formula-locale/formula-locale-data.generated.d.ts.map +1 -0
- package/dist/cjs/formula-locale/formula-locale-data.generated.js +5567 -0
- package/dist/cjs/formula-locale.d.ts +159 -0
- package/dist/cjs/formula-locale.d.ts.map +1 -0
- package/dist/cjs/formula-locale.js +804 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/selection.d.ts +3 -4
- package/dist/cjs/selection.d.ts.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/formula-locale/formula-locale-data.generated.d.ts +44 -0
- package/dist/esm/formula-locale/formula-locale-data.generated.d.ts.map +1 -0
- package/dist/esm/formula-locale/formula-locale-data.generated.js +5564 -0
- package/dist/esm/formula-locale.d.ts +159 -0
- package/dist/esm/formula-locale.d.ts.map +1 -0
- package/dist/esm/formula-locale.js +0 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/selection.d.ts +3 -4
- package/dist/esm/selection.d.ts.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,804 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var e_1, _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.localizeFunctionDescriptions = exports.localizeFunctionDescription = exports.localizeFunctionSyntax = exports.canonicalizeCellInput = exports.localizeCellInput = exports.canonicalizeFormula = exports.localizeFormula = exports.translateFormula = exports.canonicalizeErrorValue = exports.localizeErrorValue = exports.canonicalizeFunctionName = exports.localizeFunctionName = exports.getFormulaLocaleTags = exports.unregisterFormulaLocale = exports.registerFormulaLocale = exports.getFormulaLocale = exports.CANONICAL_FORMULA_LOCALE = exports.CANONICAL_ERROR_VALUES = exports.FORMULA_LOCALE_DATA_SOURCES = exports.FORMULA_LOCALE_DATA = void 0;
|
|
5
|
+
var tslib_1 = require("tslib");
|
|
6
|
+
var formula_1 = require("./formula");
|
|
7
|
+
var formula_locale_data_generated_1 = require("./formula-locale/formula-locale-data.generated");
|
|
8
|
+
var formula_locale_data_generated_2 = require("./formula-locale/formula-locale-data.generated");
|
|
9
|
+
Object.defineProperty(exports, "FORMULA_LOCALE_DATA", { enumerable: true, get: function () { return formula_locale_data_generated_2.FORMULA_LOCALE_DATA; } });
|
|
10
|
+
Object.defineProperty(exports, "FORMULA_LOCALE_DATA_SOURCES", { enumerable: true, get: function () { return formula_locale_data_generated_2.FORMULA_LOCALE_DATA_SOURCES; } });
|
|
11
|
+
var CANONICAL_TAG = "en";
|
|
12
|
+
/** Excel error values, in their canonical (English) spelling. */
|
|
13
|
+
exports.CANONICAL_ERROR_VALUES = [
|
|
14
|
+
"#NULL!",
|
|
15
|
+
"#DIV/0!",
|
|
16
|
+
"#VALUE!",
|
|
17
|
+
"#REF!",
|
|
18
|
+
"#NAME?",
|
|
19
|
+
"#NUM!",
|
|
20
|
+
"#N/A",
|
|
21
|
+
"#GETTING_DATA",
|
|
22
|
+
"#SPILL!",
|
|
23
|
+
"#CALC!",
|
|
24
|
+
"#FIELD!",
|
|
25
|
+
"#CONNECT!",
|
|
26
|
+
"#BLOCKED!",
|
|
27
|
+
"#UNKNOWN!",
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* Case fold for dictionary keys. `toUpperCase` alone leaves Turkish `İ` (dotted capital I) distinct
|
|
31
|
+
* from the `I` a lowercase `i` uppercases to, so `filtre(` would never find `FİLTRE`; folding both to
|
|
32
|
+
* `I` makes typed lowercase names resolve in every locale.
|
|
33
|
+
*/
|
|
34
|
+
var fold = function (text) { return text.toUpperCase().replace(/İ/g, "I"); };
|
|
35
|
+
var normalizeTag = function (tag) { return tag.trim().replace(/_/g, "-").toLowerCase(); };
|
|
36
|
+
/** Built-in table keyed by normalized tag. */
|
|
37
|
+
var builtIn = new Map();
|
|
38
|
+
try {
|
|
39
|
+
for (var _b = tslib_1.__values(Object.entries(formula_locale_data_generated_1.FORMULA_LOCALE_DATA)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
40
|
+
var _d = tslib_1.__read(_c.value, 2), tag = _d[0], entry = _d[1];
|
|
41
|
+
builtIn.set(normalizeTag(tag), entry);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
45
|
+
finally {
|
|
46
|
+
try {
|
|
47
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
48
|
+
}
|
|
49
|
+
finally { if (e_1) throw e_1.error; }
|
|
50
|
+
}
|
|
51
|
+
var registered = new Map();
|
|
52
|
+
var resolvedByTag = new Map();
|
|
53
|
+
var resolvedByDefinition = new WeakMap();
|
|
54
|
+
var isFormulaLocale = function (value) {
|
|
55
|
+
return typeof value === "object" &&
|
|
56
|
+
value !== null &&
|
|
57
|
+
value.functions instanceof Map &&
|
|
58
|
+
value.canonicalFunctions instanceof Map;
|
|
59
|
+
};
|
|
60
|
+
var buildLocale = function (id, name, syntax, dictionaries) {
|
|
61
|
+
var e_2, _a, e_3, _b;
|
|
62
|
+
var functions = new Map();
|
|
63
|
+
var canonicalFunctions = new Map();
|
|
64
|
+
try {
|
|
65
|
+
for (var _c = tslib_1.__values(dictionaries.functions), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
66
|
+
var _e = tslib_1.__read(_d.value, 2), canonical = _e[0], localized = _e[1];
|
|
67
|
+
var key = fold(canonical);
|
|
68
|
+
// An identity entry records "English name in this language" and needs no map entry. A name that
|
|
69
|
+
// differs only in its dotted İ (tr `ASİN`) IS kept as the display form; its reverse entry is a
|
|
70
|
+
// harmless self-map.
|
|
71
|
+
if (localized === canonical)
|
|
72
|
+
continue;
|
|
73
|
+
functions.set(key, localized);
|
|
74
|
+
canonicalFunctions.set(fold(localized), key);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
78
|
+
finally {
|
|
79
|
+
try {
|
|
80
|
+
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
81
|
+
}
|
|
82
|
+
finally { if (e_2) throw e_2.error; }
|
|
83
|
+
}
|
|
84
|
+
var errors = new Map();
|
|
85
|
+
var canonicalErrors = new Map();
|
|
86
|
+
try {
|
|
87
|
+
for (var _f = tslib_1.__values(dictionaries.errors), _g = _f.next(); !_g.done; _g = _f.next()) {
|
|
88
|
+
var _h = tslib_1.__read(_g.value, 2), canonical = _h[0], localized = _h[1];
|
|
89
|
+
var key = fold(canonical);
|
|
90
|
+
if (fold(localized) === key)
|
|
91
|
+
continue;
|
|
92
|
+
errors.set(key, localized);
|
|
93
|
+
canonicalErrors.set(fold(localized), key);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
97
|
+
finally {
|
|
98
|
+
try {
|
|
99
|
+
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
|
|
100
|
+
}
|
|
101
|
+
finally { if (e_3) throw e_3.error; }
|
|
102
|
+
}
|
|
103
|
+
var isCanonical = syntax.decimalSeparator === "." &&
|
|
104
|
+
syntax.argumentSeparator === "," &&
|
|
105
|
+
syntax.arrayColumnSeparator === "," &&
|
|
106
|
+
syntax.arrayRowSeparator === ";" &&
|
|
107
|
+
functions.size === 0 &&
|
|
108
|
+
errors.size === 0;
|
|
109
|
+
return Object.freeze({
|
|
110
|
+
id: id,
|
|
111
|
+
name: name,
|
|
112
|
+
decimalSeparator: syntax.decimalSeparator,
|
|
113
|
+
argumentSeparator: syntax.argumentSeparator,
|
|
114
|
+
arrayColumnSeparator: syntax.arrayColumnSeparator,
|
|
115
|
+
arrayRowSeparator: syntax.arrayRowSeparator,
|
|
116
|
+
unionOperator: syntax.argumentSeparator,
|
|
117
|
+
functions: functions,
|
|
118
|
+
canonicalFunctions: canonicalFunctions,
|
|
119
|
+
errors: errors,
|
|
120
|
+
canonicalErrors: canonicalErrors,
|
|
121
|
+
isCanonical: isCanonical,
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
/** The canonical dialect every formula is stored and evaluated in. */
|
|
125
|
+
exports.CANONICAL_FORMULA_LOCALE = buildLocale(CANONICAL_TAG, builtIn.get(CANONICAL_TAG).name, tslib_1.__assign({}, builtIn.get(CANONICAL_TAG).syntax), { functions: new Map(), errors: new Map() });
|
|
126
|
+
var applyDictionaryPatch = function (target, patch) {
|
|
127
|
+
var e_4, _a;
|
|
128
|
+
if (!patch)
|
|
129
|
+
return;
|
|
130
|
+
try {
|
|
131
|
+
for (var _b = tslib_1.__values(Object.entries(patch)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
132
|
+
var _d = tslib_1.__read(_c.value, 2), canonical = _d[0], localized = _d[1];
|
|
133
|
+
if (localized === null || localized === undefined) {
|
|
134
|
+
target.delete(canonical);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
target.set(canonical, localized);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
142
|
+
finally {
|
|
143
|
+
try {
|
|
144
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
145
|
+
}
|
|
146
|
+
finally { if (e_4) throw e_4.error; }
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
/** Resolve a normalized tag to its syntax + dictionaries, following `extends` chains. `depth` guards
|
|
150
|
+
* against a registration cycle (`a` extends `b` extends `a`). */
|
|
151
|
+
var resolveTag = function (tag, depth) {
|
|
152
|
+
var e_5, _a, e_6, _b;
|
|
153
|
+
var _c, _d, _e, _f, _g, _h, _j;
|
|
154
|
+
if (depth === void 0) { depth = 0; }
|
|
155
|
+
if (depth > 8) {
|
|
156
|
+
throw new Error("Formula locale \"".concat(tag, "\" has a circular \"extends\" chain"));
|
|
157
|
+
}
|
|
158
|
+
var definition = registered.get(tag);
|
|
159
|
+
if (definition) {
|
|
160
|
+
var base_1 = resolveTag(definition.extends ? normalizeTag(definition.extends) : builtIn.has(tag) ? "".concat(tag, "\0builtin") : CANONICAL_TAG, depth + 1);
|
|
161
|
+
applyDictionaryPatch(base_1.dictionaries.functions, definition.functions);
|
|
162
|
+
applyDictionaryPatch(base_1.dictionaries.errors, definition.errors);
|
|
163
|
+
return {
|
|
164
|
+
name: (_c = definition.name) !== null && _c !== void 0 ? _c : base_1.name,
|
|
165
|
+
syntax: {
|
|
166
|
+
decimalSeparator: (_d = definition.decimalSeparator) !== null && _d !== void 0 ? _d : base_1.syntax.decimalSeparator,
|
|
167
|
+
argumentSeparator: (_e = definition.argumentSeparator) !== null && _e !== void 0 ? _e : base_1.syntax.argumentSeparator,
|
|
168
|
+
arrayColumnSeparator: (_f = definition.arrayColumnSeparator) !== null && _f !== void 0 ? _f : base_1.syntax.arrayColumnSeparator,
|
|
169
|
+
arrayRowSeparator: (_g = definition.arrayRowSeparator) !== null && _g !== void 0 ? _g : base_1.syntax.arrayRowSeparator,
|
|
170
|
+
},
|
|
171
|
+
dictionaries: base_1.dictionaries,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
// A registration that overrides a built-in tag layers on that built-in's own data.
|
|
175
|
+
var builtInTag = tag.endsWith("builtin") ? tag.slice(0, -"builtin".length) : tag;
|
|
176
|
+
var entry = builtIn.get(builtInTag);
|
|
177
|
+
if (!entry) {
|
|
178
|
+
// Unknown tag: canonical syntax, no translations (callers resolve language fallbacks before this).
|
|
179
|
+
var en = builtIn.get(CANONICAL_TAG);
|
|
180
|
+
return {
|
|
181
|
+
name: en.name,
|
|
182
|
+
syntax: tslib_1.__assign({}, en.syntax),
|
|
183
|
+
dictionaries: { functions: new Map(), errors: new Map() },
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
var base = entry.extends
|
|
187
|
+
? resolveTag(normalizeTag(entry.extends), depth + 1)
|
|
188
|
+
: { dictionaries: { functions: new Map(), errors: new Map() } };
|
|
189
|
+
var dictionaries = base.dictionaries;
|
|
190
|
+
try {
|
|
191
|
+
for (var _k = tslib_1.__values(Object.entries((_h = entry.functions) !== null && _h !== void 0 ? _h : {})), _l = _k.next(); !_l.done; _l = _k.next()) {
|
|
192
|
+
var _m = tslib_1.__read(_l.value, 2), canonical = _m[0], localized = _m[1];
|
|
193
|
+
dictionaries.functions.set(canonical, localized);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
197
|
+
finally {
|
|
198
|
+
try {
|
|
199
|
+
if (_l && !_l.done && (_a = _k.return)) _a.call(_k);
|
|
200
|
+
}
|
|
201
|
+
finally { if (e_5) throw e_5.error; }
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
for (var _o = tslib_1.__values(Object.entries((_j = entry.errors) !== null && _j !== void 0 ? _j : {})), _p = _o.next(); !_p.done; _p = _o.next()) {
|
|
205
|
+
var _q = tslib_1.__read(_p.value, 2), canonical = _q[0], localized = _q[1];
|
|
206
|
+
dictionaries.errors.set(canonical, localized);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
210
|
+
finally {
|
|
211
|
+
try {
|
|
212
|
+
if (_p && !_p.done && (_b = _o.return)) _b.call(_o);
|
|
213
|
+
}
|
|
214
|
+
finally { if (e_6) throw e_6.error; }
|
|
215
|
+
}
|
|
216
|
+
return { name: entry.name, syntax: tslib_1.__assign({}, entry.syntax), dictionaries: dictionaries };
|
|
217
|
+
};
|
|
218
|
+
/** The tag (registered or built-in) that serves `tag`: exact match, then its language, then `en`. */
|
|
219
|
+
var findServingTag = function (tag) {
|
|
220
|
+
var normalized = normalizeTag(tag);
|
|
221
|
+
if (!normalized)
|
|
222
|
+
return CANONICAL_TAG;
|
|
223
|
+
if (registered.has(normalized) || builtIn.has(normalized))
|
|
224
|
+
return normalized;
|
|
225
|
+
var language = normalized.split("-")[0];
|
|
226
|
+
if (registered.has(language) || builtIn.has(language))
|
|
227
|
+
return language;
|
|
228
|
+
return CANONICAL_TAG;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Resolve a locale for formula syntax. Accepts a BCP-47 tag (`"ru-RU"` → the `ru` table, `"de-AT"` →
|
|
232
|
+
* `de`, `"de-CH"` → the Swiss row; unknown languages → canonical English), an already-resolved
|
|
233
|
+
* {@link FormulaLocale} (returned as-is), or an inline {@link FormulaLocaleDefinition} (resolved once
|
|
234
|
+
* per object). Resolution is memoized.
|
|
235
|
+
*/
|
|
236
|
+
var getFormulaLocale = function (locale) {
|
|
237
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
238
|
+
if (locale === undefined || locale === null) {
|
|
239
|
+
return (0, exports.getFormulaLocale)(CANONICAL_TAG);
|
|
240
|
+
}
|
|
241
|
+
if (isFormulaLocale(locale)) {
|
|
242
|
+
return locale;
|
|
243
|
+
}
|
|
244
|
+
if (typeof locale === "object") {
|
|
245
|
+
var cached_1 = resolvedByDefinition.get(locale);
|
|
246
|
+
if (cached_1)
|
|
247
|
+
return cached_1;
|
|
248
|
+
var baseTag = locale.extends ? findServingTag(locale.extends) : CANONICAL_TAG;
|
|
249
|
+
var base = resolveTag(baseTag);
|
|
250
|
+
applyDictionaryPatch(base.dictionaries.functions, locale.functions);
|
|
251
|
+
applyDictionaryPatch(base.dictionaries.errors, locale.errors);
|
|
252
|
+
var built_1 = buildLocale((_a = locale.id) !== null && _a !== void 0 ? _a : baseTag, (_b = locale.name) !== null && _b !== void 0 ? _b : base.name, {
|
|
253
|
+
decimalSeparator: (_c = locale.decimalSeparator) !== null && _c !== void 0 ? _c : base.syntax.decimalSeparator,
|
|
254
|
+
argumentSeparator: (_d = locale.argumentSeparator) !== null && _d !== void 0 ? _d : base.syntax.argumentSeparator,
|
|
255
|
+
arrayColumnSeparator: (_e = locale.arrayColumnSeparator) !== null && _e !== void 0 ? _e : base.syntax.arrayColumnSeparator,
|
|
256
|
+
arrayRowSeparator: (_f = locale.arrayRowSeparator) !== null && _f !== void 0 ? _f : base.syntax.arrayRowSeparator,
|
|
257
|
+
}, base.dictionaries);
|
|
258
|
+
resolvedByDefinition.set(locale, built_1);
|
|
259
|
+
return built_1;
|
|
260
|
+
}
|
|
261
|
+
var servingTag = findServingTag(locale);
|
|
262
|
+
if (servingTag === CANONICAL_TAG && !registered.has(CANONICAL_TAG)) {
|
|
263
|
+
return exports.CANONICAL_FORMULA_LOCALE;
|
|
264
|
+
}
|
|
265
|
+
var cached = resolvedByTag.get(servingTag);
|
|
266
|
+
if (cached)
|
|
267
|
+
return cached;
|
|
268
|
+
var resolved = resolveTag(servingTag);
|
|
269
|
+
var built = buildLocale((_h = (_g = registered.get(servingTag)) === null || _g === void 0 ? void 0 : _g.id) !== null && _h !== void 0 ? _h : servingTag, resolved.name, resolved.syntax, resolved.dictionaries);
|
|
270
|
+
resolvedByTag.set(servingTag, built);
|
|
271
|
+
return built;
|
|
272
|
+
};
|
|
273
|
+
exports.getFormulaLocale = getFormulaLocale;
|
|
274
|
+
/**
|
|
275
|
+
* Add a formula locale or override a built-in one for the whole application: `registerFormulaLocale
|
|
276
|
+
* ("de", { functions: { SUM: "SUMMEX" } })` layers onto the German table, `registerFormulaLocale("xx",
|
|
277
|
+
* { extends: "fr", argumentSeparator: "," })` derives a new language. Later registrations for the
|
|
278
|
+
* same tag replace earlier ones. Resolved locales are re-derived lazily.
|
|
279
|
+
*/
|
|
280
|
+
var registerFormulaLocale = function (tag, definition) {
|
|
281
|
+
var normalized = normalizeTag(tag);
|
|
282
|
+
if (!normalized) {
|
|
283
|
+
throw new Error("registerFormulaLocale: a non-empty tag is required");
|
|
284
|
+
}
|
|
285
|
+
registered.set(normalized, definition);
|
|
286
|
+
resolvedByTag.clear();
|
|
287
|
+
};
|
|
288
|
+
exports.registerFormulaLocale = registerFormulaLocale;
|
|
289
|
+
/** Remove an application registration (built-in tables are never removed). */
|
|
290
|
+
var unregisterFormulaLocale = function (tag) {
|
|
291
|
+
registered.delete(normalizeTag(tag));
|
|
292
|
+
resolvedByTag.clear();
|
|
293
|
+
};
|
|
294
|
+
exports.unregisterFormulaLocale = unregisterFormulaLocale;
|
|
295
|
+
/** Every tag with a formula-syntax table: the built-in languages plus application registrations. */
|
|
296
|
+
var getFormulaLocaleTags = function () {
|
|
297
|
+
return tslib_1.__spreadArray([], tslib_1.__read(new Set(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(Object.keys(formula_locale_data_generated_1.FORMULA_LOCALE_DATA)), false), tslib_1.__read(registered.keys()), false))), false).sort();
|
|
298
|
+
};
|
|
299
|
+
exports.getFormulaLocaleTags = getFormulaLocaleTags;
|
|
300
|
+
// ── Names and error values ───────────────────────────────────────────────────────────────────────
|
|
301
|
+
/** Localized spelling of a canonical function name (`SUM` → `СУММ`); names without a translation
|
|
302
|
+
* are returned unchanged. */
|
|
303
|
+
var localizeFunctionName = function (name, locale) {
|
|
304
|
+
var _a;
|
|
305
|
+
var l = (0, exports.getFormulaLocale)(locale);
|
|
306
|
+
if (l.isCanonical)
|
|
307
|
+
return name;
|
|
308
|
+
return (_a = l.functions.get(fold(name))) !== null && _a !== void 0 ? _a : name;
|
|
309
|
+
};
|
|
310
|
+
exports.localizeFunctionName = localizeFunctionName;
|
|
311
|
+
/** Canonical (English, uppercase) spelling of a localized function name (`СУММ` → `SUM`); names
|
|
312
|
+
* without a translation are returned unchanged, so English names are accepted in every locale. */
|
|
313
|
+
var canonicalizeFunctionName = function (name, locale) {
|
|
314
|
+
var _a;
|
|
315
|
+
var l = (0, exports.getFormulaLocale)(locale);
|
|
316
|
+
if (l.isCanonical)
|
|
317
|
+
return name;
|
|
318
|
+
return (_a = l.canonicalFunctions.get(fold(name))) !== null && _a !== void 0 ? _a : name;
|
|
319
|
+
};
|
|
320
|
+
exports.canonicalizeFunctionName = canonicalizeFunctionName;
|
|
321
|
+
/** Localized spelling of a canonical error value (`#VALUE!` → `#ЗНАЧ!`); other text passes through. */
|
|
322
|
+
var localizeErrorValue = function (value, locale) {
|
|
323
|
+
var _a;
|
|
324
|
+
if (typeof value !== "string" || value.charCodeAt(0) !== 35 /* # */)
|
|
325
|
+
return value;
|
|
326
|
+
var l = (0, exports.getFormulaLocale)(locale);
|
|
327
|
+
if (l.isCanonical)
|
|
328
|
+
return value;
|
|
329
|
+
return (_a = l.errors.get(fold(value))) !== null && _a !== void 0 ? _a : value;
|
|
330
|
+
};
|
|
331
|
+
exports.localizeErrorValue = localizeErrorValue;
|
|
332
|
+
/** Canonical spelling of a localized error value (`#ЗНАЧ!` → `#VALUE!`); other text passes through. */
|
|
333
|
+
var canonicalizeErrorValue = function (value, locale) {
|
|
334
|
+
var _a;
|
|
335
|
+
if (typeof value !== "string" || value.charCodeAt(0) !== 35 /* # */)
|
|
336
|
+
return value;
|
|
337
|
+
var l = (0, exports.getFormulaLocale)(locale);
|
|
338
|
+
if (l.isCanonical)
|
|
339
|
+
return value;
|
|
340
|
+
return (_a = l.canonicalErrors.get(fold(value))) !== null && _a !== void 0 ? _a : value;
|
|
341
|
+
};
|
|
342
|
+
exports.canonicalizeErrorValue = canonicalizeErrorValue;
|
|
343
|
+
var CH_QUOTE = 34; // "
|
|
344
|
+
var CH_HASH = 35; // #
|
|
345
|
+
var CH_APOSTROPHE = 39; // '
|
|
346
|
+
var CH_OPEN_PAREN = 40; // (
|
|
347
|
+
var CH_PLUS = 43; // +
|
|
348
|
+
var CH_MINUS = 45; // -
|
|
349
|
+
var CH_DOT = 46; // .
|
|
350
|
+
var CH_0 = 48;
|
|
351
|
+
var CH_9 = 57;
|
|
352
|
+
var CH_UPPER_E = 69;
|
|
353
|
+
var CH_OPEN_BRACKET = 91; // [
|
|
354
|
+
var CH_CLOSE_BRACKET = 93; // ]
|
|
355
|
+
var CH_UNDERSCORE = 95; // _
|
|
356
|
+
var CH_LOWER_E = 101;
|
|
357
|
+
var CH_OPEN_BRACE = 123; // {
|
|
358
|
+
var CH_CLOSE_BRACE = 125; // }
|
|
359
|
+
var isDigit = function (code) { return code >= CH_0 && code <= CH_9; };
|
|
360
|
+
var isAsciiLetter = function (code) {
|
|
361
|
+
return (code >= 65 && code <= 90) || (code >= 97 && code <= 122);
|
|
362
|
+
};
|
|
363
|
+
/** Identifier start: ASCII letter, `_`, or any non-ASCII letter (Cyrillic/accented names, sheet names). */
|
|
364
|
+
var isIdentifierStart = function (code) {
|
|
365
|
+
return isAsciiLetter(code) || code === CH_UNDERSCORE || code >= 0xc0;
|
|
366
|
+
};
|
|
367
|
+
/** Identifier continuation additionally admits digits and `.` (`T.TEST`, `A1.prop`, `Sheet1`). */
|
|
368
|
+
var isIdentifierPart = function (code) {
|
|
369
|
+
return isIdentifierStart(code) || isDigit(code) || code === CH_DOT;
|
|
370
|
+
};
|
|
371
|
+
var TRUE_KEY = "TRUE";
|
|
372
|
+
var FALSE_KEY = "FALSE";
|
|
373
|
+
/** Error literals a locale may spell: the canonical set plus its own localized spellings, longest
|
|
374
|
+
* first so `#N/A` never wins over `#NAME?`-style prefixes of another spelling. */
|
|
375
|
+
var errorLiteralsCache = new WeakMap();
|
|
376
|
+
var errorLiteralsOf = function (locale) {
|
|
377
|
+
var literals = errorLiteralsCache.get(locale);
|
|
378
|
+
if (!literals) {
|
|
379
|
+
literals = tslib_1.__spreadArray([], tslib_1.__read(new Set(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(exports.CANONICAL_ERROR_VALUES), false), tslib_1.__read(locale.errors.values()), false))), false).sort(function (a, b) { return b.length - a.length; });
|
|
380
|
+
errorLiteralsCache.set(locale, literals);
|
|
381
|
+
}
|
|
382
|
+
return literals;
|
|
383
|
+
};
|
|
384
|
+
var startsWithFolded = function (text, index, literal) {
|
|
385
|
+
return text.length - index >= literal.length &&
|
|
386
|
+
fold(text.slice(index, index + literal.length)) === fold(literal);
|
|
387
|
+
};
|
|
388
|
+
var translateName = function (name, from, to, functionNameCase) {
|
|
389
|
+
var _a;
|
|
390
|
+
var key = fold(name);
|
|
391
|
+
// Localized (from) spelling → canonical key; a name the source locale doesn't translate is taken
|
|
392
|
+
// as its own canonical spelling (so English names are accepted in every locale).
|
|
393
|
+
var canonical = from.isCanonical ? key : (_a = from.canonicalFunctions.get(key)) !== null && _a !== void 0 ? _a : key;
|
|
394
|
+
var localized = to.isCanonical ? undefined : to.functions.get(canonical);
|
|
395
|
+
if (localized !== undefined)
|
|
396
|
+
return localized;
|
|
397
|
+
// Translated to English, or spelled with characters that only fold to the canonical name (tr
|
|
398
|
+
// `ASİN` → `ASIN`): emit the canonical spelling. Otherwise keep the typed case unless asked not to.
|
|
399
|
+
if (canonical !== key || name.toUpperCase() !== key)
|
|
400
|
+
return canonical;
|
|
401
|
+
return functionNameCase === "upper" ? canonical : name;
|
|
402
|
+
};
|
|
403
|
+
/**
|
|
404
|
+
* Rewrite formula text from one locale's syntax to another's. This is the single scanner behind
|
|
405
|
+
* {@link localizeFormula} (canonical → locale) and {@link canonicalizeFormula} (locale → canonical);
|
|
406
|
+
* see the module comment for what is and is not rewritten.
|
|
407
|
+
*/
|
|
408
|
+
var translateFormula = function (text, from, to, options) {
|
|
409
|
+
var e_7, _a;
|
|
410
|
+
var _b, _c;
|
|
411
|
+
if (options === void 0) { options = {}; }
|
|
412
|
+
var source = (0, exports.getFormulaLocale)(from);
|
|
413
|
+
var target = (0, exports.getFormulaLocale)(to);
|
|
414
|
+
var _d = options.functionNameCase, functionNameCase = _d === void 0 ? "preserve" : _d, _e = options.trackOffsets, trackOffsets = _e === void 0 ? false : _e;
|
|
415
|
+
var length = text.length;
|
|
416
|
+
// Segments: [sourceFrom, sourceTo, outputFrom, outputTo] flattened. Only recorded when offsets
|
|
417
|
+
// are wanted; verbatim runs are coalesced.
|
|
418
|
+
var segments = [];
|
|
419
|
+
var out = "";
|
|
420
|
+
var verbatimStart = -1;
|
|
421
|
+
var verbatimOut = 0;
|
|
422
|
+
var flushVerbatim = function (end) {
|
|
423
|
+
if (verbatimStart === -1)
|
|
424
|
+
return;
|
|
425
|
+
if (trackOffsets)
|
|
426
|
+
segments.push(verbatimStart, end, verbatimOut, verbatimOut + (end - verbatimStart));
|
|
427
|
+
verbatimStart = -1;
|
|
428
|
+
};
|
|
429
|
+
var copy = function (from, to) {
|
|
430
|
+
if (from >= to)
|
|
431
|
+
return;
|
|
432
|
+
if (verbatimStart === -1) {
|
|
433
|
+
verbatimStart = from;
|
|
434
|
+
verbatimOut = out.length;
|
|
435
|
+
}
|
|
436
|
+
out += text.slice(from, to);
|
|
437
|
+
};
|
|
438
|
+
var emit = function (from, to, replacement) {
|
|
439
|
+
if (replacement === text.slice(from, to)) {
|
|
440
|
+
copy(from, to);
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
flushVerbatim(from);
|
|
444
|
+
if (trackOffsets)
|
|
445
|
+
segments.push(from, to, out.length, out.length + replacement.length);
|
|
446
|
+
out += replacement;
|
|
447
|
+
};
|
|
448
|
+
var sourceDecimal = source.decimalSeparator;
|
|
449
|
+
var sourceDecimalCode = sourceDecimal.charCodeAt(0);
|
|
450
|
+
var targetDecimal = target.decimalSeparator;
|
|
451
|
+
var sourceErrorLiterals = errorLiteralsOf(source);
|
|
452
|
+
var braceDepth = 0;
|
|
453
|
+
var i = 0;
|
|
454
|
+
/** Whether the previous significant character continues an identifier/number (so a decimal mark
|
|
455
|
+
* right after it cannot start a new number literal). */
|
|
456
|
+
var previousWasWordChar = false;
|
|
457
|
+
while (i < length) {
|
|
458
|
+
var code = text.charCodeAt(i);
|
|
459
|
+
// "…" string literal (with "" escapes): verbatim.
|
|
460
|
+
if (code === CH_QUOTE) {
|
|
461
|
+
var j = i + 1;
|
|
462
|
+
while (j < length) {
|
|
463
|
+
if (text.charCodeAt(j) === CH_QUOTE) {
|
|
464
|
+
if (text.charCodeAt(j + 1) === CH_QUOTE) {
|
|
465
|
+
j += 2;
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
j++;
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
j++;
|
|
472
|
+
}
|
|
473
|
+
copy(i, j);
|
|
474
|
+
i = j;
|
|
475
|
+
previousWasWordChar = false;
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
// '…' quoted sheet / workbook name (with '' escapes): verbatim.
|
|
479
|
+
if (code === CH_APOSTROPHE) {
|
|
480
|
+
var j = i + 1;
|
|
481
|
+
while (j < length) {
|
|
482
|
+
if (text.charCodeAt(j) === CH_APOSTROPHE) {
|
|
483
|
+
if (text.charCodeAt(j + 1) === CH_APOSTROPHE) {
|
|
484
|
+
j += 2;
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
j++;
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
j++;
|
|
491
|
+
}
|
|
492
|
+
copy(i, j);
|
|
493
|
+
i = j;
|
|
494
|
+
previousWasWordChar = true; // 'Sheet 1'!A1 — the `!` and reference follow as one word
|
|
495
|
+
continue;
|
|
496
|
+
}
|
|
497
|
+
// [ … ] structured-reference item / R1C1 offset. Column names, special items (`#Headers`) and
|
|
498
|
+
// `'X` escapes are kept as typed; the ONE thing Excel localizes here is the list separator
|
|
499
|
+
// between items directly inside the outer bracket (`Table1[[#Headers],[Qty]]` → `;` locales),
|
|
500
|
+
// which is unambiguous because a column name containing a separator must sit in its own inner
|
|
501
|
+
// brackets.
|
|
502
|
+
if (code === CH_OPEN_BRACKET) {
|
|
503
|
+
var depth = 0;
|
|
504
|
+
var j = i;
|
|
505
|
+
while (j < length) {
|
|
506
|
+
var c = text.charCodeAt(j);
|
|
507
|
+
if (c === CH_APOSTROPHE && j + 1 < length) {
|
|
508
|
+
j += 2; // escaped character inside a column specifier
|
|
509
|
+
continue;
|
|
510
|
+
}
|
|
511
|
+
if (c === CH_OPEN_BRACKET)
|
|
512
|
+
depth++;
|
|
513
|
+
else if (c === CH_CLOSE_BRACKET) {
|
|
514
|
+
depth--;
|
|
515
|
+
if (depth === 0) {
|
|
516
|
+
j++;
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
else if (depth === 1 && text[j] === source.argumentSeparator) {
|
|
521
|
+
copy(i, j);
|
|
522
|
+
emit(j, j + 1, target.argumentSeparator);
|
|
523
|
+
i = j + 1;
|
|
524
|
+
}
|
|
525
|
+
j++;
|
|
526
|
+
}
|
|
527
|
+
copy(i, j);
|
|
528
|
+
i = j;
|
|
529
|
+
previousWasWordChar = true;
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
if (code === CH_OPEN_BRACE) {
|
|
533
|
+
braceDepth++;
|
|
534
|
+
copy(i, i + 1);
|
|
535
|
+
i++;
|
|
536
|
+
previousWasWordChar = false;
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
if (code === CH_CLOSE_BRACE) {
|
|
540
|
+
if (braceDepth > 0)
|
|
541
|
+
braceDepth--;
|
|
542
|
+
copy(i, i + 1);
|
|
543
|
+
i++;
|
|
544
|
+
previousWasWordChar = true;
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
// #VALUE! / #ЗНАЧ! … error values.
|
|
548
|
+
if (code === CH_HASH) {
|
|
549
|
+
var matched = void 0;
|
|
550
|
+
try {
|
|
551
|
+
for (var sourceErrorLiterals_1 = (e_7 = void 0, tslib_1.__values(sourceErrorLiterals)), sourceErrorLiterals_1_1 = sourceErrorLiterals_1.next(); !sourceErrorLiterals_1_1.done; sourceErrorLiterals_1_1 = sourceErrorLiterals_1.next()) {
|
|
552
|
+
var literal = sourceErrorLiterals_1_1.value;
|
|
553
|
+
if (startsWithFolded(text, i, literal)) {
|
|
554
|
+
matched = literal;
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
560
|
+
finally {
|
|
561
|
+
try {
|
|
562
|
+
if (sourceErrorLiterals_1_1 && !sourceErrorLiterals_1_1.done && (_a = sourceErrorLiterals_1.return)) _a.call(sourceErrorLiterals_1);
|
|
563
|
+
}
|
|
564
|
+
finally { if (e_7) throw e_7.error; }
|
|
565
|
+
}
|
|
566
|
+
if (matched) {
|
|
567
|
+
var canonical = (_b = source.canonicalErrors.get(fold(matched))) !== null && _b !== void 0 ? _b : fold(matched);
|
|
568
|
+
var localized = (_c = target.errors.get(canonical)) !== null && _c !== void 0 ? _c : canonical;
|
|
569
|
+
emit(i, i + matched.length, localized);
|
|
570
|
+
i += matched.length;
|
|
571
|
+
previousWasWordChar = true;
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
copy(i, i + 1);
|
|
575
|
+
i++;
|
|
576
|
+
previousWasWordChar = false;
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
// Number literal: digits [decimal digits*] [E[+-]digits], or a bare `.5` after a non-word char.
|
|
580
|
+
var startsNumber = isDigit(code) ||
|
|
581
|
+
(code === sourceDecimalCode && !previousWasWordChar && isDigit(text.charCodeAt(i + 1)));
|
|
582
|
+
if (startsNumber) {
|
|
583
|
+
var j = i;
|
|
584
|
+
var sawDecimal = false;
|
|
585
|
+
while (j < length) {
|
|
586
|
+
var c = text.charCodeAt(j);
|
|
587
|
+
if (isDigit(c)) {
|
|
588
|
+
j++;
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
if (!sawDecimal && c === sourceDecimalCode && (j > i || isDigit(text.charCodeAt(j + 1)))) {
|
|
592
|
+
// A decimal mark is part of the literal when digits precede it (`1.` is Excel's 1) or
|
|
593
|
+
// follow it (`.5`).
|
|
594
|
+
sawDecimal = true;
|
|
595
|
+
j++;
|
|
596
|
+
continue;
|
|
597
|
+
}
|
|
598
|
+
break;
|
|
599
|
+
}
|
|
600
|
+
// Exponent — only when something numeric follows the E.
|
|
601
|
+
if (j < length) {
|
|
602
|
+
var c = text.charCodeAt(j);
|
|
603
|
+
if (c === CH_UPPER_E || c === CH_LOWER_E) {
|
|
604
|
+
var k = j + 1;
|
|
605
|
+
var sign = text.charCodeAt(k);
|
|
606
|
+
if (sign === CH_PLUS || sign === CH_MINUS)
|
|
607
|
+
k++;
|
|
608
|
+
if (isDigit(text.charCodeAt(k))) {
|
|
609
|
+
while (k < length && isDigit(text.charCodeAt(k)))
|
|
610
|
+
k++;
|
|
611
|
+
j = k;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
var literal = text.slice(i, j);
|
|
616
|
+
emit(i, j, sawDecimal && sourceDecimal !== targetDecimal ? literal.split(sourceDecimal).join(targetDecimal) : literal);
|
|
617
|
+
i = j;
|
|
618
|
+
previousWasWordChar = true;
|
|
619
|
+
continue;
|
|
620
|
+
}
|
|
621
|
+
// Identifier: function name (when followed by `(`), TRUE/FALSE, or a reference/name (verbatim).
|
|
622
|
+
if (isIdentifierStart(code)) {
|
|
623
|
+
var j = i + 1;
|
|
624
|
+
// `.` is an identifier character (`T.TEST`, `A1.prop`) — except inside an array constant of a
|
|
625
|
+
// locale whose column separator IS `.` (`{1.FALSCH.2}` in de), where it separates items.
|
|
626
|
+
while (j < length && isIdentifierPart(text.charCodeAt(j))) {
|
|
627
|
+
if (braceDepth > 0 &&
|
|
628
|
+
(text[j] === source.arrayColumnSeparator || text[j] === source.arrayRowSeparator)) {
|
|
629
|
+
break;
|
|
630
|
+
}
|
|
631
|
+
j++;
|
|
632
|
+
}
|
|
633
|
+
var word = text.slice(i, j);
|
|
634
|
+
if (text.charCodeAt(j) === CH_OPEN_PAREN) {
|
|
635
|
+
emit(i, j, translateName(word, source, target, functionNameCase));
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
var key = fold(word);
|
|
639
|
+
var canonicalBoolean = key === TRUE_KEY || key === FALSE_KEY
|
|
640
|
+
? key
|
|
641
|
+
: source.canonicalFunctions.get(key);
|
|
642
|
+
if (canonicalBoolean === TRUE_KEY || canonicalBoolean === FALSE_KEY) {
|
|
643
|
+
var localized = target.functions.get(canonicalBoolean);
|
|
644
|
+
emit(i, j, localized !== null && localized !== void 0 ? localized : (canonicalBoolean === key && functionNameCase !== "upper" ? word : canonicalBoolean));
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
copy(i, j);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
i = j;
|
|
651
|
+
previousWasWordChar = true;
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
654
|
+
// Separators.
|
|
655
|
+
var ch = text[i];
|
|
656
|
+
if (braceDepth > 0) {
|
|
657
|
+
if (ch === source.arrayColumnSeparator) {
|
|
658
|
+
emit(i, i + 1, target.arrayColumnSeparator);
|
|
659
|
+
i++;
|
|
660
|
+
previousWasWordChar = false;
|
|
661
|
+
continue;
|
|
662
|
+
}
|
|
663
|
+
if (ch === source.arrayRowSeparator) {
|
|
664
|
+
emit(i, i + 1, target.arrayRowSeparator);
|
|
665
|
+
i++;
|
|
666
|
+
previousWasWordChar = false;
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
else if (ch === source.argumentSeparator) {
|
|
671
|
+
emit(i, i + 1, target.argumentSeparator);
|
|
672
|
+
i++;
|
|
673
|
+
previousWasWordChar = false;
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
copy(i, i + 1);
|
|
677
|
+
i++;
|
|
678
|
+
// `$`/`!` keep a reference word going (`$A$1`, `Sheet1!A1`); anything else ends it.
|
|
679
|
+
previousWasWordChar = code === 36 /* $ */ || code === 33 /* ! */;
|
|
680
|
+
}
|
|
681
|
+
flushVerbatim(length);
|
|
682
|
+
var result = { text: out };
|
|
683
|
+
if (trackOffsets) {
|
|
684
|
+
var toOutput = new Int32Array(length + 1);
|
|
685
|
+
var toSource = new Int32Array(out.length + 1);
|
|
686
|
+
for (var s = 0; s < segments.length; s += 4) {
|
|
687
|
+
var sFrom = segments[s];
|
|
688
|
+
var sTo = segments[s + 1];
|
|
689
|
+
var oFrom = segments[s + 2];
|
|
690
|
+
var oTo = segments[s + 3];
|
|
691
|
+
if (sTo - sFrom === oTo - oFrom) {
|
|
692
|
+
for (var k = 0; k < sTo - sFrom; k++) {
|
|
693
|
+
toOutput[sFrom + k] = oFrom + k;
|
|
694
|
+
toSource[oFrom + k] = sFrom + k;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
for (var k = sFrom; k < sTo; k++)
|
|
699
|
+
toOutput[k] = oFrom;
|
|
700
|
+
for (var k = oFrom; k < oTo; k++)
|
|
701
|
+
toSource[k] = sFrom;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
toOutput[length] = out.length;
|
|
705
|
+
toSource[out.length] = length;
|
|
706
|
+
result.toOutput = toOutput;
|
|
707
|
+
result.toSource = toSource;
|
|
708
|
+
}
|
|
709
|
+
return result;
|
|
710
|
+
};
|
|
711
|
+
exports.translateFormula = translateFormula;
|
|
712
|
+
/**
|
|
713
|
+
* Canonical (stored) formula text → the locale's display syntax: `=SUM(1.5,A1)` → `=СУММ(1,5;A1)`
|
|
714
|
+
* (ru), `=SUMME(1,5;A1)` (de). Identity for the canonical locale.
|
|
715
|
+
*/
|
|
716
|
+
var localizeFormula = function (formula, locale, options) {
|
|
717
|
+
var target = (0, exports.getFormulaLocale)(locale);
|
|
718
|
+
if (target.isCanonical && !(options === null || options === void 0 ? void 0 : options.trackOffsets) && (options === null || options === void 0 ? void 0 : options.functionNameCase) !== "upper") {
|
|
719
|
+
return formula;
|
|
720
|
+
}
|
|
721
|
+
return (0, exports.translateFormula)(formula, exports.CANONICAL_FORMULA_LOCALE, target, options).text;
|
|
722
|
+
};
|
|
723
|
+
exports.localizeFormula = localizeFormula;
|
|
724
|
+
/**
|
|
725
|
+
* Text typed in the locale's syntax → canonical formula text for storage and evaluation:
|
|
726
|
+
* `=СУММ(1,5;A1)` → `=SUM(1.5,A1)`. Exact inverse of {@link localizeFormula} on canonical input;
|
|
727
|
+
* lenient on mixed input (an English name or `,` argument separator typed in a `;` locale is
|
|
728
|
+
* accepted as long as it is unambiguous).
|
|
729
|
+
*/
|
|
730
|
+
var canonicalizeFormula = function (formula, locale, options) {
|
|
731
|
+
var source = (0, exports.getFormulaLocale)(locale);
|
|
732
|
+
if (source.isCanonical && !(options === null || options === void 0 ? void 0 : options.trackOffsets) && (options === null || options === void 0 ? void 0 : options.functionNameCase) !== "upper") {
|
|
733
|
+
return formula;
|
|
734
|
+
}
|
|
735
|
+
return (0, exports.translateFormula)(formula, source, exports.CANONICAL_FORMULA_LOCALE, options).text;
|
|
736
|
+
};
|
|
737
|
+
exports.canonicalizeFormula = canonicalizeFormula;
|
|
738
|
+
// ── Cell entries ─────────────────────────────────────────────────────────────────────────────────
|
|
739
|
+
/**
|
|
740
|
+
* What the editor / formula bar SHOWS for a stored cell entry: a formula in the locale's syntax, a
|
|
741
|
+
* typed error value in the locale's spelling, any other text unchanged (`1,5` typed in de-DE is a
|
|
742
|
+
* number literal the datatype parser already reads with the locale's separators).
|
|
743
|
+
*/
|
|
744
|
+
var localizeCellInput = function (text, locale) {
|
|
745
|
+
return (0, formula_1.isAFormula)(text) ? (0, exports.localizeFormula)(text, locale) : (0, exports.localizeErrorValue)(text, locale);
|
|
746
|
+
};
|
|
747
|
+
exports.localizeCellInput = localizeCellInput;
|
|
748
|
+
/** Inverse of {@link localizeCellInput}: what the editor COMMITS — canonical formula text / error value. */
|
|
749
|
+
var canonicalizeCellInput = function (text, locale) {
|
|
750
|
+
return (0, formula_1.isAFormula)(text) ? (0, exports.canonicalizeFormula)(text, locale) : (0, exports.canonicalizeErrorValue)(text, locale);
|
|
751
|
+
};
|
|
752
|
+
exports.canonicalizeCellInput = canonicalizeCellInput;
|
|
753
|
+
// ── Function catalog (autocomplete + argument hints) ─────────────────────────────────────────────
|
|
754
|
+
/**
|
|
755
|
+
* Localize a function's documented syntax (`SUM(value1, [value2, ...])` → `СУММ(value1; [value2;
|
|
756
|
+
* ...])`): the leading name through the dictionary, every `,` outside double quotes through the
|
|
757
|
+
* argument separator. The square brackets here mark OPTIONAL arguments (not structured references),
|
|
758
|
+
* so — unlike {@link localizeFormula} — the separators inside them are localized too.
|
|
759
|
+
*/
|
|
760
|
+
var localizeFunctionSyntax = function (syntax, locale) {
|
|
761
|
+
var e_8, _a;
|
|
762
|
+
var l = (0, exports.getFormulaLocale)(locale);
|
|
763
|
+
if (l.isCanonical)
|
|
764
|
+
return syntax;
|
|
765
|
+
var open = syntax.indexOf("(");
|
|
766
|
+
var name = open === -1 ? syntax : syntax.slice(0, open);
|
|
767
|
+
var rest = open === -1 ? "" : syntax.slice(open);
|
|
768
|
+
var out = "";
|
|
769
|
+
var inString = false;
|
|
770
|
+
try {
|
|
771
|
+
for (var rest_1 = tslib_1.__values(rest), rest_1_1 = rest_1.next(); !rest_1_1.done; rest_1_1 = rest_1.next()) {
|
|
772
|
+
var ch = rest_1_1.value;
|
|
773
|
+
if (ch === '"')
|
|
774
|
+
inString = !inString;
|
|
775
|
+
out += !inString && ch === "," ? l.argumentSeparator : ch;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
779
|
+
finally {
|
|
780
|
+
try {
|
|
781
|
+
if (rest_1_1 && !rest_1_1.done && (_a = rest_1.return)) _a.call(rest_1);
|
|
782
|
+
}
|
|
783
|
+
finally { if (e_8) throw e_8.error; }
|
|
784
|
+
}
|
|
785
|
+
return (0, exports.localizeFunctionName)(name.trim(), l) + name.slice(name.trim().length) + out;
|
|
786
|
+
};
|
|
787
|
+
exports.localizeFunctionSyntax = localizeFunctionSyntax;
|
|
788
|
+
/** A {@link CalculatorFunction} with its name, syntax, example and usage lines localized. */
|
|
789
|
+
var localizeFunctionDescription = function (fn, locale) {
|
|
790
|
+
var _a;
|
|
791
|
+
var l = (0, exports.getFormulaLocale)(locale);
|
|
792
|
+
if (l.isCanonical)
|
|
793
|
+
return fn;
|
|
794
|
+
return tslib_1.__assign(tslib_1.__assign({}, fn), { title: (0, exports.localizeFunctionName)(fn.title, l), syntax: (0, exports.localizeFunctionSyntax)(fn.syntax, l), example: fn.example === undefined ? fn.example : (0, exports.localizeFormula)(fn.example, l), usage: (_a = fn.usage) === null || _a === void 0 ? void 0 : _a.map(function (usage) { return (0, exports.localizeFormula)(usage, l); }) });
|
|
795
|
+
};
|
|
796
|
+
exports.localizeFunctionDescription = localizeFunctionDescription;
|
|
797
|
+
/** {@link localizeFunctionDescription} over a catalog; the same array instance for the canonical locale. */
|
|
798
|
+
var localizeFunctionDescriptions = function (functions, locale) {
|
|
799
|
+
var l = (0, exports.getFormulaLocale)(locale);
|
|
800
|
+
if (!functions || l.isCanonical)
|
|
801
|
+
return functions;
|
|
802
|
+
return functions.map(function (fn) { return (0, exports.localizeFunctionDescription)(fn, l); });
|
|
803
|
+
};
|
|
804
|
+
exports.localizeFunctionDescriptions = localizeFunctionDescriptions;
|