@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,1243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Word Document Page Renderer — SVG Output
|
|
4
|
+
*
|
|
5
|
+
* Renders DOCX document pages to SVG strings for visual preview.
|
|
6
|
+
* Uses the layout engine for pagination and produces approximate
|
|
7
|
+
* visual representations of document content.
|
|
8
|
+
*
|
|
9
|
+
* @stability experimental
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.renderPageToSvg = renderPageToSvg;
|
|
13
|
+
exports.renderDocumentToSvg = renderDocumentToSvg;
|
|
14
|
+
exports.renderPageFromLayout = renderPageFromLayout;
|
|
15
|
+
const font_metrics_1 = require("../../../utils/font-metrics.js");
|
|
16
|
+
const encode_1 = require("../../xml/encode.js");
|
|
17
|
+
const text_utils_1 = require("../core/text-utils");
|
|
18
|
+
const units_1 = require("../units");
|
|
19
|
+
const layout_1 = require("./layout");
|
|
20
|
+
const layout_constants_1 = require("./layout-constants");
|
|
21
|
+
// =============================================================================
|
|
22
|
+
// Internal Constants
|
|
23
|
+
// =============================================================================
|
|
24
|
+
/** Conversion: twips to points. */
|
|
25
|
+
const TWIPS_TO_PT = 1 / 20;
|
|
26
|
+
/** Conversion: EMU to points. */
|
|
27
|
+
const EMU_TO_PT = 1 / units_1.EMU_PER_POINT;
|
|
28
|
+
/** Default font size in points. */
|
|
29
|
+
const DEFAULT_FONT_SIZE_PT = 12;
|
|
30
|
+
/** Default font name. */
|
|
31
|
+
const DEFAULT_FONT = "Calibri";
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// Internal Helpers
|
|
34
|
+
// =============================================================================
|
|
35
|
+
/** Convert twips to points. */
|
|
36
|
+
function twipsToPt(twips) {
|
|
37
|
+
return twips * TWIPS_TO_PT;
|
|
38
|
+
}
|
|
39
|
+
/** Convert EMU to points. */
|
|
40
|
+
function emuToPt(emu) {
|
|
41
|
+
return emu * EMU_TO_PT;
|
|
42
|
+
}
|
|
43
|
+
/** Extract font name from a Run's properties. */
|
|
44
|
+
function getRunFontName(run) {
|
|
45
|
+
const font = run.properties?.font;
|
|
46
|
+
if (!font) {
|
|
47
|
+
return DEFAULT_FONT;
|
|
48
|
+
}
|
|
49
|
+
if (typeof font === "string") {
|
|
50
|
+
return font;
|
|
51
|
+
}
|
|
52
|
+
return font.ascii ?? font.hAnsi ?? DEFAULT_FONT;
|
|
53
|
+
}
|
|
54
|
+
/** Get font size in points from RunProperties. */
|
|
55
|
+
function getRunFontSizePt(props) {
|
|
56
|
+
if (props?.size) {
|
|
57
|
+
return props.size / 2;
|
|
58
|
+
}
|
|
59
|
+
return DEFAULT_FONT_SIZE_PT;
|
|
60
|
+
}
|
|
61
|
+
/** Resolve font family for SVG (uses the fonts map if provided). */
|
|
62
|
+
function resolveFontFamily(fontName, fontsMap) {
|
|
63
|
+
if (fontsMap) {
|
|
64
|
+
const mapped = fontsMap.get(fontName);
|
|
65
|
+
if (mapped) {
|
|
66
|
+
return mapped;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Use generic sans-serif fallback for common fonts
|
|
70
|
+
const lower = fontName.toLowerCase();
|
|
71
|
+
if (lower.includes("times") || lower.includes("roman") || lower.includes("serif")) {
|
|
72
|
+
return `"${fontName}", serif`;
|
|
73
|
+
}
|
|
74
|
+
if (lower.includes("courier") || lower.includes("mono") || lower.includes("consolas")) {
|
|
75
|
+
return `"${fontName}", monospace`;
|
|
76
|
+
}
|
|
77
|
+
return `"${fontName}", sans-serif`;
|
|
78
|
+
}
|
|
79
|
+
/** Sanitize a string into a valid 6-digit hex color, or undefined. */
|
|
80
|
+
function sanitizeHexColor(raw) {
|
|
81
|
+
if (!raw) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
const stripped = raw.replace(/^#/, "");
|
|
85
|
+
if (/^[0-9a-fA-F]{6}$/.test(stripped) || /^[0-9a-fA-F]{3}$/.test(stripped)) {
|
|
86
|
+
return stripped;
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
/** Get CSS color from a hex color string or "auto". */
|
|
91
|
+
function resolveColor(color) {
|
|
92
|
+
if (!color) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
if (typeof color === "string") {
|
|
96
|
+
if (color === "auto") {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
const safe = sanitizeHexColor(color);
|
|
100
|
+
return safe ? `#${safe}` : undefined;
|
|
101
|
+
}
|
|
102
|
+
if (color.val === "auto") {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
const safe = sanitizeHexColor(color.val);
|
|
106
|
+
return safe ? `#${safe}` : undefined;
|
|
107
|
+
}
|
|
108
|
+
/** Determine heading level from paragraph style name. Returns 0 for non-headings. */
|
|
109
|
+
function getHeadingLevel(props) {
|
|
110
|
+
const style = props?.style;
|
|
111
|
+
if (!style) {
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
const match = /^[Hh]eading(\d)$/.exec(style);
|
|
115
|
+
if (match) {
|
|
116
|
+
return parseInt(match[1], 10);
|
|
117
|
+
}
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
/** Get font size multiplier based on heading level. */
|
|
121
|
+
function getHeadingFontScale(level) {
|
|
122
|
+
switch (level) {
|
|
123
|
+
case 1:
|
|
124
|
+
return 2.0;
|
|
125
|
+
case 2:
|
|
126
|
+
return 1.6;
|
|
127
|
+
case 3:
|
|
128
|
+
return 1.4;
|
|
129
|
+
case 4:
|
|
130
|
+
return 1.2;
|
|
131
|
+
case 5:
|
|
132
|
+
return 1.1;
|
|
133
|
+
case 6:
|
|
134
|
+
return 1.0;
|
|
135
|
+
default:
|
|
136
|
+
return 1.0;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/** Extract plain text from a Run. */
|
|
140
|
+
function getRunText(run) {
|
|
141
|
+
let text = "";
|
|
142
|
+
for (const item of run.content) {
|
|
143
|
+
switch (item.type) {
|
|
144
|
+
case "text":
|
|
145
|
+
text += item.text;
|
|
146
|
+
break;
|
|
147
|
+
case "tab":
|
|
148
|
+
text += " ";
|
|
149
|
+
break;
|
|
150
|
+
case "symbol":
|
|
151
|
+
text += " ";
|
|
152
|
+
break;
|
|
153
|
+
case "noBreakHyphen":
|
|
154
|
+
case "softHyphen":
|
|
155
|
+
text += "-";
|
|
156
|
+
break;
|
|
157
|
+
default:
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return text;
|
|
162
|
+
}
|
|
163
|
+
/** Get section properties for a given section index. */
|
|
164
|
+
function getSectionProps(doc, layout, pageNumber) {
|
|
165
|
+
// Find which section this page belongs to
|
|
166
|
+
let sectionIdx = 0;
|
|
167
|
+
let accumulatedPages = 0;
|
|
168
|
+
for (let s = 0; s < layout.sectionPageCounts.length; s++) {
|
|
169
|
+
accumulatedPages += layout.sectionPageCounts[s];
|
|
170
|
+
if (pageNumber <= accumulatedPages) {
|
|
171
|
+
sectionIdx = s;
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Find the section properties for this section
|
|
176
|
+
// Walk through body to find the nth section break
|
|
177
|
+
let currentSec = 0;
|
|
178
|
+
for (const item of doc.body) {
|
|
179
|
+
if (item.type === "paragraph" && item.properties?.sectionProperties) {
|
|
180
|
+
if (currentSec === sectionIdx) {
|
|
181
|
+
return item.properties.sectionProperties;
|
|
182
|
+
}
|
|
183
|
+
currentSec++;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Last section uses doc.sectionProperties
|
|
187
|
+
return doc.sectionProperties;
|
|
188
|
+
}
|
|
189
|
+
// =============================================================================
|
|
190
|
+
// Paragraph Rendering
|
|
191
|
+
// =============================================================================
|
|
192
|
+
/** Render a paragraph and return the Y advance. */
|
|
193
|
+
function renderParagraph(para, state) {
|
|
194
|
+
const props = para.properties;
|
|
195
|
+
const spacing = props?.spacing;
|
|
196
|
+
const headingLevel = getHeadingLevel(props);
|
|
197
|
+
const headingScale = getHeadingFontScale(headingLevel);
|
|
198
|
+
// Space before
|
|
199
|
+
let spaceBefore = 0;
|
|
200
|
+
if (spacing?.beforeAutoSpacing) {
|
|
201
|
+
spaceBefore = 5; // ~5pt auto spacing
|
|
202
|
+
}
|
|
203
|
+
else if (spacing?.before != null) {
|
|
204
|
+
spaceBefore = twipsToPt(spacing.before);
|
|
205
|
+
}
|
|
206
|
+
state.cursorY += spaceBefore;
|
|
207
|
+
// Thematic break (horizontal rule)
|
|
208
|
+
if (props?.thematicBreak) {
|
|
209
|
+
const lineY = state.cursorY;
|
|
210
|
+
state.elements.push(`<line x1="${state.marginLeftPt}" y1="${lineY}" x2="${state.marginLeftPt + state.contentWidthPt}" y2="${lineY}" stroke="#999999" stroke-width="1"/>`);
|
|
211
|
+
state.cursorY += 6;
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
// Determine paragraph indentation
|
|
215
|
+
const indent = props?.indent;
|
|
216
|
+
const leftIndentPt = indent?.left ? twipsToPt(indent.left) : 0;
|
|
217
|
+
const firstLineIndentPt = indent?.firstLine ? twipsToPt(indent.firstLine) : 0;
|
|
218
|
+
// Determine alignment
|
|
219
|
+
const alignment = props?.alignment ?? "left";
|
|
220
|
+
// Line height
|
|
221
|
+
let lineHeightPt = DEFAULT_FONT_SIZE_PT * 1.2;
|
|
222
|
+
if (spacing?.line) {
|
|
223
|
+
const rule = spacing.lineRule ?? "auto";
|
|
224
|
+
switch (rule) {
|
|
225
|
+
case "exact":
|
|
226
|
+
lineHeightPt = twipsToPt(spacing.line);
|
|
227
|
+
break;
|
|
228
|
+
case "atLeast":
|
|
229
|
+
lineHeightPt = Math.max(twipsToPt(spacing.line), lineHeightPt);
|
|
230
|
+
break;
|
|
231
|
+
case "auto":
|
|
232
|
+
lineHeightPt = DEFAULT_FONT_SIZE_PT * 1.2 * (spacing.line / 240);
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// Apply heading scale to line height
|
|
237
|
+
lineHeightPt *= headingScale;
|
|
238
|
+
// Collect runs and render as text spans on lines
|
|
239
|
+
const runs = collectParagraphRuns(para);
|
|
240
|
+
if (runs.length === 0) {
|
|
241
|
+
// Empty paragraph — advance by line height
|
|
242
|
+
state.cursorY += lineHeightPt;
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// Simple line wrapping: measure text and wrap at content width
|
|
246
|
+
const availableWidth = state.contentWidthPt - leftIndentPt;
|
|
247
|
+
const lines = wrapRunsToLines(runs, availableWidth, firstLineIndentPt, headingScale);
|
|
248
|
+
for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
|
|
249
|
+
const line = lines[lineIdx];
|
|
250
|
+
state.cursorY += lineHeightPt;
|
|
251
|
+
// Calculate x position based on alignment
|
|
252
|
+
let xOffset = state.marginLeftPt + leftIndentPt;
|
|
253
|
+
if (lineIdx === 0) {
|
|
254
|
+
xOffset += firstLineIndentPt;
|
|
255
|
+
}
|
|
256
|
+
if (alignment === "center") {
|
|
257
|
+
const lineWidth = measureLineWidth(line, headingScale);
|
|
258
|
+
xOffset = state.marginLeftPt + (state.contentWidthPt - lineWidth) / 2;
|
|
259
|
+
}
|
|
260
|
+
else if (alignment === "right" || alignment === "end") {
|
|
261
|
+
const lineWidth = measureLineWidth(line, headingScale);
|
|
262
|
+
xOffset = state.marginLeftPt + state.contentWidthPt - lineWidth;
|
|
263
|
+
}
|
|
264
|
+
// Render each run segment on this line
|
|
265
|
+
let currentX = xOffset;
|
|
266
|
+
for (const segment of line) {
|
|
267
|
+
const fontSize = getRunFontSizePt(segment.properties) * headingScale;
|
|
268
|
+
const fontFamily = resolveFontFamily(getRunFontName({ properties: segment.properties, content: [] }), state.fontsMap);
|
|
269
|
+
const isBold = segment.properties?.bold || headingLevel > 0;
|
|
270
|
+
const isItalic = segment.properties?.italic;
|
|
271
|
+
const color = resolveColor(segment.properties?.color);
|
|
272
|
+
const underline = segment.properties?.underline;
|
|
273
|
+
const strike = segment.properties?.strike;
|
|
274
|
+
// Build style attributes
|
|
275
|
+
let attrs = `x="${currentX.toFixed(2)}" y="${state.cursorY.toFixed(2)}"`;
|
|
276
|
+
attrs += ` font-family="${(0, encode_1.xmlEncodeAttr)(fontFamily)}"`;
|
|
277
|
+
attrs += ` font-size="${fontSize.toFixed(1)}"`;
|
|
278
|
+
if (isBold) {
|
|
279
|
+
attrs += ` font-weight="bold"`;
|
|
280
|
+
}
|
|
281
|
+
if (isItalic) {
|
|
282
|
+
attrs += ` font-style="italic"`;
|
|
283
|
+
}
|
|
284
|
+
if (color) {
|
|
285
|
+
attrs += ` fill="${color}"`;
|
|
286
|
+
}
|
|
287
|
+
if (underline && underline !== "none") {
|
|
288
|
+
// underline can be true, a style string, or UnderlineSpec
|
|
289
|
+
const isNone = typeof underline === "object" && "style" in underline && underline.style === "none";
|
|
290
|
+
if (!isNone) {
|
|
291
|
+
attrs += ` text-decoration="underline"`;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
else if (strike) {
|
|
295
|
+
attrs += ` text-decoration="line-through"`;
|
|
296
|
+
}
|
|
297
|
+
const escapedText = (0, encode_1.xmlEncode)(segment.text);
|
|
298
|
+
if (escapedText.length > 0) {
|
|
299
|
+
state.elements.push(`<text ${attrs}>${escapedText}</text>`);
|
|
300
|
+
}
|
|
301
|
+
// Advance X position using text measurement
|
|
302
|
+
const measuredFont = (0, font_metrics_1.mapToStandardFont)(getRunFontName({ properties: segment.properties, content: [] }));
|
|
303
|
+
const textWidth = (0, font_metrics_1.measureTextWidth)(segment.text, measuredFont, fontSize);
|
|
304
|
+
currentX += textWidth;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// Handle inline images within the paragraph
|
|
309
|
+
renderParagraphImages(para, state);
|
|
310
|
+
// Space after
|
|
311
|
+
let spaceAfter = 0;
|
|
312
|
+
if (spacing?.afterAutoSpacing) {
|
|
313
|
+
spaceAfter = 5;
|
|
314
|
+
}
|
|
315
|
+
else if (spacing?.after != null) {
|
|
316
|
+
spaceAfter = twipsToPt(spacing.after);
|
|
317
|
+
}
|
|
318
|
+
state.cursorY += spaceAfter;
|
|
319
|
+
}
|
|
320
|
+
/** Collect all text segments from a paragraph's children. */
|
|
321
|
+
function collectParagraphRuns(para) {
|
|
322
|
+
const segments = [];
|
|
323
|
+
for (const child of para.children) {
|
|
324
|
+
if ((0, text_utils_1.isRun)(child)) {
|
|
325
|
+
const text = getRunText(child);
|
|
326
|
+
if (text.length > 0) {
|
|
327
|
+
segments.push({ text, properties: child.properties });
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else if ((0, text_utils_1.isHyperlink)(child)) {
|
|
331
|
+
for (const run of child.children) {
|
|
332
|
+
const text = getRunText(run);
|
|
333
|
+
if (text.length > 0) {
|
|
334
|
+
segments.push({ text, properties: run.properties });
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return segments;
|
|
340
|
+
}
|
|
341
|
+
/** Wrap text segments into lines based on available width. */
|
|
342
|
+
function wrapRunsToLines(segments, availableWidth, firstLineIndent, headingScale) {
|
|
343
|
+
const lines = [];
|
|
344
|
+
let currentLine = [];
|
|
345
|
+
let currentLineWidth = 0;
|
|
346
|
+
let isFirstLine = true;
|
|
347
|
+
let effectiveWidth = availableWidth - firstLineIndent;
|
|
348
|
+
for (const segment of segments) {
|
|
349
|
+
const fontSize = getRunFontSizePt(segment.properties) * headingScale;
|
|
350
|
+
const fontName = (0, font_metrics_1.mapToStandardFont)(getRunFontName({ properties: segment.properties, content: [] }));
|
|
351
|
+
const segmentWidth = (0, font_metrics_1.measureTextWidth)(segment.text, fontName, fontSize);
|
|
352
|
+
if (currentLineWidth + segmentWidth <= effectiveWidth || currentLine.length === 0) {
|
|
353
|
+
// Fits on current line
|
|
354
|
+
currentLine.push(segment);
|
|
355
|
+
currentLineWidth += segmentWidth;
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
// Need to wrap — try word-level splitting
|
|
359
|
+
const words = segment.text.split(/(\s+)/);
|
|
360
|
+
let bufferedText = "";
|
|
361
|
+
let bufferedWidth = 0;
|
|
362
|
+
for (const word of words) {
|
|
363
|
+
const wordWidth = (0, font_metrics_1.measureTextWidth)(word, fontName, fontSize);
|
|
364
|
+
if (currentLineWidth + bufferedWidth + wordWidth <= effectiveWidth ||
|
|
365
|
+
(currentLine.length === 0 && bufferedText.length === 0)) {
|
|
366
|
+
bufferedText += word;
|
|
367
|
+
bufferedWidth += wordWidth;
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
// Flush buffered text to current line
|
|
371
|
+
if (bufferedText.length > 0) {
|
|
372
|
+
currentLine.push({ text: bufferedText, properties: segment.properties });
|
|
373
|
+
}
|
|
374
|
+
// Start new line
|
|
375
|
+
lines.push(currentLine);
|
|
376
|
+
currentLine = [];
|
|
377
|
+
currentLineWidth = 0;
|
|
378
|
+
if (isFirstLine) {
|
|
379
|
+
isFirstLine = false;
|
|
380
|
+
effectiveWidth = availableWidth;
|
|
381
|
+
}
|
|
382
|
+
bufferedText = word;
|
|
383
|
+
bufferedWidth = wordWidth;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
// Flush remaining buffered text
|
|
387
|
+
if (bufferedText.length > 0) {
|
|
388
|
+
currentLine.push({ text: bufferedText, properties: segment.properties });
|
|
389
|
+
currentLineWidth += bufferedWidth;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
if (currentLine.length > 0) {
|
|
394
|
+
lines.push(currentLine);
|
|
395
|
+
}
|
|
396
|
+
// Ensure at least one empty line for non-empty segments
|
|
397
|
+
if (lines.length === 0 && segments.length > 0) {
|
|
398
|
+
lines.push(segments);
|
|
399
|
+
}
|
|
400
|
+
return lines;
|
|
401
|
+
}
|
|
402
|
+
/** Measure the total width of a line of segments in points. */
|
|
403
|
+
function measureLineWidth(segments, headingScale) {
|
|
404
|
+
let total = 0;
|
|
405
|
+
for (const segment of segments) {
|
|
406
|
+
const fontSize = getRunFontSizePt(segment.properties) * headingScale;
|
|
407
|
+
const fontName = (0, font_metrics_1.mapToStandardFont)(getRunFontName({ properties: segment.properties, content: [] }));
|
|
408
|
+
total += (0, font_metrics_1.measureTextWidth)(segment.text, fontName, fontSize);
|
|
409
|
+
}
|
|
410
|
+
return total;
|
|
411
|
+
}
|
|
412
|
+
/** Render inline images found in paragraph runs. */
|
|
413
|
+
function renderParagraphImages(para, state) {
|
|
414
|
+
for (const child of para.children) {
|
|
415
|
+
if (!(0, text_utils_1.isRun)(child)) {
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
for (const item of child.content) {
|
|
419
|
+
if (item.type === "image") {
|
|
420
|
+
const img = item;
|
|
421
|
+
const widthPt = emuToPt(img.width);
|
|
422
|
+
const heightPt = emuToPt(img.height);
|
|
423
|
+
// Find image data from document
|
|
424
|
+
const imgData = findImageData(state.doc, img.rId);
|
|
425
|
+
if (imgData) {
|
|
426
|
+
const dataUri = `data:${imageMediaTypeToMime(imgData.mediaType)};base64,${uint8ToBase64(imgData.data)}`;
|
|
427
|
+
state.elements.push(`<image x="${state.marginLeftPt}" y="${state.cursorY}" width="${widthPt.toFixed(1)}" height="${heightPt.toFixed(1)}" href="${(0, encode_1.xmlEncodeAttr)(dataUri)}"/>`);
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
// Render placeholder rectangle
|
|
431
|
+
state.elements.push(`<rect x="${state.marginLeftPt}" y="${state.cursorY}" width="${widthPt.toFixed(1)}" height="${heightPt.toFixed(1)}" fill="#f0f0f0" stroke="#cccccc" stroke-width="0.5"/>` +
|
|
432
|
+
`<text x="${(state.marginLeftPt + widthPt / 2).toFixed(1)}" y="${(state.cursorY + heightPt / 2).toFixed(1)}" text-anchor="middle" font-size="8" fill="#999999">[Image]</text>`);
|
|
433
|
+
}
|
|
434
|
+
state.cursorY += heightPt;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
/** Find image data by relationship ID. */
|
|
440
|
+
function findImageData(doc, rId) {
|
|
441
|
+
if (!doc.images) {
|
|
442
|
+
return undefined;
|
|
443
|
+
}
|
|
444
|
+
for (const img of doc.images) {
|
|
445
|
+
if (img.rId === rId) {
|
|
446
|
+
return { data: img.data, mediaType: img.mediaType };
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
return undefined;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Map an `ImageMediaType` value (e.g. "png", "svg") to the MIME type required
|
|
453
|
+
* by `data:` URIs. The model uses short tokens, but data URIs need full
|
|
454
|
+
* `image/<subtype>` form — without this, browsers fail to decode the SVG
|
|
455
|
+
* preview's embedded images.
|
|
456
|
+
*/
|
|
457
|
+
function imageMediaTypeToMime(mediaType) {
|
|
458
|
+
switch (mediaType) {
|
|
459
|
+
case "svg":
|
|
460
|
+
return "image/svg+xml";
|
|
461
|
+
case "jpeg":
|
|
462
|
+
case "png":
|
|
463
|
+
case "gif":
|
|
464
|
+
case "bmp":
|
|
465
|
+
case "tiff":
|
|
466
|
+
case "webp":
|
|
467
|
+
return `image/${mediaType}`;
|
|
468
|
+
case "emf":
|
|
469
|
+
return "image/x-emf";
|
|
470
|
+
case "wmf":
|
|
471
|
+
return "image/x-wmf";
|
|
472
|
+
default:
|
|
473
|
+
return `image/${mediaType}`;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
/** Convert Uint8Array to base64 string. */
|
|
477
|
+
function uint8ToBase64(data) {
|
|
478
|
+
// Process in chunks to avoid call stack overflow with large arrays
|
|
479
|
+
const CHUNK_SIZE = 8192;
|
|
480
|
+
let binary = "";
|
|
481
|
+
for (let i = 0; i < data.length; i += CHUNK_SIZE) {
|
|
482
|
+
const chunk = data.subarray(i, Math.min(i + CHUNK_SIZE, data.length));
|
|
483
|
+
for (let j = 0; j < chunk.length; j++) {
|
|
484
|
+
binary += String.fromCharCode(chunk[j]);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return btoa(binary);
|
|
488
|
+
}
|
|
489
|
+
// =============================================================================
|
|
490
|
+
// Table Rendering
|
|
491
|
+
// =============================================================================
|
|
492
|
+
/** Render a table. */
|
|
493
|
+
function renderTable(table, state) {
|
|
494
|
+
const startY = state.cursorY;
|
|
495
|
+
const tableX = state.marginLeftPt;
|
|
496
|
+
// Calculate column widths
|
|
497
|
+
const colWidths = computeTableColumnWidths(table, state.contentWidthPt);
|
|
498
|
+
const totalWidth = colWidths.reduce((sum, w) => sum + w, 0);
|
|
499
|
+
// Track row Y positions for border drawing
|
|
500
|
+
const rowYPositions = [startY];
|
|
501
|
+
for (const row of table.rows) {
|
|
502
|
+
const rowStartY = state.cursorY;
|
|
503
|
+
const rowHeight = estimateRowHeightPt(row, colWidths, state);
|
|
504
|
+
// Render cell backgrounds and content
|
|
505
|
+
let cellX = tableX;
|
|
506
|
+
for (let c = 0; c < row.cells.length; c++) {
|
|
507
|
+
const cell = row.cells[c];
|
|
508
|
+
const gridSpan = cell.properties?.gridSpan ?? 1;
|
|
509
|
+
let cellWidth = 0;
|
|
510
|
+
for (let g = 0; g < gridSpan && c + g < colWidths.length; g++) {
|
|
511
|
+
cellWidth += colWidths[c + g];
|
|
512
|
+
}
|
|
513
|
+
// Cell background
|
|
514
|
+
const shading = cell.properties?.shading;
|
|
515
|
+
if (shading?.fill && shading.fill !== "auto") {
|
|
516
|
+
const safeFill = sanitizeHexColor(shading.fill);
|
|
517
|
+
if (safeFill) {
|
|
518
|
+
state.elements.push(`<rect x="${cellX.toFixed(2)}" y="${rowStartY.toFixed(2)}" width="${cellWidth.toFixed(2)}" height="${rowHeight.toFixed(2)}" fill="#${safeFill}" stroke="none"/>`);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
// Render cell content (simplified — just text)
|
|
522
|
+
const cellPadding = 4; // ~4pt padding
|
|
523
|
+
let cellCursorY = rowStartY + cellPadding;
|
|
524
|
+
for (const content of cell.content) {
|
|
525
|
+
if (content.type === "paragraph") {
|
|
526
|
+
// Simplified: render first run of each paragraph
|
|
527
|
+
const runs = collectParagraphRuns(content);
|
|
528
|
+
if (runs.length > 0) {
|
|
529
|
+
const allText = runs.map(r => r.text).join("");
|
|
530
|
+
const firstRun = runs[0];
|
|
531
|
+
const fontSize = getRunFontSizePt(firstRun.properties);
|
|
532
|
+
const fontFamily = resolveFontFamily(getRunFontName({ properties: firstRun.properties, content: [] }), state.fontsMap);
|
|
533
|
+
const isBold = firstRun.properties?.bold;
|
|
534
|
+
cellCursorY += fontSize * 1.2;
|
|
535
|
+
let textAttrs = `x="${(cellX + cellPadding).toFixed(2)}" y="${cellCursorY.toFixed(2)}"`;
|
|
536
|
+
textAttrs += ` font-family="${(0, encode_1.xmlEncodeAttr)(fontFamily)}"`;
|
|
537
|
+
textAttrs += ` font-size="${fontSize.toFixed(1)}"`;
|
|
538
|
+
if (isBold) {
|
|
539
|
+
textAttrs += ` font-weight="bold"`;
|
|
540
|
+
}
|
|
541
|
+
// Clip text to cell width
|
|
542
|
+
const maxChars = Math.floor((cellWidth - cellPadding * 2) / (fontSize * 0.5));
|
|
543
|
+
const displayText = allText.length > maxChars ? allText.slice(0, maxChars) + "…" : allText;
|
|
544
|
+
state.elements.push(`<text ${textAttrs}>${(0, encode_1.xmlEncode)(displayText)}</text>`);
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
cellCursorY += DEFAULT_FONT_SIZE_PT * 1.2;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
cellX += cellWidth;
|
|
552
|
+
}
|
|
553
|
+
state.cursorY += rowHeight;
|
|
554
|
+
rowYPositions.push(state.cursorY);
|
|
555
|
+
}
|
|
556
|
+
// Draw table borders (outer rect + row/col lines)
|
|
557
|
+
const tableEndY = state.cursorY;
|
|
558
|
+
const borderColor = getTableBorderColor(table);
|
|
559
|
+
// Outer border
|
|
560
|
+
state.elements.push(`<rect x="${tableX.toFixed(2)}" y="${startY.toFixed(2)}" width="${totalWidth.toFixed(2)}" height="${(tableEndY - startY).toFixed(2)}" fill="none" stroke="${borderColor}" stroke-width="0.75"/>`);
|
|
561
|
+
// Horizontal row lines
|
|
562
|
+
for (let r = 1; r < rowYPositions.length - 1; r++) {
|
|
563
|
+
const y = rowYPositions[r];
|
|
564
|
+
state.elements.push(`<line x1="${tableX.toFixed(2)}" y1="${y.toFixed(2)}" x2="${(tableX + totalWidth).toFixed(2)}" y2="${y.toFixed(2)}" stroke="${borderColor}" stroke-width="0.5"/>`);
|
|
565
|
+
}
|
|
566
|
+
// Vertical column lines
|
|
567
|
+
let colX = tableX;
|
|
568
|
+
for (let c = 0; c < colWidths.length - 1; c++) {
|
|
569
|
+
colX += colWidths[c];
|
|
570
|
+
state.elements.push(`<line x1="${colX.toFixed(2)}" y1="${startY.toFixed(2)}" x2="${colX.toFixed(2)}" y2="${tableEndY.toFixed(2)}" stroke="${borderColor}" stroke-width="0.5"/>`);
|
|
571
|
+
}
|
|
572
|
+
// Add some spacing after the table
|
|
573
|
+
state.cursorY += 6;
|
|
574
|
+
}
|
|
575
|
+
/** Compute column widths in points for a table. */
|
|
576
|
+
function computeTableColumnWidths(table, availableWidthPt) {
|
|
577
|
+
if (table.columnWidths && table.columnWidths.length > 0) {
|
|
578
|
+
return table.columnWidths.map(w => twipsToPt(w));
|
|
579
|
+
}
|
|
580
|
+
// Fall back to equal distribution based on max cell count
|
|
581
|
+
let maxCols = 0;
|
|
582
|
+
for (const row of table.rows) {
|
|
583
|
+
if (row.cells.length > maxCols) {
|
|
584
|
+
maxCols = row.cells.length;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
if (maxCols === 0) {
|
|
588
|
+
return [availableWidthPt];
|
|
589
|
+
}
|
|
590
|
+
const colWidth = availableWidthPt / maxCols;
|
|
591
|
+
return Array.from({ length: maxCols }, () => colWidth);
|
|
592
|
+
}
|
|
593
|
+
/** Estimate row height in points. */
|
|
594
|
+
function estimateRowHeightPt(row, colWidths, state) {
|
|
595
|
+
// Check explicit height
|
|
596
|
+
if (row.properties?.height?.value) {
|
|
597
|
+
const rule = row.properties.height.rule;
|
|
598
|
+
if (rule === "exact") {
|
|
599
|
+
return twipsToPt(row.properties.height.value);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
// Estimate from content
|
|
603
|
+
let maxHeight = DEFAULT_FONT_SIZE_PT * 1.2 + 8; // minimum: one line + padding
|
|
604
|
+
for (let c = 0; c < row.cells.length; c++) {
|
|
605
|
+
const cell = row.cells[c];
|
|
606
|
+
let cellHeight = 8; // padding
|
|
607
|
+
for (const content of cell.content) {
|
|
608
|
+
if (content.type === "paragraph") {
|
|
609
|
+
const runs = collectParagraphRuns(content);
|
|
610
|
+
const lineHeight = DEFAULT_FONT_SIZE_PT * 1.2;
|
|
611
|
+
if (runs.length === 0) {
|
|
612
|
+
cellHeight += lineHeight;
|
|
613
|
+
}
|
|
614
|
+
else {
|
|
615
|
+
// Estimate line count
|
|
616
|
+
const allText = runs.map(r => r.text).join("");
|
|
617
|
+
const gridSpan = cell.properties?.gridSpan ?? 1;
|
|
618
|
+
let cellWidth = 0;
|
|
619
|
+
for (let g = 0; g < gridSpan && c + g < colWidths.length; g++) {
|
|
620
|
+
cellWidth += colWidths[c + g];
|
|
621
|
+
}
|
|
622
|
+
const charsPerLine = Math.max(1, Math.floor((cellWidth - 8) / (DEFAULT_FONT_SIZE_PT * 0.5)));
|
|
623
|
+
const lineCount = Math.max(1, Math.ceil(allText.length / charsPerLine));
|
|
624
|
+
cellHeight += lineCount * lineHeight;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
if (cellHeight > maxHeight) {
|
|
629
|
+
maxHeight = cellHeight;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
// Respect atLeast constraint
|
|
633
|
+
if (row.properties?.height?.value) {
|
|
634
|
+
return Math.max(twipsToPt(row.properties.height.value), maxHeight);
|
|
635
|
+
}
|
|
636
|
+
return maxHeight;
|
|
637
|
+
}
|
|
638
|
+
/** Get the border color for a table. */
|
|
639
|
+
function getTableBorderColor(table) {
|
|
640
|
+
const borders = table.properties?.borders;
|
|
641
|
+
if (borders?.top?.color && borders.top.color !== "auto") {
|
|
642
|
+
const safe = sanitizeHexColor(borders.top.color);
|
|
643
|
+
if (safe) {
|
|
644
|
+
return `#${safe}`;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
return "#000000";
|
|
648
|
+
}
|
|
649
|
+
// =============================================================================
|
|
650
|
+
// Floating Image Rendering
|
|
651
|
+
// =============================================================================
|
|
652
|
+
/** Render a floating image. */
|
|
653
|
+
function renderFloatingImage(item, state) {
|
|
654
|
+
const img = item;
|
|
655
|
+
const widthPt = emuToPt(img.width);
|
|
656
|
+
const heightPt = emuToPt(img.height);
|
|
657
|
+
const imgData = findImageData(state.doc, img.rId);
|
|
658
|
+
if (imgData) {
|
|
659
|
+
const dataUri = `data:${imageMediaTypeToMime(imgData.mediaType)};base64,${uint8ToBase64(imgData.data)}`;
|
|
660
|
+
state.elements.push(`<image x="${state.marginLeftPt}" y="${state.cursorY.toFixed(2)}" width="${widthPt.toFixed(1)}" height="${heightPt.toFixed(1)}" href="${(0, encode_1.xmlEncodeAttr)(dataUri)}"/>`);
|
|
661
|
+
}
|
|
662
|
+
else {
|
|
663
|
+
state.elements.push(`<rect x="${state.marginLeftPt}" y="${state.cursorY.toFixed(2)}" width="${widthPt.toFixed(1)}" height="${heightPt.toFixed(1)}" fill="#f0f0f0" stroke="#cccccc" stroke-width="0.5"/>` +
|
|
664
|
+
`<text x="${(state.marginLeftPt + widthPt / 2).toFixed(1)}" y="${(state.cursorY + heightPt / 2).toFixed(1)}" text-anchor="middle" font-size="8" fill="#999999">[Image]</text>`);
|
|
665
|
+
}
|
|
666
|
+
// topAndBottom wrap consumes space
|
|
667
|
+
const wrapStyle = img.wrap?.style;
|
|
668
|
+
if (wrapStyle === "topAndBottom" || !wrapStyle) {
|
|
669
|
+
state.cursorY += heightPt;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
// =============================================================================
|
|
673
|
+
// Page Rendering Core
|
|
674
|
+
// =============================================================================
|
|
675
|
+
/** Render a single page's content to SVG elements. */
|
|
676
|
+
function renderPageContent(doc, layout, pageNumber, sectionProps, options) {
|
|
677
|
+
const pageWidthPt = twipsToPt(sectionProps?.pageSize?.width ?? layout_constants_1.DEFAULT_PAGE_WIDTH_TWIPS);
|
|
678
|
+
const pageHeightPt = twipsToPt(sectionProps?.pageSize?.height ?? layout_constants_1.DEFAULT_PAGE_HEIGHT_TWIPS);
|
|
679
|
+
const marginTopPt = twipsToPt(sectionProps?.margins?.top ?? layout_constants_1.DEFAULT_PAGE_MARGIN_TWIPS);
|
|
680
|
+
const marginBottomPt = twipsToPt(sectionProps?.margins?.bottom ?? layout_constants_1.DEFAULT_PAGE_MARGIN_TWIPS);
|
|
681
|
+
const marginLeftPt = twipsToPt(sectionProps?.margins?.left ?? layout_constants_1.DEFAULT_PAGE_MARGIN_TWIPS);
|
|
682
|
+
const marginRightPt = twipsToPt(sectionProps?.margins?.right ?? layout_constants_1.DEFAULT_PAGE_MARGIN_TWIPS);
|
|
683
|
+
const contentWidthPt = pageWidthPt - marginLeftPt - marginRightPt;
|
|
684
|
+
const contentHeightPt = pageHeightPt - marginTopPt - marginBottomPt;
|
|
685
|
+
const state = {
|
|
686
|
+
pageWidthPt,
|
|
687
|
+
pageHeightPt,
|
|
688
|
+
marginTopPt,
|
|
689
|
+
marginBottomPt,
|
|
690
|
+
marginLeftPt,
|
|
691
|
+
marginRightPt,
|
|
692
|
+
contentWidthPt,
|
|
693
|
+
contentHeightPt,
|
|
694
|
+
fontsMap: options?.fonts,
|
|
695
|
+
doc,
|
|
696
|
+
cursorY: marginTopPt,
|
|
697
|
+
elements: []
|
|
698
|
+
};
|
|
699
|
+
// Render body content that belongs to this page
|
|
700
|
+
for (let i = 0; i < doc.body.length; i++) {
|
|
701
|
+
const contentPage = layout.contentPages[i];
|
|
702
|
+
if (contentPage !== pageNumber) {
|
|
703
|
+
continue;
|
|
704
|
+
}
|
|
705
|
+
// Stop rendering if we've exceeded the content area
|
|
706
|
+
if (state.cursorY > pageHeightPt - marginBottomPt) {
|
|
707
|
+
break;
|
|
708
|
+
}
|
|
709
|
+
const item = doc.body[i];
|
|
710
|
+
switch (item.type) {
|
|
711
|
+
case "paragraph":
|
|
712
|
+
renderParagraph(item, state);
|
|
713
|
+
break;
|
|
714
|
+
case "table":
|
|
715
|
+
renderTable(item, state);
|
|
716
|
+
break;
|
|
717
|
+
case "floatingImage":
|
|
718
|
+
renderFloatingImage(item, state);
|
|
719
|
+
break;
|
|
720
|
+
default:
|
|
721
|
+
// Skip unsupported content types (TOC, shapes, etc.)
|
|
722
|
+
// Advance cursor slightly to maintain spacing
|
|
723
|
+
state.cursorY += DEFAULT_FONT_SIZE_PT * 1.2;
|
|
724
|
+
break;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
return { elements: state.elements, pageWidthPt, pageHeightPt };
|
|
728
|
+
}
|
|
729
|
+
// =============================================================================
|
|
730
|
+
// Public API
|
|
731
|
+
// =============================================================================
|
|
732
|
+
/**
|
|
733
|
+
* Render a specific page of a DOCX document to an SVG string.
|
|
734
|
+
*
|
|
735
|
+
* @param doc - The parsed DOCX document
|
|
736
|
+
* @param pageNumber - 1-based page number to render
|
|
737
|
+
* @param options - Rendering options
|
|
738
|
+
* @returns SVG string for the specified page
|
|
739
|
+
*
|
|
740
|
+
* @stability experimental
|
|
741
|
+
*/
|
|
742
|
+
function renderPageToSvg(doc, pageNumber, options) {
|
|
743
|
+
const layout = (0, layout_1.layoutDocument)(doc, {
|
|
744
|
+
measureText: (text, fontName, fontSize) => (0, font_metrics_1.measureTextWidth)(text, (0, font_metrics_1.mapToStandardFont)(fontName), fontSize)
|
|
745
|
+
});
|
|
746
|
+
if (pageNumber < 1 || pageNumber > layout.pageCount) {
|
|
747
|
+
throw new RangeError(`Page number ${pageNumber} out of range. Document has ${layout.pageCount} page(s).`);
|
|
748
|
+
}
|
|
749
|
+
const sectionProps = getSectionProps(doc, layout, pageNumber);
|
|
750
|
+
const { elements, pageWidthPt, pageHeightPt } = renderPageContent(doc, layout, pageNumber, sectionProps, options);
|
|
751
|
+
return buildSvgDocument(elements, pageWidthPt, pageHeightPt, options);
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Render all pages of a DOCX document to SVG strings.
|
|
755
|
+
*
|
|
756
|
+
* @param doc - The parsed DOCX document
|
|
757
|
+
* @param options - Rendering options
|
|
758
|
+
* @returns Array of SVG strings, one per page
|
|
759
|
+
*
|
|
760
|
+
* @stability experimental
|
|
761
|
+
*/
|
|
762
|
+
function renderDocumentToSvg(doc, options) {
|
|
763
|
+
const layout = (0, layout_1.layoutDocument)(doc, {
|
|
764
|
+
measureText: (text, fontName, fontSize) => (0, font_metrics_1.measureTextWidth)(text, (0, font_metrics_1.mapToStandardFont)(fontName), fontSize)
|
|
765
|
+
});
|
|
766
|
+
const svgPages = [];
|
|
767
|
+
for (let page = 1; page <= layout.pageCount; page++) {
|
|
768
|
+
const sectionProps = getSectionProps(doc, layout, page);
|
|
769
|
+
const { elements, pageWidthPt, pageHeightPt } = renderPageContent(doc, layout, page, sectionProps, options);
|
|
770
|
+
svgPages.push(buildSvgDocument(elements, pageWidthPt, pageHeightPt, options));
|
|
771
|
+
}
|
|
772
|
+
return svgPages;
|
|
773
|
+
}
|
|
774
|
+
/** Build the final SVG document string from rendered elements. */
|
|
775
|
+
function buildSvgDocument(elements, pageWidthPt, pageHeightPt, options) {
|
|
776
|
+
const scale = options?.scale ?? 1.0;
|
|
777
|
+
const bgColor = options?.backgroundColor ?? "white";
|
|
778
|
+
// Determine output dimensions
|
|
779
|
+
let outputWidth;
|
|
780
|
+
let outputHeight;
|
|
781
|
+
if (options?.width && options?.height) {
|
|
782
|
+
outputWidth = options.width;
|
|
783
|
+
outputHeight = options.height;
|
|
784
|
+
}
|
|
785
|
+
else if (options?.width) {
|
|
786
|
+
outputWidth = options.width;
|
|
787
|
+
outputHeight = (pageHeightPt / pageWidthPt) * options.width;
|
|
788
|
+
}
|
|
789
|
+
else if (options?.height) {
|
|
790
|
+
outputHeight = options.height;
|
|
791
|
+
outputWidth = (pageWidthPt / pageHeightPt) * options.height;
|
|
792
|
+
}
|
|
793
|
+
else {
|
|
794
|
+
outputWidth = pageWidthPt * scale;
|
|
795
|
+
outputHeight = pageHeightPt * scale;
|
|
796
|
+
}
|
|
797
|
+
const viewBox = `0 0 ${pageWidthPt.toFixed(2)} ${pageHeightPt.toFixed(2)}`;
|
|
798
|
+
let svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${outputWidth.toFixed(2)}" height="${outputHeight.toFixed(2)}" viewBox="${viewBox}">\n`;
|
|
799
|
+
svg += ` <rect width="100%" height="100%" fill="${(0, encode_1.xmlEncodeAttr)(bgColor)}"/>\n`;
|
|
800
|
+
for (const element of elements) {
|
|
801
|
+
svg += ` ${element}\n`;
|
|
802
|
+
}
|
|
803
|
+
svg += `</svg>`;
|
|
804
|
+
return svg;
|
|
805
|
+
}
|
|
806
|
+
// =============================================================================
|
|
807
|
+
// New API: Render from pre-computed LayoutDocument (no re-layout)
|
|
808
|
+
// =============================================================================
|
|
809
|
+
/**
|
|
810
|
+
* Render a page from a pre-computed LayoutDocument to SVG.
|
|
811
|
+
* This avoids re-computing layout — just serializes positioned elements to SVG.
|
|
812
|
+
*
|
|
813
|
+
* @param layout - A LayoutDocument produced by layoutDocumentFull().
|
|
814
|
+
* @param pageNumber - 1-based page number to render.
|
|
815
|
+
* @param options - Rendering options (scale, dimensions, background color).
|
|
816
|
+
* @returns SVG string.
|
|
817
|
+
*
|
|
818
|
+
* @stability experimental
|
|
819
|
+
*/
|
|
820
|
+
function renderPageFromLayout(layout, pageNumber, options) {
|
|
821
|
+
if (pageNumber < 1 || pageNumber > layout.totalPages) {
|
|
822
|
+
throw new RangeError(`Page number ${pageNumber} out of range. Document has ${layout.totalPages} page(s).`);
|
|
823
|
+
}
|
|
824
|
+
const page = layout.pages[pageNumber - 1];
|
|
825
|
+
const { geometry } = page;
|
|
826
|
+
const elements = [];
|
|
827
|
+
// Header / footer paragraphs and tables come with layout-y already
|
|
828
|
+
// expressed as a page-absolute offset (the layout engine adds the
|
|
829
|
+
// section's `pgMar.header` to header content and starts footer
|
|
830
|
+
// content at `pageHeight - pgMar.footer`). Use a geometry with
|
|
831
|
+
// `marginTop: 0` so SVG y-coordinates resolve straight from
|
|
832
|
+
// layout-y. Tables in header / footer are uncommon but legal —
|
|
833
|
+
// dispatch through the same renderers used for body content.
|
|
834
|
+
const bandGeometry = { ...geometry, marginTop: 0 };
|
|
835
|
+
if (page.header) {
|
|
836
|
+
for (const item of page.header) {
|
|
837
|
+
if (item.type === "paragraph") {
|
|
838
|
+
renderLayoutParagraphToSvg(item, bandGeometry, elements);
|
|
839
|
+
}
|
|
840
|
+
else {
|
|
841
|
+
renderLayoutTableToSvg(item, bandGeometry, elements);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
// Render each positioned content element. Every PageContent variant is
|
|
846
|
+
// handled — most non-paragraph/table types degrade to a placeholder rect
|
|
847
|
+
// (charts, shapes, opaque drawings), an inline glyph (check-boxes, math),
|
|
848
|
+
// or a recursive descent (text-boxes, SDTs). Adding a new PageContent
|
|
849
|
+
// variant is a build error here until a case is added.
|
|
850
|
+
for (const item of page.content) {
|
|
851
|
+
switch (item.type) {
|
|
852
|
+
case "paragraph":
|
|
853
|
+
renderLayoutParagraphToSvg(item, geometry, elements);
|
|
854
|
+
break;
|
|
855
|
+
case "table":
|
|
856
|
+
renderLayoutTableToSvg(item, geometry, elements);
|
|
857
|
+
break;
|
|
858
|
+
case "image":
|
|
859
|
+
renderLayoutImageToSvg(item, geometry, elements);
|
|
860
|
+
break;
|
|
861
|
+
case "float":
|
|
862
|
+
renderLayoutFloatToSvg(item, geometry, elements);
|
|
863
|
+
break;
|
|
864
|
+
case "textBox":
|
|
865
|
+
renderLayoutTextBoxToSvg(item, geometry, elements);
|
|
866
|
+
break;
|
|
867
|
+
case "shape":
|
|
868
|
+
renderLayoutShapeToSvg(item, geometry, elements);
|
|
869
|
+
break;
|
|
870
|
+
case "chart":
|
|
871
|
+
renderLayoutChartToSvg(item, geometry, elements);
|
|
872
|
+
break;
|
|
873
|
+
case "sdt":
|
|
874
|
+
renderLayoutSdtToSvg(item, geometry, elements);
|
|
875
|
+
break;
|
|
876
|
+
case "math":
|
|
877
|
+
renderLayoutMathToSvg(item, geometry, elements);
|
|
878
|
+
break;
|
|
879
|
+
case "checkBox":
|
|
880
|
+
renderLayoutCheckBoxToSvg(item, geometry, elements);
|
|
881
|
+
break;
|
|
882
|
+
case "tableOfContents":
|
|
883
|
+
renderLayoutTocToSvg(item, geometry, elements);
|
|
884
|
+
break;
|
|
885
|
+
case "altChunk":
|
|
886
|
+
renderLayoutPlaceholderToSvg(item.rect, geometry, `[${item.contentType}]`, elements);
|
|
887
|
+
break;
|
|
888
|
+
case "opaqueDrawing":
|
|
889
|
+
renderLayoutPlaceholderToSvg(item.rect, geometry, "[drawing]", elements);
|
|
890
|
+
break;
|
|
891
|
+
default: {
|
|
892
|
+
const _exhaustive = item;
|
|
893
|
+
throw new Error(`renderPageFromLayout: unhandled PageContent ${_exhaustive.type}`);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
// Footer — `bandGeometry` (declared near the header above) shares the
|
|
898
|
+
// same "layout-y is page-absolute" rule for both bands.
|
|
899
|
+
if (page.footer) {
|
|
900
|
+
for (const item of page.footer) {
|
|
901
|
+
if (item.type === "paragraph") {
|
|
902
|
+
renderLayoutParagraphToSvg(item, bandGeometry, elements);
|
|
903
|
+
}
|
|
904
|
+
else {
|
|
905
|
+
renderLayoutTableToSvg(item, bandGeometry, elements);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
// Footnote separator (drawn above the footnote area; see ECMA-376
|
|
910
|
+
// §17.11.10). Same coordinate convention as bands: the layout y
|
|
911
|
+
// value is page-absolute.
|
|
912
|
+
if (page.footnoteSeparator) {
|
|
913
|
+
const sep = page.footnoteSeparator;
|
|
914
|
+
const ruleWidth = sep.kind === "separator" ? geometry.contentWidth / 3 : geometry.contentWidth;
|
|
915
|
+
const x1 = geometry.marginLeft;
|
|
916
|
+
const x2 = x1 + ruleWidth;
|
|
917
|
+
elements.push(`<line x1="${x1.toFixed(2)}" y1="${sep.y.toFixed(2)}" x2="${x2.toFixed(2)}" y2="${sep.y.toFixed(2)}" stroke="black" stroke-width="0.5"/>`);
|
|
918
|
+
}
|
|
919
|
+
// Footnote area paragraphs (page-absolute y, like header/footer).
|
|
920
|
+
if (page.footnoteArea) {
|
|
921
|
+
for (const para of page.footnoteArea) {
|
|
922
|
+
renderLayoutParagraphToSvg(para, bandGeometry, elements);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
return buildSvgDocument(elements, geometry.width, geometry.height, options);
|
|
926
|
+
}
|
|
927
|
+
/** Render a LayoutParagraph to SVG text elements. */
|
|
928
|
+
function renderLayoutParagraphToSvg(para, geometry, elements) {
|
|
929
|
+
for (const line of para.lines) {
|
|
930
|
+
const lineY = geometry.marginTop + para.rect.y + line.y + line.baseline;
|
|
931
|
+
const lineTopY = geometry.marginTop + para.rect.y + line.y;
|
|
932
|
+
for (const item of line.runs) {
|
|
933
|
+
if (item.type === "image") {
|
|
934
|
+
// Inline image: bottom-aligned within the line, matching
|
|
935
|
+
// Word's default for in-line images. Empty data → emit
|
|
936
|
+
// nothing rather than an invalid <image href> with empty src.
|
|
937
|
+
if (item.data.length === 0) {
|
|
938
|
+
continue;
|
|
939
|
+
}
|
|
940
|
+
const x = geometry.marginLeft + item.x;
|
|
941
|
+
const yBottom = lineTopY + Math.min(line.height, item.height);
|
|
942
|
+
const yTop = yBottom - item.height;
|
|
943
|
+
const dataUri = `data:${item.mimeType};base64,${bytesToBase64(item.data)}`;
|
|
944
|
+
elements.push(`<image x="${x.toFixed(2)}" y="${yTop.toFixed(2)}" width="${item.width.toFixed(2)}" height="${item.height.toFixed(2)}" href="${(0, encode_1.xmlEncodeAttr)(dataUri)}"/>`);
|
|
945
|
+
continue;
|
|
946
|
+
}
|
|
947
|
+
const run = item;
|
|
948
|
+
const x = geometry.marginLeft + run.x;
|
|
949
|
+
// Sub/superscript: shift the SVG baseline. SVG y-axis points
|
|
950
|
+
// downward (opposite of PDF), so superscript moves UP (smaller
|
|
951
|
+
// y) and subscript moves DOWN (larger y) — opposite signs from
|
|
952
|
+
// the PDF code.
|
|
953
|
+
let runY = lineY;
|
|
954
|
+
if (run.verticalAlign === "superscript") {
|
|
955
|
+
runY = lineY - run.fontSize * 0.33;
|
|
956
|
+
}
|
|
957
|
+
else if (run.verticalAlign === "subscript") {
|
|
958
|
+
runY = lineY + run.fontSize * 0.33;
|
|
959
|
+
}
|
|
960
|
+
let attrs = `x="${x.toFixed(2)}" y="${runY.toFixed(2)}"`;
|
|
961
|
+
attrs += ` font-family="${(0, encode_1.xmlEncodeAttr)(run.font)}"`;
|
|
962
|
+
attrs += ` font-size="${run.fontSize.toFixed(1)}"`;
|
|
963
|
+
if (run.bold) {
|
|
964
|
+
attrs += ` font-weight="bold"`;
|
|
965
|
+
}
|
|
966
|
+
if (run.italic) {
|
|
967
|
+
attrs += ` font-style="italic"`;
|
|
968
|
+
}
|
|
969
|
+
if (run.color) {
|
|
970
|
+
const safe = sanitizeHexColor(run.color);
|
|
971
|
+
if (safe) {
|
|
972
|
+
attrs += ` fill="#${safe}"`;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
if (run.underline) {
|
|
976
|
+
attrs += ` text-decoration="underline"`;
|
|
977
|
+
}
|
|
978
|
+
else if (run.strikethrough) {
|
|
979
|
+
attrs += ` text-decoration="line-through"`;
|
|
980
|
+
}
|
|
981
|
+
const escapedText = (0, encode_1.xmlEncode)(run.text);
|
|
982
|
+
if (escapedText.length > 0) {
|
|
983
|
+
elements.push(`<text ${attrs}>${escapedText}</text>`);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
/** Render a LayoutTable to SVG (borders + cell content). */
|
|
989
|
+
function renderLayoutTableToSvg(table, geometry, elements) {
|
|
990
|
+
// Draw cell borders and content
|
|
991
|
+
for (const cell of table.cells) {
|
|
992
|
+
const cellX = geometry.marginLeft + table.rect.x + cell.rect.x;
|
|
993
|
+
const cellY = geometry.marginTop + table.rect.y + cell.rect.y;
|
|
994
|
+
const w = cell.rect.width;
|
|
995
|
+
const h = cell.rect.height;
|
|
996
|
+
// Background
|
|
997
|
+
if (cell.backgroundColor) {
|
|
998
|
+
const safeBg = sanitizeHexColor(cell.backgroundColor);
|
|
999
|
+
if (safeBg) {
|
|
1000
|
+
elements.push(`<rect x="${cellX.toFixed(2)}" y="${cellY.toFixed(2)}" width="${w.toFixed(2)}" height="${h.toFixed(2)}" fill="#${safeBg}" stroke="none"/>`);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
// Border
|
|
1004
|
+
elements.push(`<rect x="${cellX.toFixed(2)}" y="${cellY.toFixed(2)}" width="${w.toFixed(2)}" height="${h.toFixed(2)}" fill="none" stroke="#cccccc" stroke-width="0.5"/>`);
|
|
1005
|
+
// Cell paragraph content
|
|
1006
|
+
for (const content of cell.content) {
|
|
1007
|
+
if (content.type === "paragraph") {
|
|
1008
|
+
const offsetPara = {
|
|
1009
|
+
...content,
|
|
1010
|
+
rect: {
|
|
1011
|
+
...content.rect,
|
|
1012
|
+
y: table.rect.y + cell.rect.y + content.rect.y
|
|
1013
|
+
}
|
|
1014
|
+
};
|
|
1015
|
+
// Offset line runs by cell x
|
|
1016
|
+
const offsetLines = content.lines.map(line => ({
|
|
1017
|
+
...line,
|
|
1018
|
+
runs: line.runs.map(run => ({
|
|
1019
|
+
...run,
|
|
1020
|
+
x: run.x + table.rect.x + cell.rect.x
|
|
1021
|
+
}))
|
|
1022
|
+
}));
|
|
1023
|
+
renderLayoutParagraphToSvg({ ...offsetPara, lines: offsetLines }, geometry, elements);
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
// =============================================================================
|
|
1029
|
+
// SVG renderers — extended PageContent variants
|
|
1030
|
+
// =============================================================================
|
|
1031
|
+
function absRect(rect, geometry) {
|
|
1032
|
+
return {
|
|
1033
|
+
x: geometry.marginLeft + rect.x,
|
|
1034
|
+
y: geometry.marginTop + rect.y,
|
|
1035
|
+
width: rect.width,
|
|
1036
|
+
height: rect.height
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
function pushPlaceholder(abs, fillStroke, elements) {
|
|
1040
|
+
const fill = fillStroke.fill ?? "none";
|
|
1041
|
+
const stroke = fillStroke.stroke ?? "#bbbbbb";
|
|
1042
|
+
const sw = (fillStroke.strokeWidth ?? 0.5).toFixed(2);
|
|
1043
|
+
elements.push(`<rect x="${abs.x.toFixed(2)}" y="${abs.y.toFixed(2)}" width="${abs.width.toFixed(2)}" height="${abs.height.toFixed(2)}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"/>`);
|
|
1044
|
+
}
|
|
1045
|
+
function renderLayoutImageToSvg(img, geometry, elements) {
|
|
1046
|
+
const abs = absRect(img.rect, geometry);
|
|
1047
|
+
if (img.data.length === 0) {
|
|
1048
|
+
pushPlaceholder(abs, { stroke: "#888888" }, elements);
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
const dataUri = `data:${img.mimeType};base64,${bytesToBase64(img.data)}`;
|
|
1052
|
+
elements.push(`<image x="${abs.x.toFixed(2)}" y="${abs.y.toFixed(2)}" width="${abs.width.toFixed(2)}" height="${abs.height.toFixed(2)}" href="${(0, encode_1.xmlEncodeAttr)(dataUri)}"/>`);
|
|
1053
|
+
}
|
|
1054
|
+
function renderLayoutFloatToSvg(float, geometry, elements) {
|
|
1055
|
+
// Floats currently always wrap a LayoutImage. Behind-text floats render
|
|
1056
|
+
// before main content in document order; SVG is painters-algorithm so a
|
|
1057
|
+
// dedicated z-ordering pass would belong upstream — for now rendering
|
|
1058
|
+
// order matches `page.content` order which is good enough.
|
|
1059
|
+
if (float.content.type === "image") {
|
|
1060
|
+
renderLayoutImageToSvg(float.content, geometry, elements);
|
|
1061
|
+
}
|
|
1062
|
+
else {
|
|
1063
|
+
renderLayoutParagraphToSvg(float.content, geometry, elements);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
function renderLayoutTextBoxToSvg(tb, geometry, elements) {
|
|
1067
|
+
const abs = absRect(tb.rect, geometry);
|
|
1068
|
+
const safeStroke = tb.border ? sanitizeHexColor(tb.border.color) : undefined;
|
|
1069
|
+
const safeFill = tb.background ? sanitizeHexColor(tb.background) : undefined;
|
|
1070
|
+
pushPlaceholder(abs, {
|
|
1071
|
+
fill: safeFill ? `#${safeFill}` : undefined,
|
|
1072
|
+
stroke: safeStroke ? `#${safeStroke}` : undefined,
|
|
1073
|
+
strokeWidth: tb.border?.width
|
|
1074
|
+
}, elements);
|
|
1075
|
+
// Translate inner content by the text-box origin and recurse through the
|
|
1076
|
+
// generic SVG dispatcher so nested content (paragraphs, tables, even
|
|
1077
|
+
// shapes) renders correctly.
|
|
1078
|
+
const innerGeometry = {
|
|
1079
|
+
...geometry,
|
|
1080
|
+
marginLeft: geometry.marginLeft + tb.rect.x,
|
|
1081
|
+
marginTop: geometry.marginTop + tb.rect.y
|
|
1082
|
+
};
|
|
1083
|
+
renderPageContentList(tb.content, innerGeometry, elements);
|
|
1084
|
+
}
|
|
1085
|
+
function renderLayoutShapeToSvg(shape, geometry, elements) {
|
|
1086
|
+
const abs = absRect(shape.rect, geometry);
|
|
1087
|
+
const fill = shape.fillColor ? `#${sanitizeHexColor(shape.fillColor)}` : "none";
|
|
1088
|
+
const stroke = shape.strokeColor ? `#${sanitizeHexColor(shape.strokeColor)}` : "#888888";
|
|
1089
|
+
const sw = (shape.strokeWidth ?? 0.75).toFixed(2);
|
|
1090
|
+
// Map a few common preset shapes; everything else falls back to a rect.
|
|
1091
|
+
if (shape.preset === "ellipse" || shape.preset === "oval") {
|
|
1092
|
+
const cx = (abs.x + abs.width / 2).toFixed(2);
|
|
1093
|
+
const cy = (abs.y + abs.height / 2).toFixed(2);
|
|
1094
|
+
const rx = (abs.width / 2).toFixed(2);
|
|
1095
|
+
const ry = (abs.height / 2).toFixed(2);
|
|
1096
|
+
elements.push(`<ellipse cx="${cx}" cy="${cy}" rx="${rx}" ry="${ry}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"/>`);
|
|
1097
|
+
}
|
|
1098
|
+
else if (shape.preset === "line") {
|
|
1099
|
+
elements.push(`<line x1="${abs.x.toFixed(2)}" y1="${abs.y.toFixed(2)}" x2="${(abs.x + abs.width).toFixed(2)}" y2="${(abs.y + abs.height).toFixed(2)}" stroke="${stroke}" stroke-width="${sw}"/>`);
|
|
1100
|
+
}
|
|
1101
|
+
else {
|
|
1102
|
+
elements.push(`<rect x="${abs.x.toFixed(2)}" y="${abs.y.toFixed(2)}" width="${abs.width.toFixed(2)}" height="${abs.height.toFixed(2)}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"/>`);
|
|
1103
|
+
}
|
|
1104
|
+
if (shape.textContent && shape.textContent.length > 0) {
|
|
1105
|
+
const innerGeometry = {
|
|
1106
|
+
...geometry,
|
|
1107
|
+
marginLeft: geometry.marginLeft + shape.rect.x,
|
|
1108
|
+
marginTop: geometry.marginTop + shape.rect.y
|
|
1109
|
+
};
|
|
1110
|
+
renderPageContentList(shape.textContent, innerGeometry, elements);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
function renderLayoutChartToSvg(chart, geometry, elements) {
|
|
1114
|
+
const abs = absRect(chart.rect, geometry);
|
|
1115
|
+
if (chart.svg) {
|
|
1116
|
+
// Inline a pre-rendered SVG fragment inside a <g> with an absolute
|
|
1117
|
+
// translate so it ends up at the right page coordinates.
|
|
1118
|
+
elements.push(`<g transform="translate(${abs.x.toFixed(2)} ${abs.y.toFixed(2)})">${chart.svg}</g>`);
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
pushPlaceholder(abs, { stroke: "#666666" }, elements);
|
|
1122
|
+
if (chart.title) {
|
|
1123
|
+
const cx = abs.x + abs.width / 2;
|
|
1124
|
+
const cy = abs.y + abs.height / 2;
|
|
1125
|
+
elements.push(`<text x="${cx.toFixed(2)}" y="${cy.toFixed(2)}" text-anchor="middle" dominant-baseline="central" font-family="Helvetica" font-size="10" fill="#444444">${(0, encode_1.xmlEncode)(chart.title)}</text>`);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
function renderLayoutSdtToSvg(sdt, geometry, elements) {
|
|
1129
|
+
// SDT is transparent visually; recurse into its children using the
|
|
1130
|
+
// page-relative geometry but offset by the SDT's own rect.
|
|
1131
|
+
const innerGeometry = {
|
|
1132
|
+
...geometry,
|
|
1133
|
+
marginLeft: geometry.marginLeft + sdt.rect.x,
|
|
1134
|
+
marginTop: geometry.marginTop + sdt.rect.y
|
|
1135
|
+
};
|
|
1136
|
+
renderPageContentList(sdt.content, innerGeometry, elements);
|
|
1137
|
+
}
|
|
1138
|
+
function renderLayoutMathToSvg(math, geometry, elements) {
|
|
1139
|
+
const abs = absRect(math.rect, geometry);
|
|
1140
|
+
// Render the plain-text fallback. Renderers that want true math display
|
|
1141
|
+
// can read `math.mathML` from the layout document directly.
|
|
1142
|
+
elements.push(`<text x="${abs.x.toFixed(2)}" y="${(abs.y + abs.height * 0.8).toFixed(2)}" font-family="serif" font-style="italic" font-size="${(abs.height * 0.7).toFixed(1)}" fill="#000">${(0, encode_1.xmlEncode)(math.text)}</text>`);
|
|
1143
|
+
}
|
|
1144
|
+
function renderLayoutCheckBoxToSvg(cb, geometry, elements) {
|
|
1145
|
+
const abs = absRect(cb.rect, geometry);
|
|
1146
|
+
// Draw the actual square so the rendered output is independent of font
|
|
1147
|
+
// availability.
|
|
1148
|
+
elements.push(`<rect x="${abs.x.toFixed(2)}" y="${abs.y.toFixed(2)}" width="${abs.height.toFixed(2)}" height="${abs.height.toFixed(2)}" fill="white" stroke="#000" stroke-width="0.75"/>`);
|
|
1149
|
+
if (cb.checked) {
|
|
1150
|
+
const x1 = abs.x + abs.height * 0.2;
|
|
1151
|
+
const y1 = abs.y + abs.height * 0.55;
|
|
1152
|
+
const x2 = abs.x + abs.height * 0.45;
|
|
1153
|
+
const y2 = abs.y + abs.height * 0.8;
|
|
1154
|
+
const x3 = abs.x + abs.height * 0.85;
|
|
1155
|
+
const y3 = abs.y + abs.height * 0.2;
|
|
1156
|
+
elements.push(`<polyline points="${x1.toFixed(2)},${y1.toFixed(2)} ${x2.toFixed(2)},${y2.toFixed(2)} ${x3.toFixed(2)},${y3.toFixed(2)}" fill="none" stroke="#000" stroke-width="1"/>`);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
function renderLayoutTocToSvg(toc, geometry, elements) {
|
|
1160
|
+
// TOC is a list of LayoutParagraphs; render them with a y-offset by the
|
|
1161
|
+
// TOC's own rect.
|
|
1162
|
+
const innerGeometry = {
|
|
1163
|
+
...geometry,
|
|
1164
|
+
marginLeft: geometry.marginLeft + toc.rect.x,
|
|
1165
|
+
marginTop: geometry.marginTop + toc.rect.y
|
|
1166
|
+
};
|
|
1167
|
+
for (const p of toc.entries) {
|
|
1168
|
+
renderLayoutParagraphToSvg(p, innerGeometry, elements);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
function renderLayoutPlaceholderToSvg(rect, geometry, label, elements) {
|
|
1172
|
+
const abs = absRect(rect, geometry);
|
|
1173
|
+
pushPlaceholder(abs, { stroke: "#888888" }, elements);
|
|
1174
|
+
const cx = abs.x + abs.width / 2;
|
|
1175
|
+
const cy = abs.y + abs.height / 2;
|
|
1176
|
+
elements.push(`<text x="${cx.toFixed(2)}" y="${cy.toFixed(2)}" text-anchor="middle" dominant-baseline="central" font-family="Helvetica" font-size="9" fill="#666">${(0, encode_1.xmlEncode)(label)}</text>`);
|
|
1177
|
+
}
|
|
1178
|
+
/** Recursive dispatch helper used by container variants (SDT, TextBox, Shape). */
|
|
1179
|
+
function renderPageContentList(items, geometry, elements) {
|
|
1180
|
+
for (const item of items) {
|
|
1181
|
+
switch (item.type) {
|
|
1182
|
+
case "paragraph":
|
|
1183
|
+
renderLayoutParagraphToSvg(item, geometry, elements);
|
|
1184
|
+
break;
|
|
1185
|
+
case "table":
|
|
1186
|
+
renderLayoutTableToSvg(item, geometry, elements);
|
|
1187
|
+
break;
|
|
1188
|
+
case "image":
|
|
1189
|
+
renderLayoutImageToSvg(item, geometry, elements);
|
|
1190
|
+
break;
|
|
1191
|
+
case "float":
|
|
1192
|
+
renderLayoutFloatToSvg(item, geometry, elements);
|
|
1193
|
+
break;
|
|
1194
|
+
case "textBox":
|
|
1195
|
+
renderLayoutTextBoxToSvg(item, geometry, elements);
|
|
1196
|
+
break;
|
|
1197
|
+
case "shape":
|
|
1198
|
+
renderLayoutShapeToSvg(item, geometry, elements);
|
|
1199
|
+
break;
|
|
1200
|
+
case "chart":
|
|
1201
|
+
renderLayoutChartToSvg(item, geometry, elements);
|
|
1202
|
+
break;
|
|
1203
|
+
case "sdt":
|
|
1204
|
+
renderLayoutSdtToSvg(item, geometry, elements);
|
|
1205
|
+
break;
|
|
1206
|
+
case "math":
|
|
1207
|
+
renderLayoutMathToSvg(item, geometry, elements);
|
|
1208
|
+
break;
|
|
1209
|
+
case "checkBox":
|
|
1210
|
+
renderLayoutCheckBoxToSvg(item, geometry, elements);
|
|
1211
|
+
break;
|
|
1212
|
+
case "tableOfContents":
|
|
1213
|
+
renderLayoutTocToSvg(item, geometry, elements);
|
|
1214
|
+
break;
|
|
1215
|
+
case "altChunk":
|
|
1216
|
+
renderLayoutPlaceholderToSvg(item.rect, geometry, `[${item.contentType}]`, elements);
|
|
1217
|
+
break;
|
|
1218
|
+
case "opaqueDrawing":
|
|
1219
|
+
renderLayoutPlaceholderToSvg(item.rect, geometry, "[drawing]", elements);
|
|
1220
|
+
break;
|
|
1221
|
+
default: {
|
|
1222
|
+
const _exhaustive = item;
|
|
1223
|
+
throw new Error(`renderPageContentList: unhandled PageContent ${_exhaustive.type}`);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
function bytesToBase64(bytes) {
|
|
1229
|
+
// Same approach as core/internal-utils.ts to stay browser-friendly.
|
|
1230
|
+
let binary = "";
|
|
1231
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
1232
|
+
binary += String.fromCharCode(bytes[i]);
|
|
1233
|
+
}
|
|
1234
|
+
if (typeof globalThis.btoa === "function") {
|
|
1235
|
+
return globalThis.btoa(binary);
|
|
1236
|
+
}
|
|
1237
|
+
// Node fallback
|
|
1238
|
+
const buf = globalThis.Buffer;
|
|
1239
|
+
if (buf) {
|
|
1240
|
+
return buf.from(binary, "binary").toString("base64");
|
|
1241
|
+
}
|
|
1242
|
+
throw new Error("btoa / Buffer unavailable; cannot encode image data");
|
|
1243
|
+
}
|