@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,1167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Word Document Layout Engine — Advanced Pagination Model
|
|
3
|
+
*
|
|
4
|
+
* Provides page-break calculation for DOCX documents with support for:
|
|
5
|
+
* - Precise line-by-line text wrapping with greedy algorithm
|
|
6
|
+
* - CJK full-width character width awareness
|
|
7
|
+
* - First-line indent / hanging indent
|
|
8
|
+
* - Tab stop positioning
|
|
9
|
+
* - Contextual spacing (paragraph spacing collapse)
|
|
10
|
+
* - Widow & Orphan control
|
|
11
|
+
* - Footnote/Endnote space reservation
|
|
12
|
+
* - Table cell content height calculation
|
|
13
|
+
* - Inline image height contribution
|
|
14
|
+
* - Numbering (bullet/number) indent calculation
|
|
15
|
+
*
|
|
16
|
+
* Units reminder:
|
|
17
|
+
* 1 inch = 1440 twips
|
|
18
|
+
* 1 pt = 20 twips
|
|
19
|
+
* Default US Letter: 12240 × 15840 twips, margins 1440 each
|
|
20
|
+
* Half-point 24 = 12pt font; line height ~14.4pt = 288 twips (single-spaced)
|
|
21
|
+
*/
|
|
22
|
+
import { isHyperlink, isRun } from "../core/text-utils.js";
|
|
23
|
+
import { DEFAULT_PAGE_HEIGHT_TWIPS, DEFAULT_PAGE_MARGIN_TWIPS, DEFAULT_PAGE_WIDTH_TWIPS } from "./layout-constants.js";
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// Internal Constants
|
|
26
|
+
// =============================================================================
|
|
27
|
+
/** 默认字号 (半磅): 24 = 12pt */
|
|
28
|
+
const DEFAULT_FONT_SIZE_HALF_PT = 24;
|
|
29
|
+
/** 默认每行字符数 */
|
|
30
|
+
const DEFAULT_CHARS_PER_LINE = 80;
|
|
31
|
+
/** auto spacing (段前/段后自动间距),约 100 twips ≈ 5pt */
|
|
32
|
+
const AUTO_SPACING_TWIPS = 100;
|
|
33
|
+
/** Default tab stop interval (twips) — Word default is 0.5 inch = 720 twips */
|
|
34
|
+
const DEFAULT_TAB_INTERVAL = 720;
|
|
35
|
+
/** Footnote separator height (twips): line + spacing ≈ 200 twips */
|
|
36
|
+
const FOOTNOTE_SEPARATOR_HEIGHT = 200;
|
|
37
|
+
/** Estimated height per footnote reference (single line + spacing) */
|
|
38
|
+
const FOOTNOTE_ENTRY_HEIGHT = 300;
|
|
39
|
+
// =============================================================================
|
|
40
|
+
// Internal Helpers
|
|
41
|
+
// =============================================================================
|
|
42
|
+
/** 从 SectionProperties 计算可用内容高度 (twips) */
|
|
43
|
+
function computeAvailableHeight(sp) {
|
|
44
|
+
const height = sp?.pageSize?.height ?? DEFAULT_PAGE_HEIGHT_TWIPS;
|
|
45
|
+
const marginTop = sp?.margins?.top ?? DEFAULT_PAGE_MARGIN_TWIPS;
|
|
46
|
+
const marginBottom = sp?.margins?.bottom ?? DEFAULT_PAGE_MARGIN_TWIPS;
|
|
47
|
+
// 可用高度 = 页面高度 - 上边距 - 下边距
|
|
48
|
+
// Word 中 header/footer 区域位于 margin 内部,不额外占用正文空间。
|
|
49
|
+
// 简化模型:不考虑 header/footer 溢出正文区域的情况。
|
|
50
|
+
return Math.max(0, height - marginTop - marginBottom);
|
|
51
|
+
}
|
|
52
|
+
/** 从 SectionProperties 计算可用内容宽度 (twips) */
|
|
53
|
+
function computeAvailableWidth(sp) {
|
|
54
|
+
const width = sp?.pageSize?.width ?? DEFAULT_PAGE_WIDTH_TWIPS;
|
|
55
|
+
const marginLeft = sp?.margins?.left ?? DEFAULT_PAGE_MARGIN_TWIPS;
|
|
56
|
+
const marginRight = sp?.margins?.right ?? DEFAULT_PAGE_MARGIN_TWIPS;
|
|
57
|
+
const gutter = sp?.margins?.gutter ?? 0;
|
|
58
|
+
return Math.max(0, width - marginLeft - marginRight - gutter);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 根据字号计算单行行高 (twips)。
|
|
62
|
+
* 标准排版: 行高 ≈ 字号 × 1.2
|
|
63
|
+
* halfPt 24 (12pt) → 行高 14.4pt = 288 twips
|
|
64
|
+
*/
|
|
65
|
+
function baseLineHeight(fontSizeHalfPt) {
|
|
66
|
+
const ptSize = fontSizeHalfPt / 2;
|
|
67
|
+
return Math.round(ptSize * 1.2 * 20); // pt → twips: ×20
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 根据 LineSpacing 配置计算实际行高 (twips)。
|
|
71
|
+
* - auto: value 以 240ths 为单位 (240=单倍, 360=1.5倍, 480=双倍)
|
|
72
|
+
* - exact: value 即为 twips
|
|
73
|
+
* - atLeast: value 为最小值 (twips),取 max(value, baseLine)
|
|
74
|
+
*/
|
|
75
|
+
function computeLineHeight(spacing, fontSizeHalfPt) {
|
|
76
|
+
const baseLine = baseLineHeight(fontSizeHalfPt);
|
|
77
|
+
if (!spacing?.line) {
|
|
78
|
+
return baseLine;
|
|
79
|
+
}
|
|
80
|
+
const rule = spacing.lineRule ?? "auto";
|
|
81
|
+
switch (rule) {
|
|
82
|
+
case "auto": {
|
|
83
|
+
// spacing.line 以 240ths of a line 为单位
|
|
84
|
+
const multiplier = spacing.line / 240;
|
|
85
|
+
return Math.round(baseLine * multiplier);
|
|
86
|
+
}
|
|
87
|
+
case "exact":
|
|
88
|
+
return spacing.line;
|
|
89
|
+
case "atLeast":
|
|
90
|
+
return Math.max(spacing.line, baseLine);
|
|
91
|
+
default:
|
|
92
|
+
return baseLine;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** 提取段落的有效字号 (半磅) */
|
|
96
|
+
function getParagraphFontSize(props, defaultFontSize) {
|
|
97
|
+
// 段落标记的 run properties 可以指示字号
|
|
98
|
+
return props?.markRunProperties?.size ?? defaultFontSize;
|
|
99
|
+
}
|
|
100
|
+
/** 从 Run 的 font 属性中提取字体名 */
|
|
101
|
+
function getRunFontName(run) {
|
|
102
|
+
const font = run.properties?.font;
|
|
103
|
+
if (!font) {
|
|
104
|
+
return "Calibri";
|
|
105
|
+
}
|
|
106
|
+
if (typeof font === "string") {
|
|
107
|
+
return font;
|
|
108
|
+
}
|
|
109
|
+
return font.ascii ?? font.hAnsi ?? "Calibri";
|
|
110
|
+
}
|
|
111
|
+
/** 提取 Run 中的纯文本内容 */
|
|
112
|
+
function getRunText(run) {
|
|
113
|
+
let text = "";
|
|
114
|
+
for (const item of run.content) {
|
|
115
|
+
switch (item.type) {
|
|
116
|
+
case "text":
|
|
117
|
+
text += item.text;
|
|
118
|
+
break;
|
|
119
|
+
case "tab":
|
|
120
|
+
text += " "; // tab 约等于 4 个字符
|
|
121
|
+
break;
|
|
122
|
+
case "symbol":
|
|
123
|
+
text += " ";
|
|
124
|
+
break;
|
|
125
|
+
case "noBreakHyphen":
|
|
126
|
+
case "softHyphen":
|
|
127
|
+
text += "-";
|
|
128
|
+
break;
|
|
129
|
+
default:
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return text;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Check if a character is CJK (full-width) — takes approximately 2x the width of Latin chars.
|
|
137
|
+
* Covers CJK Unified Ideographs, Katakana, Hiragana, Hangul, fullwidth forms, etc.
|
|
138
|
+
*/
|
|
139
|
+
function isCjkChar(code) {
|
|
140
|
+
return ((code >= 0x2e80 && code <= 0x9fff) || // CJK Radicals, Kangxi, Ideographs
|
|
141
|
+
(code >= 0xac00 && code <= 0xd7af) || // Hangul Syllables
|
|
142
|
+
(code >= 0xf900 && code <= 0xfaff) || // CJK Compatibility Ideographs
|
|
143
|
+
(code >= 0xfe30 && code <= 0xfe4f) || // CJK Compatibility Forms
|
|
144
|
+
(code >= 0xff00 && code <= 0xff60) || // Fullwidth Forms
|
|
145
|
+
(code >= 0xffe0 && code <= 0xffe6) || // Fullwidth Signs
|
|
146
|
+
(code >= 0x20000 && code <= 0x2fa1f) // CJK Extension B-F, Compatibility Supplement
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Calculate the effective character width units for a text string.
|
|
151
|
+
* CJK characters count as 2 units, Latin/other as 1 unit.
|
|
152
|
+
*/
|
|
153
|
+
function getEffectiveTextWidth(text) {
|
|
154
|
+
let width = 0;
|
|
155
|
+
for (let i = 0; i < text.length; i++) {
|
|
156
|
+
const code = text.codePointAt(i);
|
|
157
|
+
if (code > 0xffff) {
|
|
158
|
+
// Supplementary character (surrogate pair) — skip the low surrogate
|
|
159
|
+
i++;
|
|
160
|
+
}
|
|
161
|
+
width += isCjkChar(code) ? 2 : 1;
|
|
162
|
+
}
|
|
163
|
+
return width;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Word-based line count calculation using greedy line-breaking algorithm.
|
|
167
|
+
*
|
|
168
|
+
* Splits text at word boundaries (spaces, hyphens, CJK characters) and places
|
|
169
|
+
* words on lines greedily. Accounts for tab stops at their actual positions.
|
|
170
|
+
*
|
|
171
|
+
* @param children - Paragraph children (runs and hyperlinks)
|
|
172
|
+
* @param firstLineWidth - Available width for the first line (twips)
|
|
173
|
+
* @param subsequentWidth - Available width for subsequent lines (twips)
|
|
174
|
+
* @param averageCharWidth - Average character width (twips)
|
|
175
|
+
* @param tabStops - Custom tab stop positions (twips from left margin)
|
|
176
|
+
* @returns Number of lines the paragraph occupies
|
|
177
|
+
*/
|
|
178
|
+
function computeLineCountWordBased(children, firstLineWidth, subsequentWidth, averageCharWidth, tabStops) {
|
|
179
|
+
// Collect all tokens (words, spaces, tabs, images) from all runs
|
|
180
|
+
const tokens = collectTokens(children);
|
|
181
|
+
if (tokens.length === 0) {
|
|
182
|
+
return 1;
|
|
183
|
+
}
|
|
184
|
+
let lineCount = 1;
|
|
185
|
+
let currentLineWidth = firstLineWidth;
|
|
186
|
+
let xPos = 0; // Current x position on the line (in twips)
|
|
187
|
+
for (const token of tokens) {
|
|
188
|
+
if (token.type === "tab") {
|
|
189
|
+
// Advance to next tab stop
|
|
190
|
+
const nextTab = findNextTabStop(xPos, tabStops);
|
|
191
|
+
if (nextTab > currentLineWidth) {
|
|
192
|
+
// Tab would go past line end — wrap to next line
|
|
193
|
+
lineCount++;
|
|
194
|
+
currentLineWidth = subsequentWidth;
|
|
195
|
+
xPos = 0;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
xPos = nextTab;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else if (token.type === "break") {
|
|
202
|
+
// Hard line break
|
|
203
|
+
lineCount++;
|
|
204
|
+
currentLineWidth = subsequentWidth;
|
|
205
|
+
xPos = 0;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
// Word or image token
|
|
209
|
+
const tokenWidth = token.width * averageCharWidth;
|
|
210
|
+
if (xPos + tokenWidth > currentLineWidth && xPos > 0) {
|
|
211
|
+
// Token doesn't fit — wrap to next line
|
|
212
|
+
lineCount++;
|
|
213
|
+
currentLineWidth = subsequentWidth;
|
|
214
|
+
xPos = tokenWidth;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
xPos += tokenWidth;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return lineCount;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Collect tokens from paragraph children for line-breaking.
|
|
225
|
+
* Splits text at break opportunities (spaces, after hyphens, between CJK chars).
|
|
226
|
+
*/
|
|
227
|
+
function collectTokens(children) {
|
|
228
|
+
const tokens = [];
|
|
229
|
+
for (const child of children) {
|
|
230
|
+
if (isRun(child)) {
|
|
231
|
+
collectRunTokens(child, tokens);
|
|
232
|
+
}
|
|
233
|
+
else if (isHyperlink(child)) {
|
|
234
|
+
for (const run of child.children) {
|
|
235
|
+
collectRunTokens(run, tokens);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return tokens;
|
|
240
|
+
}
|
|
241
|
+
function collectRunTokens(run, tokens) {
|
|
242
|
+
for (const item of run.content) {
|
|
243
|
+
switch (item.type) {
|
|
244
|
+
case "text": {
|
|
245
|
+
// Split text into word tokens at break opportunities
|
|
246
|
+
const words = splitIntoWords(item.text);
|
|
247
|
+
for (const word of words) {
|
|
248
|
+
if (word.length > 0) {
|
|
249
|
+
tokens.push({ type: "word", width: getEffectiveTextWidth(word) });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
case "tab":
|
|
255
|
+
tokens.push({ type: "tab" });
|
|
256
|
+
break;
|
|
257
|
+
case "break":
|
|
258
|
+
tokens.push({ type: "break" });
|
|
259
|
+
break;
|
|
260
|
+
case "image": {
|
|
261
|
+
const img = item;
|
|
262
|
+
const w = img.width ? Math.ceil(emuToTwips(img.width) / 120) : 10;
|
|
263
|
+
tokens.push({ type: "image", width: w });
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
case "symbol":
|
|
267
|
+
tokens.push({ type: "word", width: 1 });
|
|
268
|
+
break;
|
|
269
|
+
case "noBreakHyphen":
|
|
270
|
+
tokens.push({ type: "word", width: 1 });
|
|
271
|
+
break;
|
|
272
|
+
default:
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Split text into words at break opportunities.
|
|
279
|
+
* Break opportunities: after space, after hyphen, between CJK characters.
|
|
280
|
+
* Spaces are included with the preceding word (trailing space model).
|
|
281
|
+
*/
|
|
282
|
+
function splitIntoWords(text) {
|
|
283
|
+
const words = [];
|
|
284
|
+
let current = "";
|
|
285
|
+
for (let i = 0; i < text.length; i++) {
|
|
286
|
+
const code = text.codePointAt(i);
|
|
287
|
+
const ch = String.fromCodePoint(code);
|
|
288
|
+
if (code > 0xffff) {
|
|
289
|
+
i++; // Skip surrogate pair low half
|
|
290
|
+
}
|
|
291
|
+
if (code === 0x20 || code === 0x0a) {
|
|
292
|
+
// Space — attach to current word and break after
|
|
293
|
+
current += ch;
|
|
294
|
+
words.push(current);
|
|
295
|
+
current = "";
|
|
296
|
+
}
|
|
297
|
+
else if (code === 0x2d || code === 0x2010 || code === 0x2011) {
|
|
298
|
+
// Hyphen — break after hyphen
|
|
299
|
+
current += ch;
|
|
300
|
+
words.push(current);
|
|
301
|
+
current = "";
|
|
302
|
+
}
|
|
303
|
+
else if (isCjkChar(code)) {
|
|
304
|
+
// CJK characters: each is its own break opportunity
|
|
305
|
+
if (current.length > 0) {
|
|
306
|
+
words.push(current);
|
|
307
|
+
current = "";
|
|
308
|
+
}
|
|
309
|
+
words.push(ch);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
current += ch;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (current.length > 0) {
|
|
316
|
+
words.push(current);
|
|
317
|
+
}
|
|
318
|
+
return words;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Find the next tab stop position (in twips) after the given x position.
|
|
322
|
+
*/
|
|
323
|
+
function findNextTabStop(xPos, tabStops) {
|
|
324
|
+
if (tabStops && tabStops.length > 0) {
|
|
325
|
+
// Find the first tab stop after xPos
|
|
326
|
+
for (const stop of tabStops) {
|
|
327
|
+
if (stop > xPos) {
|
|
328
|
+
return stop;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// All defined stops passed — use interval from last stop
|
|
332
|
+
const lastStop = tabStops[tabStops.length - 1];
|
|
333
|
+
const interval = DEFAULT_TAB_INTERVAL;
|
|
334
|
+
return lastStop + Math.ceil((xPos - lastStop) / interval) * interval + interval;
|
|
335
|
+
}
|
|
336
|
+
// Default: advance to next multiple of DEFAULT_TAB_INTERVAL
|
|
337
|
+
return (Math.floor(xPos / DEFAULT_TAB_INTERVAL) + 1) * DEFAULT_TAB_INTERVAL;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Compute the effective available width for text in a paragraph, accounting for:
|
|
341
|
+
* - First line indent / hanging indent
|
|
342
|
+
* - Numbering indent
|
|
343
|
+
* Returns [firstLineWidth, subsequentLineWidth] in twips.
|
|
344
|
+
*/
|
|
345
|
+
function computeParagraphLineWidths(props, availableWidth) {
|
|
346
|
+
const indent = props?.indent;
|
|
347
|
+
const leftIndent = indent?.left ?? 0;
|
|
348
|
+
const rightIndent = indent?.right ?? 0;
|
|
349
|
+
const firstLine = indent?.firstLine ?? 0;
|
|
350
|
+
const hanging = indent?.hanging ?? 0;
|
|
351
|
+
// Base width after left/right indents
|
|
352
|
+
const baseWidth = Math.max(1, availableWidth - leftIndent - rightIndent);
|
|
353
|
+
// firstLine means the first line is indented additionally (less available width)
|
|
354
|
+
// hanging means subsequent lines are indented (first line gets extra width)
|
|
355
|
+
if (hanging > 0) {
|
|
356
|
+
return [Math.max(1, baseWidth + hanging), baseWidth];
|
|
357
|
+
}
|
|
358
|
+
if (firstLine > 0) {
|
|
359
|
+
return [Math.max(1, baseWidth - firstLine), baseWidth];
|
|
360
|
+
}
|
|
361
|
+
return [baseWidth, baseWidth];
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Check if a paragraph has an inline image that contributes line height.
|
|
365
|
+
* Returns the maximum image height in twips found in the paragraph, or 0.
|
|
366
|
+
*/
|
|
367
|
+
function getInlineImageMaxHeight(children) {
|
|
368
|
+
let maxHeight = 0;
|
|
369
|
+
for (const child of children) {
|
|
370
|
+
if (isRun(child)) {
|
|
371
|
+
for (const item of child.content) {
|
|
372
|
+
if (item.type === "image") {
|
|
373
|
+
const img = item;
|
|
374
|
+
if (img.height) {
|
|
375
|
+
const h = emuToTwips(img.height);
|
|
376
|
+
if (h > maxHeight) {
|
|
377
|
+
maxHeight = h;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return maxHeight;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Count footnote/endnote references in a paragraph.
|
|
388
|
+
*/
|
|
389
|
+
function countFootnoteRefs(children) {
|
|
390
|
+
let count = 0;
|
|
391
|
+
for (const child of children) {
|
|
392
|
+
if (isRun(child)) {
|
|
393
|
+
for (const item of child.content) {
|
|
394
|
+
if (item.type === "footnoteRef" || item.type === "endnoteRef") {
|
|
395
|
+
count++;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return count;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Count hard line break elements in a paragraph (type "break" without breakType "page"/"column").
|
|
404
|
+
*/
|
|
405
|
+
function countBreakElements(children) {
|
|
406
|
+
let count = 0;
|
|
407
|
+
for (const child of children) {
|
|
408
|
+
if (isRun(child)) {
|
|
409
|
+
for (const item of child.content) {
|
|
410
|
+
if (item.type === "break") {
|
|
411
|
+
const breakType = item.breakType;
|
|
412
|
+
if (!breakType || breakType === "textWrapping") {
|
|
413
|
+
count++;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
else if (isHyperlink(child)) {
|
|
419
|
+
for (const run of child.children) {
|
|
420
|
+
for (const item of run.content) {
|
|
421
|
+
if (item.type === "break") {
|
|
422
|
+
const breakType = item.breakType;
|
|
423
|
+
if (!breakType || breakType === "textWrapping") {
|
|
424
|
+
count++;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return count;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* 使用 measureText 回调计算段落总文本宽度 (points)。
|
|
435
|
+
* 对每个 Run 根据其字体和字号分别测量,然后求和。
|
|
436
|
+
*/
|
|
437
|
+
function measureParagraphTextWidth(children, defaultFontSize, measureFn) {
|
|
438
|
+
let totalWidth = 0;
|
|
439
|
+
for (const child of children) {
|
|
440
|
+
if (isRun(child)) {
|
|
441
|
+
const text = getRunText(child);
|
|
442
|
+
if (text.length > 0) {
|
|
443
|
+
const fontName = getRunFontName(child);
|
|
444
|
+
const fontSize = (child.properties?.size ?? defaultFontSize) / 2; // half-pt → pt
|
|
445
|
+
totalWidth += measureFn(text, fontName, fontSize);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else if (isHyperlink(child)) {
|
|
449
|
+
for (const run of child.children) {
|
|
450
|
+
const text = getRunText(run);
|
|
451
|
+
if (text.length > 0) {
|
|
452
|
+
const fontName = getRunFontName(run);
|
|
453
|
+
const fontSize = (run.properties?.size ?? defaultFontSize) / 2;
|
|
454
|
+
totalWidth += measureFn(text, fontName, fontSize);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return totalWidth;
|
|
460
|
+
}
|
|
461
|
+
/** 获取段落中 run 的最大字号 */
|
|
462
|
+
function getMaxRunFontSize(children, defaultFontSize) {
|
|
463
|
+
let maxSize = 0;
|
|
464
|
+
for (const child of children) {
|
|
465
|
+
if (isRun(child)) {
|
|
466
|
+
const size = child.properties?.size ?? defaultFontSize;
|
|
467
|
+
if (size > maxSize) {
|
|
468
|
+
maxSize = size;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
else if (isHyperlink(child)) {
|
|
472
|
+
for (const run of child.children) {
|
|
473
|
+
const size = run.properties?.size ?? defaultFontSize;
|
|
474
|
+
if (size > maxSize) {
|
|
475
|
+
maxSize = size;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return maxSize || defaultFontSize;
|
|
481
|
+
}
|
|
482
|
+
/** 检查段落 run content 中是否有 page break */
|
|
483
|
+
function hasPageBreakInRuns(children) {
|
|
484
|
+
for (const child of children) {
|
|
485
|
+
if (isRun(child)) {
|
|
486
|
+
for (const item of child.content) {
|
|
487
|
+
if (item.type === "break" && item.breakType === "page") {
|
|
488
|
+
return true;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
/** 检查段落 run content 中是否有 column break */
|
|
496
|
+
function hasColumnBreakInRuns(children) {
|
|
497
|
+
for (const child of children) {
|
|
498
|
+
if (isRun(child)) {
|
|
499
|
+
for (const item of child.content) {
|
|
500
|
+
if (item.type === "break" && item.breakType === "column") {
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* 估算段落高度 (twips)。
|
|
510
|
+
*
|
|
511
|
+
* 高度 = spaceBefore + (行数 × 行高) + spaceAfter
|
|
512
|
+
*
|
|
513
|
+
* Line count calculation:
|
|
514
|
+
* 1. If measureTextFn is provided → precise measurement
|
|
515
|
+
* 2. Otherwise → CJK-aware effective width estimation with indent handling
|
|
516
|
+
*
|
|
517
|
+
* Also accounts for:
|
|
518
|
+
* - Inline images that exceed line height
|
|
519
|
+
* - First-line / hanging indent
|
|
520
|
+
* - Tab stop positioning
|
|
521
|
+
*/
|
|
522
|
+
function estimateParagraphHeight(para, availableWidth, defaultFontSize, defaultCharsPerLine, averageCharWidth, measureTextFn) {
|
|
523
|
+
const props = para.properties;
|
|
524
|
+
const spacing = props?.spacing;
|
|
525
|
+
// 段前间距
|
|
526
|
+
let spaceBefore = 0;
|
|
527
|
+
if (spacing?.beforeAutoSpacing) {
|
|
528
|
+
spaceBefore = AUTO_SPACING_TWIPS;
|
|
529
|
+
}
|
|
530
|
+
else if (spacing?.before != null) {
|
|
531
|
+
spaceBefore = spacing.before;
|
|
532
|
+
}
|
|
533
|
+
// 段后间距
|
|
534
|
+
let spaceAfter = 0;
|
|
535
|
+
if (spacing?.afterAutoSpacing) {
|
|
536
|
+
spaceAfter = AUTO_SPACING_TWIPS;
|
|
537
|
+
}
|
|
538
|
+
else if (spacing?.after != null) {
|
|
539
|
+
spaceAfter = spacing.after;
|
|
540
|
+
}
|
|
541
|
+
// 确定段落字号
|
|
542
|
+
const fontSize = getMaxRunFontSize(para.children, getParagraphFontSize(props, defaultFontSize));
|
|
543
|
+
// 计算行高
|
|
544
|
+
const lineHeight = computeLineHeight(spacing, fontSize);
|
|
545
|
+
// Check if inline images increase the effective line height
|
|
546
|
+
const imgMaxHeight = getInlineImageMaxHeight(para.children);
|
|
547
|
+
const effectiveLineHeight = Math.max(lineHeight, imgMaxHeight);
|
|
548
|
+
// 计算行数
|
|
549
|
+
let lineCount;
|
|
550
|
+
if (measureTextFn) {
|
|
551
|
+
// 精确测量:考虑首行/后续行不同宽度
|
|
552
|
+
const [firstLineW, subsequentW] = computeParagraphLineWidths(props, availableWidth);
|
|
553
|
+
const textWidthPt = measureParagraphTextWidth(para.children, defaultFontSize, measureTextFn);
|
|
554
|
+
const textWidthTwips = textWidthPt * 20; // 1pt = 20 twips
|
|
555
|
+
// Count hard line breaks in the paragraph
|
|
556
|
+
const breakCount = countBreakElements(para.children);
|
|
557
|
+
if (breakCount > 0) {
|
|
558
|
+
// If there are hard breaks, use word-based line counting for accuracy
|
|
559
|
+
const charWidth = averageCharWidth > 0 ? averageCharWidth : 120;
|
|
560
|
+
const tabStops = props?.tabs?.map(t => t.position).filter((p) => p != null);
|
|
561
|
+
lineCount = computeLineCountWordBased(para.children, firstLineW, subsequentW, charWidth, tabStops);
|
|
562
|
+
}
|
|
563
|
+
else if (textWidthTwips <= firstLineW) {
|
|
564
|
+
lineCount = 1;
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
// First line fills firstLineW, remaining fills subsequentW
|
|
568
|
+
const remaining = textWidthTwips - firstLineW;
|
|
569
|
+
lineCount = 1 + Math.max(1, Math.ceil(remaining / subsequentW));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
// Word-based line breaking with CJK awareness and tab stop support
|
|
574
|
+
const [firstLineW, subsequentW] = computeParagraphLineWidths(props, availableWidth);
|
|
575
|
+
const charWidth = averageCharWidth > 0 ? averageCharWidth : 120;
|
|
576
|
+
// Extract tab stop positions from paragraph properties
|
|
577
|
+
const tabStops = props?.tabs?.map(t => t.position).filter((p) => p != null);
|
|
578
|
+
lineCount = computeLineCountWordBased(para.children, firstLineW, subsequentW, charWidth, tabStops);
|
|
579
|
+
}
|
|
580
|
+
return spaceBefore + lineCount * effectiveLineHeight + spaceAfter;
|
|
581
|
+
}
|
|
582
|
+
/** 估算表格单行高度 (twips),考虑单元格内容 */
|
|
583
|
+
function estimateRowHeight(table, rowIndex, defaultFontSize, availableWidth, defaultCharsPerLine, averageCharWidth, measureTextFn) {
|
|
584
|
+
const row = table.rows[rowIndex];
|
|
585
|
+
// If explicit height is set with "exact" rule, use it directly
|
|
586
|
+
if (row.properties?.height?.value) {
|
|
587
|
+
const rule = row.properties.height.rule;
|
|
588
|
+
if (rule === "exact") {
|
|
589
|
+
return row.properties.height.value;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
// Calculate the maximum content height across all cells in this row
|
|
593
|
+
const colCount = row.cells.length;
|
|
594
|
+
const colWidths = table.columnWidths;
|
|
595
|
+
let maxCellHeight = 0;
|
|
596
|
+
for (let c = 0; c < colCount; c++) {
|
|
597
|
+
const cell = row.cells[c];
|
|
598
|
+
// Estimate cell width from column widths or divide equally
|
|
599
|
+
let cellWidth;
|
|
600
|
+
if (colWidths && c < colWidths.length) {
|
|
601
|
+
const gridSpan = cell.properties?.gridSpan ?? 1;
|
|
602
|
+
cellWidth = 0;
|
|
603
|
+
for (let g = 0; g < gridSpan && c + g < colWidths.length; g++) {
|
|
604
|
+
cellWidth += colWidths[c + g];
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
cellWidth = Math.floor(availableWidth / Math.max(1, colCount));
|
|
609
|
+
}
|
|
610
|
+
// Subtract cell margins (default ~108 twips each side in Word)
|
|
611
|
+
const cellMarginLeft = 108;
|
|
612
|
+
const cellMarginRight = 108;
|
|
613
|
+
const cellContentWidth = Math.max(1, cellWidth - cellMarginLeft - cellMarginRight);
|
|
614
|
+
// Calculate height of cell content (paragraphs + nested tables)
|
|
615
|
+
let cellHeight = 0;
|
|
616
|
+
for (const content of cell.content) {
|
|
617
|
+
if (content.type === "paragraph") {
|
|
618
|
+
cellHeight += estimateParagraphHeight(content, cellContentWidth, defaultFontSize, defaultCharsPerLine, averageCharWidth, measureTextFn);
|
|
619
|
+
}
|
|
620
|
+
else if (content.type === "table") {
|
|
621
|
+
cellHeight += estimateTableHeight(content, defaultFontSize, cellContentWidth, defaultCharsPerLine, averageCharWidth, measureTextFn);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
// Add cell top/bottom padding (default ~40 twips each)
|
|
625
|
+
cellHeight += 80;
|
|
626
|
+
if (cellHeight > maxCellHeight) {
|
|
627
|
+
maxCellHeight = cellHeight;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
// Respect "atLeast" height constraint
|
|
631
|
+
if (row.properties?.height?.value) {
|
|
632
|
+
return Math.max(row.properties.height.value, maxCellHeight);
|
|
633
|
+
}
|
|
634
|
+
// Minimum height: at least one line
|
|
635
|
+
const minHeight = baseLineHeight(defaultFontSize) + 80;
|
|
636
|
+
return Math.max(minHeight, maxCellHeight);
|
|
637
|
+
}
|
|
638
|
+
/** 估算表格总高度 (twips) */
|
|
639
|
+
function estimateTableHeight(table, defaultFontSize, availableWidth, defaultCharsPerLine, averageCharWidth, measureTextFn) {
|
|
640
|
+
let total = 0;
|
|
641
|
+
for (let i = 0; i < table.rows.length; i++) {
|
|
642
|
+
total += estimateRowHeight(table, i, defaultFontSize, availableWidth, defaultCharsPerLine, averageCharWidth, measureTextFn);
|
|
643
|
+
}
|
|
644
|
+
return total;
|
|
645
|
+
}
|
|
646
|
+
/** EMU → twips 转换 (1 inch = 914400 EMU = 1440 twips) */
|
|
647
|
+
function emuToTwips(emu) {
|
|
648
|
+
return Math.round(emu / 635);
|
|
649
|
+
}
|
|
650
|
+
/** 计算浮动图片在文档流中占用的高度 (twips)。
|
|
651
|
+
* - "topAndBottom" 包裹模式:图片占据垂直空间
|
|
652
|
+
* - 其他浮动模式:不占用正文流空间
|
|
653
|
+
*/
|
|
654
|
+
function estimateFloatingImageHeight(img) {
|
|
655
|
+
const wrapStyle = img.wrap?.style;
|
|
656
|
+
// topAndBottom wrapping style causes the image to consume vertical space
|
|
657
|
+
if (wrapStyle === "topAndBottom") {
|
|
658
|
+
return emuToTwips(img.height);
|
|
659
|
+
}
|
|
660
|
+
// All other floating modes don't consume flow space
|
|
661
|
+
return 0;
|
|
662
|
+
}
|
|
663
|
+
/** 计算 DrawingShape 在文档流中占用的高度 (twips)。 */
|
|
664
|
+
function estimateDrawingShapeHeight(shape) {
|
|
665
|
+
const wrapStyle = shape.wrap?.style;
|
|
666
|
+
// topAndBottom wrapping style causes the shape to consume vertical space
|
|
667
|
+
if (wrapStyle === "topAndBottom") {
|
|
668
|
+
return emuToTwips(shape.height);
|
|
669
|
+
}
|
|
670
|
+
// Inline/no-wrap shapes that appear in body content consume flow space
|
|
671
|
+
if (!wrapStyle || wrapStyle === "none") {
|
|
672
|
+
return emuToTwips(shape.height);
|
|
673
|
+
}
|
|
674
|
+
return 0;
|
|
675
|
+
}
|
|
676
|
+
/** 计算可用列宽(考虑多栏布局) */
|
|
677
|
+
function computeColumnWidth(availableWidth, columns) {
|
|
678
|
+
if (!columns) {
|
|
679
|
+
return availableWidth;
|
|
680
|
+
}
|
|
681
|
+
const count = columns.count ?? 1;
|
|
682
|
+
if (count <= 1) {
|
|
683
|
+
return availableWidth;
|
|
684
|
+
}
|
|
685
|
+
const space = columns.space ?? 720; // 默认 0.5 inch 间距
|
|
686
|
+
// 总宽度 = count * colWidth + (count - 1) * space
|
|
687
|
+
// colWidth = (totalWidth - (count - 1) * space) / count
|
|
688
|
+
return Math.max(1, Math.floor((availableWidth - (count - 1) * space) / count));
|
|
689
|
+
}
|
|
690
|
+
/** 收集段落中的书签 */
|
|
691
|
+
function collectBookmarks(children, currentPage, bookmarkPages) {
|
|
692
|
+
for (const child of children) {
|
|
693
|
+
if ("type" in child &&
|
|
694
|
+
child.type === "bookmarkStart" &&
|
|
695
|
+
"name" in child) {
|
|
696
|
+
const bookmark = child;
|
|
697
|
+
bookmarkPages.set(bookmark.name, currentPage);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
// =============================================================================
|
|
702
|
+
// Main Layout Function
|
|
703
|
+
// =============================================================================
|
|
704
|
+
/**
|
|
705
|
+
* 对文档进行分页布局计算。
|
|
706
|
+
* 返回每个 body content 所在的页码和总页数。
|
|
707
|
+
*/
|
|
708
|
+
export function layoutDocument(doc, options) {
|
|
709
|
+
const defaultFontSize = options?.defaultFontSize ?? DEFAULT_FONT_SIZE_HALF_PT;
|
|
710
|
+
const defaultCharsPerLine = options?.defaultCharsPerLine ?? DEFAULT_CHARS_PER_LINE;
|
|
711
|
+
// 平均字符宽度 (twips): 12pt 字体约 6pt 宽 = 120 twips
|
|
712
|
+
const averageCharWidth = options?.averageCharWidth ?? Math.round((defaultFontSize / 2) * 0.5 * 20);
|
|
713
|
+
const measureTextFn = options?.measureText;
|
|
714
|
+
const body = doc.body;
|
|
715
|
+
const contentPages = [];
|
|
716
|
+
const contentSections = [];
|
|
717
|
+
const bookmarkPages = new Map();
|
|
718
|
+
const sectionPageCounts = [];
|
|
719
|
+
// 布局状态
|
|
720
|
+
let currentPage = 1; // 1-based 页码
|
|
721
|
+
let currentSection = 0; // 0-based 节号
|
|
722
|
+
let sectionStartPage = 1; // 当前节起始页码
|
|
723
|
+
let currentY = 0; // 当前页面 Y 偏移 (twips from top of content area)
|
|
724
|
+
// 多栏状态
|
|
725
|
+
let currentColumn = 0; // 当前列(0-based)
|
|
726
|
+
let columnCount = 1; // 当前节的列数
|
|
727
|
+
// 当前节的页面属性(从最后一个 section properties 开始)
|
|
728
|
+
// 文档结构:每个节的 SectionProperties 出现在该节最后一个段落的属性中,
|
|
729
|
+
// 而文档最终节的属性在 doc.sectionProperties 中
|
|
730
|
+
let currentSectionProps = findFirstSectionProps(body) ?? doc.sectionProperties;
|
|
731
|
+
let availableHeight = computeAvailableHeight(currentSectionProps);
|
|
732
|
+
let availableWidth = computeAvailableWidth(currentSectionProps);
|
|
733
|
+
// 实际可用列宽(考虑多栏)
|
|
734
|
+
let effectiveWidth = computeColumnWidth(availableWidth, currentSectionProps?.columns);
|
|
735
|
+
/** 更新列数和有效宽度 */
|
|
736
|
+
function updateColumnLayout() {
|
|
737
|
+
columnCount = currentSectionProps?.columns?.count ?? 1;
|
|
738
|
+
if (columnCount < 1) {
|
|
739
|
+
columnCount = 1;
|
|
740
|
+
}
|
|
741
|
+
effectiveWidth = computeColumnWidth(availableWidth, currentSectionProps?.columns);
|
|
742
|
+
}
|
|
743
|
+
// 初始化多栏
|
|
744
|
+
updateColumnLayout();
|
|
745
|
+
/** 开始新页 */
|
|
746
|
+
function newPage() {
|
|
747
|
+
currentPage++;
|
|
748
|
+
currentY = 0;
|
|
749
|
+
currentColumn = 0;
|
|
750
|
+
}
|
|
751
|
+
/** 进入下一列(多栏布局),如果已在最后一列则换页 */
|
|
752
|
+
function nextColumn() {
|
|
753
|
+
if (columnCount > 1 && currentColumn < columnCount - 1) {
|
|
754
|
+
currentColumn++;
|
|
755
|
+
currentY = 0;
|
|
756
|
+
}
|
|
757
|
+
else {
|
|
758
|
+
newPage();
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
/** 开始新节 */
|
|
762
|
+
function newSection(breakType, nextSectionProps) {
|
|
763
|
+
// 记录当前节的页数
|
|
764
|
+
sectionPageCounts.push(currentPage - sectionStartPage + 1);
|
|
765
|
+
currentSection++;
|
|
766
|
+
const nextProps = nextSectionProps ?? doc.sectionProperties;
|
|
767
|
+
switch (breakType) {
|
|
768
|
+
case "nextPage":
|
|
769
|
+
newPage();
|
|
770
|
+
break;
|
|
771
|
+
case "evenPage": {
|
|
772
|
+
// 跳到下一个偶数页
|
|
773
|
+
newPage();
|
|
774
|
+
if (currentPage % 2 !== 0) {
|
|
775
|
+
newPage();
|
|
776
|
+
}
|
|
777
|
+
break;
|
|
778
|
+
}
|
|
779
|
+
case "oddPage": {
|
|
780
|
+
// 跳到下一个奇数页
|
|
781
|
+
newPage();
|
|
782
|
+
if (currentPage % 2 !== 1) {
|
|
783
|
+
newPage();
|
|
784
|
+
}
|
|
785
|
+
break;
|
|
786
|
+
}
|
|
787
|
+
case "continuous": {
|
|
788
|
+
// 如果页面设置(尺寸)改变,则需要分页
|
|
789
|
+
const currentWidth = currentSectionProps?.pageSize?.width ?? DEFAULT_PAGE_WIDTH_TWIPS;
|
|
790
|
+
const currentHeight = currentSectionProps?.pageSize?.height ?? DEFAULT_PAGE_HEIGHT_TWIPS;
|
|
791
|
+
const nextWidth = nextProps?.pageSize?.width ?? DEFAULT_PAGE_WIDTH_TWIPS;
|
|
792
|
+
const nextHeight = nextProps?.pageSize?.height ?? DEFAULT_PAGE_HEIGHT_TWIPS;
|
|
793
|
+
if (currentWidth !== nextWidth || currentHeight !== nextHeight) {
|
|
794
|
+
newPage();
|
|
795
|
+
}
|
|
796
|
+
// 否则继续在当前位置
|
|
797
|
+
break;
|
|
798
|
+
}
|
|
799
|
+
case "nextColumn":
|
|
800
|
+
// 多栏布局下进入下一列
|
|
801
|
+
nextColumn();
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
sectionStartPage = currentPage;
|
|
805
|
+
currentSectionProps = nextProps;
|
|
806
|
+
availableHeight = computeAvailableHeight(currentSectionProps);
|
|
807
|
+
availableWidth = computeAvailableWidth(currentSectionProps);
|
|
808
|
+
updateColumnLayout();
|
|
809
|
+
}
|
|
810
|
+
/** 尝试在当前页添加内容,如果放不下则分页 */
|
|
811
|
+
function addContent(height) {
|
|
812
|
+
if (currentY + height > availableHeight && currentY > 0) {
|
|
813
|
+
// 当前页/列放不下,移到下一页/列
|
|
814
|
+
if (columnCount > 1 && currentColumn < columnCount - 1) {
|
|
815
|
+
nextColumn();
|
|
816
|
+
}
|
|
817
|
+
else {
|
|
818
|
+
newPage();
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
currentY += height;
|
|
822
|
+
}
|
|
823
|
+
/** 表格跨页布局:逐行分配,处理 cantSplit 和 header 行重复 */
|
|
824
|
+
function layoutTable(table) {
|
|
825
|
+
const totalHeight = estimateTableHeight(table, defaultFontSize, effectiveWidth, defaultCharsPerLine, averageCharWidth, measureTextFn);
|
|
826
|
+
// 快速路径:如果表格整体能放入当前页剩余空间,直接放入
|
|
827
|
+
if (currentY + totalHeight <= availableHeight) {
|
|
828
|
+
currentY += totalHeight;
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
// 如果当前页完全空且表格仍放不下,则需要跨页处理
|
|
832
|
+
// 如果当前页非空且放不下第一行,先换页
|
|
833
|
+
const firstRowHeight = estimateRowHeight(table, 0, defaultFontSize, effectiveWidth, defaultCharsPerLine, averageCharWidth, measureTextFn);
|
|
834
|
+
if (currentY > 0 && currentY + firstRowHeight > availableHeight) {
|
|
835
|
+
if (columnCount > 1 && currentColumn < columnCount - 1) {
|
|
836
|
+
nextColumn();
|
|
837
|
+
}
|
|
838
|
+
else {
|
|
839
|
+
newPage();
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
// 确定 header 行(tableHeader = true 的行在每页重复)
|
|
843
|
+
let headerHeight = 0;
|
|
844
|
+
const headerRows = [];
|
|
845
|
+
for (let r = 0; r < table.rows.length; r++) {
|
|
846
|
+
if (table.rows[r].properties?.tableHeader) {
|
|
847
|
+
headerRows.push(r);
|
|
848
|
+
headerHeight += estimateRowHeight(table, r, defaultFontSize, effectiveWidth, defaultCharsPerLine, averageCharWidth, measureTextFn);
|
|
849
|
+
}
|
|
850
|
+
else {
|
|
851
|
+
break; // header 行必须从第一行开始连续
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
// 逐行布局
|
|
855
|
+
for (let r = 0; r < table.rows.length; r++) {
|
|
856
|
+
const row = table.rows[r];
|
|
857
|
+
const rowHeight = estimateRowHeight(table, r, defaultFontSize, effectiveWidth, defaultCharsPerLine, averageCharWidth, measureTextFn);
|
|
858
|
+
// header 行在新页开头已经由 headerHeight 预留
|
|
859
|
+
if (headerRows.includes(r)) {
|
|
860
|
+
// header 行直接放入
|
|
861
|
+
currentY += rowHeight;
|
|
862
|
+
continue;
|
|
863
|
+
}
|
|
864
|
+
// cantSplit: 该行不能被分页拆分 — 如果放不下,必须整行移到下一页
|
|
865
|
+
const cantSplit = row.properties?.cantSplit ?? false;
|
|
866
|
+
if (cantSplit || rowHeight <= availableHeight) {
|
|
867
|
+
// 检查当前页是否还能放下这一行
|
|
868
|
+
if (currentY + rowHeight > availableHeight) {
|
|
869
|
+
// 需要换页/换列
|
|
870
|
+
if (columnCount > 1 && currentColumn < columnCount - 1) {
|
|
871
|
+
nextColumn();
|
|
872
|
+
}
|
|
873
|
+
else {
|
|
874
|
+
newPage();
|
|
875
|
+
}
|
|
876
|
+
// 新页顶部先放 header 行
|
|
877
|
+
currentY += headerHeight;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
else {
|
|
881
|
+
// 行高超过整个页面高度(极端情况),只能直接放
|
|
882
|
+
if (currentY + rowHeight > availableHeight && currentY > 0) {
|
|
883
|
+
if (columnCount > 1 && currentColumn < columnCount - 1) {
|
|
884
|
+
nextColumn();
|
|
885
|
+
}
|
|
886
|
+
else {
|
|
887
|
+
newPage();
|
|
888
|
+
}
|
|
889
|
+
currentY += headerHeight;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
currentY += rowHeight;
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
// =========================================================================
|
|
896
|
+
// 遍历 body content
|
|
897
|
+
// =========================================================================
|
|
898
|
+
for (let i = 0; i < body.length; i++) {
|
|
899
|
+
const item = body[i];
|
|
900
|
+
switch (item.type) {
|
|
901
|
+
case "paragraph": {
|
|
902
|
+
const para = item;
|
|
903
|
+
const props = para.properties;
|
|
904
|
+
// 收集书签
|
|
905
|
+
collectBookmarks(para.children, currentPage, bookmarkPages);
|
|
906
|
+
// 检查段落 sectionProperties(节内分节符)
|
|
907
|
+
// 注意:带 sectionProperties 的段落是其所属节的最后一个段落
|
|
908
|
+
// sectionProperties 定义了当前节的页面设置
|
|
909
|
+
if (props?.sectionProperties) {
|
|
910
|
+
// 先渲染该段落本身
|
|
911
|
+
const paraHeight = estimateParagraphHeight(para, effectiveWidth, defaultFontSize, defaultCharsPerLine, averageCharWidth, measureTextFn);
|
|
912
|
+
handleParagraphLayout(para, paraHeight, i, body);
|
|
913
|
+
contentPages.push(currentPage);
|
|
914
|
+
contentSections.push(currentSection);
|
|
915
|
+
// 然后开始新节
|
|
916
|
+
const nextSP = findNextSectionProps(body, i + 1) ?? doc.sectionProperties;
|
|
917
|
+
newSection(props.sectionProperties.breakType ?? "nextPage", nextSP);
|
|
918
|
+
break;
|
|
919
|
+
}
|
|
920
|
+
// pageBreakBefore: 强制在段落前分页
|
|
921
|
+
if (props?.pageBreakBefore && currentY > 0) {
|
|
922
|
+
newPage();
|
|
923
|
+
}
|
|
924
|
+
// 检查 run 中是否有 page break
|
|
925
|
+
if (hasPageBreakInRuns(para.children) && currentY > 0) {
|
|
926
|
+
newPage();
|
|
927
|
+
}
|
|
928
|
+
// column break: 多栏布局下进入下一列
|
|
929
|
+
if (hasColumnBreakInRuns(para.children) && currentY > 0) {
|
|
930
|
+
nextColumn();
|
|
931
|
+
}
|
|
932
|
+
const paraHeight = estimateParagraphHeight(para, effectiveWidth, defaultFontSize, defaultCharsPerLine, averageCharWidth, measureTextFn);
|
|
933
|
+
handleParagraphLayout(para, paraHeight, i, body);
|
|
934
|
+
contentPages.push(currentPage);
|
|
935
|
+
contentSections.push(currentSection);
|
|
936
|
+
break;
|
|
937
|
+
}
|
|
938
|
+
case "table": {
|
|
939
|
+
const tableStartPage = currentPage;
|
|
940
|
+
layoutTable(item);
|
|
941
|
+
contentPages.push(tableStartPage);
|
|
942
|
+
contentSections.push(currentSection);
|
|
943
|
+
break;
|
|
944
|
+
}
|
|
945
|
+
default: {
|
|
946
|
+
// FloatingImage, TableOfContents, MathBlock, TextBox, CheckBox,
|
|
947
|
+
// DrawingShape, OpaqueDrawing, ChartContent, AltChunk, SDT
|
|
948
|
+
const minHeight = baseLineHeight(defaultFontSize);
|
|
949
|
+
if (item.type === "tableOfContents") {
|
|
950
|
+
// TOC 通常有多个段落
|
|
951
|
+
const tocParas = item.cachedParagraphs;
|
|
952
|
+
const tocHeight = tocParas
|
|
953
|
+
? tocParas.length * baseLineHeight(defaultFontSize)
|
|
954
|
+
: minHeight * 5;
|
|
955
|
+
addContent(tocHeight);
|
|
956
|
+
}
|
|
957
|
+
else if (item.type === "floatingImage") {
|
|
958
|
+
// 根据 wrap style 判断是否占用正文流空间
|
|
959
|
+
const imgHeight = estimateFloatingImageHeight(item);
|
|
960
|
+
if (imgHeight > 0) {
|
|
961
|
+
addContent(imgHeight);
|
|
962
|
+
}
|
|
963
|
+
// 其他浮动模式不占用正文流空间
|
|
964
|
+
}
|
|
965
|
+
else if (item.type === "drawingShape") {
|
|
966
|
+
// 根据 wrap style 和尺寸计算占用高度
|
|
967
|
+
const shapeHeight = estimateDrawingShapeHeight(item);
|
|
968
|
+
if (shapeHeight > 0) {
|
|
969
|
+
addContent(shapeHeight);
|
|
970
|
+
}
|
|
971
|
+
else {
|
|
972
|
+
addContent(minHeight);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
else {
|
|
976
|
+
addContent(minHeight);
|
|
977
|
+
}
|
|
978
|
+
contentPages.push(currentPage);
|
|
979
|
+
contentSections.push(currentSection);
|
|
980
|
+
break;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
// 记录最后一个节的页数
|
|
985
|
+
sectionPageCounts.push(currentPage - sectionStartPage + 1);
|
|
986
|
+
return {
|
|
987
|
+
pageCount: currentPage,
|
|
988
|
+
sectionPageCounts,
|
|
989
|
+
contentPages,
|
|
990
|
+
contentSections,
|
|
991
|
+
bookmarkPages
|
|
992
|
+
};
|
|
993
|
+
// =========================================================================
|
|
994
|
+
// 段落布局辅助(处理 keepNext, keepLines, widowControl, orphanControl)
|
|
995
|
+
// =========================================================================
|
|
996
|
+
function handleParagraphLayout(para, paraHeight, index, bodyContent) {
|
|
997
|
+
const props = para.properties;
|
|
998
|
+
const spacing = props?.spacing;
|
|
999
|
+
const fontSize = getMaxRunFontSize(para.children, getParagraphFontSize(props, defaultFontSize));
|
|
1000
|
+
const lineHeight = computeLineHeight(spacing, fontSize);
|
|
1001
|
+
// 计算段落行数(CJK-aware)
|
|
1002
|
+
let lineCount;
|
|
1003
|
+
if (measureTextFn) {
|
|
1004
|
+
const [firstLineW, subsequentW] = computeParagraphLineWidths(props, effectiveWidth);
|
|
1005
|
+
const textWidthPt = measureParagraphTextWidth(para.children, defaultFontSize, measureTextFn);
|
|
1006
|
+
const textWidthTwips = textWidthPt * 20;
|
|
1007
|
+
// Count hard line breaks in the paragraph
|
|
1008
|
+
const breakCount = countBreakElements(para.children);
|
|
1009
|
+
if (breakCount > 0) {
|
|
1010
|
+
// If there are hard breaks, use word-based line counting for accuracy
|
|
1011
|
+
const charWidth = averageCharWidth > 0 ? averageCharWidth : 120;
|
|
1012
|
+
const tabStops = props?.tabs?.map(t => t.position).filter((p) => p != null);
|
|
1013
|
+
lineCount = computeLineCountWordBased(para.children, firstLineW, subsequentW, charWidth, tabStops);
|
|
1014
|
+
}
|
|
1015
|
+
else if (textWidthTwips <= firstLineW) {
|
|
1016
|
+
lineCount = 1;
|
|
1017
|
+
}
|
|
1018
|
+
else {
|
|
1019
|
+
lineCount = 1 + Math.max(1, Math.ceil((textWidthTwips - firstLineW) / subsequentW));
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
else {
|
|
1023
|
+
const [firstLineW, subsequentW] = computeParagraphLineWidths(props, effectiveWidth);
|
|
1024
|
+
const charWidth = averageCharWidth > 0 ? averageCharWidth : 120;
|
|
1025
|
+
const tabStops = props?.tabs?.map(t => t.position).filter((p) => p != null);
|
|
1026
|
+
lineCount = computeLineCountWordBased(para.children, firstLineW, subsequentW, charWidth, tabStops);
|
|
1027
|
+
}
|
|
1028
|
+
// Contextual spacing: collapse space between paragraphs with same style
|
|
1029
|
+
if (props?.contextualSpacing && index > 0) {
|
|
1030
|
+
const prevItem = bodyContent[index - 1];
|
|
1031
|
+
if (prevItem.type === "paragraph" && prevItem.properties?.style === props.style) {
|
|
1032
|
+
// Collapse spaceBefore — already accounted for in paraHeight but we subtract it
|
|
1033
|
+
const spaceBefore = spacing?.before ?? 0;
|
|
1034
|
+
if (spaceBefore > 0) {
|
|
1035
|
+
// Adjust currentY back by the collapsed space
|
|
1036
|
+
currentY -= Math.min(spaceBefore, currentY);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
// keepLines: 整段必须在同一页
|
|
1041
|
+
if (props?.keepLines) {
|
|
1042
|
+
if (currentY + paraHeight > availableHeight && currentY > 0) {
|
|
1043
|
+
if (columnCount > 1 && currentColumn < columnCount - 1) {
|
|
1044
|
+
nextColumn();
|
|
1045
|
+
}
|
|
1046
|
+
else {
|
|
1047
|
+
newPage();
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
currentY += paraHeight;
|
|
1051
|
+
// Footnote space reservation
|
|
1052
|
+
reserveFootnoteSpace(para);
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
// widowControl: 避免只有 1 行在当前页(至少 2 行,或者整段移走)
|
|
1056
|
+
// orphanControl: 避免最后 1 行单独在下一页(确保至少 2 行在下一页)
|
|
1057
|
+
if (props?.widowControl !== false && lineCount > 1) {
|
|
1058
|
+
let spaceBefore = 0;
|
|
1059
|
+
if (spacing?.beforeAutoSpacing) {
|
|
1060
|
+
spaceBefore = AUTO_SPACING_TWIPS;
|
|
1061
|
+
}
|
|
1062
|
+
else if (spacing?.before != null) {
|
|
1063
|
+
spaceBefore = spacing.before;
|
|
1064
|
+
}
|
|
1065
|
+
const remainingSpace = availableHeight - currentY;
|
|
1066
|
+
const linesOnCurrentPage = Math.floor(Math.max(0, remainingSpace - spaceBefore) / lineHeight);
|
|
1067
|
+
// Widow: only 1 line fits on current page → move whole paragraph
|
|
1068
|
+
if (linesOnCurrentPage === 1 && lineCount > 1) {
|
|
1069
|
+
if (currentY > 0) {
|
|
1070
|
+
if (columnCount > 1 && currentColumn < columnCount - 1) {
|
|
1071
|
+
nextColumn();
|
|
1072
|
+
}
|
|
1073
|
+
else {
|
|
1074
|
+
newPage();
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
// Orphan: only 1 line would be on next page → keep one more line with it
|
|
1079
|
+
else if (linesOnCurrentPage > 0 && linesOnCurrentPage === lineCount - 1) {
|
|
1080
|
+
// Move one line from current page to keep 2 lines on next page
|
|
1081
|
+
// Effectively: move (lineCount - linesOnCurrentPage + 1) lines to next page
|
|
1082
|
+
// → keep (linesOnCurrentPage - 1) lines on current page
|
|
1083
|
+
if (linesOnCurrentPage > 2) {
|
|
1084
|
+
// Can safely split: leave (lines - 2) on current page, 2 on next
|
|
1085
|
+
// Do nothing special — just let it split naturally, but ensure at least 2 on next
|
|
1086
|
+
// The simplest approach: move whole paragraph if splitting would leave orphan
|
|
1087
|
+
if (currentY > 0) {
|
|
1088
|
+
if (columnCount > 1 && currentColumn < columnCount - 1) {
|
|
1089
|
+
nextColumn();
|
|
1090
|
+
}
|
|
1091
|
+
else {
|
|
1092
|
+
newPage();
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
// keepNext: 当前段落需要和下一个段落在同一页
|
|
1099
|
+
if (props?.keepNext && index + 1 < bodyContent.length) {
|
|
1100
|
+
const nextItem = bodyContent[index + 1];
|
|
1101
|
+
if (nextItem.type === "paragraph") {
|
|
1102
|
+
const nextHeight = estimateParagraphHeight(nextItem, effectiveWidth, defaultFontSize, defaultCharsPerLine, averageCharWidth, measureTextFn);
|
|
1103
|
+
// 如果两个段落一起放不下当前页,把当前段移到下一页
|
|
1104
|
+
if (currentY + paraHeight + nextHeight > availableHeight && currentY > 0) {
|
|
1105
|
+
if (columnCount > 1 && currentColumn < columnCount - 1) {
|
|
1106
|
+
nextColumn();
|
|
1107
|
+
}
|
|
1108
|
+
else {
|
|
1109
|
+
newPage();
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
// 普通添加
|
|
1115
|
+
addContent(paraHeight);
|
|
1116
|
+
// Footnote space reservation
|
|
1117
|
+
reserveFootnoteSpace(para);
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* Reserve space at the bottom of the page for footnotes.
|
|
1121
|
+
* Each footnote reference in a paragraph adds to the page's footnote area.
|
|
1122
|
+
*/
|
|
1123
|
+
function reserveFootnoteSpace(para) {
|
|
1124
|
+
const fnCount = countFootnoteRefs(para.children);
|
|
1125
|
+
if (fnCount > 0) {
|
|
1126
|
+
// Add footnote separator once per page (tracked implicitly by adding space)
|
|
1127
|
+
const fnSpace = FOOTNOTE_SEPARATOR_HEIGHT + fnCount * FOOTNOTE_ENTRY_HEIGHT;
|
|
1128
|
+
// Reduce available height for this page
|
|
1129
|
+
// We implement this by advancing currentY (simplification)
|
|
1130
|
+
currentY += fnSpace;
|
|
1131
|
+
// If this pushes us past the page, let normal pagination handle it
|
|
1132
|
+
if (currentY > availableHeight) {
|
|
1133
|
+
newPage();
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
// =============================================================================
|
|
1139
|
+
// Section Properties Lookup Helpers
|
|
1140
|
+
// =============================================================================
|
|
1141
|
+
/**
|
|
1142
|
+
* 在 body 中查找第一个节的 SectionProperties。
|
|
1143
|
+
* 文档中,每个节(除最后一节)的属性在该节最后一个段落的 pPr/sectPr 中。
|
|
1144
|
+
* 这里找第一个含 sectionProperties 的段落之前的区域所适用的属性。
|
|
1145
|
+
* 由于第一个节的属性就是第一个 sectPr(如果存在),我们返回它。
|
|
1146
|
+
*/
|
|
1147
|
+
function findFirstSectionProps(body) {
|
|
1148
|
+
for (const item of body) {
|
|
1149
|
+
if (item.type === "paragraph" && item.properties?.sectionProperties) {
|
|
1150
|
+
return item.properties.sectionProperties;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
return undefined;
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* 从指定位置开始查找下一个节的 SectionProperties。
|
|
1157
|
+
* 返回 body[startIndex..] 中第一个包含 sectionProperties 的段落的 sectionProperties。
|
|
1158
|
+
*/
|
|
1159
|
+
function findNextSectionProps(body, startIndex) {
|
|
1160
|
+
for (let i = startIndex; i < body.length; i++) {
|
|
1161
|
+
const item = body[i];
|
|
1162
|
+
if (item.type === "paragraph" && item.properties?.sectionProperties) {
|
|
1163
|
+
return item.properties.sectionProperties;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
return undefined;
|
|
1167
|
+
}
|