@cj-tech-master/excelts 9.5.4 → 9.5.5
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/browser/modules/archive/compression/streaming-compress.browser.js +29 -0
- package/dist/browser/modules/archive/compression/streaming-compress.js +9 -0
- package/dist/browser/modules/archive/compression/worker-pool/pool.browser.js +26 -1
- package/dist/browser/modules/archive/fs/archive-file.d.ts +8 -5
- package/dist/browser/modules/archive/fs/archive-file.js +78 -16
- package/dist/browser/modules/archive/unzip/stream.browser.js +43 -2
- package/dist/browser/modules/excel/chart/chart-ex-builder.js +7 -2
- package/dist/browser/modules/excel/chart/chart-ex-renderer.js +4 -9
- package/dist/browser/modules/excel/chart/chart-ex-types.d.ts +0 -12
- package/dist/browser/modules/excel/chart/chart.d.ts +1 -5
- package/dist/browser/modules/excel/chart/chart.js +1 -7
- package/dist/browser/modules/excel/chart/types.d.ts +0 -6
- package/dist/browser/modules/excel/stream/workbook-reader.browser.js +25 -1
- package/dist/browser/modules/excel/stream/workbook-reader.js +9 -0
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +40 -0
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +228 -13
- package/dist/browser/modules/excel/utils/string-buf.d.ts +5 -26
- package/dist/browser/modules/excel/utils/string-buf.js +4 -81
- package/dist/browser/modules/excel/workbook.browser.js +135 -25
- package/dist/browser/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
- package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +19 -9
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +32 -8
- package/dist/browser/modules/excel/xlsx/xlsx.d.ts +10 -2
- package/dist/browser/modules/excel/xlsx/xlsx.js +9 -1
- package/dist/browser/modules/pdf/excel-bridge.d.ts +30 -1
- package/dist/browser/modules/pdf/excel-bridge.js +32 -0
- package/dist/browser/modules/pdf/font/metrics.d.ts +3 -52
- package/dist/browser/modules/pdf/font/metrics.js +3 -237
- package/dist/browser/modules/pdf/index.d.ts +1 -1
- package/dist/browser/modules/pdf/index.js +1 -1
- package/dist/browser/modules/pdf/render-layout-to-pdf.d.ts +66 -0
- package/dist/browser/modules/pdf/render-layout-to-pdf.js +647 -0
- package/dist/browser/modules/pdf/word-bridge.d.ts +80 -12
- package/dist/browser/modules/pdf/word-bridge.js +122 -274
- package/dist/browser/modules/stream/index.base.d.ts +2 -0
- package/dist/browser/modules/stream/index.base.js +2 -1
- package/dist/browser/modules/stream/internal/sink-adapter.d.ts +65 -0
- package/dist/browser/modules/stream/internal/sink-adapter.js +198 -0
- package/dist/browser/modules/stream/pull-stream.d.ts +19 -2
- package/dist/browser/modules/stream/pull-stream.js +51 -5
- package/dist/browser/modules/stream/types.d.ts +13 -1
- package/dist/browser/modules/word/advanced/diff.d.ts +61 -0
- package/dist/browser/modules/word/advanced/diff.js +167 -0
- package/dist/browser/modules/word/advanced/drawing-shapes.d.ts +269 -0
- package/dist/browser/modules/word/advanced/drawing-shapes.js +268 -0
- package/dist/browser/modules/word/advanced/field-engine.d.ts +43 -0
- package/dist/browser/modules/word/advanced/field-engine.js +1225 -0
- package/dist/browser/modules/word/advanced/glossary.d.ts +86 -0
- package/dist/browser/modules/word/advanced/glossary.js +79 -0
- package/dist/browser/modules/word/advanced/math-convert.d.ts +30 -0
- package/dist/browser/modules/word/advanced/math-convert.js +595 -0
- package/dist/browser/modules/word/advanced/ole-objects.d.ts +115 -0
- package/dist/browser/modules/word/advanced/ole-objects.js +271 -0
- package/dist/browser/modules/word/advanced/style-map.d.ts +105 -0
- package/dist/browser/modules/word/advanced/style-map.js +322 -0
- package/dist/browser/modules/word/advanced/validation.d.ts +56 -0
- package/dist/browser/modules/word/advanced/validation.js +1065 -0
- package/dist/browser/modules/word/advanced/vba-project.d.ts +91 -0
- package/dist/browser/modules/word/advanced/vba-project.js +265 -0
- package/dist/browser/modules/word/bridge/excel-bridge.d.ts +127 -0
- package/dist/browser/modules/word/bridge/excel-bridge.js +980 -0
- package/dist/browser/modules/word/builder/document-handle.d.ts +151 -0
- package/dist/browser/modules/word/builder/document-handle.js +664 -0
- package/dist/browser/modules/word/builder/paragraph-builders.d.ts +61 -0
- package/dist/browser/modules/word/builder/paragraph-builders.js +90 -0
- package/dist/browser/modules/word/builder/run-builders.d.ts +374 -0
- package/dist/browser/modules/word/builder/run-builders.js +600 -0
- package/dist/browser/modules/word/builder/table-builders.d.ts +23 -0
- package/dist/browser/modules/word/builder/table-builders.js +45 -0
- package/dist/browser/modules/word/constants.d.ts +39 -1
- package/dist/browser/modules/word/constants.js +109 -1
- package/dist/browser/modules/word/convert/conversion-ir.d.ts +210 -0
- package/dist/browser/modules/word/convert/conversion-ir.js +31 -0
- package/dist/browser/modules/word/convert/docx-to-semantic.d.ts +39 -0
- package/dist/browser/modules/word/convert/docx-to-semantic.js +499 -0
- package/dist/browser/modules/word/convert/flat-opc.d.ts +44 -0
- package/dist/browser/modules/word/convert/flat-opc.js +385 -0
- package/dist/browser/modules/word/convert/html/html-import.d.ts +50 -0
- package/dist/browser/modules/word/convert/html/html-import.js +1907 -0
- package/dist/{types/modules/word → browser/modules/word/convert/html}/html-renderer.d.ts +14 -1
- package/dist/{esm/modules/word → browser/modules/word/convert/html}/html-renderer.js +420 -69
- package/dist/browser/modules/word/convert/html/html.d.ts +15 -0
- package/dist/browser/modules/word/convert/html/html.js +15 -0
- package/dist/browser/modules/word/convert/markdown/markdown-import.d.ts +68 -0
- package/dist/browser/modules/word/convert/markdown/markdown-import.js +1325 -0
- package/dist/browser/modules/word/convert/markdown/markdown-renderer.d.ts +25 -0
- package/dist/browser/modules/word/convert/markdown/markdown-renderer.js +634 -0
- package/dist/browser/modules/word/convert/markdown/markdown.d.ts +15 -0
- package/dist/browser/modules/word/convert/markdown/markdown.js +15 -0
- package/dist/browser/modules/word/convert/odt/odt.d.ts +41 -0
- package/dist/browser/modules/word/convert/odt/odt.js +1932 -0
- package/dist/browser/modules/word/{color-utils.d.ts → core/color-utils.d.ts} +8 -1
- package/dist/browser/modules/word/core/color-utils.js +43 -0
- package/dist/browser/modules/word/core/internal-utils.d.ts +90 -0
- package/dist/browser/modules/word/core/internal-utils.js +209 -0
- package/dist/browser/modules/word/core/mapper.d.ts +44 -0
- package/dist/browser/modules/word/core/mapper.js +427 -0
- package/dist/browser/modules/word/core/opc-paths.d.ts +33 -0
- package/dist/browser/modules/word/core/opc-paths.js +48 -0
- package/dist/browser/modules/word/core/text-utils.d.ts +38 -0
- package/dist/browser/modules/word/core/text-utils.js +202 -0
- package/dist/browser/modules/word/core/walker.d.ts +119 -0
- package/dist/browser/modules/word/core/walker.js +570 -0
- package/dist/browser/modules/word/crypto.d.ts +14 -9
- package/dist/browser/modules/word/crypto.js +13 -7
- package/dist/browser/modules/word/document-io.d.ts +59 -27
- package/dist/browser/modules/word/document-io.js +80 -197
- package/dist/browser/modules/word/errors.d.ts +44 -1
- package/dist/browser/modules/word/errors.js +54 -2
- package/dist/browser/modules/word/excel.d.ts +14 -0
- package/dist/browser/modules/word/excel.js +13 -0
- package/dist/browser/modules/word/font/font-embed.d.ts +112 -0
- package/dist/browser/modules/word/font/font-embed.js +646 -0
- package/dist/{esm/modules/word → browser/modules/word/font}/font-obfuscation.js +4 -9
- package/dist/browser/modules/word/font/hyphenation.d.ts +65 -0
- package/dist/browser/modules/word/font/hyphenation.js +4210 -0
- package/dist/browser/modules/word/font/text-shaping.d.ts +58 -0
- package/dist/browser/modules/word/font/text-shaping.js +635 -0
- package/dist/browser/modules/word/html.d.ts +7 -6
- package/dist/browser/modules/word/html.js +6 -5
- package/dist/browser/modules/word/incremental-edit.d.ts +123 -0
- package/dist/browser/modules/word/incremental-edit.js +361 -0
- package/dist/browser/modules/word/index.base.d.ts +194 -10
- package/dist/browser/modules/word/index.base.js +138 -29
- package/dist/browser/modules/word/layout/layout-constants.d.ts +17 -0
- package/dist/browser/modules/word/layout/layout-constants.js +17 -0
- package/dist/browser/modules/word/layout/layout-full.d.ts +53 -0
- package/dist/browser/modules/word/layout/layout-full.js +1696 -0
- package/dist/browser/modules/word/layout/layout-model.d.ts +344 -0
- package/dist/browser/modules/word/layout/layout-model.js +16 -0
- package/dist/browser/modules/word/layout/layout.d.ts +63 -0
- package/dist/browser/modules/word/layout/layout.js +1167 -0
- package/dist/browser/modules/word/layout/render-page.d.ts +57 -0
- package/dist/browser/modules/word/layout/render-page.js +1238 -0
- package/dist/browser/modules/word/markdown.d.ts +14 -0
- package/dist/browser/modules/word/markdown.js +13 -0
- package/dist/browser/modules/word/patcher.d.ts +62 -0
- package/dist/browser/modules/word/patcher.js +537 -0
- package/dist/browser/modules/word/query/compat.d.ts +25 -0
- package/dist/browser/modules/word/query/compat.js +58 -0
- package/dist/browser/modules/word/query/data-binding.d.ts +22 -0
- package/dist/browser/modules/word/query/data-binding.js +392 -0
- package/dist/browser/modules/word/query/form-fields.d.ts +41 -0
- package/dist/browser/modules/word/query/form-fields.js +268 -0
- package/dist/browser/modules/word/query/format-search.d.ts +99 -0
- package/dist/browser/modules/word/query/format-search.js +329 -0
- package/dist/browser/modules/word/query/mail-merge.d.ts +25 -0
- package/dist/browser/modules/word/query/mail-merge.js +111 -0
- package/dist/browser/modules/word/query/merge.d.ts +50 -0
- package/dist/browser/modules/word/query/merge.js +617 -0
- package/dist/browser/modules/word/query/replace.d.ts +47 -0
- package/dist/browser/modules/word/query/replace.js +301 -0
- package/dist/browser/modules/word/query/revisions.d.ts +67 -0
- package/dist/browser/modules/word/query/revisions.js +879 -0
- package/dist/browser/modules/word/query/search.d.ts +129 -0
- package/dist/browser/modules/word/query/search.js +346 -0
- package/dist/browser/modules/word/query/split.d.ts +44 -0
- package/dist/browser/modules/word/query/split.js +135 -0
- package/dist/browser/modules/word/query/style-resolve.d.ts +104 -0
- package/dist/browser/modules/word/query/style-resolve.js +368 -0
- package/dist/browser/modules/word/reader/chart-parser.d.ts +20 -0
- package/dist/browser/modules/word/reader/chart-parser.js +810 -0
- package/dist/browser/modules/word/reader/comments-parser.d.ts +26 -0
- package/dist/browser/modules/word/reader/comments-parser.js +92 -0
- package/dist/browser/modules/word/reader/doc-props-parsers.d.ts +15 -0
- package/dist/browser/modules/word/reader/doc-props-parsers.js +190 -0
- package/dist/browser/modules/word/reader/docx-reader.d.ts +27 -0
- package/dist/browser/modules/word/reader/docx-reader.js +2557 -0
- package/dist/browser/modules/word/reader/drawing-helpers.d.ts +27 -0
- package/dist/browser/modules/word/reader/drawing-helpers.js +84 -0
- package/dist/browser/modules/word/reader/form-field-parser.d.ts +21 -0
- package/dist/browser/modules/word/reader/form-field-parser.js +82 -0
- package/dist/browser/modules/word/reader/image-parsers.d.ts +11 -0
- package/dist/browser/modules/word/reader/image-parsers.js +291 -0
- package/dist/browser/modules/word/reader/math-parser.d.ts +12 -0
- package/dist/browser/modules/word/reader/math-parser.js +422 -0
- package/dist/browser/modules/word/reader/metadata-parsers.d.ts +17 -0
- package/dist/browser/modules/word/reader/metadata-parsers.js +87 -0
- package/dist/browser/modules/word/reader/numbering-parser.d.ts +13 -0
- package/dist/browser/modules/word/reader/numbering-parser.js +166 -0
- package/dist/browser/modules/word/reader/paragraph-section-parsers.d.ts +12 -0
- package/dist/browser/modules/word/reader/paragraph-section-parsers.js +503 -0
- package/dist/browser/modules/word/reader/parse-utils.d.ts +91 -0
- package/dist/browser/modules/word/reader/parse-utils.js +249 -0
- package/dist/browser/modules/word/reader/properties-parsers.d.ts +21 -0
- package/dist/browser/modules/word/reader/properties-parsers.js +332 -0
- package/dist/browser/modules/word/reader/reader-context.d.ts +69 -0
- package/dist/browser/modules/word/reader/reader-context.js +61 -0
- package/dist/browser/modules/word/reader/sdt-helpers.d.ts +29 -0
- package/dist/browser/modules/word/reader/sdt-helpers.js +111 -0
- package/dist/browser/modules/word/reader/settings-parser.d.ts +8 -0
- package/dist/browser/modules/word/reader/settings-parser.js +263 -0
- package/dist/browser/modules/word/reader/styles-parser.d.ts +12 -0
- package/dist/browser/modules/word/reader/styles-parser.js +147 -0
- package/dist/browser/modules/word/reader/table-properties-parsers.d.ts +12 -0
- package/dist/browser/modules/word/reader/table-properties-parsers.js +234 -0
- package/dist/browser/modules/word/reader/theme-parser.d.ts +8 -0
- package/dist/browser/modules/word/reader/theme-parser.js +167 -0
- package/dist/browser/modules/word/reader/watermark-parser.d.ts +15 -0
- package/dist/browser/modules/word/reader/watermark-parser.js +110 -0
- package/dist/browser/modules/word/security/cfb-reader.d.ts +37 -0
- package/dist/browser/modules/word/security/cfb-reader.js +410 -0
- package/dist/browser/modules/word/{digital-signatures.d.ts → security/digital-signatures.d.ts} +19 -11
- package/dist/browser/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
- package/dist/browser/modules/word/security/document-protection.d.ts +93 -0
- package/dist/browser/modules/word/security/document-protection.js +201 -0
- package/dist/{types/modules/word → browser/modules/word/security}/encryption.d.ts +51 -4
- package/dist/browser/modules/word/security/encryption.js +602 -0
- package/dist/browser/modules/word/security/policy.d.ts +80 -0
- package/dist/browser/modules/word/security/policy.js +102 -0
- package/dist/browser/modules/word/template/template-chart.d.ts +56 -0
- package/dist/browser/modules/word/template/template-chart.js +167 -0
- package/dist/browser/modules/word/template/template-datasource.d.ts +154 -0
- package/dist/browser/modules/word/template/template-datasource.js +541 -0
- package/dist/browser/modules/word/template/template-engine.d.ts +121 -0
- package/dist/browser/modules/word/template/template-engine.js +1435 -0
- package/dist/browser/modules/word/types.d.ts +224 -25
- package/dist/browser/modules/word/units.d.ts +26 -0
- package/dist/browser/modules/word/units.js +43 -14
- package/dist/browser/modules/word/{writers → writer}/chart-writer.js +164 -23
- package/dist/browser/modules/word/writer/checkbox-writer.d.ts +17 -0
- package/dist/browser/modules/word/writer/checkbox-writer.js +79 -0
- package/dist/{types/modules/word/writers → browser/modules/word/writer}/comment-writer.d.ts +2 -1
- package/dist/browser/modules/word/{writers → writer}/comment-writer.js +8 -6
- package/dist/browser/modules/word/writer/common-parts.d.ts +57 -0
- package/dist/browser/modules/word/writer/common-parts.js +101 -0
- package/dist/{types/modules/word → browser/modules/word/writer}/content-types.d.ts +2 -2
- package/dist/{esm/modules/word → browser/modules/word/writer}/content-types.js +14 -6
- package/dist/browser/modules/word/writer/document-writer.d.ts +24 -0
- package/dist/browser/modules/word/writer/document-writer.js +473 -0
- package/dist/browser/modules/word/writer/docx-packager.d.ts +35 -0
- package/dist/browser/modules/word/writer/docx-packager.js +1515 -0
- package/dist/{types/modules/word/writers → browser/modules/word/writer}/footnote-writer.d.ts +3 -2
- package/dist/{esm/modules/word/writers → browser/modules/word/writer}/footnote-writer.js +13 -10
- package/dist/{types/modules/word/writers → browser/modules/word/writer}/header-footer-writer.d.ts +3 -2
- package/dist/{esm/modules/word/writers → browser/modules/word/writer}/header-footer-writer.js +39 -21
- package/dist/{types/modules/word/writers → browser/modules/word/writer}/image-writer.d.ts +1 -1
- package/dist/browser/modules/word/{writers → writer}/image-writer.js +11 -7
- package/dist/browser/modules/word/writer/math-writer.d.ts +20 -0
- package/dist/{esm/modules/word/writers → browser/modules/word/writer}/math-writer.js +21 -1
- package/dist/browser/modules/word/{writers → writer}/numbering-writer.d.ts +1 -1
- package/dist/{esm/modules/word/writers → browser/modules/word/writer}/numbering-writer.js +11 -4
- package/dist/browser/modules/word/{writers → writer}/paragraph-writer.d.ts +2 -1
- package/dist/browser/modules/word/{writers → writer}/paragraph-writer.js +73 -38
- package/dist/browser/modules/word/{writers → writer}/parts-writer.d.ts +3 -3
- package/dist/{esm/modules/word/writers → browser/modules/word/writer}/parts-writer.js +91 -12
- package/dist/browser/modules/word/writer/reference-scanners.d.ts +42 -0
- package/dist/browser/modules/word/writer/reference-scanners.js +111 -0
- package/dist/browser/modules/word/writer/relationships.d.ts +52 -0
- package/dist/browser/modules/word/writer/relationships.js +117 -0
- package/dist/browser/modules/word/writer/render-context.d.ts +124 -0
- package/dist/browser/modules/word/writer/render-context.js +46 -0
- package/dist/browser/modules/word/{writers → writer}/run-writer.d.ts +10 -1
- package/dist/{esm/modules/word/writers → browser/modules/word/writer}/run-writer.js +126 -24
- package/dist/browser/modules/word/writer/sdt-writer.d.ts +25 -0
- package/dist/browser/modules/word/writer/sdt-writer.js +189 -0
- package/dist/browser/modules/word/writer/stream-buf.d.ts +37 -0
- package/dist/browser/modules/word/writer/stream-buf.js +73 -0
- package/dist/browser/modules/word/writer/streaming-writer.d.ts +344 -0
- package/dist/browser/modules/word/writer/streaming-writer.js +1382 -0
- package/dist/browser/modules/word/writer/string-buf.d.ts +8 -0
- package/dist/browser/modules/word/writer/string-buf.js +7 -0
- package/dist/browser/modules/word/{writers → writer}/styles-writer.js +32 -1
- package/dist/browser/modules/word/{writers → writer}/table-writer.d.ts +2 -1
- package/dist/browser/modules/word/{writers → writer}/table-writer.js +94 -11
- package/dist/browser/modules/xml/types.d.ts +22 -0
- package/dist/browser/utils/crypto.browser.d.ts +3 -1
- package/dist/browser/utils/crypto.browser.js +3 -1
- package/dist/browser/utils/crypto.d.ts +4 -1
- package/dist/browser/utils/crypto.js +4 -1
- package/dist/browser/utils/font-metrics.d.ts +63 -0
- package/dist/browser/utils/font-metrics.js +293 -0
- package/dist/browser/utils/string-buf.d.ts +42 -0
- package/dist/browser/utils/string-buf.js +89 -0
- package/dist/browser/utils/theme-colors.d.ts +55 -0
- package/dist/browser/utils/theme-colors.js +120 -0
- package/dist/cjs/modules/archive/compression/streaming-compress.browser.js +29 -0
- package/dist/cjs/modules/archive/compression/streaming-compress.js +9 -0
- package/dist/cjs/modules/archive/compression/worker-pool/pool.browser.js +26 -1
- package/dist/cjs/modules/archive/fs/archive-file.js +78 -16
- package/dist/cjs/modules/archive/unzip/stream.browser.js +43 -2
- package/dist/cjs/modules/excel/chart/chart-ex-builder.js +7 -2
- package/dist/cjs/modules/excel/chart/chart-ex-renderer.js +4 -9
- package/dist/cjs/modules/excel/chart/chart.js +1 -7
- package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +25 -1
- package/dist/cjs/modules/excel/stream/workbook-reader.js +9 -0
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +228 -13
- package/dist/cjs/modules/excel/utils/string-buf.js +5 -81
- package/dist/cjs/modules/excel/workbook.browser.js +135 -25
- package/dist/cjs/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +32 -8
- package/dist/cjs/modules/excel/xlsx/xlsx.js +9 -1
- package/dist/cjs/modules/pdf/excel-bridge.js +33 -0
- package/dist/cjs/modules/pdf/font/metrics.js +11 -244
- package/dist/cjs/modules/pdf/index.js +2 -1
- package/dist/cjs/modules/pdf/render-layout-to-pdf.js +651 -0
- package/dist/cjs/modules/pdf/word-bridge.js +155 -274
- package/dist/cjs/modules/stream/index.base.js +4 -2
- package/dist/cjs/modules/stream/internal/sink-adapter.js +202 -0
- package/dist/cjs/modules/stream/pull-stream.js +51 -5
- package/dist/cjs/modules/word/advanced/diff.js +170 -0
- package/dist/cjs/modules/word/advanced/drawing-shapes.js +279 -0
- package/dist/cjs/modules/word/advanced/field-engine.js +1229 -0
- package/dist/cjs/modules/word/advanced/glossary.js +87 -0
- package/dist/cjs/modules/word/advanced/math-convert.js +599 -0
- package/dist/cjs/modules/word/advanced/ole-objects.js +277 -0
- package/dist/cjs/modules/word/advanced/style-map.js +329 -0
- package/dist/cjs/modules/word/advanced/validation.js +1068 -0
- package/dist/cjs/modules/word/advanced/vba-project.js +274 -0
- package/dist/cjs/modules/word/bridge/excel-bridge.js +1020 -0
- package/dist/cjs/modules/word/builder/document-handle.js +667 -0
- package/dist/cjs/modules/word/builder/paragraph-builders.js +109 -0
- package/dist/cjs/modules/word/builder/run-builders.js +676 -0
- package/dist/cjs/modules/word/builder/table-builders.js +53 -0
- package/dist/cjs/modules/word/constants.js +111 -2
- package/dist/cjs/modules/word/convert/conversion-ir.js +34 -0
- package/dist/cjs/modules/word/convert/docx-to-semantic.js +502 -0
- package/dist/cjs/modules/word/convert/flat-opc.js +390 -0
- package/dist/cjs/modules/word/convert/html/html-import.js +1910 -0
- package/dist/cjs/modules/word/{html-renderer.js → convert/html/html-renderer.js} +420 -69
- package/dist/cjs/modules/word/convert/html/html.js +20 -0
- package/dist/cjs/modules/word/convert/markdown/markdown-import.js +1329 -0
- package/dist/cjs/modules/word/convert/markdown/markdown-renderer.js +637 -0
- package/dist/cjs/modules/word/convert/markdown/markdown.js +21 -0
- package/dist/cjs/modules/word/convert/odt/odt.js +1936 -0
- package/dist/cjs/modules/word/core/color-utils.js +47 -0
- package/dist/cjs/modules/word/core/internal-utils.js +219 -0
- package/dist/cjs/modules/word/core/mapper.js +430 -0
- package/dist/cjs/modules/word/core/opc-paths.js +53 -0
- package/dist/cjs/modules/word/core/text-utils.js +210 -0
- package/dist/cjs/modules/word/core/walker.js +577 -0
- package/dist/cjs/modules/word/crypto.js +19 -8
- package/dist/cjs/modules/word/document-io.js +117 -197
- package/dist/cjs/modules/word/errors.js +59 -13
- package/dist/cjs/modules/word/excel.js +22 -0
- package/dist/cjs/modules/word/font/font-embed.js +652 -0
- package/dist/cjs/modules/word/{font-obfuscation.js → font/font-obfuscation.js} +4 -9
- package/dist/cjs/modules/word/font/hyphenation.js +4216 -0
- package/dist/cjs/modules/word/font/text-shaping.js +640 -0
- package/dist/cjs/modules/word/html.js +9 -7
- package/dist/cjs/modules/word/incremental-edit.js +366 -0
- package/dist/cjs/modules/word/index.base.js +370 -137
- package/dist/cjs/modules/word/layout/layout-constants.js +20 -0
- package/dist/cjs/modules/word/layout/layout-full.js +1699 -0
- package/dist/cjs/modules/word/layout/layout-model.js +17 -0
- package/dist/cjs/modules/word/layout/layout.js +1170 -0
- package/dist/cjs/modules/word/layout/render-page.js +1243 -0
- package/dist/cjs/modules/word/markdown.js +19 -0
- package/dist/cjs/modules/word/patcher.js +539 -0
- package/dist/cjs/modules/word/query/compat.js +61 -0
- package/dist/cjs/modules/word/query/data-binding.js +395 -0
- package/dist/cjs/modules/word/query/form-fields.js +272 -0
- package/dist/cjs/modules/word/query/format-search.js +334 -0
- package/dist/cjs/modules/word/query/mail-merge.js +114 -0
- package/dist/cjs/modules/word/query/merge.js +620 -0
- package/dist/cjs/modules/word/query/replace.js +304 -0
- package/dist/cjs/modules/word/query/revisions.js +885 -0
- package/dist/cjs/modules/word/query/search.js +361 -0
- package/dist/cjs/modules/word/query/split.js +138 -0
- package/dist/cjs/modules/word/query/style-resolve.js +374 -0
- package/dist/cjs/modules/word/reader/chart-parser.js +814 -0
- package/dist/cjs/modules/word/reader/comments-parser.js +96 -0
- package/dist/cjs/modules/word/reader/doc-props-parsers.js +194 -0
- package/dist/cjs/modules/word/reader/docx-reader.js +2560 -0
- package/dist/cjs/modules/word/reader/drawing-helpers.js +90 -0
- package/dist/cjs/modules/word/reader/form-field-parser.js +85 -0
- package/dist/cjs/modules/word/reader/image-parsers.js +293 -0
- package/dist/cjs/modules/word/reader/math-parser.js +424 -0
- package/dist/cjs/modules/word/reader/metadata-parsers.js +93 -0
- package/dist/cjs/modules/word/reader/numbering-parser.js +168 -0
- package/dist/cjs/modules/word/reader/paragraph-section-parsers.js +505 -0
- package/dist/cjs/modules/word/reader/parse-utils.js +271 -0
- package/dist/cjs/modules/word/reader/properties-parsers.js +338 -0
- package/dist/cjs/modules/word/reader/reader-context.js +66 -0
- package/dist/cjs/modules/word/reader/sdt-helpers.js +114 -0
- package/dist/cjs/modules/word/reader/settings-parser.js +265 -0
- package/dist/cjs/modules/word/reader/styles-parser.js +149 -0
- package/dist/cjs/modules/word/reader/table-properties-parsers.js +237 -0
- package/dist/cjs/modules/word/reader/theme-parser.js +169 -0
- package/dist/cjs/modules/word/reader/watermark-parser.js +113 -0
- package/dist/cjs/modules/word/security/cfb-reader.js +414 -0
- package/dist/cjs/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
- package/dist/cjs/modules/word/security/document-protection.js +208 -0
- package/dist/cjs/modules/word/security/encryption.js +612 -0
- package/dist/cjs/modules/word/security/policy.js +106 -0
- package/dist/cjs/modules/word/template/template-chart.js +170 -0
- package/dist/cjs/modules/word/template/template-datasource.js +549 -0
- package/dist/cjs/modules/word/template/template-engine.js +1430 -0
- package/dist/cjs/modules/word/units.js +44 -14
- package/dist/cjs/modules/word/{writers → writer}/chart-writer.js +163 -22
- package/dist/cjs/modules/word/writer/checkbox-writer.js +82 -0
- package/dist/cjs/modules/word/{writers → writer}/comment-writer.js +8 -6
- package/dist/cjs/modules/word/writer/common-parts.js +104 -0
- package/dist/cjs/modules/word/{content-types.js → writer/content-types.js} +14 -6
- package/dist/cjs/modules/word/writer/document-writer.js +478 -0
- package/dist/cjs/modules/word/writer/docx-packager.js +1551 -0
- package/dist/cjs/modules/word/{writers → writer}/footnote-writer.js +13 -10
- package/dist/cjs/modules/word/{writers → writer}/header-footer-writer.js +38 -20
- package/dist/cjs/modules/word/{writers → writer}/image-writer.js +11 -7
- package/dist/cjs/modules/word/{writers → writer}/math-writer.js +21 -1
- package/dist/cjs/modules/word/{writers → writer}/numbering-writer.js +11 -4
- package/dist/cjs/modules/word/{writers → writer}/paragraph-writer.js +72 -37
- package/dist/cjs/modules/word/{writers → writer}/parts-writer.js +91 -12
- package/dist/cjs/modules/word/writer/reference-scanners.js +120 -0
- package/dist/cjs/modules/word/writer/relationships.js +124 -0
- package/dist/cjs/modules/word/writer/render-context.js +51 -0
- package/dist/cjs/modules/word/{writers → writer}/run-writer.js +127 -24
- package/dist/cjs/modules/word/writer/sdt-writer.js +192 -0
- package/dist/cjs/modules/word/writer/stream-buf.js +76 -0
- package/dist/cjs/modules/word/writer/streaming-writer.js +1387 -0
- package/dist/cjs/modules/word/writer/string-buf.js +11 -0
- package/dist/cjs/modules/word/{writers → writer}/styles-writer.js +32 -1
- package/dist/cjs/modules/word/{writers → writer}/table-writer.js +94 -11
- package/dist/cjs/utils/crypto.browser.js +3 -1
- package/dist/cjs/utils/crypto.js +4 -1
- package/dist/cjs/utils/font-metrics.js +303 -0
- package/dist/cjs/utils/string-buf.js +92 -0
- package/dist/cjs/utils/theme-colors.js +126 -0
- package/dist/esm/modules/archive/compression/streaming-compress.browser.js +29 -0
- package/dist/esm/modules/archive/compression/streaming-compress.js +9 -0
- package/dist/esm/modules/archive/compression/worker-pool/pool.browser.js +26 -1
- package/dist/esm/modules/archive/fs/archive-file.js +78 -16
- package/dist/esm/modules/archive/unzip/stream.browser.js +43 -2
- package/dist/esm/modules/excel/chart/chart-ex-builder.js +7 -2
- package/dist/esm/modules/excel/chart/chart-ex-renderer.js +4 -9
- package/dist/esm/modules/excel/chart/chart.js +1 -7
- package/dist/esm/modules/excel/stream/workbook-reader.browser.js +25 -1
- package/dist/esm/modules/excel/stream/workbook-reader.js +9 -0
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +228 -13
- package/dist/esm/modules/excel/utils/string-buf.js +4 -81
- package/dist/esm/modules/excel/workbook.browser.js +135 -25
- package/dist/esm/modules/excel/xlsx/xform/chart/chart-space-xform.js +6 -20
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +32 -8
- package/dist/esm/modules/excel/xlsx/xlsx.js +9 -1
- package/dist/esm/modules/pdf/excel-bridge.js +32 -0
- package/dist/esm/modules/pdf/font/metrics.js +3 -237
- package/dist/esm/modules/pdf/index.js +1 -1
- package/dist/esm/modules/pdf/render-layout-to-pdf.js +647 -0
- package/dist/esm/modules/pdf/word-bridge.js +122 -274
- package/dist/esm/modules/stream/index.base.js +2 -1
- package/dist/esm/modules/stream/internal/sink-adapter.js +198 -0
- package/dist/esm/modules/stream/pull-stream.js +51 -5
- package/dist/esm/modules/word/advanced/diff.js +167 -0
- package/dist/esm/modules/word/advanced/drawing-shapes.js +268 -0
- package/dist/esm/modules/word/advanced/field-engine.js +1225 -0
- package/dist/esm/modules/word/advanced/glossary.js +79 -0
- package/dist/esm/modules/word/advanced/math-convert.js +595 -0
- package/dist/esm/modules/word/advanced/ole-objects.js +271 -0
- package/dist/esm/modules/word/advanced/style-map.js +322 -0
- package/dist/esm/modules/word/advanced/validation.js +1065 -0
- package/dist/esm/modules/word/advanced/vba-project.js +265 -0
- package/dist/esm/modules/word/bridge/excel-bridge.js +980 -0
- package/dist/esm/modules/word/builder/document-handle.js +664 -0
- package/dist/esm/modules/word/builder/paragraph-builders.js +90 -0
- package/dist/esm/modules/word/builder/run-builders.js +600 -0
- package/dist/esm/modules/word/builder/table-builders.js +45 -0
- package/dist/esm/modules/word/constants.js +109 -1
- package/dist/esm/modules/word/convert/conversion-ir.js +31 -0
- package/dist/esm/modules/word/convert/docx-to-semantic.js +499 -0
- package/dist/esm/modules/word/convert/flat-opc.js +385 -0
- package/dist/esm/modules/word/convert/html/html-import.js +1907 -0
- package/dist/{browser/modules/word → esm/modules/word/convert/html}/html-renderer.js +420 -69
- package/dist/esm/modules/word/convert/html/html.js +15 -0
- package/dist/esm/modules/word/convert/markdown/markdown-import.js +1325 -0
- package/dist/esm/modules/word/convert/markdown/markdown-renderer.js +634 -0
- package/dist/esm/modules/word/convert/markdown/markdown.js +15 -0
- package/dist/esm/modules/word/convert/odt/odt.js +1932 -0
- package/dist/esm/modules/word/core/color-utils.js +43 -0
- package/dist/esm/modules/word/core/internal-utils.js +209 -0
- package/dist/esm/modules/word/core/mapper.js +427 -0
- package/dist/esm/modules/word/core/opc-paths.js +48 -0
- package/dist/esm/modules/word/core/text-utils.js +202 -0
- package/dist/esm/modules/word/core/walker.js +570 -0
- package/dist/esm/modules/word/crypto.js +13 -7
- package/dist/esm/modules/word/document-io.js +80 -197
- package/dist/esm/modules/word/errors.js +54 -2
- package/dist/esm/modules/word/excel.js +13 -0
- package/dist/esm/modules/word/font/font-embed.js +646 -0
- package/dist/{browser/modules/word → esm/modules/word/font}/font-obfuscation.js +4 -9
- package/dist/esm/modules/word/font/hyphenation.js +4210 -0
- package/dist/esm/modules/word/font/text-shaping.js +635 -0
- package/dist/esm/modules/word/html.js +6 -5
- package/dist/esm/modules/word/incremental-edit.js +361 -0
- package/dist/esm/modules/word/index.base.js +138 -29
- package/dist/esm/modules/word/layout/layout-constants.js +17 -0
- package/dist/esm/modules/word/layout/layout-full.js +1696 -0
- package/dist/esm/modules/word/layout/layout-model.js +16 -0
- package/dist/esm/modules/word/layout/layout.js +1167 -0
- package/dist/esm/modules/word/layout/render-page.js +1238 -0
- package/dist/esm/modules/word/markdown.js +13 -0
- package/dist/esm/modules/word/patcher.js +537 -0
- package/dist/esm/modules/word/query/compat.js +58 -0
- package/dist/esm/modules/word/query/data-binding.js +392 -0
- package/dist/esm/modules/word/query/form-fields.js +268 -0
- package/dist/esm/modules/word/query/format-search.js +329 -0
- package/dist/esm/modules/word/query/mail-merge.js +111 -0
- package/dist/esm/modules/word/query/merge.js +617 -0
- package/dist/esm/modules/word/query/replace.js +301 -0
- package/dist/esm/modules/word/query/revisions.js +879 -0
- package/dist/esm/modules/word/query/search.js +346 -0
- package/dist/esm/modules/word/query/split.js +135 -0
- package/dist/esm/modules/word/query/style-resolve.js +368 -0
- package/dist/esm/modules/word/reader/chart-parser.js +810 -0
- package/dist/esm/modules/word/reader/comments-parser.js +92 -0
- package/dist/esm/modules/word/reader/doc-props-parsers.js +190 -0
- package/dist/esm/modules/word/reader/docx-reader.js +2557 -0
- package/dist/esm/modules/word/reader/drawing-helpers.js +84 -0
- package/dist/esm/modules/word/reader/form-field-parser.js +82 -0
- package/dist/esm/modules/word/reader/image-parsers.js +291 -0
- package/dist/esm/modules/word/reader/math-parser.js +422 -0
- package/dist/esm/modules/word/reader/metadata-parsers.js +87 -0
- package/dist/esm/modules/word/reader/numbering-parser.js +166 -0
- package/dist/esm/modules/word/reader/paragraph-section-parsers.js +503 -0
- package/dist/esm/modules/word/reader/parse-utils.js +249 -0
- package/dist/esm/modules/word/reader/properties-parsers.js +332 -0
- package/dist/esm/modules/word/reader/reader-context.js +61 -0
- package/dist/esm/modules/word/reader/sdt-helpers.js +111 -0
- package/dist/esm/modules/word/reader/settings-parser.js +263 -0
- package/dist/esm/modules/word/reader/styles-parser.js +147 -0
- package/dist/esm/modules/word/reader/table-properties-parsers.js +234 -0
- package/dist/esm/modules/word/reader/theme-parser.js +167 -0
- package/dist/esm/modules/word/reader/watermark-parser.js +110 -0
- package/dist/esm/modules/word/security/cfb-reader.js +410 -0
- package/dist/esm/modules/word/{digital-signatures.js → security/digital-signatures.js} +34 -34
- package/dist/esm/modules/word/security/document-protection.js +201 -0
- package/dist/esm/modules/word/security/encryption.js +602 -0
- package/dist/esm/modules/word/security/policy.js +102 -0
- package/dist/esm/modules/word/template/template-chart.js +167 -0
- package/dist/esm/modules/word/template/template-datasource.js +541 -0
- package/dist/esm/modules/word/template/template-engine.js +1435 -0
- package/dist/esm/modules/word/units.js +43 -14
- package/dist/esm/modules/word/{writers → writer}/chart-writer.js +164 -23
- package/dist/esm/modules/word/writer/checkbox-writer.js +79 -0
- package/dist/esm/modules/word/{writers → writer}/comment-writer.js +8 -6
- package/dist/esm/modules/word/writer/common-parts.js +101 -0
- package/dist/{browser/modules/word → esm/modules/word/writer}/content-types.js +14 -6
- package/dist/esm/modules/word/writer/document-writer.js +473 -0
- package/dist/esm/modules/word/writer/docx-packager.js +1515 -0
- package/dist/{browser/modules/word/writers → esm/modules/word/writer}/footnote-writer.js +13 -10
- package/dist/{browser/modules/word/writers → esm/modules/word/writer}/header-footer-writer.js +39 -21
- package/dist/esm/modules/word/{writers → writer}/image-writer.js +11 -7
- package/dist/{browser/modules/word/writers → esm/modules/word/writer}/math-writer.js +21 -1
- package/dist/{browser/modules/word/writers → esm/modules/word/writer}/numbering-writer.js +11 -4
- package/dist/esm/modules/word/{writers → writer}/paragraph-writer.js +73 -38
- package/dist/{browser/modules/word/writers → esm/modules/word/writer}/parts-writer.js +91 -12
- package/dist/esm/modules/word/writer/reference-scanners.js +111 -0
- package/dist/esm/modules/word/writer/relationships.js +117 -0
- package/dist/esm/modules/word/writer/render-context.js +46 -0
- package/dist/{browser/modules/word/writers → esm/modules/word/writer}/run-writer.js +126 -24
- package/dist/esm/modules/word/writer/sdt-writer.js +189 -0
- package/dist/esm/modules/word/writer/stream-buf.js +73 -0
- package/dist/esm/modules/word/writer/streaming-writer.js +1382 -0
- package/dist/esm/modules/word/writer/string-buf.js +7 -0
- package/dist/esm/modules/word/{writers → writer}/styles-writer.js +32 -1
- package/dist/esm/modules/word/{writers → writer}/table-writer.js +94 -11
- package/dist/esm/utils/crypto.browser.js +3 -1
- package/dist/esm/utils/crypto.js +4 -1
- package/dist/esm/utils/font-metrics.js +293 -0
- package/dist/esm/utils/string-buf.js +89 -0
- package/dist/esm/utils/theme-colors.js +120 -0
- package/dist/iife/excelts.iife.js +70692 -70337
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +57 -57
- package/dist/types/modules/archive/fs/archive-file.d.ts +8 -5
- package/dist/types/modules/excel/chart/chart-ex-types.d.ts +0 -12
- package/dist/types/modules/excel/chart/chart.d.ts +1 -5
- package/dist/types/modules/excel/chart/types.d.ts +0 -6
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +40 -0
- package/dist/types/modules/excel/utils/string-buf.d.ts +5 -26
- package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +19 -9
- package/dist/types/modules/excel/xlsx/xlsx.d.ts +10 -2
- package/dist/types/modules/pdf/excel-bridge.d.ts +30 -1
- package/dist/types/modules/pdf/font/metrics.d.ts +3 -52
- package/dist/types/modules/pdf/index.d.ts +1 -1
- package/dist/types/modules/pdf/render-layout-to-pdf.d.ts +66 -0
- package/dist/types/modules/pdf/word-bridge.d.ts +80 -12
- package/dist/types/modules/stream/index.base.d.ts +2 -0
- package/dist/types/modules/stream/internal/sink-adapter.d.ts +65 -0
- package/dist/types/modules/stream/pull-stream.d.ts +19 -2
- package/dist/types/modules/stream/types.d.ts +13 -1
- package/dist/types/modules/word/advanced/diff.d.ts +61 -0
- package/dist/types/modules/word/advanced/drawing-shapes.d.ts +269 -0
- package/dist/types/modules/word/advanced/field-engine.d.ts +43 -0
- package/dist/types/modules/word/advanced/glossary.d.ts +86 -0
- package/dist/types/modules/word/advanced/math-convert.d.ts +30 -0
- package/dist/types/modules/word/advanced/ole-objects.d.ts +115 -0
- package/dist/types/modules/word/advanced/style-map.d.ts +105 -0
- package/dist/types/modules/word/advanced/validation.d.ts +56 -0
- package/dist/types/modules/word/advanced/vba-project.d.ts +91 -0
- package/dist/types/modules/word/bridge/excel-bridge.d.ts +127 -0
- package/dist/types/modules/word/builder/document-handle.d.ts +151 -0
- package/dist/types/modules/word/builder/paragraph-builders.d.ts +61 -0
- package/dist/types/modules/word/builder/run-builders.d.ts +374 -0
- package/dist/types/modules/word/builder/table-builders.d.ts +23 -0
- package/dist/types/modules/word/constants.d.ts +39 -1
- package/dist/types/modules/word/convert/conversion-ir.d.ts +210 -0
- package/dist/types/modules/word/convert/docx-to-semantic.d.ts +39 -0
- package/dist/types/modules/word/convert/flat-opc.d.ts +44 -0
- package/dist/types/modules/word/convert/html/html-import.d.ts +50 -0
- package/dist/{browser/modules/word → types/modules/word/convert/html}/html-renderer.d.ts +14 -1
- package/dist/types/modules/word/convert/html/html.d.ts +15 -0
- package/dist/types/modules/word/convert/markdown/markdown-import.d.ts +68 -0
- package/dist/types/modules/word/convert/markdown/markdown-renderer.d.ts +25 -0
- package/dist/types/modules/word/convert/markdown/markdown.d.ts +15 -0
- package/dist/types/modules/word/convert/odt/odt.d.ts +41 -0
- package/dist/types/modules/word/{color-utils.d.ts → core/color-utils.d.ts} +8 -1
- package/dist/types/modules/word/core/internal-utils.d.ts +90 -0
- package/dist/types/modules/word/core/mapper.d.ts +44 -0
- package/dist/types/modules/word/core/opc-paths.d.ts +33 -0
- package/dist/types/modules/word/core/text-utils.d.ts +38 -0
- package/dist/types/modules/word/core/walker.d.ts +119 -0
- package/dist/types/modules/word/crypto.d.ts +14 -9
- package/dist/types/modules/word/document-io.d.ts +59 -27
- package/dist/types/modules/word/errors.d.ts +44 -1
- package/dist/types/modules/word/excel.d.ts +14 -0
- package/dist/types/modules/word/font/font-embed.d.ts +112 -0
- package/dist/types/modules/word/font/hyphenation.d.ts +65 -0
- package/dist/types/modules/word/font/text-shaping.d.ts +58 -0
- package/dist/types/modules/word/html.d.ts +7 -6
- package/dist/types/modules/word/incremental-edit.d.ts +123 -0
- package/dist/types/modules/word/index.base.d.ts +194 -10
- package/dist/types/modules/word/layout/layout-constants.d.ts +17 -0
- package/dist/types/modules/word/layout/layout-full.d.ts +53 -0
- package/dist/types/modules/word/layout/layout-model.d.ts +344 -0
- package/dist/types/modules/word/layout/layout.d.ts +63 -0
- package/dist/types/modules/word/layout/render-page.d.ts +57 -0
- package/dist/types/modules/word/markdown.d.ts +14 -0
- package/dist/types/modules/word/patcher.d.ts +62 -0
- package/dist/types/modules/word/query/compat.d.ts +25 -0
- package/dist/types/modules/word/query/data-binding.d.ts +22 -0
- package/dist/types/modules/word/query/form-fields.d.ts +41 -0
- package/dist/types/modules/word/query/format-search.d.ts +99 -0
- package/dist/types/modules/word/query/mail-merge.d.ts +25 -0
- package/dist/types/modules/word/query/merge.d.ts +50 -0
- package/dist/types/modules/word/query/replace.d.ts +47 -0
- package/dist/types/modules/word/query/revisions.d.ts +67 -0
- package/dist/types/modules/word/query/search.d.ts +129 -0
- package/dist/types/modules/word/query/split.d.ts +44 -0
- package/dist/types/modules/word/query/style-resolve.d.ts +104 -0
- package/dist/types/modules/word/reader/chart-parser.d.ts +20 -0
- package/dist/types/modules/word/reader/comments-parser.d.ts +26 -0
- package/dist/types/modules/word/reader/doc-props-parsers.d.ts +15 -0
- package/dist/types/modules/word/reader/docx-reader.d.ts +27 -0
- package/dist/types/modules/word/reader/drawing-helpers.d.ts +27 -0
- package/dist/types/modules/word/reader/form-field-parser.d.ts +21 -0
- package/dist/types/modules/word/reader/image-parsers.d.ts +11 -0
- package/dist/types/modules/word/reader/math-parser.d.ts +12 -0
- package/dist/types/modules/word/reader/metadata-parsers.d.ts +17 -0
- package/dist/types/modules/word/reader/numbering-parser.d.ts +13 -0
- package/dist/types/modules/word/reader/paragraph-section-parsers.d.ts +12 -0
- package/dist/types/modules/word/reader/parse-utils.d.ts +91 -0
- package/dist/types/modules/word/reader/properties-parsers.d.ts +21 -0
- package/dist/types/modules/word/reader/reader-context.d.ts +69 -0
- package/dist/types/modules/word/reader/sdt-helpers.d.ts +29 -0
- package/dist/types/modules/word/reader/settings-parser.d.ts +8 -0
- package/dist/types/modules/word/reader/styles-parser.d.ts +12 -0
- package/dist/types/modules/word/reader/table-properties-parsers.d.ts +12 -0
- package/dist/types/modules/word/reader/theme-parser.d.ts +8 -0
- package/dist/types/modules/word/reader/watermark-parser.d.ts +15 -0
- package/dist/types/modules/word/security/cfb-reader.d.ts +37 -0
- package/dist/types/modules/word/{digital-signatures.d.ts → security/digital-signatures.d.ts} +19 -11
- package/dist/types/modules/word/security/document-protection.d.ts +93 -0
- package/dist/{browser/modules/word → types/modules/word/security}/encryption.d.ts +51 -4
- package/dist/types/modules/word/security/policy.d.ts +80 -0
- package/dist/types/modules/word/template/template-chart.d.ts +56 -0
- package/dist/types/modules/word/template/template-datasource.d.ts +154 -0
- package/dist/types/modules/word/template/template-engine.d.ts +121 -0
- package/dist/types/modules/word/types.d.ts +224 -25
- package/dist/types/modules/word/units.d.ts +26 -0
- package/dist/types/modules/word/writer/checkbox-writer.d.ts +17 -0
- package/dist/{browser/modules/word/writers → types/modules/word/writer}/comment-writer.d.ts +2 -1
- package/dist/types/modules/word/writer/common-parts.d.ts +57 -0
- package/dist/{browser/modules/word → types/modules/word/writer}/content-types.d.ts +2 -2
- package/dist/types/modules/word/writer/document-writer.d.ts +24 -0
- package/dist/types/modules/word/writer/docx-packager.d.ts +35 -0
- package/dist/{browser/modules/word/writers → types/modules/word/writer}/footnote-writer.d.ts +3 -2
- package/dist/{browser/modules/word/writers → types/modules/word/writer}/header-footer-writer.d.ts +3 -2
- package/dist/{browser/modules/word/writers → types/modules/word/writer}/image-writer.d.ts +1 -1
- package/dist/types/modules/word/writer/math-writer.d.ts +20 -0
- package/dist/types/modules/word/{writers → writer}/numbering-writer.d.ts +1 -1
- package/dist/types/modules/word/{writers → writer}/paragraph-writer.d.ts +2 -1
- package/dist/types/modules/word/{writers → writer}/parts-writer.d.ts +3 -3
- package/dist/types/modules/word/writer/reference-scanners.d.ts +42 -0
- package/dist/types/modules/word/writer/relationships.d.ts +52 -0
- package/dist/types/modules/word/writer/render-context.d.ts +124 -0
- package/dist/types/modules/word/{writers → writer}/run-writer.d.ts +10 -1
- package/dist/types/modules/word/writer/sdt-writer.d.ts +25 -0
- package/dist/types/modules/word/writer/stream-buf.d.ts +37 -0
- package/dist/types/modules/word/writer/streaming-writer.d.ts +344 -0
- package/dist/types/modules/word/writer/string-buf.d.ts +8 -0
- package/dist/types/modules/word/{writers → writer}/table-writer.d.ts +2 -1
- package/dist/types/modules/xml/types.d.ts +22 -0
- package/dist/types/utils/crypto.browser.d.ts +3 -1
- package/dist/types/utils/crypto.d.ts +4 -1
- package/dist/types/utils/font-metrics.d.ts +63 -0
- package/dist/types/utils/string-buf.d.ts +42 -0
- package/dist/types/utils/theme-colors.d.ts +55 -0
- package/package.json +121 -39
- package/dist/browser/modules/word/color-utils.js +0 -94
- package/dist/browser/modules/word/document.d.ts +0 -657
- package/dist/browser/modules/word/document.js +0 -1533
- package/dist/browser/modules/word/docx-packager.d.ts +0 -14
- package/dist/browser/modules/word/docx-packager.js +0 -822
- package/dist/browser/modules/word/docx-reader.d.ts +0 -11
- package/dist/browser/modules/word/docx-reader.js +0 -4929
- package/dist/browser/modules/word/encryption.js +0 -274
- package/dist/browser/modules/word/internal-utils.d.ts +0 -23
- package/dist/browser/modules/word/internal-utils.js +0 -54
- package/dist/browser/modules/word/namespaces.d.ts +0 -159
- package/dist/browser/modules/word/namespaces.js +0 -189
- package/dist/browser/modules/word/relationships.d.ts +0 -30
- package/dist/browser/modules/word/relationships.js +0 -48
- package/dist/browser/modules/word/writers/checkbox-writer.d.ts +0 -9
- package/dist/browser/modules/word/writers/checkbox-writer.js +0 -42
- package/dist/browser/modules/word/writers/document-writer.d.ts +0 -16
- package/dist/browser/modules/word/writers/document-writer.js +0 -461
- package/dist/browser/modules/word/writers/math-writer.d.ts +0 -9
- package/dist/cjs/modules/word/color-utils.js +0 -97
- package/dist/cjs/modules/word/document.js +0 -1645
- package/dist/cjs/modules/word/docx-packager.js +0 -825
- package/dist/cjs/modules/word/docx-reader.js +0 -4932
- package/dist/cjs/modules/word/encryption.js +0 -282
- package/dist/cjs/modules/word/internal-utils.js +0 -59
- package/dist/cjs/modules/word/namespaces.js +0 -192
- package/dist/cjs/modules/word/relationships.js +0 -55
- package/dist/cjs/modules/word/writers/checkbox-writer.js +0 -45
- package/dist/cjs/modules/word/writers/document-writer.js +0 -465
- package/dist/esm/modules/word/color-utils.js +0 -94
- package/dist/esm/modules/word/document.js +0 -1533
- package/dist/esm/modules/word/docx-packager.js +0 -822
- package/dist/esm/modules/word/docx-reader.js +0 -4929
- package/dist/esm/modules/word/encryption.js +0 -274
- package/dist/esm/modules/word/internal-utils.js +0 -54
- package/dist/esm/modules/word/namespaces.js +0 -189
- package/dist/esm/modules/word/relationships.js +0 -48
- package/dist/esm/modules/word/writers/checkbox-writer.js +0 -42
- package/dist/esm/modules/word/writers/document-writer.js +0 -461
- package/dist/types/modules/word/document.d.ts +0 -657
- package/dist/types/modules/word/docx-packager.d.ts +0 -14
- package/dist/types/modules/word/docx-reader.d.ts +0 -11
- package/dist/types/modules/word/internal-utils.d.ts +0 -23
- package/dist/types/modules/word/namespaces.d.ts +0 -159
- package/dist/types/modules/word/relationships.d.ts +0 -30
- package/dist/types/modules/word/writers/checkbox-writer.d.ts +0 -9
- package/dist/types/modules/word/writers/document-writer.d.ts +0 -16
- package/dist/types/modules/word/writers/math-writer.d.ts +0 -9
- /package/dist/browser/modules/word/{font-obfuscation.d.ts → font/font-obfuscation.d.ts} +0 -0
- /package/dist/browser/modules/word/{writers → writer}/chart-writer.d.ts +0 -0
- /package/dist/browser/modules/word/{writers → writer}/section-writer.d.ts +0 -0
- /package/dist/browser/modules/word/{writers → writer}/section-writer.js +0 -0
- /package/dist/browser/modules/word/{writers → writer}/styles-writer.d.ts +0 -0
- /package/dist/browser/modules/word/{writers → writer}/textbox-writer.d.ts +0 -0
- /package/dist/browser/modules/word/{writers → writer}/textbox-writer.js +0 -0
- /package/dist/browser/modules/word/{writers → writer}/toc-writer.d.ts +0 -0
- /package/dist/browser/modules/word/{writers → writer}/toc-writer.js +0 -0
- /package/dist/cjs/modules/word/{writers → writer}/section-writer.js +0 -0
- /package/dist/cjs/modules/word/{writers → writer}/textbox-writer.js +0 -0
- /package/dist/cjs/modules/word/{writers → writer}/toc-writer.js +0 -0
- /package/dist/esm/modules/word/{writers → writer}/section-writer.js +0 -0
- /package/dist/esm/modules/word/{writers → writer}/textbox-writer.js +0 -0
- /package/dist/esm/modules/word/{writers → writer}/toc-writer.js +0 -0
- /package/dist/types/modules/word/{font-obfuscation.d.ts → font/font-obfuscation.d.ts} +0 -0
- /package/dist/types/modules/word/{writers → writer}/chart-writer.d.ts +0 -0
- /package/dist/types/modules/word/{writers → writer}/section-writer.d.ts +0 -0
- /package/dist/types/modules/word/{writers → writer}/styles-writer.d.ts +0 -0
- /package/dist/types/modules/word/{writers → writer}/textbox-writer.d.ts +0 -0
- /package/dist/types/modules/word/{writers → writer}/toc-writer.d.ts +0 -0
|
@@ -0,0 +1,1225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Word Document Field Calculation Engine
|
|
3
|
+
*
|
|
4
|
+
* Computes and updates field cachedValues based on layout (pagination) results.
|
|
5
|
+
* Supports PAGE, NUMPAGES, SECTIONPAGES, SECTION, TOC, REF, PAGEREF, SEQ, IF, STYLEREF,
|
|
6
|
+
* INDEX, = (formula), INCLUDETEXT.
|
|
7
|
+
*
|
|
8
|
+
* The engine performs a layout pass via layoutDocument, then traverses the document
|
|
9
|
+
* body to update each field's cachedValue in an immutable-style manner (deep-cloning
|
|
10
|
+
* modified portions of the tree).
|
|
11
|
+
*/
|
|
12
|
+
import { extractParagraphText, isRun } from "../core/text-utils.js";
|
|
13
|
+
import { walkBlocks } from "../core/walker.js";
|
|
14
|
+
import { layoutDocument } from "../layout/layout.js";
|
|
15
|
+
// =============================================================================
|
|
16
|
+
// Public API
|
|
17
|
+
// =============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* 更新文档中所有字段的 cachedValue。
|
|
20
|
+
*
|
|
21
|
+
* 执行分页布局,然后遍历所有字段更新其缓存值。
|
|
22
|
+
* 对于 TOC 字段,会生成完整的目录段落。
|
|
23
|
+
*
|
|
24
|
+
* @param doc - 文档模型(不会被修改,返回新对象)
|
|
25
|
+
* @param options - 更新选项
|
|
26
|
+
* @returns 更新后的文档模型
|
|
27
|
+
*/
|
|
28
|
+
export function updateFields(doc, options) {
|
|
29
|
+
const opts = {
|
|
30
|
+
layoutOptions: options?.layoutOptions,
|
|
31
|
+
updateToc: options?.updateToc ?? true,
|
|
32
|
+
updatePageFields: options?.updatePageFields ?? true,
|
|
33
|
+
updateReferences: options?.updateReferences ?? true,
|
|
34
|
+
updateSequences: options?.updateSequences ?? true
|
|
35
|
+
};
|
|
36
|
+
// Perform layout pass
|
|
37
|
+
const layout = layoutDocument(doc, opts.layoutOptions);
|
|
38
|
+
// Build bookmark info map
|
|
39
|
+
const bookmarkInfo = opts.updateReferences ? collectBookmarkInfo(doc, layout) : new Map();
|
|
40
|
+
// Build SEQ counters
|
|
41
|
+
const seqValues = opts.updateSequences ? computeSeqValues(doc) : new Map();
|
|
42
|
+
// Build style → paragraphs index for STYLEREF
|
|
43
|
+
const styleIndex = buildStyleIndex(doc);
|
|
44
|
+
// Collect INDEX entries (XE fields) from all body content
|
|
45
|
+
const indexEntries = collectIndexEntries(doc);
|
|
46
|
+
// Update body content
|
|
47
|
+
const newBody = updateBody(doc, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, opts);
|
|
48
|
+
// If TOC was updated, register the TOC1..TOCn paragraph styles so the
|
|
49
|
+
// cached TOC entries don't reference undefined styles. Only do this when
|
|
50
|
+
// the document actually contains a <toc> — otherwise we'd mutate doc
|
|
51
|
+
// shape for no reason and break === comparisons in callers.
|
|
52
|
+
let nextDoc = doc;
|
|
53
|
+
if (newBody !== doc.body) {
|
|
54
|
+
nextDoc = { ...doc, body: newBody };
|
|
55
|
+
}
|
|
56
|
+
if (opts.updateToc && doc.body.some(item => item.type === "tableOfContents")) {
|
|
57
|
+
const headings = collectHeadings(doc, layout);
|
|
58
|
+
nextDoc = ensureTocStyles(nextDoc, headings);
|
|
59
|
+
}
|
|
60
|
+
return nextDoc;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 仅更新 TOC(目录)字段。
|
|
64
|
+
* 扫描文档中的标题(Heading1-9 样式或 outline level),
|
|
65
|
+
* 生成目录缓存段落。
|
|
66
|
+
*/
|
|
67
|
+
export function updateTableOfContents(doc, options) {
|
|
68
|
+
// Skip the entire pipeline (including TOC style registration) when the
|
|
69
|
+
// document has no <toc> block at all — callers rely on `updateTableOfContents`
|
|
70
|
+
// returning the same reference in that case so they can detect "nothing
|
|
71
|
+
// changed" with a `===` check.
|
|
72
|
+
const hasToc = doc.body.some(item => item.type === "tableOfContents");
|
|
73
|
+
if (!hasToc) {
|
|
74
|
+
return doc;
|
|
75
|
+
}
|
|
76
|
+
const layout = layoutDocument(doc, options?.layoutOptions);
|
|
77
|
+
const headings = collectHeadings(doc, layout);
|
|
78
|
+
const newBody = doc.body.map(item => {
|
|
79
|
+
if (item.type === "tableOfContents") {
|
|
80
|
+
return updateTocContent(item, headings);
|
|
81
|
+
}
|
|
82
|
+
return item;
|
|
83
|
+
});
|
|
84
|
+
const changed = newBody.some((item, i) => item !== doc.body[i]);
|
|
85
|
+
const stage1 = changed ? { ...doc, body: newBody } : doc;
|
|
86
|
+
return ensureTocStyles(stage1, headings);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Register TOC1..TOCn paragraph styles for every heading level present in
|
|
90
|
+
* the document. The cached TOC paragraphs reference these styles by id, so
|
|
91
|
+
* if they aren't defined Word logs a "missing referenced style" warning on
|
|
92
|
+
* every TOC entry.
|
|
93
|
+
*/
|
|
94
|
+
function ensureTocStyles(doc, headings) {
|
|
95
|
+
if (headings.length === 0) {
|
|
96
|
+
return doc;
|
|
97
|
+
}
|
|
98
|
+
const usedTocLevels = new Set();
|
|
99
|
+
for (const h of headings) {
|
|
100
|
+
usedTocLevels.add(Math.max(1, Math.min(9, h.level)));
|
|
101
|
+
}
|
|
102
|
+
const existingStyles = doc.styles ?? [];
|
|
103
|
+
const definedIds = new Set(existingStyles.map(s => s.styleId));
|
|
104
|
+
const stylesToAdd = [];
|
|
105
|
+
for (const lvl of usedTocLevels) {
|
|
106
|
+
const id = `TOC${lvl}`;
|
|
107
|
+
if (definedIds.has(id)) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
stylesToAdd.push({
|
|
111
|
+
type: "paragraph",
|
|
112
|
+
styleId: id,
|
|
113
|
+
name: `toc ${lvl}`,
|
|
114
|
+
basedOn: "Normal",
|
|
115
|
+
next: "Normal",
|
|
116
|
+
uiPriority: 39,
|
|
117
|
+
unhideWhenUsed: true,
|
|
118
|
+
paragraphProperties: {
|
|
119
|
+
spacing: { after: 100 },
|
|
120
|
+
indent: { left: (lvl - 1) * 220 }
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (stylesToAdd.length === 0) {
|
|
125
|
+
return doc;
|
|
126
|
+
}
|
|
127
|
+
return { ...doc, styles: [...existingStyles, ...stylesToAdd] };
|
|
128
|
+
}
|
|
129
|
+
// =============================================================================
|
|
130
|
+
// Field Instruction Parsing
|
|
131
|
+
// =============================================================================
|
|
132
|
+
/** Parse a field instruction string to get the field type and arguments. */
|
|
133
|
+
function parseFieldInstruction(instruction) {
|
|
134
|
+
const trimmed = instruction.trim();
|
|
135
|
+
// Special case: formula fields start with "=" (may or may not have space after)
|
|
136
|
+
if (trimmed.startsWith("=")) {
|
|
137
|
+
return { type: "=", args: trimmed.slice(1).trim() };
|
|
138
|
+
}
|
|
139
|
+
const spaceIdx = trimmed.indexOf(" ");
|
|
140
|
+
if (spaceIdx === -1) {
|
|
141
|
+
return { type: trimmed.toUpperCase(), args: "" };
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
type: trimmed.slice(0, spaceIdx).toUpperCase(),
|
|
145
|
+
args: trimmed.slice(spaceIdx + 1).trim()
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/** Parse TOC instruction to extract outline level range. */
|
|
149
|
+
function parseTocLevels(args) {
|
|
150
|
+
// Match \o "1-3" pattern
|
|
151
|
+
const match = /\\o\s*"(\d+)-(\d+)"/.exec(args);
|
|
152
|
+
if (match) {
|
|
153
|
+
return { min: parseInt(match[1], 10), max: parseInt(match[2], 10) };
|
|
154
|
+
}
|
|
155
|
+
// Default: all heading levels 1-9
|
|
156
|
+
return { min: 1, max: 9 };
|
|
157
|
+
}
|
|
158
|
+
/** Parse SEQ switches: \h (hidden), \r N (reset to N), \c (repeat). */
|
|
159
|
+
function parseSeqSwitches(args) {
|
|
160
|
+
let identifier = "";
|
|
161
|
+
let hidden = false;
|
|
162
|
+
let resetTo = null;
|
|
163
|
+
let repeat = false;
|
|
164
|
+
// Extract identifier (first word before any switches)
|
|
165
|
+
const parts = args.split(/\s+/);
|
|
166
|
+
if (parts.length > 0 && !parts[0].startsWith("\\")) {
|
|
167
|
+
identifier = parts[0];
|
|
168
|
+
}
|
|
169
|
+
if (/\\h\b/i.test(args)) {
|
|
170
|
+
hidden = true;
|
|
171
|
+
}
|
|
172
|
+
if (/\\c\b/i.test(args)) {
|
|
173
|
+
repeat = true;
|
|
174
|
+
}
|
|
175
|
+
const resetMatch = /\\r\s+(\d+)/i.exec(args);
|
|
176
|
+
if (resetMatch) {
|
|
177
|
+
resetTo = parseInt(resetMatch[1], 10);
|
|
178
|
+
}
|
|
179
|
+
return { identifier, hidden, resetTo, repeat };
|
|
180
|
+
}
|
|
181
|
+
/** Parse IF field: IF expr1 op expr2 "trueText" "falseText" */
|
|
182
|
+
function parseIfField(args) {
|
|
183
|
+
// Pattern: expr1 = expr2 "trueText" "falseText"
|
|
184
|
+
// Supports both quoted and unquoted operands.
|
|
185
|
+
// Two-character operators must come first or `<=` would match `<` only.
|
|
186
|
+
const match = /^"?([^"=<>!]*?)"?\s*(<=|>=|<>|=|<|>)\s*"?([^"]*?)"?\s+"([^"]*)"\s+"([^"]*)"/.exec(args);
|
|
187
|
+
if (match) {
|
|
188
|
+
return {
|
|
189
|
+
left: match[1].trim(),
|
|
190
|
+
operator: match[2],
|
|
191
|
+
right: match[3].trim(),
|
|
192
|
+
trueText: match[4],
|
|
193
|
+
falseText: match[5]
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
// Simpler pattern without quotes on operands
|
|
197
|
+
const simpleMatch = /^(\S+)\s*(<=|>=|<>|=|<|>)\s*(\S+)\s+"([^"]*)"\s+"([^"]*)"/.exec(args);
|
|
198
|
+
if (simpleMatch) {
|
|
199
|
+
return {
|
|
200
|
+
left: simpleMatch[1],
|
|
201
|
+
operator: simpleMatch[2],
|
|
202
|
+
right: simpleMatch[3],
|
|
203
|
+
trueText: simpleMatch[4],
|
|
204
|
+
falseText: simpleMatch[5]
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
/** Parse STYLEREF field to get the style name. */
|
|
210
|
+
function parseStyleRef(args) {
|
|
211
|
+
// STYLEREF "StyleName" or STYLEREF StyleName
|
|
212
|
+
const quotedMatch = /^"([^"]+)"/.exec(args);
|
|
213
|
+
if (quotedMatch) {
|
|
214
|
+
return quotedMatch[1];
|
|
215
|
+
}
|
|
216
|
+
const parts = args.split(/\s+/);
|
|
217
|
+
return parts[0] ?? "";
|
|
218
|
+
}
|
|
219
|
+
// =============================================================================
|
|
220
|
+
// Bookmark Collection
|
|
221
|
+
// =============================================================================
|
|
222
|
+
/** Collect all bookmarks with their text and page numbers.
|
|
223
|
+
*
|
|
224
|
+
* Walks the entire document (including tables, SDTs, text boxes, etc.) so
|
|
225
|
+
* bookmarks placed inside nested structures still feed PAGEREF / TOC
|
|
226
|
+
* resolution. Page numbers come from `layout.bookmarkPages` when the
|
|
227
|
+
* layout engine has registered them; otherwise we fall back to the
|
|
228
|
+
* top-level body block's `contentPages` entry.
|
|
229
|
+
*/
|
|
230
|
+
function collectBookmarkInfo(doc, layout) {
|
|
231
|
+
const map = new Map();
|
|
232
|
+
const { contentPages } = layout;
|
|
233
|
+
// Track the current top-level body index so we can fall back to
|
|
234
|
+
// contentPages[i] when the bookmark wasn't seen by the layout pass.
|
|
235
|
+
let topLevelIndex = -1;
|
|
236
|
+
walkBlocks(doc.body, {
|
|
237
|
+
enterParagraph(para) {
|
|
238
|
+
const text = extractParagraphText(para);
|
|
239
|
+
for (const child of para.children) {
|
|
240
|
+
if (isBookmarkStart(child)) {
|
|
241
|
+
const fallbackPage = topLevelIndex >= 0 && contentPages[topLevelIndex] !== undefined
|
|
242
|
+
? contentPages[topLevelIndex]
|
|
243
|
+
: 1;
|
|
244
|
+
const page = layout.bookmarkPages.get(child.name) ?? fallbackPage;
|
|
245
|
+
map.set(child.name, { text, page });
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
// The walker doesn't expose top-level indexing directly, so re-walk only
|
|
251
|
+
// body to keep `topLevelIndex` synchronised. The previous loop's results
|
|
252
|
+
// already reflect bookmarks via `layout.bookmarkPages` for everything
|
|
253
|
+
// layout could see; this second pass refines the fallback page for
|
|
254
|
+
// bookmarks layout missed (very rare in practice).
|
|
255
|
+
for (let i = 0; i < doc.body.length; i++) {
|
|
256
|
+
topLevelIndex = i;
|
|
257
|
+
const item = doc.body[i];
|
|
258
|
+
if (item.type !== "paragraph") {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
for (const child of item.children) {
|
|
262
|
+
if (isBookmarkStart(child)) {
|
|
263
|
+
const existing = map.get(child.name);
|
|
264
|
+
if (existing && existing.page === 1 && contentPages[i] !== undefined) {
|
|
265
|
+
map.set(child.name, { ...existing, page: contentPages[i] });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return map;
|
|
271
|
+
}
|
|
272
|
+
function isBookmarkStart(child) {
|
|
273
|
+
return "type" in child && child.type === "bookmarkStart";
|
|
274
|
+
}
|
|
275
|
+
// =============================================================================
|
|
276
|
+
// Heading Collection
|
|
277
|
+
// =============================================================================
|
|
278
|
+
/** Collect headings from the document for TOC generation.
|
|
279
|
+
*
|
|
280
|
+
* Walks the entire document — headings inside tables (very common) or text
|
|
281
|
+
* boxes / SDTs / TOC cached content also feed the TOC. Page numbers for
|
|
282
|
+
* top-level headings come from `layout.contentPages`; nested headings use
|
|
283
|
+
* the outer block's page or fall back to 1.
|
|
284
|
+
*/
|
|
285
|
+
function collectHeadings(doc, layout) {
|
|
286
|
+
const headings = [];
|
|
287
|
+
const { contentPages } = layout;
|
|
288
|
+
// Walk body twice to track the enclosing top-level body index. First pass:
|
|
289
|
+
// record outer index per top-level block, then traverse its subtree.
|
|
290
|
+
for (let i = 0; i < doc.body.length; i++) {
|
|
291
|
+
const item = doc.body[i];
|
|
292
|
+
const fallbackPage = contentPages[i] ?? 1;
|
|
293
|
+
walkBlocks([item], {
|
|
294
|
+
enterParagraph(para) {
|
|
295
|
+
const level = getHeadingLevel(para, doc.styles);
|
|
296
|
+
if (level !== null) {
|
|
297
|
+
headings.push({
|
|
298
|
+
text: extractParagraphText(para),
|
|
299
|
+
level,
|
|
300
|
+
page: fallbackPage
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return headings;
|
|
307
|
+
}
|
|
308
|
+
/** Determine if a paragraph is a heading and return its level (1-9), or null. */
|
|
309
|
+
function getHeadingLevel(para, styles) {
|
|
310
|
+
const props = para.properties;
|
|
311
|
+
// Check outlineLevel directly on paragraph
|
|
312
|
+
if (props?.outlineLevel != null && props.outlineLevel >= 0 && props.outlineLevel <= 8) {
|
|
313
|
+
return props.outlineLevel + 1; // outlineLevel is 0-based, heading level is 1-based
|
|
314
|
+
}
|
|
315
|
+
// Check style name
|
|
316
|
+
const styleId = props?.style;
|
|
317
|
+
if (styleId) {
|
|
318
|
+
// Direct pattern match: Heading1, Heading2, etc.
|
|
319
|
+
const headingMatch = /^[Hh]eading(\d)$/.exec(styleId);
|
|
320
|
+
if (headingMatch) {
|
|
321
|
+
return parseInt(headingMatch[1], 10);
|
|
322
|
+
}
|
|
323
|
+
// Look up in styles array
|
|
324
|
+
if (styles) {
|
|
325
|
+
const styleDef = styles.find(s => s.styleId === styleId);
|
|
326
|
+
if (styleDef) {
|
|
327
|
+
// Check style name pattern
|
|
328
|
+
const nameMatch = /^[Hh]eading\s*(\d)$/.exec(styleDef.name);
|
|
329
|
+
if (nameMatch) {
|
|
330
|
+
return parseInt(nameMatch[1], 10);
|
|
331
|
+
}
|
|
332
|
+
// Check outlineLevel on style
|
|
333
|
+
if (styleDef.outlineLevel != null &&
|
|
334
|
+
styleDef.outlineLevel >= 0 &&
|
|
335
|
+
styleDef.outlineLevel <= 8) {
|
|
336
|
+
return styleDef.outlineLevel + 1;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
// =============================================================================
|
|
344
|
+
// SEQ Value Computation
|
|
345
|
+
// =============================================================================
|
|
346
|
+
/** Compute all SEQ field values by traversing the document in order.
|
|
347
|
+
*
|
|
348
|
+
* Walks every paragraph reachable from the body — including ones inside
|
|
349
|
+
* tables / SDTs / text boxes / TOC caches — so SEQ counters in tabular
|
|
350
|
+
* figure / table captions advance correctly. Field index ordering across
|
|
351
|
+
* nested blocks matches the document reading order produced by
|
|
352
|
+
* walkBlocks (depth-first).
|
|
353
|
+
*/
|
|
354
|
+
function computeSeqValues(doc) {
|
|
355
|
+
const counters = new Map();
|
|
356
|
+
const values = new Map();
|
|
357
|
+
const state = { fieldIndex: 0 };
|
|
358
|
+
walkBlocks(doc.body, {
|
|
359
|
+
enterParagraph(para) {
|
|
360
|
+
state.fieldIndex = processSeqInParagraph(para, counters, values, state.fieldIndex);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
return values;
|
|
364
|
+
}
|
|
365
|
+
function processSeqInParagraph(para, counters, values, startIndex) {
|
|
366
|
+
let fieldIndex = startIndex;
|
|
367
|
+
// Walk every visible Run reachable from the paragraph — including ones
|
|
368
|
+
// nested inside hyperlinks (`<w:hyperlink>`), tracked-insertion
|
|
369
|
+
// wrappers (`<w:ins>`) and moved-to wrappers (`<w:moveTo>`). The
|
|
370
|
+
// previous implementation only saw top-level runs, so common cases
|
|
371
|
+
// like a SEQ field placed inside `Figure 1` (typically wrapped in a
|
|
372
|
+
// hyperlink for cross-references) silently skipped the SEQ counter
|
|
373
|
+
// and produced wrong figure numbering throughout the document.
|
|
374
|
+
forEachVisibleRun(para.children, run => {
|
|
375
|
+
for (const content of run.content) {
|
|
376
|
+
if (content.type !== "field") {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
const { type, args } = parseFieldInstruction(content.instruction);
|
|
380
|
+
if (type !== "SEQ") {
|
|
381
|
+
fieldIndex++;
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
const { identifier, hidden: _hidden, resetTo, repeat } = parseSeqSwitches(args);
|
|
385
|
+
if (!identifier) {
|
|
386
|
+
fieldIndex++;
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
if (resetTo !== null) {
|
|
390
|
+
counters.set(identifier, resetTo);
|
|
391
|
+
}
|
|
392
|
+
if (repeat) {
|
|
393
|
+
// \c: repeat last value without incrementing
|
|
394
|
+
const current = counters.get(identifier) ?? 0;
|
|
395
|
+
values.set(fieldIndex, current);
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
const current = (counters.get(identifier) ?? 0) + 1;
|
|
399
|
+
counters.set(identifier, current);
|
|
400
|
+
values.set(fieldIndex, current);
|
|
401
|
+
}
|
|
402
|
+
fieldIndex++;
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
return fieldIndex;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Walk every "visible" Run reachable from a paragraph child list.
|
|
409
|
+
*
|
|
410
|
+
* Visible runs are:
|
|
411
|
+
* - bare Run children;
|
|
412
|
+
* - Run children inside a Hyperlink wrapper;
|
|
413
|
+
* - the inner `run` of an `insertedRun` or `movedToRun` wrapper.
|
|
414
|
+
*
|
|
415
|
+
* `deletedRun` / `movedFromRun` represent pending removals and so are
|
|
416
|
+
* skipped, matching the convention used by `extractParagraphText` and
|
|
417
|
+
* `replaceText`.
|
|
418
|
+
*/
|
|
419
|
+
function forEachVisibleRun(children, cb) {
|
|
420
|
+
for (const child of children) {
|
|
421
|
+
if (isRun(child)) {
|
|
422
|
+
cb(child);
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
if ("type" in child) {
|
|
426
|
+
const t = child.type;
|
|
427
|
+
if (t === "hyperlink") {
|
|
428
|
+
forEachVisibleRun(child.children, cb);
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
if (t === "insertedRun" || t === "movedToRun") {
|
|
432
|
+
const inner = child.run;
|
|
433
|
+
if (inner) {
|
|
434
|
+
cb(inner);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
// =============================================================================
|
|
441
|
+
// Style Index (for STYLEREF)
|
|
442
|
+
// =============================================================================
|
|
443
|
+
/** Build index from style ID → paragraph entries with their body index. */
|
|
444
|
+
function buildStyleIndex(doc) {
|
|
445
|
+
const map = new Map();
|
|
446
|
+
for (let i = 0; i < doc.body.length; i++) {
|
|
447
|
+
const item = doc.body[i];
|
|
448
|
+
if (item.type !== "paragraph") {
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
const styleId = item.properties?.style;
|
|
452
|
+
if (!styleId) {
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
let entries = map.get(styleId);
|
|
456
|
+
if (!entries) {
|
|
457
|
+
entries = [];
|
|
458
|
+
map.set(styleId, entries);
|
|
459
|
+
}
|
|
460
|
+
entries.push({ index: i, text: extractParagraphText(item) });
|
|
461
|
+
}
|
|
462
|
+
return map;
|
|
463
|
+
}
|
|
464
|
+
/** Find the nearest paragraph with the given style before bodyIndex. */
|
|
465
|
+
function findStyleRef(styleIndex, styleName, bodyIndex) {
|
|
466
|
+
const entries = styleIndex.get(styleName);
|
|
467
|
+
if (!entries || entries.length === 0) {
|
|
468
|
+
return "";
|
|
469
|
+
}
|
|
470
|
+
// Find the last entry whose index <= bodyIndex
|
|
471
|
+
let best;
|
|
472
|
+
for (const entry of entries) {
|
|
473
|
+
if (entry.index <= bodyIndex) {
|
|
474
|
+
best = entry;
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return best?.text ?? entries[0].text ?? "";
|
|
481
|
+
}
|
|
482
|
+
// =============================================================================
|
|
483
|
+
// Index Entry Collection (for INDEX field)
|
|
484
|
+
// =============================================================================
|
|
485
|
+
/** Collect all XE (Index Entry) fields from the document body. */
|
|
486
|
+
function collectIndexEntries(doc) {
|
|
487
|
+
const entries = [];
|
|
488
|
+
walkBlocks(doc.body, {
|
|
489
|
+
visitRunContent(content) {
|
|
490
|
+
if (content.type !== "field") {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
const { type, args } = parseFieldInstruction(content.instruction);
|
|
494
|
+
if (type === "XE") {
|
|
495
|
+
const term = parseXeTerm(args);
|
|
496
|
+
if (term) {
|
|
497
|
+
entries.push({ term, page: 1 });
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
return entries;
|
|
503
|
+
}
|
|
504
|
+
/** Parse the term from an XE field argument: XE "term" or XE term. */
|
|
505
|
+
function parseXeTerm(args) {
|
|
506
|
+
const quotedMatch = /^"([^"]+)"/.exec(args);
|
|
507
|
+
if (quotedMatch) {
|
|
508
|
+
return quotedMatch[1];
|
|
509
|
+
}
|
|
510
|
+
const raw = args.split(/\s+/)[0];
|
|
511
|
+
return raw ?? "";
|
|
512
|
+
}
|
|
513
|
+
/** Build index content from collected entries. */
|
|
514
|
+
function buildIndexContent(entries, args) {
|
|
515
|
+
if (entries.length === 0) {
|
|
516
|
+
return "";
|
|
517
|
+
}
|
|
518
|
+
// Sort entries alphabetically by term
|
|
519
|
+
const sorted = [...entries].sort((a, b) => a.term.localeCompare(b.term));
|
|
520
|
+
// Check for \h switch (group by first letter with headings)
|
|
521
|
+
const grouped = /\\h\b/i.test(args);
|
|
522
|
+
if (!grouped) {
|
|
523
|
+
return sorted.map(e => `${e.term}\t${e.page}`).join("\n");
|
|
524
|
+
}
|
|
525
|
+
// Group by first letter
|
|
526
|
+
const lines = [];
|
|
527
|
+
let currentLetter = "";
|
|
528
|
+
for (const entry of sorted) {
|
|
529
|
+
const letter = entry.term.charAt(0).toUpperCase();
|
|
530
|
+
if (letter !== currentLetter) {
|
|
531
|
+
currentLetter = letter;
|
|
532
|
+
if (lines.length > 0) {
|
|
533
|
+
lines.push("");
|
|
534
|
+
}
|
|
535
|
+
lines.push(currentLetter);
|
|
536
|
+
}
|
|
537
|
+
lines.push(`${entry.term}\t${entry.page}`);
|
|
538
|
+
}
|
|
539
|
+
return lines.join("\n");
|
|
540
|
+
}
|
|
541
|
+
// =============================================================================
|
|
542
|
+
// Formula Evaluation (for = field)
|
|
543
|
+
// =============================================================================
|
|
544
|
+
/**
|
|
545
|
+
* Evaluate a simple math formula expression.
|
|
546
|
+
* Supports: +, -, *, /, (), numbers, and SUM(ABOVE)/SUM(LEFT).
|
|
547
|
+
*/
|
|
548
|
+
function evaluateFormula(args, bodyIndex, doc, cellCtx) {
|
|
549
|
+
// Extract the number format switch \# "format"
|
|
550
|
+
const formatMatch = /\\#\s*"([^"]+)"/.exec(args);
|
|
551
|
+
const format = formatMatch ? formatMatch[1] : null;
|
|
552
|
+
// Remove format switch from expression
|
|
553
|
+
let expr = args.replace(/\\#\s*"[^"]*"/, "").trim();
|
|
554
|
+
// Handle SUM(ABOVE) and SUM(LEFT)
|
|
555
|
+
expr = expr.replace(/SUM\s*\(\s*ABOVE\s*\)/gi, () => {
|
|
556
|
+
return String(sumAbove(bodyIndex, doc, cellCtx));
|
|
557
|
+
});
|
|
558
|
+
expr = expr.replace(/SUM\s*\(\s*LEFT\s*\)/gi, () => {
|
|
559
|
+
return String(sumLeft(bodyIndex, doc, cellCtx));
|
|
560
|
+
});
|
|
561
|
+
// Evaluate the arithmetic expression
|
|
562
|
+
const result = evalArithmetic(expr);
|
|
563
|
+
if (result === null) {
|
|
564
|
+
return "!";
|
|
565
|
+
}
|
|
566
|
+
return format ? formatNumber(result, format) : String(result);
|
|
567
|
+
}
|
|
568
|
+
/** Evaluate a simple arithmetic expression with +, -, *, /, (). */
|
|
569
|
+
function evalArithmetic(expr) {
|
|
570
|
+
// Remove whitespace
|
|
571
|
+
const tokens = tokenizeExpression(expr.replace(/\s+/g, ""));
|
|
572
|
+
if (tokens === null) {
|
|
573
|
+
return null;
|
|
574
|
+
}
|
|
575
|
+
// The parser surfaces malformed input via `ctx.error` instead of an
|
|
576
|
+
// exception so the field engine doesn't need a try/catch around what is
|
|
577
|
+
// already a control-flow path. Any token that fails to parse as a number
|
|
578
|
+
// sets the flag and the result is discarded.
|
|
579
|
+
const ctx = { pos: 0, error: false };
|
|
580
|
+
const result = parseExpression(tokens, ctx);
|
|
581
|
+
if (ctx.error) {
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
return result;
|
|
585
|
+
}
|
|
586
|
+
/** Tokenize arithmetic expression into numbers, operators, and parens. */
|
|
587
|
+
function tokenizeExpression(expr) {
|
|
588
|
+
const tokens = [];
|
|
589
|
+
let i = 0;
|
|
590
|
+
while (i < expr.length) {
|
|
591
|
+
const ch = expr[i];
|
|
592
|
+
if (ch === "+" || ch === "-" || ch === "*" || ch === "/" || ch === "(" || ch === ")") {
|
|
593
|
+
// Handle negative numbers: minus after operator or at start
|
|
594
|
+
if (ch === "-" &&
|
|
595
|
+
(tokens.length === 0 ||
|
|
596
|
+
tokens[tokens.length - 1] === "(" ||
|
|
597
|
+
isOperator(tokens[tokens.length - 1]))) {
|
|
598
|
+
let num = "-";
|
|
599
|
+
i++;
|
|
600
|
+
while (i < expr.length && isDigitOrDot(expr[i])) {
|
|
601
|
+
num += expr[i];
|
|
602
|
+
i++;
|
|
603
|
+
}
|
|
604
|
+
if (num === "-") {
|
|
605
|
+
return null;
|
|
606
|
+
}
|
|
607
|
+
tokens.push(num);
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
tokens.push(ch);
|
|
611
|
+
i++;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
else if (isDigitOrDot(ch)) {
|
|
615
|
+
let num = "";
|
|
616
|
+
while (i < expr.length && isDigitOrDot(expr[i])) {
|
|
617
|
+
num += expr[i];
|
|
618
|
+
i++;
|
|
619
|
+
}
|
|
620
|
+
tokens.push(num);
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
return null; // Invalid character
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
return tokens;
|
|
627
|
+
}
|
|
628
|
+
function isDigitOrDot(ch) {
|
|
629
|
+
return (ch >= "0" && ch <= "9") || ch === ".";
|
|
630
|
+
}
|
|
631
|
+
function isOperator(token) {
|
|
632
|
+
return token === "+" || token === "-" || token === "*" || token === "/";
|
|
633
|
+
}
|
|
634
|
+
/** Recursive descent parser for arithmetic expressions. */
|
|
635
|
+
function parseExpression(tokens, ctx) {
|
|
636
|
+
let left = parseTerm(tokens, ctx);
|
|
637
|
+
while (ctx.pos < tokens.length) {
|
|
638
|
+
const op = tokens[ctx.pos];
|
|
639
|
+
if (op !== "+" && op !== "-") {
|
|
640
|
+
break;
|
|
641
|
+
}
|
|
642
|
+
ctx.pos++;
|
|
643
|
+
const right = parseTerm(tokens, ctx);
|
|
644
|
+
left = op === "+" ? left + right : left - right;
|
|
645
|
+
}
|
|
646
|
+
return left;
|
|
647
|
+
}
|
|
648
|
+
function parseTerm(tokens, ctx) {
|
|
649
|
+
let left = parseFactor(tokens, ctx);
|
|
650
|
+
while (ctx.pos < tokens.length) {
|
|
651
|
+
const op = tokens[ctx.pos];
|
|
652
|
+
if (op !== "*" && op !== "/") {
|
|
653
|
+
break;
|
|
654
|
+
}
|
|
655
|
+
ctx.pos++;
|
|
656
|
+
const right = parseFactor(tokens, ctx);
|
|
657
|
+
left = op === "*" ? left * right : left / right;
|
|
658
|
+
}
|
|
659
|
+
return left;
|
|
660
|
+
}
|
|
661
|
+
function parseFactor(tokens, ctx) {
|
|
662
|
+
const token = tokens[ctx.pos];
|
|
663
|
+
if (token === "(") {
|
|
664
|
+
ctx.pos++;
|
|
665
|
+
const result = parseExpression(tokens, ctx);
|
|
666
|
+
if (tokens[ctx.pos] === ")") {
|
|
667
|
+
ctx.pos++;
|
|
668
|
+
}
|
|
669
|
+
return result;
|
|
670
|
+
}
|
|
671
|
+
ctx.pos++;
|
|
672
|
+
const num = parseFloat(token);
|
|
673
|
+
if (isNaN(num)) {
|
|
674
|
+
ctx.error = true;
|
|
675
|
+
return 0;
|
|
676
|
+
}
|
|
677
|
+
return num;
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Sum numeric values from cells above the current cell in a table.
|
|
681
|
+
* `cellCtx` identifies which cell the formula is being evaluated in.
|
|
682
|
+
* Without it the previous heuristic returned the first formula-bearing
|
|
683
|
+
* cell of the first table in the document, producing wrong sums whenever
|
|
684
|
+
* more than one cell carried a formula.
|
|
685
|
+
*/
|
|
686
|
+
function sumAbove(bodyIndex, doc, cellCtx) {
|
|
687
|
+
const location = cellCtx ?? findCellInTable(bodyIndex, doc);
|
|
688
|
+
if (!location) {
|
|
689
|
+
return 0;
|
|
690
|
+
}
|
|
691
|
+
const { table, rowIndex, colIndex } = location;
|
|
692
|
+
let sum = 0;
|
|
693
|
+
for (let r = 0; r < rowIndex; r++) {
|
|
694
|
+
const cell = table.rows[r]?.cells[colIndex];
|
|
695
|
+
if (cell) {
|
|
696
|
+
sum += extractCellNumericValue(cell);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
return sum;
|
|
700
|
+
}
|
|
701
|
+
/** Sum numeric values from cells to the left of the current cell. */
|
|
702
|
+
function sumLeft(bodyIndex, doc, cellCtx) {
|
|
703
|
+
const location = cellCtx ?? findCellInTable(bodyIndex, doc);
|
|
704
|
+
if (!location) {
|
|
705
|
+
return 0;
|
|
706
|
+
}
|
|
707
|
+
const { table, rowIndex, colIndex } = location;
|
|
708
|
+
let sum = 0;
|
|
709
|
+
const row = table.rows[rowIndex];
|
|
710
|
+
if (row) {
|
|
711
|
+
for (let c = 0; c < colIndex; c++) {
|
|
712
|
+
const cell = row.cells[c];
|
|
713
|
+
if (cell) {
|
|
714
|
+
sum += extractCellNumericValue(cell);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return sum;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* Find which table/row/col a given body-level paragraph belongs to.
|
|
722
|
+
* Searches top-level tables in the body for a paragraph that contains a formula field
|
|
723
|
+
* at the given body index.
|
|
724
|
+
*/
|
|
725
|
+
function findCellInTable(bodyIndex, doc) {
|
|
726
|
+
// The formula field is inside a table — we scan all tables looking for a match.
|
|
727
|
+
// We track body items: tables contain paragraphs internally but bodyIndex here is
|
|
728
|
+
// the top-level index. When the body item at bodyIndex is a table itself, we search within.
|
|
729
|
+
// However, our engine flattens paragraphs: if the body item IS a table, it won't be processed
|
|
730
|
+
// as a paragraph. So we look at surrounding tables to find where the field might be.
|
|
731
|
+
// Strategy: walk backwards from bodyIndex to find the enclosing table.
|
|
732
|
+
// But in our document model, table cells' paragraphs are not at the top level.
|
|
733
|
+
// Instead, formula fields inside tables will be visited via the body flattening that the
|
|
734
|
+
// engine does not currently do. For simplicity, we search all tables for a cell matching.
|
|
735
|
+
for (const item of doc.body) {
|
|
736
|
+
if (item.type !== "table") {
|
|
737
|
+
continue;
|
|
738
|
+
}
|
|
739
|
+
for (let r = 0; r < item.rows.length; r++) {
|
|
740
|
+
const row = item.rows[r];
|
|
741
|
+
for (let c = 0; c < row.cells.length; c++) {
|
|
742
|
+
const cell = row.cells[c];
|
|
743
|
+
let found = false;
|
|
744
|
+
walkBlocks(cell.content, {
|
|
745
|
+
visitRunContent(content) {
|
|
746
|
+
if (content.type === "field") {
|
|
747
|
+
const { type } = parseFieldInstruction(content.instruction);
|
|
748
|
+
if (type === "=") {
|
|
749
|
+
found = true;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
});
|
|
754
|
+
if (found) {
|
|
755
|
+
// Heuristic: return first match since we can't precisely map bodyIndex to cell
|
|
756
|
+
// In practice, the engine would need cell-level tracking; this is a best-effort approach.
|
|
757
|
+
return { table: item, rowIndex: r, colIndex: c };
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
return null;
|
|
763
|
+
}
|
|
764
|
+
/** Extract numeric value from a table cell (first number found in text). */
|
|
765
|
+
function extractCellNumericValue(cell) {
|
|
766
|
+
let text = "";
|
|
767
|
+
for (const content of cell.content) {
|
|
768
|
+
if (content.type === "paragraph") {
|
|
769
|
+
text += extractParagraphText(content);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
// Try to parse the entire text as a number (with possible comma separators)
|
|
773
|
+
const cleaned = text.replace(/,/g, "").trim();
|
|
774
|
+
const num = parseFloat(cleaned);
|
|
775
|
+
return isNaN(num) ? 0 : num;
|
|
776
|
+
}
|
|
777
|
+
/** Format a number according to a simple format string (e.g. "#,##0", "0.00"). */
|
|
778
|
+
function formatNumber(value, format) {
|
|
779
|
+
// Determine decimal places from format
|
|
780
|
+
const dotIndex = format.indexOf(".");
|
|
781
|
+
let decimals = 0;
|
|
782
|
+
if (dotIndex !== -1) {
|
|
783
|
+
decimals = format.length - dotIndex - 1;
|
|
784
|
+
}
|
|
785
|
+
// Check if format uses thousand separators
|
|
786
|
+
const useThousands = format.includes(",");
|
|
787
|
+
if (useThousands) {
|
|
788
|
+
const fixed = value.toFixed(decimals);
|
|
789
|
+
const [intPart, decPart] = fixed.split(".");
|
|
790
|
+
const withCommas = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
791
|
+
return decPart ? `${withCommas}.${decPart}` : withCommas;
|
|
792
|
+
}
|
|
793
|
+
return value.toFixed(decimals);
|
|
794
|
+
}
|
|
795
|
+
// =============================================================================
|
|
796
|
+
// Body Update
|
|
797
|
+
// =============================================================================
|
|
798
|
+
function updateBody(doc, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, opts) {
|
|
799
|
+
const body = doc.body;
|
|
800
|
+
let changed = false;
|
|
801
|
+
let globalFieldIndex = 0;
|
|
802
|
+
const newBody = [];
|
|
803
|
+
for (let i = 0; i < body.length; i++) {
|
|
804
|
+
const item = body[i];
|
|
805
|
+
if (item.type === "paragraph") {
|
|
806
|
+
const result = updateParagraphFields(item, i, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, doc, globalFieldIndex, opts,
|
|
807
|
+
// No cell context at the body level — formulas here can still
|
|
808
|
+
// call SUM(ABOVE/LEFT) but findCellInTable will be used as a
|
|
809
|
+
// fallback (likely returning null at the body level).
|
|
810
|
+
undefined);
|
|
811
|
+
globalFieldIndex = result.nextFieldIndex;
|
|
812
|
+
if (result.paragraph !== item) {
|
|
813
|
+
changed = true;
|
|
814
|
+
}
|
|
815
|
+
newBody.push(result.paragraph);
|
|
816
|
+
}
|
|
817
|
+
else if (item.type === "tableOfContents" && opts.updateToc) {
|
|
818
|
+
const headings = collectHeadingsFromLayout(body, layout);
|
|
819
|
+
const updated = updateTocContent(item, headings);
|
|
820
|
+
if (updated !== item) {
|
|
821
|
+
changed = true;
|
|
822
|
+
}
|
|
823
|
+
newBody.push(updated);
|
|
824
|
+
}
|
|
825
|
+
else if (item.type === "table") {
|
|
826
|
+
// Recurse into table cells to update fields within tables
|
|
827
|
+
const updatedTable = updateTableFields(item, i, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, doc, globalFieldIndex, opts);
|
|
828
|
+
if (updatedTable.table !== item) {
|
|
829
|
+
changed = true;
|
|
830
|
+
}
|
|
831
|
+
globalFieldIndex = updatedTable.nextFieldIndex;
|
|
832
|
+
newBody.push(updatedTable.table);
|
|
833
|
+
}
|
|
834
|
+
else {
|
|
835
|
+
newBody.push(item);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
return changed ? newBody : body;
|
|
839
|
+
}
|
|
840
|
+
/** Recursively update fields inside a table's cells. */
|
|
841
|
+
function updateTableFields(table, bodyIndex, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, doc, startFieldIndex, opts) {
|
|
842
|
+
let fieldIndex = startFieldIndex;
|
|
843
|
+
let tableChanged = false;
|
|
844
|
+
const newRows = table.rows.map((row, rowIndex) => {
|
|
845
|
+
let rowChanged = false;
|
|
846
|
+
const newCells = row.cells.map((cell, colIndex) => {
|
|
847
|
+
let cellChanged = false;
|
|
848
|
+
const newContent = [];
|
|
849
|
+
// Build the cell context once per cell so SUM(ABOVE)/SUM(LEFT)
|
|
850
|
+
// resolves against THIS cell's coordinates, not whichever cell
|
|
851
|
+
// happened to be the first formula-bearing cell in the table.
|
|
852
|
+
const cellCtx = { table, rowIndex, colIndex };
|
|
853
|
+
for (const block of cell.content) {
|
|
854
|
+
if (block.type === "paragraph") {
|
|
855
|
+
const result = updateParagraphFields(block, bodyIndex, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, doc, fieldIndex, opts, cellCtx);
|
|
856
|
+
fieldIndex = result.nextFieldIndex;
|
|
857
|
+
if (result.paragraph !== block) {
|
|
858
|
+
cellChanged = true;
|
|
859
|
+
}
|
|
860
|
+
newContent.push(result.paragraph);
|
|
861
|
+
}
|
|
862
|
+
else if (block.type === "table") {
|
|
863
|
+
const nested = updateTableFields(block, bodyIndex, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, doc, fieldIndex, opts);
|
|
864
|
+
fieldIndex = nested.nextFieldIndex;
|
|
865
|
+
if (nested.table !== block) {
|
|
866
|
+
cellChanged = true;
|
|
867
|
+
}
|
|
868
|
+
newContent.push(nested.table);
|
|
869
|
+
}
|
|
870
|
+
else {
|
|
871
|
+
newContent.push(block);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
if (cellChanged) {
|
|
875
|
+
rowChanged = true;
|
|
876
|
+
return { ...cell, content: newContent };
|
|
877
|
+
}
|
|
878
|
+
return cell;
|
|
879
|
+
});
|
|
880
|
+
if (rowChanged) {
|
|
881
|
+
tableChanged = true;
|
|
882
|
+
return { ...row, cells: newCells };
|
|
883
|
+
}
|
|
884
|
+
return row;
|
|
885
|
+
});
|
|
886
|
+
if (tableChanged) {
|
|
887
|
+
return { table: { ...table, rows: newRows }, nextFieldIndex: fieldIndex };
|
|
888
|
+
}
|
|
889
|
+
return { table, nextFieldIndex: fieldIndex };
|
|
890
|
+
}
|
|
891
|
+
/** Collect headings directly from body with layout info (avoiding a second layout pass). */
|
|
892
|
+
function collectHeadingsFromLayout(body, layout) {
|
|
893
|
+
const headings = [];
|
|
894
|
+
const { contentPages } = layout;
|
|
895
|
+
for (let i = 0; i < body.length; i++) {
|
|
896
|
+
const item = body[i];
|
|
897
|
+
if (item.type !== "paragraph") {
|
|
898
|
+
continue;
|
|
899
|
+
}
|
|
900
|
+
const level = getHeadingLevelSimple(item);
|
|
901
|
+
if (level !== null) {
|
|
902
|
+
headings.push({
|
|
903
|
+
text: extractParagraphText(item),
|
|
904
|
+
level,
|
|
905
|
+
page: contentPages[i] ?? 1
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
return headings;
|
|
910
|
+
}
|
|
911
|
+
/** Simple heading level detection without full style lookup. */
|
|
912
|
+
function getHeadingLevelSimple(para) {
|
|
913
|
+
const props = para.properties;
|
|
914
|
+
if (props?.outlineLevel != null && props.outlineLevel >= 0 && props.outlineLevel <= 8) {
|
|
915
|
+
return props.outlineLevel + 1;
|
|
916
|
+
}
|
|
917
|
+
const styleId = props?.style;
|
|
918
|
+
if (styleId) {
|
|
919
|
+
const match = /^[Hh]eading(\d)$/.exec(styleId);
|
|
920
|
+
if (match) {
|
|
921
|
+
return parseInt(match[1], 10);
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
return null;
|
|
925
|
+
}
|
|
926
|
+
// =============================================================================
|
|
927
|
+
// Paragraph Field Update
|
|
928
|
+
// =============================================================================
|
|
929
|
+
function updateParagraphFields(para, bodyIndex, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, doc, startFieldIndex, opts, cellCtx) {
|
|
930
|
+
let fieldIndex = startFieldIndex;
|
|
931
|
+
let childrenChanged = false;
|
|
932
|
+
const newChildren = [];
|
|
933
|
+
// Helper that runs `updateRunFields` against a single Run and returns
|
|
934
|
+
// the (possibly new) Run reference.
|
|
935
|
+
const updateRun = (r) => {
|
|
936
|
+
const runResult = updateRunFields(r, bodyIndex, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, doc, fieldIndex, opts, cellCtx);
|
|
937
|
+
fieldIndex = runResult.nextFieldIndex;
|
|
938
|
+
return runResult.run;
|
|
939
|
+
};
|
|
940
|
+
for (const child of para.children) {
|
|
941
|
+
if (isRun(child)) {
|
|
942
|
+
const updated = updateRun(child);
|
|
943
|
+
if (updated !== child) {
|
|
944
|
+
childrenChanged = true;
|
|
945
|
+
}
|
|
946
|
+
newChildren.push(updated);
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
// Hyperlink: descend into its run children so fields like SEQ/REF
|
|
950
|
+
// wrapped in a hyperlink are still evaluated.
|
|
951
|
+
if ("type" in child && child.type === "hyperlink") {
|
|
952
|
+
const hl = child;
|
|
953
|
+
let hlChanged = false;
|
|
954
|
+
const newRuns = hl.children.map(r => {
|
|
955
|
+
const upd = updateRun(r);
|
|
956
|
+
if (upd !== r) {
|
|
957
|
+
hlChanged = true;
|
|
958
|
+
}
|
|
959
|
+
return upd;
|
|
960
|
+
});
|
|
961
|
+
if (hlChanged) {
|
|
962
|
+
childrenChanged = true;
|
|
963
|
+
newChildren.push({ ...hl, children: newRuns });
|
|
964
|
+
}
|
|
965
|
+
else {
|
|
966
|
+
newChildren.push(child);
|
|
967
|
+
}
|
|
968
|
+
continue;
|
|
969
|
+
}
|
|
970
|
+
// Tracked-insert / moved-to wrappers: update the inner run in place.
|
|
971
|
+
if ("type" in child &&
|
|
972
|
+
(child.type === "insertedRun" ||
|
|
973
|
+
child.type === "movedToRun")) {
|
|
974
|
+
const wrap = child;
|
|
975
|
+
const updated = updateRun(wrap.run);
|
|
976
|
+
if (updated !== wrap.run) {
|
|
977
|
+
childrenChanged = true;
|
|
978
|
+
newChildren.push({ ...wrap, run: updated });
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
newChildren.push(child);
|
|
982
|
+
}
|
|
983
|
+
continue;
|
|
984
|
+
}
|
|
985
|
+
newChildren.push(child);
|
|
986
|
+
}
|
|
987
|
+
if (!childrenChanged) {
|
|
988
|
+
return { paragraph: para, nextFieldIndex: fieldIndex };
|
|
989
|
+
}
|
|
990
|
+
return {
|
|
991
|
+
paragraph: { ...para, children: newChildren },
|
|
992
|
+
nextFieldIndex: fieldIndex
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
// =============================================================================
|
|
996
|
+
// Run Field Update
|
|
997
|
+
// =============================================================================
|
|
998
|
+
function updateRunFields(run, bodyIndex, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, doc, startFieldIndex, opts, cellCtx) {
|
|
999
|
+
let fieldIndex = startFieldIndex;
|
|
1000
|
+
let contentChanged = false;
|
|
1001
|
+
const newContent = [];
|
|
1002
|
+
for (const item of run.content) {
|
|
1003
|
+
if (item.type !== "field") {
|
|
1004
|
+
newContent.push(item);
|
|
1005
|
+
continue;
|
|
1006
|
+
}
|
|
1007
|
+
const updated = computeFieldValue(item, bodyIndex, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, doc, fieldIndex, opts, cellCtx);
|
|
1008
|
+
fieldIndex++;
|
|
1009
|
+
if (updated !== item) {
|
|
1010
|
+
contentChanged = true;
|
|
1011
|
+
}
|
|
1012
|
+
newContent.push(updated);
|
|
1013
|
+
}
|
|
1014
|
+
if (!contentChanged) {
|
|
1015
|
+
return { run, nextFieldIndex: fieldIndex };
|
|
1016
|
+
}
|
|
1017
|
+
return {
|
|
1018
|
+
run: { ...run, content: newContent },
|
|
1019
|
+
nextFieldIndex: fieldIndex
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
// =============================================================================
|
|
1023
|
+
// Field Value Computation
|
|
1024
|
+
// =============================================================================
|
|
1025
|
+
function computeFieldValue(field, bodyIndex, layout, bookmarkInfo, seqValues, styleIndex, indexEntries, doc, fieldIndex, opts, cellCtx) {
|
|
1026
|
+
const { type, args } = parseFieldInstruction(field.instruction);
|
|
1027
|
+
switch (type) {
|
|
1028
|
+
case "PAGE": {
|
|
1029
|
+
if (!opts.updatePageFields) {
|
|
1030
|
+
return field;
|
|
1031
|
+
}
|
|
1032
|
+
const page = layout.contentPages[bodyIndex] ?? 1;
|
|
1033
|
+
const value = String(page);
|
|
1034
|
+
if (field.cachedValue === value) {
|
|
1035
|
+
return field;
|
|
1036
|
+
}
|
|
1037
|
+
return { ...field, cachedValue: value };
|
|
1038
|
+
}
|
|
1039
|
+
case "NUMPAGES": {
|
|
1040
|
+
if (!opts.updatePageFields) {
|
|
1041
|
+
return field;
|
|
1042
|
+
}
|
|
1043
|
+
const value = String(layout.pageCount);
|
|
1044
|
+
if (field.cachedValue === value) {
|
|
1045
|
+
return field;
|
|
1046
|
+
}
|
|
1047
|
+
return { ...field, cachedValue: value };
|
|
1048
|
+
}
|
|
1049
|
+
case "SECTIONPAGES": {
|
|
1050
|
+
if (!opts.updatePageFields) {
|
|
1051
|
+
return field;
|
|
1052
|
+
}
|
|
1053
|
+
const sectionIdx = layout.contentSections[bodyIndex] ?? 0;
|
|
1054
|
+
const pages = layout.sectionPageCounts[sectionIdx] ?? 1;
|
|
1055
|
+
const value = String(pages);
|
|
1056
|
+
if (field.cachedValue === value) {
|
|
1057
|
+
return field;
|
|
1058
|
+
}
|
|
1059
|
+
return { ...field, cachedValue: value };
|
|
1060
|
+
}
|
|
1061
|
+
case "SECTION": {
|
|
1062
|
+
if (!opts.updatePageFields) {
|
|
1063
|
+
return field;
|
|
1064
|
+
}
|
|
1065
|
+
const sectionIdx = layout.contentSections[bodyIndex] ?? 0;
|
|
1066
|
+
const value = String(sectionIdx + 1);
|
|
1067
|
+
if (field.cachedValue === value) {
|
|
1068
|
+
return field;
|
|
1069
|
+
}
|
|
1070
|
+
return { ...field, cachedValue: value };
|
|
1071
|
+
}
|
|
1072
|
+
case "REF": {
|
|
1073
|
+
if (!opts.updateReferences) {
|
|
1074
|
+
return field;
|
|
1075
|
+
}
|
|
1076
|
+
const bookmarkName = args.split(/\s+/)[0] ?? "";
|
|
1077
|
+
const data = bookmarkInfo.get(bookmarkName);
|
|
1078
|
+
const value = data?.text ?? "";
|
|
1079
|
+
if (field.cachedValue === value) {
|
|
1080
|
+
return field;
|
|
1081
|
+
}
|
|
1082
|
+
return { ...field, cachedValue: value };
|
|
1083
|
+
}
|
|
1084
|
+
case "PAGEREF": {
|
|
1085
|
+
if (!opts.updateReferences) {
|
|
1086
|
+
return field;
|
|
1087
|
+
}
|
|
1088
|
+
const bookmarkName = args.split(/\s+/)[0] ?? "";
|
|
1089
|
+
const page = layout.bookmarkPages.get(bookmarkName);
|
|
1090
|
+
const value = page != null ? String(page) : "?";
|
|
1091
|
+
if (field.cachedValue === value) {
|
|
1092
|
+
return field;
|
|
1093
|
+
}
|
|
1094
|
+
return { ...field, cachedValue: value };
|
|
1095
|
+
}
|
|
1096
|
+
case "SEQ": {
|
|
1097
|
+
if (!opts.updateSequences) {
|
|
1098
|
+
return field;
|
|
1099
|
+
}
|
|
1100
|
+
const seqVal = seqValues.get(fieldIndex);
|
|
1101
|
+
if (seqVal == null) {
|
|
1102
|
+
return field;
|
|
1103
|
+
}
|
|
1104
|
+
const value = String(seqVal);
|
|
1105
|
+
if (field.cachedValue === value) {
|
|
1106
|
+
return field;
|
|
1107
|
+
}
|
|
1108
|
+
return { ...field, cachedValue: value };
|
|
1109
|
+
}
|
|
1110
|
+
case "IF": {
|
|
1111
|
+
const parsed = parseIfField(args);
|
|
1112
|
+
if (!parsed) {
|
|
1113
|
+
return field;
|
|
1114
|
+
}
|
|
1115
|
+
const result = evaluateCondition(parsed.left, parsed.operator, parsed.right);
|
|
1116
|
+
const value = result ? parsed.trueText : parsed.falseText;
|
|
1117
|
+
if (field.cachedValue === value) {
|
|
1118
|
+
return field;
|
|
1119
|
+
}
|
|
1120
|
+
return { ...field, cachedValue: value };
|
|
1121
|
+
}
|
|
1122
|
+
case "STYLEREF": {
|
|
1123
|
+
const styleName = parseStyleRef(args);
|
|
1124
|
+
if (!styleName) {
|
|
1125
|
+
return field;
|
|
1126
|
+
}
|
|
1127
|
+
const value = findStyleRef(styleIndex, styleName, bodyIndex);
|
|
1128
|
+
if (field.cachedValue === value) {
|
|
1129
|
+
return field;
|
|
1130
|
+
}
|
|
1131
|
+
return { ...field, cachedValue: value };
|
|
1132
|
+
}
|
|
1133
|
+
case "INDEX": {
|
|
1134
|
+
const value = buildIndexContent(indexEntries, args);
|
|
1135
|
+
if (field.cachedValue === value) {
|
|
1136
|
+
return field;
|
|
1137
|
+
}
|
|
1138
|
+
return { ...field, cachedValue: value };
|
|
1139
|
+
}
|
|
1140
|
+
case "=": {
|
|
1141
|
+
const value = evaluateFormula(args, bodyIndex, doc, cellCtx);
|
|
1142
|
+
if (field.cachedValue === value) {
|
|
1143
|
+
return field;
|
|
1144
|
+
}
|
|
1145
|
+
return { ...field, cachedValue: value };
|
|
1146
|
+
}
|
|
1147
|
+
case "INCLUDETEXT": {
|
|
1148
|
+
// INCLUDETEXT requires file system access; mark as not evaluable
|
|
1149
|
+
const path = args.split(/\s+/)[0] ?? "";
|
|
1150
|
+
const value = `[INCLUDETEXT: ${path}]`;
|
|
1151
|
+
if (field.cachedValue === value) {
|
|
1152
|
+
return field;
|
|
1153
|
+
}
|
|
1154
|
+
return { ...field, cachedValue: value };
|
|
1155
|
+
}
|
|
1156
|
+
default:
|
|
1157
|
+
return field;
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
/** Evaluate a simple comparison between two string values. */
|
|
1161
|
+
function evaluateCondition(left, operator, right) {
|
|
1162
|
+
switch (operator) {
|
|
1163
|
+
case "=":
|
|
1164
|
+
return left === right;
|
|
1165
|
+
case "<>":
|
|
1166
|
+
return left !== right;
|
|
1167
|
+
case "<":
|
|
1168
|
+
return left < right;
|
|
1169
|
+
case ">":
|
|
1170
|
+
return left > right;
|
|
1171
|
+
case "<=":
|
|
1172
|
+
return left <= right;
|
|
1173
|
+
case ">=":
|
|
1174
|
+
return left >= right;
|
|
1175
|
+
default:
|
|
1176
|
+
return false;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
// =============================================================================
|
|
1180
|
+
// TOC Update
|
|
1181
|
+
// =============================================================================
|
|
1182
|
+
/** Update a TableOfContents body content with generated cached paragraphs. */
|
|
1183
|
+
function updateTocContent(toc, headings) {
|
|
1184
|
+
const { min, max } = parseTocLevels(buildTocInstruction(toc));
|
|
1185
|
+
// Filter headings by level range
|
|
1186
|
+
const filtered = headings.filter(h => h.level >= min && h.level <= max);
|
|
1187
|
+
// Generate cached paragraphs for each heading
|
|
1188
|
+
const cachedParagraphs = filtered.map(heading => buildTocEntryParagraph(heading));
|
|
1189
|
+
// Check if content actually changed
|
|
1190
|
+
if (toc.cachedParagraphs &&
|
|
1191
|
+
toc.cachedParagraphs.length === cachedParagraphs.length &&
|
|
1192
|
+
cachedParagraphs.every((p, i) => extractParagraphText(p) === extractParagraphText(toc.cachedParagraphs[i]))) {
|
|
1193
|
+
return toc;
|
|
1194
|
+
}
|
|
1195
|
+
return { ...toc, cachedParagraphs };
|
|
1196
|
+
}
|
|
1197
|
+
/** Reconstruct a TOC instruction string from TOC properties. */
|
|
1198
|
+
function buildTocInstruction(toc) {
|
|
1199
|
+
let instruction = "TOC";
|
|
1200
|
+
if (toc.headingStyleRange) {
|
|
1201
|
+
instruction += ` \\o "${toc.headingStyleRange}"`;
|
|
1202
|
+
}
|
|
1203
|
+
if (toc.hyperlink) {
|
|
1204
|
+
instruction += " \\h";
|
|
1205
|
+
}
|
|
1206
|
+
return instruction;
|
|
1207
|
+
}
|
|
1208
|
+
/** Build a single TOC entry paragraph. */
|
|
1209
|
+
function buildTocEntryParagraph(heading) {
|
|
1210
|
+
// Build: "HeadingText\tPageNumber"
|
|
1211
|
+
const textRun = {
|
|
1212
|
+
content: [
|
|
1213
|
+
{ type: "text", text: heading.text },
|
|
1214
|
+
{ type: "tab" },
|
|
1215
|
+
{ type: "text", text: String(heading.page) }
|
|
1216
|
+
]
|
|
1217
|
+
};
|
|
1218
|
+
return {
|
|
1219
|
+
type: "paragraph",
|
|
1220
|
+
properties: {
|
|
1221
|
+
style: `TOC${heading.level}`
|
|
1222
|
+
},
|
|
1223
|
+
children: [textRun]
|
|
1224
|
+
};
|
|
1225
|
+
}
|