@cj-tech-master/excelts 9.2.1 → 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/README.md +25 -2
- package/README_zh.md +29 -6
- package/dist/browser/index.browser.d.ts +1 -1
- package/dist/browser/index.browser.js +4 -0
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +4 -0
- package/dist/browser/modules/excel/cell.d.ts +17 -3
- package/dist/browser/modules/excel/cell.js +170 -22
- package/dist/browser/modules/excel/defined-names.d.ts +96 -1
- package/dist/browser/modules/excel/defined-names.js +411 -21
- package/dist/browser/modules/excel/image.d.ts +11 -0
- package/dist/browser/modules/excel/image.js +24 -1
- package/dist/browser/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
- package/dist/browser/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/browser/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/browser/modules/excel/stream/workbook-writer.d.ts +3 -2
- package/dist/browser/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/browser/modules/excel/stream/worksheet-writer.d.ts +39 -6
- package/dist/browser/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/browser/modules/excel/table.js +15 -2
- package/dist/browser/modules/excel/types.d.ts +133 -2
- package/dist/browser/modules/excel/utils/col-cache.d.ts +1 -0
- package/dist/browser/modules/excel/utils/col-cache.js +15 -0
- package/dist/browser/modules/excel/utils/drawing-utils.d.ts +3 -3
- package/dist/browser/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/browser/modules/excel/utils/external-link-formula.d.ts +76 -0
- package/dist/browser/modules/excel/utils/external-link-formula.js +208 -0
- package/dist/browser/modules/excel/utils/iterate-stream.d.ts +9 -3
- package/dist/browser/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +19 -0
- package/dist/browser/modules/excel/utils/ooxml-paths.js +37 -2
- package/dist/browser/modules/excel/utils/shared-strings.d.ts +8 -3
- package/dist/browser/modules/excel/utils/shared-strings.js +21 -2
- package/dist/browser/modules/excel/utils/workbook-protection.d.ts +30 -0
- package/dist/browser/modules/excel/utils/workbook-protection.js +30 -0
- package/dist/browser/modules/excel/workbook.browser.d.ts +257 -6
- package/dist/browser/modules/excel/workbook.browser.js +318 -34
- package/dist/browser/modules/excel/workbook.d.ts +1 -1
- package/dist/browser/modules/excel/worksheet.d.ts +3 -1
- package/dist/browser/modules/excel/worksheet.js +21 -2
- package/dist/browser/modules/excel/xlsx/rel-type.d.ts +15 -0
- package/dist/browser/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
- package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
- package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/browser/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +410 -20
- package/dist/browser/modules/excel/xlsx/xlsx.d.ts +7 -4
- package/dist/browser/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/browser/modules/formula/compile/address-utils.d.ts +62 -0
- package/dist/browser/modules/formula/compile/address-utils.js +83 -0
- package/dist/browser/modules/formula/compile/binder.d.ts +42 -0
- package/dist/browser/modules/formula/compile/binder.js +487 -0
- package/dist/browser/modules/formula/compile/bound-ast.d.ts +230 -0
- package/dist/browser/modules/formula/compile/bound-ast.js +80 -0
- package/dist/browser/modules/formula/compile/compiled-formula.d.ts +137 -0
- package/dist/browser/modules/formula/compile/compiled-formula.js +383 -0
- package/dist/browser/modules/formula/compile/dependency-analysis.d.ts +93 -0
- package/dist/browser/modules/formula/compile/dependency-analysis.js +432 -0
- package/dist/browser/modules/formula/compile/structured-ref-utils.d.ts +93 -0
- package/dist/browser/modules/formula/compile/structured-ref-utils.js +136 -0
- package/dist/browser/modules/formula/default-syntax-probe.d.ts +79 -0
- package/dist/browser/modules/formula/default-syntax-probe.js +83 -0
- package/dist/browser/modules/formula/functions/_date-context.d.ts +4 -0
- package/dist/browser/modules/formula/functions/_date-context.js +29 -0
- package/dist/browser/modules/formula/functions/_shared.d.ts +121 -0
- package/dist/browser/modules/formula/functions/_shared.js +381 -0
- package/dist/browser/modules/formula/functions/conditional.d.ts +27 -0
- package/dist/browser/modules/formula/functions/conditional.js +343 -0
- package/dist/browser/modules/formula/functions/database.d.ts +37 -0
- package/dist/browser/modules/formula/functions/database.js +274 -0
- package/dist/browser/modules/formula/functions/date.d.ts +61 -0
- package/dist/browser/modules/formula/functions/date.js +855 -0
- package/dist/browser/modules/formula/functions/dynamic-array.d.ts +23 -0
- package/dist/browser/modules/formula/functions/dynamic-array.js +860 -0
- package/dist/browser/modules/formula/functions/engineering.d.ts +57 -0
- package/dist/browser/modules/formula/functions/engineering.js +1128 -0
- package/dist/browser/modules/formula/functions/financial.d.ts +202 -0
- package/dist/browser/modules/formula/functions/financial.js +2296 -0
- package/dist/browser/modules/formula/functions/lookup.d.ts +18 -0
- package/dist/browser/modules/formula/functions/lookup.js +886 -0
- package/dist/browser/modules/formula/functions/math.d.ts +114 -0
- package/dist/browser/modules/formula/functions/math.js +1406 -0
- package/dist/browser/modules/formula/functions/statistical.d.ts +193 -0
- package/dist/browser/modules/formula/functions/statistical.js +3390 -0
- package/dist/browser/modules/formula/functions/text.d.ts +86 -0
- package/dist/browser/modules/formula/functions/text.js +1845 -0
- package/dist/browser/modules/formula/host-registry.d.ts +53 -0
- package/dist/browser/modules/formula/host-registry.js +69 -0
- package/dist/browser/modules/formula/index.d.ts +39 -0
- package/dist/browser/modules/formula/index.js +49 -0
- package/dist/browser/modules/formula/install.d.ts +62 -0
- package/dist/browser/modules/formula/install.js +88 -0
- package/dist/browser/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
- package/dist/browser/modules/formula/integration/apply-writeback-plan.js +210 -0
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +616 -0
- package/dist/browser/modules/formula/integration/calculate-formulas.d.ts +67 -0
- package/dist/browser/modules/formula/integration/calculate-formulas.js +68 -0
- package/dist/browser/modules/formula/integration/formula-instance.d.ts +64 -0
- package/dist/browser/modules/formula/integration/formula-instance.js +79 -0
- package/dist/browser/modules/formula/integration/workbook-adapter.d.ts +26 -0
- package/dist/browser/modules/formula/integration/workbook-adapter.js +324 -0
- package/dist/browser/modules/formula/integration/workbook-snapshot.d.ts +267 -0
- package/dist/browser/modules/formula/integration/workbook-snapshot.js +77 -0
- package/dist/browser/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
- package/dist/browser/modules/formula/materialize/build-writeback-plan.js +473 -0
- package/dist/browser/modules/formula/materialize/spill-engine.d.ts +9 -0
- package/dist/browser/modules/formula/materialize/spill-engine.js +38 -0
- package/dist/browser/modules/formula/materialize/types.d.ts +179 -0
- package/dist/browser/modules/formula/materialize/types.js +29 -0
- package/dist/browser/modules/formula/materialize/writeback-plan.d.ts +167 -0
- package/dist/browser/modules/formula/materialize/writeback-plan.js +27 -0
- package/dist/browser/modules/formula/runtime/evaluator.d.ts +151 -0
- package/dist/browser/modules/formula/runtime/evaluator.js +2291 -0
- package/dist/browser/modules/formula/runtime/function-registry.d.ts +47 -0
- package/dist/browser/modules/formula/runtime/function-registry.js +840 -0
- package/dist/browser/modules/formula/runtime/values.d.ts +211 -0
- package/dist/browser/modules/formula/runtime/values.js +385 -0
- package/dist/browser/modules/formula/syntax/ast.d.ts +129 -0
- package/dist/browser/modules/formula/syntax/ast.js +28 -0
- package/dist/browser/modules/formula/syntax/parser.d.ts +18 -0
- package/dist/browser/modules/formula/syntax/parser.js +439 -0
- package/dist/browser/modules/formula/syntax/token-types.d.ts +153 -0
- package/dist/browser/modules/formula/syntax/token-types.js +59 -0
- package/dist/browser/modules/formula/syntax/tokenizer.d.ts +10 -0
- package/dist/browser/modules/formula/syntax/tokenizer.js +1074 -0
- package/dist/browser/modules/pdf/excel-bridge.js +9 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/modules/excel/cell.js +170 -22
- package/dist/cjs/modules/excel/defined-names.js +411 -21
- package/dist/cjs/modules/excel/image.js +24 -1
- package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/cjs/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/cjs/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/cjs/modules/excel/table.js +15 -2
- package/dist/cjs/modules/excel/utils/col-cache.js +15 -0
- package/dist/cjs/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/cjs/modules/excel/utils/external-link-formula.js +212 -0
- package/dist/cjs/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/cjs/modules/excel/utils/ooxml-paths.js +42 -2
- package/dist/cjs/modules/excel/utils/shared-strings.js +21 -2
- package/dist/cjs/modules/excel/utils/workbook-protection.js +33 -0
- package/dist/cjs/modules/excel/workbook.browser.js +318 -34
- package/dist/cjs/modules/excel/worksheet.js +20 -1
- package/dist/cjs/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +333 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/external-reference-xform.js +27 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-protection-xform.js +69 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +18 -0
- package/dist/cjs/modules/excel/xlsx/xform/core/metadata-xform.js +161 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +108 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +83 -0
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/cjs/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +408 -18
- package/dist/cjs/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/cjs/modules/formula/compile/address-utils.js +89 -0
- package/dist/cjs/modules/formula/compile/binder.js +489 -0
- package/dist/cjs/modules/formula/compile/bound-ast.js +68 -0
- package/dist/cjs/modules/formula/compile/compiled-formula.js +387 -0
- package/dist/cjs/modules/formula/compile/dependency-analysis.js +437 -0
- package/dist/cjs/modules/formula/compile/structured-ref-utils.js +141 -0
- package/dist/cjs/modules/formula/default-syntax-probe.js +87 -0
- package/dist/cjs/modules/formula/functions/_date-context.js +33 -0
- package/dist/cjs/modules/formula/functions/_shared.js +396 -0
- package/dist/cjs/modules/formula/functions/conditional.js +354 -0
- package/dist/cjs/modules/formula/functions/database.js +288 -0
- package/dist/cjs/modules/formula/functions/date.js +883 -0
- package/dist/cjs/modules/formula/functions/dynamic-array.js +881 -0
- package/dist/cjs/modules/formula/functions/engineering.js +1183 -0
- package/dist/cjs/modules/formula/functions/financial.js +2348 -0
- package/dist/cjs/modules/formula/functions/lookup.js +902 -0
- package/dist/cjs/modules/formula/functions/math.js +1487 -0
- package/dist/cjs/modules/formula/functions/statistical.js +3488 -0
- package/dist/cjs/modules/formula/functions/text.js +1889 -0
- package/dist/cjs/modules/formula/host-registry.js +75 -0
- package/dist/cjs/modules/formula/index.js +58 -0
- package/dist/cjs/modules/formula/install.js +93 -0
- package/dist/cjs/modules/formula/integration/apply-writeback-plan.js +213 -0
- package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +619 -0
- package/dist/cjs/modules/formula/integration/calculate-formulas.js +71 -0
- package/dist/cjs/modules/formula/integration/formula-instance.js +82 -0
- package/dist/cjs/modules/formula/integration/workbook-adapter.js +327 -0
- package/dist/cjs/modules/formula/integration/workbook-snapshot.js +84 -0
- package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +475 -0
- package/dist/cjs/modules/formula/materialize/spill-engine.js +42 -0
- package/dist/cjs/modules/formula/materialize/types.js +32 -0
- package/dist/cjs/modules/formula/materialize/writeback-plan.js +28 -0
- package/dist/cjs/modules/formula/runtime/evaluator.js +2298 -0
- package/dist/cjs/modules/formula/runtime/function-registry.js +846 -0
- package/dist/cjs/modules/formula/runtime/values.js +385 -0
- package/dist/cjs/modules/formula/syntax/ast.js +8 -0
- package/dist/cjs/modules/formula/syntax/parser.js +440 -0
- package/dist/cjs/modules/formula/syntax/token-types.js +32 -0
- package/dist/cjs/modules/formula/syntax/tokenizer.js +1076 -0
- package/dist/cjs/modules/pdf/excel-bridge.js +9 -0
- package/dist/esm/index.browser.js +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/modules/excel/cell.js +170 -22
- package/dist/esm/modules/excel/defined-names.js +411 -21
- package/dist/esm/modules/excel/image.js +24 -1
- package/dist/esm/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/esm/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/esm/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/esm/modules/excel/table.js +15 -2
- package/dist/esm/modules/excel/utils/col-cache.js +15 -0
- package/dist/esm/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/esm/modules/excel/utils/external-link-formula.js +208 -0
- package/dist/esm/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/esm/modules/excel/utils/ooxml-paths.js +37 -2
- package/dist/esm/modules/excel/utils/shared-strings.js +21 -2
- package/dist/esm/modules/excel/utils/workbook-protection.js +30 -0
- package/dist/esm/modules/excel/workbook.browser.js +318 -34
- package/dist/esm/modules/excel/worksheet.js +21 -2
- package/dist/esm/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
- package/dist/esm/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
- package/dist/esm/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/esm/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +410 -20
- package/dist/esm/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/esm/modules/formula/compile/address-utils.js +83 -0
- package/dist/esm/modules/formula/compile/binder.js +487 -0
- package/dist/esm/modules/formula/compile/bound-ast.js +80 -0
- package/dist/esm/modules/formula/compile/compiled-formula.js +383 -0
- package/dist/esm/modules/formula/compile/dependency-analysis.js +432 -0
- package/dist/esm/modules/formula/compile/structured-ref-utils.js +136 -0
- package/dist/esm/modules/formula/default-syntax-probe.js +83 -0
- package/dist/esm/modules/formula/functions/_date-context.js +29 -0
- package/dist/esm/modules/formula/functions/_shared.js +381 -0
- package/dist/esm/modules/formula/functions/conditional.js +343 -0
- package/dist/esm/modules/formula/functions/database.js +274 -0
- package/dist/esm/modules/formula/functions/date.js +855 -0
- package/dist/esm/modules/formula/functions/dynamic-array.js +860 -0
- package/dist/esm/modules/formula/functions/engineering.js +1128 -0
- package/dist/esm/modules/formula/functions/financial.js +2296 -0
- package/dist/esm/modules/formula/functions/lookup.js +886 -0
- package/dist/esm/modules/formula/functions/math.js +1406 -0
- package/dist/esm/modules/formula/functions/statistical.js +3390 -0
- package/dist/esm/modules/formula/functions/text.js +1845 -0
- package/dist/esm/modules/formula/host-registry.js +69 -0
- package/dist/esm/modules/formula/index.js +49 -0
- package/dist/esm/modules/formula/install.js +88 -0
- package/dist/esm/modules/formula/integration/apply-writeback-plan.js +210 -0
- package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +616 -0
- package/dist/esm/modules/formula/integration/calculate-formulas.js +68 -0
- package/dist/esm/modules/formula/integration/formula-instance.js +79 -0
- package/dist/esm/modules/formula/integration/workbook-adapter.js +324 -0
- package/dist/esm/modules/formula/integration/workbook-snapshot.js +77 -0
- package/dist/esm/modules/formula/materialize/build-writeback-plan.js +473 -0
- package/dist/esm/modules/formula/materialize/spill-engine.js +38 -0
- package/dist/esm/modules/formula/materialize/types.js +29 -0
- package/dist/esm/modules/formula/materialize/writeback-plan.js +27 -0
- package/dist/esm/modules/formula/runtime/evaluator.js +2291 -0
- package/dist/esm/modules/formula/runtime/function-registry.js +840 -0
- package/dist/esm/modules/formula/runtime/values.js +385 -0
- package/dist/esm/modules/formula/syntax/ast.js +28 -0
- package/dist/esm/modules/formula/syntax/parser.js +439 -0
- package/dist/esm/modules/formula/syntax/token-types.js +59 -0
- package/dist/esm/modules/formula/syntax/tokenizer.js +1074 -0
- package/dist/esm/modules/pdf/excel-bridge.js +9 -0
- package/dist/iife/excelts.iife.js +2302 -373
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +34 -34
- package/dist/types/index.browser.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/modules/excel/cell.d.ts +17 -3
- package/dist/types/modules/excel/defined-names.d.ts +96 -1
- package/dist/types/modules/excel/image.d.ts +11 -0
- package/dist/types/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
- package/dist/types/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
- package/dist/types/modules/excel/stream/workbook-writer.d.ts +3 -2
- package/dist/types/modules/excel/stream/worksheet-writer.d.ts +39 -6
- package/dist/types/modules/excel/types.d.ts +133 -2
- package/dist/types/modules/excel/utils/col-cache.d.ts +1 -0
- package/dist/types/modules/excel/utils/drawing-utils.d.ts +3 -3
- package/dist/types/modules/excel/utils/external-link-formula.d.ts +76 -0
- package/dist/types/modules/excel/utils/iterate-stream.d.ts +9 -3
- package/dist/types/modules/excel/utils/ooxml-paths.d.ts +19 -0
- package/dist/types/modules/excel/utils/shared-strings.d.ts +8 -3
- package/dist/types/modules/excel/utils/workbook-protection.d.ts +30 -0
- package/dist/types/modules/excel/workbook.browser.d.ts +257 -6
- package/dist/types/modules/excel/workbook.d.ts +1 -1
- package/dist/types/modules/excel/worksheet.d.ts +3 -1
- package/dist/types/modules/excel/xlsx/rel-type.d.ts +15 -0
- package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
- package/dist/types/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
- package/dist/types/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
- package/dist/types/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
- package/dist/types/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
- package/dist/types/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
- package/dist/types/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/types/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
- package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
- package/dist/types/modules/excel/xlsx/xlsx.d.ts +7 -4
- package/dist/types/modules/formula/compile/address-utils.d.ts +62 -0
- package/dist/types/modules/formula/compile/binder.d.ts +42 -0
- package/dist/types/modules/formula/compile/bound-ast.d.ts +230 -0
- package/dist/types/modules/formula/compile/compiled-formula.d.ts +137 -0
- package/dist/types/modules/formula/compile/dependency-analysis.d.ts +93 -0
- package/dist/types/modules/formula/compile/structured-ref-utils.d.ts +93 -0
- package/dist/types/modules/formula/default-syntax-probe.d.ts +79 -0
- package/dist/types/modules/formula/functions/_date-context.d.ts +4 -0
- package/dist/types/modules/formula/functions/_shared.d.ts +121 -0
- package/dist/types/modules/formula/functions/conditional.d.ts +27 -0
- package/dist/types/modules/formula/functions/database.d.ts +37 -0
- package/dist/types/modules/formula/functions/date.d.ts +61 -0
- package/dist/types/modules/formula/functions/dynamic-array.d.ts +23 -0
- package/dist/types/modules/formula/functions/engineering.d.ts +57 -0
- package/dist/types/modules/formula/functions/financial.d.ts +202 -0
- package/dist/types/modules/formula/functions/lookup.d.ts +18 -0
- package/dist/types/modules/formula/functions/math.d.ts +114 -0
- package/dist/types/modules/formula/functions/statistical.d.ts +193 -0
- package/dist/types/modules/formula/functions/text.d.ts +86 -0
- package/dist/types/modules/formula/host-registry.d.ts +53 -0
- package/dist/types/modules/formula/index.d.ts +39 -0
- package/dist/types/modules/formula/install.d.ts +62 -0
- package/dist/types/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
- package/dist/types/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
- package/dist/types/modules/formula/integration/calculate-formulas.d.ts +67 -0
- package/dist/types/modules/formula/integration/formula-instance.d.ts +64 -0
- package/dist/types/modules/formula/integration/workbook-adapter.d.ts +26 -0
- package/dist/types/modules/formula/integration/workbook-snapshot.d.ts +267 -0
- package/dist/types/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
- package/dist/types/modules/formula/materialize/spill-engine.d.ts +9 -0
- package/dist/types/modules/formula/materialize/types.d.ts +179 -0
- package/dist/types/modules/formula/materialize/writeback-plan.d.ts +167 -0
- package/dist/types/modules/formula/runtime/evaluator.d.ts +151 -0
- package/dist/types/modules/formula/runtime/function-registry.d.ts +47 -0
- package/dist/types/modules/formula/runtime/values.d.ts +211 -0
- package/dist/types/modules/formula/syntax/ast.d.ts +129 -0
- package/dist/types/modules/formula/syntax/parser.d.ts +18 -0
- package/dist/types/modules/formula/syntax/token-types.d.ts +153 -0
- package/dist/types/modules/formula/syntax/tokenizer.d.ts +10 -0
- package/package.json +28 -28
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AST Node Types for Formula Parser
|
|
3
|
+
*
|
|
4
|
+
* Defines the Abstract Syntax Tree node types as a proper discriminated union.
|
|
5
|
+
* Each node variant carries only the data relevant to its type.
|
|
6
|
+
*/
|
|
7
|
+
export declare const enum NodeType {
|
|
8
|
+
Number = 1,
|
|
9
|
+
String = 2,
|
|
10
|
+
Boolean = 3,
|
|
11
|
+
Error = 4,
|
|
12
|
+
CellRef = 5,
|
|
13
|
+
RangeRef = 6,
|
|
14
|
+
BinaryOp = 7,
|
|
15
|
+
UnaryOp = 8,
|
|
16
|
+
FunctionCall = 9,
|
|
17
|
+
Array = 10,
|
|
18
|
+
Percent = 11,
|
|
19
|
+
Name = 12,
|
|
20
|
+
ColRangeRef = 13,
|
|
21
|
+
RowRangeRef = 14,
|
|
22
|
+
StructuredRef = 15,
|
|
23
|
+
Missing = 16
|
|
24
|
+
}
|
|
25
|
+
export interface NumberNode {
|
|
26
|
+
type: NodeType.Number;
|
|
27
|
+
value: number;
|
|
28
|
+
}
|
|
29
|
+
export interface StringNode {
|
|
30
|
+
type: NodeType.String;
|
|
31
|
+
value: string;
|
|
32
|
+
}
|
|
33
|
+
export interface BooleanNode {
|
|
34
|
+
type: NodeType.Boolean;
|
|
35
|
+
value: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface ErrorNode {
|
|
38
|
+
type: NodeType.Error;
|
|
39
|
+
value: string;
|
|
40
|
+
}
|
|
41
|
+
export interface CellRefNode {
|
|
42
|
+
type: NodeType.CellRef;
|
|
43
|
+
/** Uppercase column letters, e.g. "A" */
|
|
44
|
+
col: string;
|
|
45
|
+
/** Row number as string, e.g. "1" */
|
|
46
|
+
row: string;
|
|
47
|
+
colAbsolute: boolean;
|
|
48
|
+
rowAbsolute: boolean;
|
|
49
|
+
/** Optional sheet name for cross-sheet references */
|
|
50
|
+
sheet?: string;
|
|
51
|
+
/** Optional end sheet name for 3D references (e.g. Sheet1:Sheet3!A1) */
|
|
52
|
+
endSheet?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface RangeRefNode {
|
|
55
|
+
type: NodeType.RangeRef;
|
|
56
|
+
/** Top-left cell */
|
|
57
|
+
start: CellRefNode;
|
|
58
|
+
/** Bottom-right cell */
|
|
59
|
+
end: CellRefNode;
|
|
60
|
+
/** Sheet name — both start and end share same sheet */
|
|
61
|
+
sheet?: string;
|
|
62
|
+
/** Optional end sheet name for 3D references (e.g. Sheet1:Sheet3!A1:B2) */
|
|
63
|
+
endSheet?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface BinaryOpNode {
|
|
66
|
+
type: NodeType.BinaryOp;
|
|
67
|
+
op: string;
|
|
68
|
+
left: AstNode;
|
|
69
|
+
right: AstNode;
|
|
70
|
+
}
|
|
71
|
+
export interface UnaryOpNode {
|
|
72
|
+
type: NodeType.UnaryOp;
|
|
73
|
+
op: string;
|
|
74
|
+
operand: AstNode;
|
|
75
|
+
}
|
|
76
|
+
export interface FunctionCallNode {
|
|
77
|
+
type: NodeType.FunctionCall;
|
|
78
|
+
name: string;
|
|
79
|
+
args: AstNode[];
|
|
80
|
+
}
|
|
81
|
+
export interface ArrayNode {
|
|
82
|
+
type: NodeType.Array;
|
|
83
|
+
/** rows[i][j] = element */
|
|
84
|
+
rows: AstNode[][];
|
|
85
|
+
}
|
|
86
|
+
export interface PercentNode {
|
|
87
|
+
type: NodeType.Percent;
|
|
88
|
+
operand: AstNode;
|
|
89
|
+
}
|
|
90
|
+
export interface NameNode {
|
|
91
|
+
type: NodeType.Name;
|
|
92
|
+
name: string;
|
|
93
|
+
}
|
|
94
|
+
export interface ColRangeRefNode {
|
|
95
|
+
type: NodeType.ColRangeRef;
|
|
96
|
+
/** Start column (e.g. "A") */
|
|
97
|
+
startCol: string;
|
|
98
|
+
/** End column (e.g. "B") */
|
|
99
|
+
endCol: string;
|
|
100
|
+
/** Optional sheet name */
|
|
101
|
+
sheet?: string;
|
|
102
|
+
/** Optional end sheet name for 3D references */
|
|
103
|
+
endSheet?: string;
|
|
104
|
+
}
|
|
105
|
+
export interface RowRangeRefNode {
|
|
106
|
+
type: NodeType.RowRangeRef;
|
|
107
|
+
/** Start row (1-based) */
|
|
108
|
+
startRow: number;
|
|
109
|
+
/** End row (1-based) */
|
|
110
|
+
endRow: number;
|
|
111
|
+
/** Optional sheet name */
|
|
112
|
+
sheet?: string;
|
|
113
|
+
/** Optional end sheet name for 3D references */
|
|
114
|
+
endSheet?: string;
|
|
115
|
+
}
|
|
116
|
+
export interface StructuredRefNode {
|
|
117
|
+
type: NodeType.StructuredRef;
|
|
118
|
+
/** Table name (empty string for implicit [@Col] syntax) */
|
|
119
|
+
tableName: string;
|
|
120
|
+
/** Column references (e.g. ["Column1", "Column2"] for a column range) */
|
|
121
|
+
columns: string[];
|
|
122
|
+
/** Special items (e.g. ["#Headers", "#Data", "#Totals", "#All", "#This Row"]) */
|
|
123
|
+
specials: string[];
|
|
124
|
+
}
|
|
125
|
+
/** Represents an omitted/missing argument in a function call (e.g., the middle arg in IF(A1,,0)). */
|
|
126
|
+
export interface MissingNode {
|
|
127
|
+
type: NodeType.Missing;
|
|
128
|
+
}
|
|
129
|
+
export type AstNode = NumberNode | StringNode | BooleanNode | ErrorNode | CellRefNode | RangeRefNode | BinaryOpNode | UnaryOpNode | FunctionCallNode | ArrayNode | PercentNode | NameNode | ColRangeRefNode | RowRangeRefNode | StructuredRefNode | MissingNode;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AST Node Types for Formula Parser
|
|
3
|
+
*
|
|
4
|
+
* Defines the Abstract Syntax Tree node types as a proper discriminated union.
|
|
5
|
+
* Each node variant carries only the data relevant to its type.
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Node Type Enum
|
|
9
|
+
// ============================================================================
|
|
10
|
+
export var NodeType;
|
|
11
|
+
(function (NodeType) {
|
|
12
|
+
NodeType[NodeType["Number"] = 1] = "Number";
|
|
13
|
+
NodeType[NodeType["String"] = 2] = "String";
|
|
14
|
+
NodeType[NodeType["Boolean"] = 3] = "Boolean";
|
|
15
|
+
NodeType[NodeType["Error"] = 4] = "Error";
|
|
16
|
+
NodeType[NodeType["CellRef"] = 5] = "CellRef";
|
|
17
|
+
NodeType[NodeType["RangeRef"] = 6] = "RangeRef";
|
|
18
|
+
NodeType[NodeType["BinaryOp"] = 7] = "BinaryOp";
|
|
19
|
+
NodeType[NodeType["UnaryOp"] = 8] = "UnaryOp";
|
|
20
|
+
NodeType[NodeType["FunctionCall"] = 9] = "FunctionCall";
|
|
21
|
+
NodeType[NodeType["Array"] = 10] = "Array";
|
|
22
|
+
NodeType[NodeType["Percent"] = 11] = "Percent";
|
|
23
|
+
NodeType[NodeType["Name"] = 12] = "Name";
|
|
24
|
+
NodeType[NodeType["ColRangeRef"] = 13] = "ColRangeRef";
|
|
25
|
+
NodeType[NodeType["RowRangeRef"] = 14] = "RowRangeRef";
|
|
26
|
+
NodeType[NodeType["StructuredRef"] = 15] = "StructuredRef";
|
|
27
|
+
NodeType[NodeType["Missing"] = 16] = "Missing";
|
|
28
|
+
})(NodeType || (NodeType = {}));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formula Parser
|
|
3
|
+
*
|
|
4
|
+
* Converts a token stream into an Abstract Syntax Tree (AST).
|
|
5
|
+
* Implements a Pratt parser (top-down operator precedence) for correct
|
|
6
|
+
* handling of operator precedence and associativity.
|
|
7
|
+
*
|
|
8
|
+
* Excel operator precedence (highest to lowest):
|
|
9
|
+
* 1. Unary + / - / %
|
|
10
|
+
* 2. ^ (exponentiation, right-assoc)
|
|
11
|
+
* 3. * /
|
|
12
|
+
* 4. + -
|
|
13
|
+
* 5. & (concatenation)
|
|
14
|
+
* 6. = <> < > <= >= (comparison)
|
|
15
|
+
*/
|
|
16
|
+
import { type AstNode } from "./ast.js";
|
|
17
|
+
import { type Token } from "./token-types.js";
|
|
18
|
+
export declare function parse(tokens: Token[]): AstNode;
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formula Parser
|
|
3
|
+
*
|
|
4
|
+
* Converts a token stream into an Abstract Syntax Tree (AST).
|
|
5
|
+
* Implements a Pratt parser (top-down operator precedence) for correct
|
|
6
|
+
* handling of operator precedence and associativity.
|
|
7
|
+
*
|
|
8
|
+
* Excel operator precedence (highest to lowest):
|
|
9
|
+
* 1. Unary + / - / %
|
|
10
|
+
* 2. ^ (exponentiation, right-assoc)
|
|
11
|
+
* 3. * /
|
|
12
|
+
* 4. + -
|
|
13
|
+
* 5. & (concatenation)
|
|
14
|
+
* 6. = <> < > <= >= (comparison)
|
|
15
|
+
*/
|
|
16
|
+
import { NodeType } from "./ast.js";
|
|
17
|
+
import { TokenType } from "./token-types.js";
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Operator Precedence
|
|
20
|
+
// ============================================================================
|
|
21
|
+
function prefixBindingPower(op) {
|
|
22
|
+
switch (op) {
|
|
23
|
+
case "+":
|
|
24
|
+
case "-":
|
|
25
|
+
// Must be lower than ^ (60/61) so that -2^3 parses as -(2^3), not (-2)^3.
|
|
26
|
+
// Excel: -2^2 = -4, not 4.
|
|
27
|
+
return 55;
|
|
28
|
+
default:
|
|
29
|
+
return 0;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function infixBindingPower(op) {
|
|
33
|
+
// Returns [left bp, right bp]. Higher = tighter binding.
|
|
34
|
+
// Left < Right for left-associative, Left > Right for right-associative.
|
|
35
|
+
switch (op) {
|
|
36
|
+
case "=":
|
|
37
|
+
case "<>":
|
|
38
|
+
case "<":
|
|
39
|
+
case ">":
|
|
40
|
+
case "<=":
|
|
41
|
+
case ">=":
|
|
42
|
+
return [10, 11];
|
|
43
|
+
case "&":
|
|
44
|
+
return [20, 21];
|
|
45
|
+
case "+":
|
|
46
|
+
case "-":
|
|
47
|
+
return [30, 31];
|
|
48
|
+
case "*":
|
|
49
|
+
case "/":
|
|
50
|
+
return [40, 41];
|
|
51
|
+
case "^":
|
|
52
|
+
return [61, 60]; // right-associative
|
|
53
|
+
// Intersection operator — whitespace between two refs. In Excel
|
|
54
|
+
// precedence this sits between `:` (range, already handled at the
|
|
55
|
+
// tokenizer level) and unary +/-. Left-associative, binds tighter
|
|
56
|
+
// than every arithmetic operator.
|
|
57
|
+
case " ":
|
|
58
|
+
return [80, 81];
|
|
59
|
+
default:
|
|
60
|
+
return [0, 0];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// Parser
|
|
65
|
+
// ============================================================================
|
|
66
|
+
class Parser {
|
|
67
|
+
constructor(tokens) {
|
|
68
|
+
this.MAX_DEPTH = 256;
|
|
69
|
+
this.tokens = tokens;
|
|
70
|
+
this.pos = 0;
|
|
71
|
+
this.depth = 0;
|
|
72
|
+
}
|
|
73
|
+
enter() {
|
|
74
|
+
if (++this.depth > this.MAX_DEPTH) {
|
|
75
|
+
throw new Error(`Formula nested too deep (> ${this.MAX_DEPTH} levels)`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
leave() {
|
|
79
|
+
this.depth--;
|
|
80
|
+
}
|
|
81
|
+
peek() {
|
|
82
|
+
return this.tokens[this.pos];
|
|
83
|
+
}
|
|
84
|
+
next() {
|
|
85
|
+
return this.tokens[this.pos++];
|
|
86
|
+
}
|
|
87
|
+
expect(type) {
|
|
88
|
+
const t = this.next();
|
|
89
|
+
if (!t || t.type !== type) {
|
|
90
|
+
throw new Error(`Expected token type ${type}, got ${t?.type ?? "EOF"}`);
|
|
91
|
+
}
|
|
92
|
+
return t;
|
|
93
|
+
}
|
|
94
|
+
// Entry point
|
|
95
|
+
parse() {
|
|
96
|
+
const node = this.parseExpr(0);
|
|
97
|
+
// After parsing a complete expression, every token must have been
|
|
98
|
+
// consumed. Otherwise inputs like "A1:B2:C3" or "1+2 3" would silently
|
|
99
|
+
// produce an AST that drops the trailing tokens.
|
|
100
|
+
if (this.pos !== this.tokens.length) {
|
|
101
|
+
const t = this.tokens[this.pos];
|
|
102
|
+
throw new Error(`Unexpected trailing token at position ${this.pos} (type ${t.type})`);
|
|
103
|
+
}
|
|
104
|
+
return node;
|
|
105
|
+
}
|
|
106
|
+
parseExpr(minBp) {
|
|
107
|
+
this.enter();
|
|
108
|
+
try {
|
|
109
|
+
return this.parseExprInner(minBp);
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
this.leave();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
parseExprInner(minBp) {
|
|
116
|
+
let left = this.parsePrefix();
|
|
117
|
+
while (true) {
|
|
118
|
+
const t = this.peek();
|
|
119
|
+
if (!t) {
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
// Postfix: %
|
|
123
|
+
if (t.type === TokenType.Percent) {
|
|
124
|
+
this.next();
|
|
125
|
+
left = { type: NodeType.Percent, operand: left };
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
// Infix operators
|
|
129
|
+
if (t.type === TokenType.Operator) {
|
|
130
|
+
const [lbp, rbp] = infixBindingPower(t.value);
|
|
131
|
+
if (lbp === 0 || lbp < minBp) {
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
this.next();
|
|
135
|
+
const right = this.parseExpr(rbp);
|
|
136
|
+
left = { type: NodeType.BinaryOp, op: t.value, left, right };
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
// Intersection: whitespace separating two refs. Modelled as a binary
|
|
140
|
+
// operation with op=" ". The evaluator resolves both sides to refs
|
|
141
|
+
// and returns their rectangle intersection (or `#NULL!`).
|
|
142
|
+
if (t.type === TokenType.Intersect) {
|
|
143
|
+
const [lbp, rbp] = infixBindingPower(" ");
|
|
144
|
+
if (lbp < minBp) {
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
this.next();
|
|
148
|
+
const right = this.parseExpr(rbp);
|
|
149
|
+
left = { type: NodeType.BinaryOp, op: " ", left, right };
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// Range operator `:` — binds tighter than intersection. Normally
|
|
153
|
+
// `A1:B2` is merged into a single Range token by the tokenizer,
|
|
154
|
+
// but patterns like `B11:INDIRECT("B" & ROW()-1)` where one side
|
|
155
|
+
// is a function call leave the colon as a standalone token. The
|
|
156
|
+
// evaluator then coerces both sides to references and constructs
|
|
157
|
+
// the union rectangle.
|
|
158
|
+
if (t.type === TokenType.Colon) {
|
|
159
|
+
// Right-biased binding power to guarantee higher precedence than
|
|
160
|
+
// every other operator in the table above.
|
|
161
|
+
const lbp = 100;
|
|
162
|
+
const rbp = 101;
|
|
163
|
+
if (lbp < minBp) {
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
this.next();
|
|
167
|
+
const right = this.parseExpr(rbp);
|
|
168
|
+
left = { type: NodeType.BinaryOp, op: ":", left, right };
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
return left;
|
|
174
|
+
}
|
|
175
|
+
parsePrefix() {
|
|
176
|
+
this.enter();
|
|
177
|
+
try {
|
|
178
|
+
const result = this.parsePrefixInner();
|
|
179
|
+
// If the SheetRef consumer below set pendingSheet but the prefix that
|
|
180
|
+
// followed wasn't a ref (CellRef / Range / ColRange / RowRange), the
|
|
181
|
+
// sheet qualifier would leak into the next parse and silently attach
|
|
182
|
+
// itself to an unrelated node. Detect it here.
|
|
183
|
+
if (this.pendingSheet !== undefined) {
|
|
184
|
+
const sheet = this.pendingSheet;
|
|
185
|
+
this.pendingSheet = undefined;
|
|
186
|
+
this.pendingEndSheet = undefined;
|
|
187
|
+
throw new Error(`Sheet reference '${sheet}' not followed by a cell or range`);
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
this.leave();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
parsePrefixInner() {
|
|
196
|
+
const t = this.peek();
|
|
197
|
+
if (!t) {
|
|
198
|
+
throw new Error("Unexpected end of formula");
|
|
199
|
+
}
|
|
200
|
+
// SheetRef: consume and set pending sheet for next cell/range
|
|
201
|
+
if (t.type === TokenType.SheetRef) {
|
|
202
|
+
this.next();
|
|
203
|
+
this.pendingSheet = t.sheetName;
|
|
204
|
+
this.pendingEndSheet = t.endSheetName;
|
|
205
|
+
return this.parsePrefix();
|
|
206
|
+
}
|
|
207
|
+
// Unary prefix: + -
|
|
208
|
+
if (t.type === TokenType.UnaryPrefix) {
|
|
209
|
+
this.next();
|
|
210
|
+
const bp = prefixBindingPower(t.value);
|
|
211
|
+
const operand = this.parseExpr(bp);
|
|
212
|
+
return { type: NodeType.UnaryOp, op: t.value, operand };
|
|
213
|
+
}
|
|
214
|
+
// @ implicit intersection prefix (Excel 365)
|
|
215
|
+
if (t.type === TokenType.AtSign) {
|
|
216
|
+
this.next();
|
|
217
|
+
const operand = this.parseExpr(55); // same precedence as unary +/-
|
|
218
|
+
return { type: NodeType.UnaryOp, op: "@", operand };
|
|
219
|
+
}
|
|
220
|
+
// Number literal
|
|
221
|
+
if (t.type === TokenType.Number) {
|
|
222
|
+
this.next();
|
|
223
|
+
const n = parseFloat(t.value);
|
|
224
|
+
// Reject non-finite literals at parse time. `1e400` would otherwise
|
|
225
|
+
// become `Infinity` and flow through arithmetic, requiring every
|
|
226
|
+
// downstream consumer to guard. Surfacing the overflow as a #NUM!
|
|
227
|
+
// error node keeps the engine's invariant that numeric values are
|
|
228
|
+
// always finite.
|
|
229
|
+
if (!Number.isFinite(n)) {
|
|
230
|
+
return { type: NodeType.Error, value: "#NUM!" };
|
|
231
|
+
}
|
|
232
|
+
return { type: NodeType.Number, value: n };
|
|
233
|
+
}
|
|
234
|
+
// String literal
|
|
235
|
+
if (t.type === TokenType.String) {
|
|
236
|
+
this.next();
|
|
237
|
+
return { type: NodeType.String, value: t.value };
|
|
238
|
+
}
|
|
239
|
+
// Boolean literal
|
|
240
|
+
if (t.type === TokenType.Boolean) {
|
|
241
|
+
this.next();
|
|
242
|
+
return { type: NodeType.Boolean, value: t.value === "TRUE" };
|
|
243
|
+
}
|
|
244
|
+
// Error literal
|
|
245
|
+
if (t.type === TokenType.Error) {
|
|
246
|
+
this.next();
|
|
247
|
+
return { type: NodeType.Error, value: t.value };
|
|
248
|
+
}
|
|
249
|
+
// Parenthesized expression
|
|
250
|
+
if (t.type === TokenType.OpenParen) {
|
|
251
|
+
this.next();
|
|
252
|
+
const expr = this.parseExpr(0);
|
|
253
|
+
this.expect(TokenType.CloseParen);
|
|
254
|
+
return expr;
|
|
255
|
+
}
|
|
256
|
+
// Array constant: {1,2;3,4}
|
|
257
|
+
if (t.type === TokenType.OpenBrace) {
|
|
258
|
+
return this.parseArrayConstant();
|
|
259
|
+
}
|
|
260
|
+
// Function call: NAME(args)
|
|
261
|
+
if (t.type === TokenType.Function) {
|
|
262
|
+
return this.parseFunctionCall();
|
|
263
|
+
}
|
|
264
|
+
// Cell reference (may become range via tokenizer)
|
|
265
|
+
if (t.type === TokenType.CellRef) {
|
|
266
|
+
this.next();
|
|
267
|
+
const ref = this.parseCellRefFromToken(t);
|
|
268
|
+
const sheet = this.pendingSheet;
|
|
269
|
+
const endSheet = this.pendingEndSheet;
|
|
270
|
+
this.pendingSheet = undefined;
|
|
271
|
+
this.pendingEndSheet = undefined;
|
|
272
|
+
ref.sheet = sheet;
|
|
273
|
+
ref.endSheet = endSheet;
|
|
274
|
+
return ref;
|
|
275
|
+
}
|
|
276
|
+
// Range reference (already parsed by tokenizer as A1:B2)
|
|
277
|
+
if (t.type === TokenType.Range) {
|
|
278
|
+
this.next();
|
|
279
|
+
const sheet = this.pendingSheet;
|
|
280
|
+
const endSheet = this.pendingEndSheet;
|
|
281
|
+
this.pendingSheet = undefined;
|
|
282
|
+
this.pendingEndSheet = undefined;
|
|
283
|
+
return this.parseRangeFromToken(t, sheet, endSheet);
|
|
284
|
+
}
|
|
285
|
+
// Named range / defined name
|
|
286
|
+
if (t.type === TokenType.Name) {
|
|
287
|
+
this.next();
|
|
288
|
+
return { type: NodeType.Name, name: t.value };
|
|
289
|
+
}
|
|
290
|
+
// Whole-column range (e.g. A:B, $C:$D)
|
|
291
|
+
if (t.type === TokenType.ColRange) {
|
|
292
|
+
this.next();
|
|
293
|
+
const sheet = this.pendingSheet;
|
|
294
|
+
const endSheet = this.pendingEndSheet;
|
|
295
|
+
this.pendingSheet = undefined;
|
|
296
|
+
this.pendingEndSheet = undefined;
|
|
297
|
+
const parts = t.value.split(":");
|
|
298
|
+
const startCol = parts[0].replace(/\$/g, "").toUpperCase();
|
|
299
|
+
const endCol = parts[1].replace(/\$/g, "").toUpperCase();
|
|
300
|
+
return { type: NodeType.ColRangeRef, startCol, endCol, sheet, endSheet };
|
|
301
|
+
}
|
|
302
|
+
// Whole-row range (e.g. 1:5, $3:$7)
|
|
303
|
+
if (t.type === TokenType.RowRange) {
|
|
304
|
+
this.next();
|
|
305
|
+
const sheet = this.pendingSheet;
|
|
306
|
+
const endSheet = this.pendingEndSheet;
|
|
307
|
+
this.pendingSheet = undefined;
|
|
308
|
+
this.pendingEndSheet = undefined;
|
|
309
|
+
const parts = t.value.split(":");
|
|
310
|
+
const startRow = parseInt(parts[0].replace(/\$/g, ""), 10);
|
|
311
|
+
const endRow = parseInt(parts[1].replace(/\$/g, ""), 10);
|
|
312
|
+
return { type: NodeType.RowRangeRef, startRow, endRow, sheet, endSheet };
|
|
313
|
+
}
|
|
314
|
+
// Structured reference (e.g. Table1[Column], [@Column])
|
|
315
|
+
if (t.type === TokenType.StructuredRef) {
|
|
316
|
+
this.next();
|
|
317
|
+
return {
|
|
318
|
+
type: NodeType.StructuredRef,
|
|
319
|
+
tableName: t.tableName,
|
|
320
|
+
columns: t.columns,
|
|
321
|
+
specials: t.specials
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
throw new Error(`Unexpected token: ${t.type}`);
|
|
325
|
+
}
|
|
326
|
+
parseCellRefFromToken(t) {
|
|
327
|
+
return {
|
|
328
|
+
type: NodeType.CellRef,
|
|
329
|
+
col: t.col,
|
|
330
|
+
row: t.row,
|
|
331
|
+
colAbsolute: t.colAbsolute,
|
|
332
|
+
rowAbsolute: t.rowAbsolute
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
parseRangeFromToken(t, sheet, endSheet) {
|
|
336
|
+
// Token value is like "A1:B2" or "$A$1:$B$2"
|
|
337
|
+
const parts = t.value.split(":");
|
|
338
|
+
const startRef = parseCellRefStr(parts[0]);
|
|
339
|
+
const endRef = parseCellRefStr(parts[1]);
|
|
340
|
+
return {
|
|
341
|
+
type: NodeType.RangeRef,
|
|
342
|
+
start: { ...startRef, sheet },
|
|
343
|
+
end: { ...endRef, sheet },
|
|
344
|
+
sheet,
|
|
345
|
+
endSheet
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
parseFunctionCall() {
|
|
349
|
+
const nameToken = this.next(); // function name
|
|
350
|
+
this.expect(TokenType.OpenParen);
|
|
351
|
+
const args = [];
|
|
352
|
+
if (this.peek()?.type !== TokenType.CloseParen) {
|
|
353
|
+
// First argument: might be missing if comma is next
|
|
354
|
+
if (this.peek()?.type === TokenType.Comma) {
|
|
355
|
+
args.push({ type: NodeType.Missing });
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
args.push(this.parseExpr(0));
|
|
359
|
+
}
|
|
360
|
+
while (this.peek()?.type === TokenType.Comma) {
|
|
361
|
+
this.next(); // skip comma
|
|
362
|
+
// Next argument: missing if followed by comma or close paren
|
|
363
|
+
if (this.peek()?.type === TokenType.Comma || this.peek()?.type === TokenType.CloseParen) {
|
|
364
|
+
args.push({ type: NodeType.Missing });
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
args.push(this.parseExpr(0));
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
this.expect(TokenType.CloseParen);
|
|
372
|
+
return {
|
|
373
|
+
type: NodeType.FunctionCall,
|
|
374
|
+
name: nameToken.name,
|
|
375
|
+
args
|
|
376
|
+
};
|
|
377
|
+
}
|
|
378
|
+
parseArrayConstant() {
|
|
379
|
+
this.next(); // skip {
|
|
380
|
+
const rows = [];
|
|
381
|
+
let currentRow = [];
|
|
382
|
+
if (this.peek()?.type !== TokenType.CloseBrace) {
|
|
383
|
+
currentRow.push(this.parseExpr(0));
|
|
384
|
+
while (this.peek()) {
|
|
385
|
+
const t = this.peek();
|
|
386
|
+
if (t.type === TokenType.Comma) {
|
|
387
|
+
this.next();
|
|
388
|
+
currentRow.push(this.parseExpr(0));
|
|
389
|
+
}
|
|
390
|
+
else if (t.type === TokenType.Semicolon) {
|
|
391
|
+
this.next();
|
|
392
|
+
rows.push(currentRow);
|
|
393
|
+
currentRow = [];
|
|
394
|
+
currentRow.push(this.parseExpr(0));
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
rows.push(currentRow);
|
|
402
|
+
this.expect(TokenType.CloseBrace);
|
|
403
|
+
return { type: NodeType.Array, rows };
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
// Helper to parse a cell reference string like "$A$1" or "B2"
|
|
407
|
+
function parseCellRefStr(s) {
|
|
408
|
+
let i = 0;
|
|
409
|
+
let colAbsolute = false;
|
|
410
|
+
let rowAbsolute = false;
|
|
411
|
+
if (s[i] === "$") {
|
|
412
|
+
colAbsolute = true;
|
|
413
|
+
i++;
|
|
414
|
+
}
|
|
415
|
+
const colStart = i;
|
|
416
|
+
while (i < s.length && ((s[i] >= "A" && s[i] <= "Z") || (s[i] >= "a" && s[i] <= "z"))) {
|
|
417
|
+
i++;
|
|
418
|
+
}
|
|
419
|
+
const col = s.slice(colStart, i).toUpperCase();
|
|
420
|
+
if (i < s.length && s[i] === "$") {
|
|
421
|
+
rowAbsolute = true;
|
|
422
|
+
i++;
|
|
423
|
+
}
|
|
424
|
+
const row = s.slice(i);
|
|
425
|
+
return {
|
|
426
|
+
type: NodeType.CellRef,
|
|
427
|
+
col,
|
|
428
|
+
row,
|
|
429
|
+
colAbsolute,
|
|
430
|
+
rowAbsolute
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
// ============================================================================
|
|
434
|
+
// Public API
|
|
435
|
+
// ============================================================================
|
|
436
|
+
export function parse(tokens) {
|
|
437
|
+
const parser = new Parser(tokens);
|
|
438
|
+
return parser.parse();
|
|
439
|
+
}
|