ooxml-core 1.8.3 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/PptxHandler-AT7FVG5Q.mjs +2 -0
- package/dist/{PptxHandler-BL4B7CZO.mjs → PptxHandler-EX4WBIQQ.mjs} +2 -2
- package/dist/PptxHandler-VFSCECPL.cjs +11 -0
- package/dist/automation/index.cjs +7380 -4682
- package/dist/automation/index.mjs +7380 -4682
- package/dist/chunk-AT66SA5M.cjs +44423 -0
- package/dist/{chunk-TTPZITQN.mjs → chunk-FIELY5PI.mjs} +1 -1
- package/dist/{chunk-ZAP5WLEN.mjs → chunk-IGOA57LE.mjs} +1 -1
- package/dist/chunk-LCS3J3QI.mjs +87604 -0
- package/dist/{chunk-NIHPA63A.mjs → chunk-M76PHYRR.mjs} +54 -37
- package/dist/chunk-OB277ZGE.mjs +44107 -0
- package/dist/{chunk-GAGSCAR3.mjs → chunk-OXHMZS7B.mjs} +552 -178
- package/dist/chunk-SWF7KVL5.cjs +87610 -0
- package/dist/{chunk-Z7IQR4S4.mjs → chunk-WSO4T2LJ.mjs} +246 -21
- package/dist/docx/block-parser.d.ts.map +1 -1
- package/dist/docx/cell-blocks.d.ts +4 -0
- package/dist/docx/cell-blocks.d.ts.map +1 -0
- package/dist/docx/document-paragraphs.d.ts.map +1 -1
- package/dist/docx/document-parts.d.ts +2 -0
- package/dist/docx/document-parts.d.ts.map +1 -1
- package/dist/docx/embedded.cjs +189 -20
- package/dist/docx/embedded.mjs +189 -20
- package/dist/docx/index.cjs +219 -24
- package/dist/docx/index.mjs +219 -24
- package/dist/docx/layout/adapt-table.d.ts.map +1 -1
- package/dist/docx/layout/adapter.d.ts.map +1 -1
- package/dist/docx/layout/flow-paragraph.d.ts +5 -0
- package/dist/docx/layout/flow-paragraph.d.ts.map +1 -1
- package/dist/docx/layout/flow-table.d.ts +2 -1
- package/dist/docx/layout/flow-table.d.ts.map +1 -1
- package/dist/docx/layout/footnote-columns.d.ts +22 -0
- package/dist/docx/layout/footnote-columns.d.ts.map +1 -0
- package/dist/docx/layout/footnote-flow.d.ts +27 -0
- package/dist/docx/layout/footnote-flow.d.ts.map +1 -0
- package/dist/docx/layout/footnote-split.d.ts +7 -0
- package/dist/docx/layout/footnote-split.d.ts.map +1 -0
- package/dist/docx/layout/index.cjs +1099 -92
- package/dist/docx/layout/index.mjs +1099 -92
- package/dist/docx/layout/input.d.ts +17 -1
- package/dist/docx/layout/input.d.ts.map +1 -1
- package/dist/docx/layout/legacy-footnote-flow.d.ts +18 -0
- package/dist/docx/layout/legacy-footnote-flow.d.ts.map +1 -0
- package/dist/docx/layout/line-metrics.d.ts.map +1 -1
- package/dist/docx/layout/page-cursor.d.ts +13 -8
- package/dist/docx/layout/page-cursor.d.ts.map +1 -1
- package/dist/docx/layout/page-flow.d.ts.map +1 -1
- package/dist/docx/layout/paragraph-layout.d.ts.map +1 -1
- package/dist/docx/layout/paragraph-tokens.d.ts +2 -0
- package/dist/docx/layout/paragraph-tokens.d.ts.map +1 -1
- package/dist/docx/layout/reference-footnotes.d.ts +7 -0
- package/dist/docx/layout/reference-footnotes.d.ts.map +1 -0
- package/dist/docx/layout/result.d.ts +31 -0
- package/dist/docx/layout/result.d.ts.map +1 -1
- package/dist/docx/layout/section-flow.d.ts +2 -0
- package/dist/docx/layout/section-flow.d.ts.map +1 -1
- package/dist/docx/layout/table-cell-layout.d.ts +11 -0
- package/dist/docx/layout/table-cell-layout.d.ts.map +1 -0
- package/dist/docx/layout/table-footnotes.d.ts +27 -0
- package/dist/docx/layout/table-footnotes.d.ts.map +1 -0
- package/dist/docx/layout/table-layout.d.ts +10 -4
- package/dist/docx/layout/table-layout.d.ts.map +1 -1
- package/dist/docx/load/index.cjs +194 -25
- package/dist/docx/load/index.mjs +194 -25
- package/dist/docx/model-run.d.ts +2 -0
- package/dist/docx/model-run.d.ts.map +1 -1
- package/dist/docx/model.d.ts +7 -0
- package/dist/docx/model.d.ts.map +1 -1
- package/dist/docx/notes.d.ts +5 -0
- package/dist/docx/notes.d.ts.map +1 -1
- package/dist/docx/parse-table.d.ts.map +1 -1
- package/dist/docx/parse.d.ts.map +1 -1
- package/dist/docx/save.d.ts.map +1 -1
- package/dist/docx/section-model.d.ts +2 -0
- package/dist/docx/section-model.d.ts.map +1 -1
- package/dist/docx/sections.d.ts.map +1 -1
- package/dist/docx/settings.d.ts +2 -0
- package/dist/docx/settings.d.ts.map +1 -1
- package/dist/docx/table-model.d.ts +3 -1
- package/dist/docx/table-model.d.ts.map +1 -1
- package/dist/docx/ui/index.cjs +55 -0
- package/dist/docx/ui/index.d.ts +1 -0
- package/dist/docx/ui/index.d.ts.map +1 -1
- package/dist/docx/ui/index.mjs +55 -1
- package/dist/docx/ui/table-structure-guard.d.ts +4 -0
- package/dist/docx/ui/table-structure-guard.d.ts.map +1 -0
- package/dist/docx/write-footnote-columns.d.ts +3 -0
- package/dist/docx/write-footnote-columns.d.ts.map +1 -0
- package/dist/docx/write-notes.d.ts.map +1 -1
- package/dist/docx/write-run.d.ts.map +1 -1
- package/dist/docx/write-sections.d.ts.map +1 -1
- package/dist/index.cjs +8 -5
- package/dist/index.mjs +8 -5
- package/dist/opc/clone-part-graph.d.ts +4 -0
- package/dist/opc/clone-part-graph.d.ts.map +1 -1
- package/dist/opc/index.cjs +8 -5
- package/dist/opc/index.mjs +8 -5
- package/dist/pptx/automation/index.cjs +621 -207
- package/dist/pptx/automation/index.d.ts +3 -3
- package/dist/pptx/automation/index.mjs +5 -5
- package/dist/pptx/chunks/{index-Cn-GzYGp.d.ts → index-B4cnSPNz.d.ts} +33 -4
- package/dist/pptx/chunks/index-B4cnSPNz.d.ts.map +1 -0
- package/dist/pptx/chunks/{index-CKIUurnd.d.ts → index-BZh-IMkN.d.ts} +14 -9
- package/dist/pptx/chunks/{index-CKIUurnd.d.ts.map → index-BZh-IMkN.d.ts.map} +1 -1
- package/dist/pptx/chunks/{text-operations-BHfAm5K9.d.ts → text-operations-BLodkuXE.d.ts} +29 -12
- package/dist/pptx/chunks/text-operations-BLodkuXE.d.ts.map +1 -0
- package/dist/pptx/cli/index.cjs +622 -213
- package/dist/pptx/cli/index.d.ts +1 -1
- package/dist/pptx/cli/index.mjs +4 -4
- package/dist/pptx/converter/index.cjs +53 -36
- package/dist/pptx/converter/index.d.ts +1 -1
- package/dist/pptx/converter/index.mjs +2 -2
- package/dist/pptx/editor/render/find-replace.cjs +416 -45
- package/dist/pptx/editor/render/find-replace.d.ts +35 -4
- package/dist/pptx/editor/render/find-replace.d.ts.map +1 -1
- package/dist/pptx/editor/render/find-replace.mjs +416 -46
- package/dist/pptx/editor/render/slide-operations.cjs +87 -0
- package/dist/pptx/editor/render/slide-operations.d.ts +17 -1
- package/dist/pptx/editor/render/slide-operations.d.ts.map +1 -1
- package/dist/pptx/editor/render/slide-operations.mjs +83 -1
- package/dist/pptx/editor/render/slide-search.cjs +6 -10
- package/dist/pptx/editor/render/slide-search.d.ts +1 -1
- package/dist/pptx/editor/render/slide-search.mjs +6 -10
- package/dist/pptx/editor/render/template-editing.d.ts +1 -1
- package/dist/pptx/editor/render/template-editing.d.ts.map +1 -1
- package/dist/pptx/index.cjs +889 -237
- package/dist/pptx/index.d.ts +4 -4
- package/dist/pptx/index.mjs +5 -5
- package/dist/teams/index.cjs +672 -37
- package/dist/teams/index.mjs +672 -37
- package/dist/visio/accessibility.d.ts +10 -0
- package/dist/visio/accessibility.d.ts.map +1 -0
- package/dist/visio/cell-formula.d.ts +2 -0
- package/dist/visio/cell-formula.d.ts.map +1 -1
- package/dist/visio/connector-curve-aligned.d.ts +5 -0
- package/dist/visio/connector-curve-aligned.d.ts.map +1 -0
- package/dist/visio/connector-curve-spans.d.ts +14 -0
- package/dist/visio/connector-curve-spans.d.ts.map +1 -0
- package/dist/visio/connector-jumps.d.ts +5 -0
- package/dist/visio/connector-jumps.d.ts.map +1 -0
- package/dist/visio/connector-route-walk.d.ts +2 -1
- package/dist/visio/connector-route-walk.d.ts.map +1 -1
- package/dist/visio/edit-alt-text-scope.d.ts +5 -0
- package/dist/visio/edit-alt-text-scope.d.ts.map +1 -0
- package/dist/visio/edit-alt-text.d.ts +3 -0
- package/dist/visio/edit-alt-text.d.ts.map +1 -0
- package/dist/visio/edit-commands.d.ts +7 -2
- package/dist/visio/edit-commands.d.ts.map +1 -1
- package/dist/visio/edit-formatting-commands.d.ts +5 -0
- package/dist/visio/edit-formatting-commands.d.ts.map +1 -1
- package/dist/visio/edit-formatting-paint.d.ts.map +1 -1
- package/dist/visio/edit-formatting-scope.d.ts.map +1 -1
- package/dist/visio/edit-line-jump-cache.d.ts +4 -0
- package/dist/visio/edit-line-jump-cache.d.ts.map +1 -0
- package/dist/visio/edit-master-index.d.ts.map +1 -1
- package/dist/visio/edit-metadata-commands.d.ts +10 -2
- package/dist/visio/edit-metadata-commands.d.ts.map +1 -1
- package/dist/visio/edit-metadata.d.ts +3 -1
- package/dist/visio/edit-metadata.d.ts.map +1 -1
- package/dist/visio/edit-page-alt-text.d.ts +4 -0
- package/dist/visio/edit-page-alt-text.d.ts.map +1 -0
- package/dist/visio/edit-page-layout.d.ts.map +1 -1
- package/dist/visio/edit-page-rename.d.ts.map +1 -1
- package/dist/visio/edit-page-setup-commands.d.ts +7 -1
- package/dist/visio/edit-page-setup-commands.d.ts.map +1 -1
- package/dist/visio/edit-page-size.d.ts.map +1 -1
- package/dist/visio/edit-pages.d.ts.map +1 -1
- package/dist/visio/edit-recalculate-index.d.ts.map +1 -1
- package/dist/visio/edit-scope.d.ts.map +1 -1
- package/dist/visio/edit-shape-create.d.ts.map +1 -1
- package/dist/visio/edit-stencil-connector-write.d.ts.map +1 -1
- package/dist/visio/edit-style-admission.d.ts.map +1 -1
- package/dist/visio/edit-text.d.ts.map +1 -1
- package/dist/visio/edit.d.ts +1 -1
- package/dist/visio/edit.d.ts.map +1 -1
- package/dist/visio/index.cjs +1091 -233
- package/dist/visio/index.d.ts +2 -1
- package/dist/visio/index.d.ts.map +1 -1
- package/dist/visio/index.mjs +1091 -234
- package/dist/visio/line-jumps.d.ts +1 -5
- package/dist/visio/line-jumps.d.ts.map +1 -1
- package/dist/visio/model.d.ts +13 -0
- package/dist/visio/model.d.ts.map +1 -1
- package/dist/visio/page-layout.d.ts +11 -2
- package/dist/visio/page-layout.d.ts.map +1 -1
- package/dist/visio/parser.d.ts.map +1 -1
- package/dist/visio/shape-metadata.d.ts +6 -0
- package/dist/visio/shape-metadata.d.ts.map +1 -1
- package/dist/visio/shapes.d.ts.map +1 -1
- package/dist/visio/text-field-case.d.ts +2 -0
- package/dist/visio/text-field-case.d.ts.map +1 -0
- package/dist/visio/text-field-display.d.ts.map +1 -1
- package/dist/visio/text-field-numeric.d.ts +4 -0
- package/dist/visio/text-field-numeric.d.ts.map +1 -0
- package/dist/visio/ui/connector-preview.d.ts +1 -1
- package/dist/visio/ui/connector-preview.d.ts.map +1 -1
- package/dist/visio/ui/data-graphic-rules.d.ts +2 -0
- package/dist/visio/ui/data-graphic-rules.d.ts.map +1 -1
- package/dist/visio/ui/data-graphics.d.ts +3 -2
- package/dist/visio/ui/data-graphics.d.ts.map +1 -1
- package/dist/visio/ui/edit-commands.d.ts.map +1 -1
- package/dist/visio/ui/index.cjs +16898 -15855
- package/dist/visio/ui/index.mjs +16898 -15856
- package/dist/visio/ui/scene-details.d.ts.map +1 -1
- package/dist/visio/ui/scene-validation.d.ts.map +1 -1
- package/dist/visio/ui/snapshot-scene.d.ts +2 -1
- package/dist/visio/ui/snapshot-scene.d.ts.map +1 -1
- package/dist/visio/xml-attribute-whitespace.d.ts +5 -0
- package/dist/visio/xml-attribute-whitespace.d.ts.map +1 -0
- package/dist/xlsx/edit/index.d.ts +1 -0
- package/dist/xlsx/edit/index.d.ts.map +1 -1
- package/dist/xlsx/edit/insert-guard.d.ts.map +1 -1
- package/dist/xlsx/edit/merge.d.ts.map +1 -1
- package/dist/xlsx/edit/page-breaks.d.ts +5 -0
- package/dist/xlsx/edit/page-breaks.d.ts.map +1 -0
- package/dist/xlsx/edit/pivots.d.ts +8 -0
- package/dist/xlsx/edit/pivots.d.ts.map +1 -0
- package/dist/xlsx/edit/print-titles.d.ts +7 -0
- package/dist/xlsx/edit/print-titles.d.ts.map +1 -0
- package/dist/xlsx/edit/session.d.ts.map +1 -1
- package/dist/xlsx/edit/sheets.d.ts.map +1 -1
- package/dist/xlsx/edit/shift-formulas.d.ts.map +1 -1
- package/dist/xlsx/edit/shift-sheet.d.ts.map +1 -1
- package/dist/xlsx/edit/sparkline-ranges.d.ts +11 -0
- package/dist/xlsx/edit/sparkline-ranges.d.ts.map +1 -0
- package/dist/xlsx/edit/sparkline-xml.d.ts +13 -0
- package/dist/xlsx/edit/sparkline-xml.d.ts.map +1 -0
- package/dist/xlsx/edit/sparklines.d.ts +16 -0
- package/dist/xlsx/edit/sparklines.d.ts.map +1 -0
- package/dist/xlsx/edit/table-edits.d.ts.map +1 -1
- package/dist/xlsx/edit/tables.d.ts.map +1 -1
- package/dist/xlsx/edit/types.d.ts +22 -1
- package/dist/xlsx/edit/types.d.ts.map +1 -1
- package/dist/xlsx/formula/functions/text-regex.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +3415 -1374
- package/dist/xlsx/index.d.ts +1 -0
- package/dist/xlsx/index.d.ts.map +1 -1
- package/dist/xlsx/index.mjs +3396 -1375
- package/dist/xlsx/layout/cell-view.d.ts +2 -0
- package/dist/xlsx/layout/cell-view.d.ts.map +1 -1
- package/dist/xlsx/layout/header-footer.d.ts +58 -0
- package/dist/xlsx/layout/header-footer.d.ts.map +1 -0
- package/dist/xlsx/layout/index.d.ts +5 -0
- package/dist/xlsx/layout/index.d.ts.map +1 -1
- package/dist/xlsx/layout/print-breaks.d.ts +11 -0
- package/dist/xlsx/layout/print-breaks.d.ts.map +1 -0
- package/dist/xlsx/layout/print-layout.d.ts +34 -0
- package/dist/xlsx/layout/print-layout.d.ts.map +1 -0
- package/dist/xlsx/layout/print-merges.d.ts +18 -0
- package/dist/xlsx/layout/print-merges.d.ts.map +1 -0
- package/dist/xlsx/layout/print-repeat.d.ts +12 -0
- package/dist/xlsx/layout/print-repeat.d.ts.map +1 -0
- package/dist/xlsx/layout/print-titles.d.ts +20 -0
- package/dist/xlsx/layout/print-titles.d.ts.map +1 -0
- package/dist/xlsx/layout/sparkline-data.d.ts.map +1 -1
- package/dist/xlsx/layout/sparkline-view.d.ts.map +1 -1
- package/dist/xlsx/load/index.cjs +7831 -6961
- package/dist/xlsx/load/index.mjs +7831 -6961
- package/dist/xlsx/model-pivots.d.ts +46 -0
- package/dist/xlsx/model-pivots.d.ts.map +1 -0
- package/dist/xlsx/model.d.ts +5 -0
- package/dist/xlsx/model.d.ts.map +1 -1
- package/dist/xlsx/pivot/admission.d.ts +5 -0
- package/dist/xlsx/pivot/admission.d.ts.map +1 -0
- package/dist/xlsx/pivot/aggregate.d.ts +19 -0
- package/dist/xlsx/pivot/aggregate.d.ts.map +1 -0
- package/dist/xlsx/pivot/cache-xml.d.ts +9 -0
- package/dist/xlsx/pivot/cache-xml.d.ts.map +1 -0
- package/dist/xlsx/pivot/data.d.ts +12 -0
- package/dist/xlsx/pivot/data.d.ts.map +1 -0
- package/dist/xlsx/pivot/hierarchy.d.ts +7 -0
- package/dist/xlsx/pivot/hierarchy.d.ts.map +1 -0
- package/dist/xlsx/pivot/index.d.ts +3 -0
- package/dist/xlsx/pivot/index.d.ts.map +1 -0
- package/dist/xlsx/pivot/read.d.ts +5 -0
- package/dist/xlsx/pivot/read.d.ts.map +1 -0
- package/dist/xlsx/pivot/table-xml.d.ts +5 -0
- package/dist/xlsx/pivot/table-xml.d.ts.map +1 -0
- package/dist/xlsx/pivot/write.d.ts +11 -0
- package/dist/xlsx/pivot/write.d.ts.map +1 -0
- package/dist/xlsx/read/load.d.ts.map +1 -1
- package/dist/xlsx/read/sheet-props.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/i18n/index.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/i18n/navigation.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/i18n/pivots.d.ts +3 -0
- package/dist/xlsx/ui/commands/i18n/pivots.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/i18n/print-layout.d.ts +3 -0
- package/dist/xlsx/ui/commands/i18n/print-layout.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/i18n/sparklines.d.ts +3 -0
- package/dist/xlsx/ui/commands/i18n/sparklines.d.ts.map +1 -0
- package/dist/xlsx/ui/commands/i18n/tools.d.ts.map +1 -1
- package/dist/xlsx/ui/commands/page-breaks.d.ts +3 -0
- package/dist/xlsx/ui/commands/page-breaks.d.ts.map +1 -0
- package/dist/xlsx/ui/index.cjs +2451 -737
- package/dist/xlsx/ui/index.d.ts +1 -0
- package/dist/xlsx/ui/index.d.ts.map +1 -1
- package/dist/xlsx/ui/index.mjs +2451 -738
- package/dist/xlsx/write/chart-cache.d.ts +8 -0
- package/dist/xlsx/write/chart-cache.d.ts.map +1 -0
- package/dist/xlsx/write/page-setup.d.ts.map +1 -1
- package/dist/xlsx/write/save.d.ts.map +1 -1
- package/dist/xlsx/write/sheet-parts.d.ts +1 -0
- package/dist/xlsx/write/sheet-parts.d.ts.map +1 -1
- package/dist/xlsx/write/workbook-part.d.ts +1 -1
- package/dist/xlsx/write/workbook-part.d.ts.map +1 -1
- package/dist/xlsx/write/worksheet.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/pptx/chunks/index-Cn-GzYGp.d.ts.map +0 -1
- package/dist/pptx/chunks/text-operations-BHfAm5K9.d.ts.map +0 -1
|
@@ -37,8 +37,8 @@ function named(element, local, ns, lenient = true) {
|
|
|
37
37
|
}
|
|
38
38
|
var children = (parent, local, ns, lenient = true) => elements(parent).filter((element) => named(element, local, ns, lenient));
|
|
39
39
|
var first = (parent, local, ns, lenient = true) => parent ? children(parent, local, ns, lenient)[0] : void 0;
|
|
40
|
-
function attr(element, local, ns,
|
|
41
|
-
return element?.getAttributeNS(ns, local) ?? element?.getAttribute(`${
|
|
40
|
+
function attr(element, local, ns, prefix2) {
|
|
41
|
+
return element?.getAttributeNS(ns, local) ?? element?.getAttribute(`${prefix2}:${local}`) ?? void 0;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// docx/xml.ts
|
|
@@ -2649,11 +2649,11 @@ function cssFontFamily(name) {
|
|
|
2649
2649
|
// chart/render/chart-svg-appearance.ts
|
|
2650
2650
|
var nextPaintId = 0;
|
|
2651
2651
|
function chartGradientPaint(model, width = 1024, height = 768) {
|
|
2652
|
-
const
|
|
2652
|
+
const prefix2 = `xlsx-chart-${++nextPaintId}`;
|
|
2653
2653
|
const appearance = { ...model.appearance };
|
|
2654
2654
|
const defs = [];
|
|
2655
2655
|
const shadowPaint = (shadow, suffix) => {
|
|
2656
|
-
const id = `${
|
|
2656
|
+
const id = `${prefix2}-${suffix}`;
|
|
2657
2657
|
const pad = Math.max(4, shadow.blur * 3 + Math.abs(shadow.dx) + Math.abs(shadow.dy));
|
|
2658
2658
|
defs.push(
|
|
2659
2659
|
`<filter id="${id}" filterUnits="userSpaceOnUse" x="${n(-pad)}" y="${n(-pad)}" width="${n(width + pad * 2)}" height="${n(height + pad * 2)}" color-interpolation-filters="sRGB">${svgDropShadowElement(shadow, { number: n, color: (value) => esc(value) })}</filter>`
|
|
@@ -2668,7 +2668,7 @@ function chartGradientPaint(model, width = 1024, height = 768) {
|
|
|
2668
2668
|
};
|
|
2669
2669
|
}
|
|
2670
2670
|
const paint = (gradient, suffix, bounds) => {
|
|
2671
|
-
const def = buildChartGradientDef(`${
|
|
2671
|
+
const def = buildChartGradientDef(`${prefix2}-${suffix}`, gradient, bounds);
|
|
2672
2672
|
defs.push(chartGradientMarkup(def));
|
|
2673
2673
|
return `url(#${def.id})`;
|
|
2674
2674
|
};
|
|
@@ -3708,6 +3708,14 @@ function mapDocumentParagraphs(model, map) {
|
|
|
3708
3708
|
...section.footers ? { footers: slots(section.footers) } : {}
|
|
3709
3709
|
}))
|
|
3710
3710
|
} : {},
|
|
3711
|
+
...model.footnoteSeparators ? {
|
|
3712
|
+
footnoteSeparators: Object.fromEntries(
|
|
3713
|
+
Object.entries(model.footnoteSeparators).map(([kind, note]) => [
|
|
3714
|
+
kind,
|
|
3715
|
+
{ ...note, blocks: mapBlockParagraphs(note.blocks, map) }
|
|
3716
|
+
])
|
|
3717
|
+
)
|
|
3718
|
+
} : {},
|
|
3711
3719
|
...model.footnotes ? {
|
|
3712
3720
|
footnotes: model.footnotes.map((note) => ({
|
|
3713
3721
|
...note,
|
|
@@ -3728,6 +3736,32 @@ function fieldName(instr) {
|
|
|
3728
3736
|
return instr.trim().split(/\s+/)[0]?.toUpperCase() ?? "";
|
|
3729
3737
|
}
|
|
3730
3738
|
|
|
3739
|
+
// docx/cell-blocks.ts
|
|
3740
|
+
function cellSourceBlocks(cell) {
|
|
3741
|
+
if (!cell.sourceBlocks) return cell.paragraphs;
|
|
3742
|
+
const originalIds = new Set(
|
|
3743
|
+
cell.sourceBlocks.filter((block) => block.type === "paragraph").map((block) => block.id)
|
|
3744
|
+
);
|
|
3745
|
+
const positions = new Map(cell.paragraphs.map((paragraph, index) => [paragraph.id, index]));
|
|
3746
|
+
const blocks = [];
|
|
3747
|
+
let cursor = 0;
|
|
3748
|
+
for (const source of cell.sourceBlocks) {
|
|
3749
|
+
if (source.type === "table") {
|
|
3750
|
+
blocks.push(source);
|
|
3751
|
+
continue;
|
|
3752
|
+
}
|
|
3753
|
+
const position = positions.get(source.id);
|
|
3754
|
+
if (position !== void 0 && position >= cursor) {
|
|
3755
|
+
blocks.push(...cell.paragraphs.slice(cursor, position + 1));
|
|
3756
|
+
cursor = position + 1;
|
|
3757
|
+
}
|
|
3758
|
+
while (cursor < cell.paragraphs.length && !originalIds.has(cell.paragraphs[cursor].id))
|
|
3759
|
+
blocks.push(cell.paragraphs[cursor++]);
|
|
3760
|
+
}
|
|
3761
|
+
blocks.push(...cell.paragraphs.slice(cursor));
|
|
3762
|
+
return blocks;
|
|
3763
|
+
}
|
|
3764
|
+
|
|
3731
3765
|
// docx/notes.ts
|
|
3732
3766
|
var romanNumerals = [
|
|
3733
3767
|
[1e3, "M"],
|
|
@@ -3792,7 +3826,7 @@ function walkBlocks(blocks, kind, order) {
|
|
|
3792
3826
|
if (block.type === "paragraph") walkParagraph(block, kind, order);
|
|
3793
3827
|
else
|
|
3794
3828
|
for (const row of block.rows)
|
|
3795
|
-
for (const cell of row) walkBlocks(cell
|
|
3829
|
+
for (const cell of row) walkBlocks(cellSourceBlocks(cell), kind, order);
|
|
3796
3830
|
}
|
|
3797
3831
|
}
|
|
3798
3832
|
function numberNotesInOrder(blocks, kind) {
|
|
@@ -4503,6 +4537,9 @@ function resolveIndents(paragraph) {
|
|
|
4503
4537
|
firstLineExtraPx
|
|
4504
4538
|
};
|
|
4505
4539
|
}
|
|
4540
|
+
function sourceLengthOf(run) {
|
|
4541
|
+
return run.sourceLength ?? (run.object ? 1 : run.text.length || (run.breakAfter ? 1 : 0));
|
|
4542
|
+
}
|
|
4506
4543
|
function tokenizeParagraph(paragraph) {
|
|
4507
4544
|
const tokens = [];
|
|
4508
4545
|
const runOffsets = [];
|
|
@@ -4510,7 +4547,7 @@ function tokenizeParagraph(paragraph) {
|
|
|
4510
4547
|
paragraph.runs.forEach((run, runIndex) => {
|
|
4511
4548
|
runOffsets.push(cursor);
|
|
4512
4549
|
if (run.hidden) {
|
|
4513
|
-
if (!run.synthetic) cursor += run
|
|
4550
|
+
if (!run.synthetic) cursor += sourceLengthOf(run);
|
|
4514
4551
|
return;
|
|
4515
4552
|
}
|
|
4516
4553
|
if (run.object) tokens.push({ kind: "object", runIndex, sourceStart: 0 });
|
|
@@ -4526,7 +4563,7 @@ function tokenizeParagraph(paragraph) {
|
|
|
4526
4563
|
if (run.breakAfter) appendBreakMarker(tokens, runIndex, run.text.length, run.breakAfter);
|
|
4527
4564
|
if (run.synthetic) {
|
|
4528
4565
|
for (const token of tokens) if (token.runIndex === runIndex) token.sourceStart = 0;
|
|
4529
|
-
} else cursor += run
|
|
4566
|
+
} else cursor += sourceLengthOf(run);
|
|
4530
4567
|
});
|
|
4531
4568
|
return { tokens, runOffsets };
|
|
4532
4569
|
}
|
|
@@ -4548,7 +4585,9 @@ function lineMetrics(placed, fonts, paragraph, measurer) {
|
|
|
4548
4585
|
let above = 0;
|
|
4549
4586
|
let below = 0;
|
|
4550
4587
|
for (const token of tokens) {
|
|
4551
|
-
const
|
|
4588
|
+
const run = paragraph.runs[token.runIndex];
|
|
4589
|
+
const metrics = run?.object?.noteSeparator ? fontMetrics(measurer, fonts[token.runIndex] ?? fontOf(run)) : void 0;
|
|
4590
|
+
const extent = metrics ? { above: metrics.ascent, below: metrics.descent } : tokenExtent(token, paragraph, fonts, measurer);
|
|
4552
4591
|
above = Math.max(above, extent.above);
|
|
4553
4592
|
below = Math.max(below, extent.below);
|
|
4554
4593
|
}
|
|
@@ -4623,7 +4662,18 @@ function layoutParagraph(paragraph, contentWidthPx, measurer, note, lineBox, sta
|
|
|
4623
4662
|
const bodyWidth = Math.max(1, contentWidthPx - leftPx - rightPx);
|
|
4624
4663
|
const fonts = paragraph.runs.map(fontOf);
|
|
4625
4664
|
const { tokens, runOffsets } = tokenizeParagraph(paragraph);
|
|
4626
|
-
const globalOffset = (token
|
|
4665
|
+
const globalOffset = (token, advance = 0) => {
|
|
4666
|
+
const run = expectDefined(paragraph.runs[token.runIndex], "source run");
|
|
4667
|
+
const length = sourceLengthOf(run);
|
|
4668
|
+
const offset = run.synthetic ? 0 : Math.max(
|
|
4669
|
+
0,
|
|
4670
|
+
Math.min(
|
|
4671
|
+
length,
|
|
4672
|
+
Math.round((token.sourceStart + advance) * length / Math.max(1, run.text.length))
|
|
4673
|
+
)
|
|
4674
|
+
);
|
|
4675
|
+
return expectDefined(runOffsets[token.runIndex], "run offset index") + offset;
|
|
4676
|
+
};
|
|
4627
4677
|
const effectiveAlign = paragraph.align ?? (paragraph.direction === "rtl" ? "right" : "left");
|
|
4628
4678
|
const lines = [];
|
|
4629
4679
|
const pageBreakAfterLine = /* @__PURE__ */ new Set();
|
|
@@ -4674,9 +4724,9 @@ function layoutParagraph(paragraph, contentWidthPx, measurer, note, lineBox, sta
|
|
|
4674
4724
|
const token = expectDefined(tokens[next], "token index");
|
|
4675
4725
|
if (ends.has(token.kind)) break;
|
|
4676
4726
|
if (beforeDecimalPx === void 0 && token.kind === "word" && /[.,]/.test(token.text)) {
|
|
4677
|
-
const
|
|
4727
|
+
const prefix2 = token.text.slice(0, token.text.search(/[.,]/));
|
|
4678
4728
|
beforeDecimalPx = followingPx + runTextWidth(
|
|
4679
|
-
|
|
4729
|
+
prefix2,
|
|
4680
4730
|
expectDefined(paragraph.runs[token.runIndex], "decimal run"),
|
|
4681
4731
|
measurer
|
|
4682
4732
|
);
|
|
@@ -4695,14 +4745,17 @@ function layoutParagraph(paragraph, contentWidthPx, measurer, note, lineBox, sta
|
|
|
4695
4745
|
const [firstPlaced] = placed;
|
|
4696
4746
|
const start = firstPlaced ? globalOffset(firstPlaced.token) : 0;
|
|
4697
4747
|
const last = placed.at(-1)?.token;
|
|
4698
|
-
const end = last ? globalOffset(last
|
|
4748
|
+
const end = last ? globalOffset(last, last.kind === "word" || last.kind === "space" ? last.text.length : 1) : start;
|
|
4699
4749
|
const gapBeforePx = boxFor(lineIndex).gapBeforePx;
|
|
4700
4750
|
const { heightPx, baselinePx } = lineMetrics(placed, fonts, paragraph, measurer);
|
|
4701
4751
|
rendered.forEach(({ token }, index) => {
|
|
4702
4752
|
const extent2 = tokenExtent(token, paragraph, fonts, measurer);
|
|
4703
4753
|
const fragment = expectDefined(fragments[index], "fragment for rendered token");
|
|
4704
4754
|
fragment.sourceStart = globalOffset(token);
|
|
4705
|
-
fragment.sourceEnd =
|
|
4755
|
+
fragment.sourceEnd = globalOffset(
|
|
4756
|
+
token,
|
|
4757
|
+
token.kind === "word" || token.kind === "space" ? token.text.length : 1
|
|
4758
|
+
);
|
|
4706
4759
|
fragment.topPx = baselinePx - extent2.above;
|
|
4707
4760
|
if (token.kind !== "object") fragment.boxHeightPx = extent2.ascent + extent2.descent;
|
|
4708
4761
|
});
|
|
@@ -4836,6 +4889,57 @@ function widowControlEnabled(value) {
|
|
|
4836
4889
|
return value !== false;
|
|
4837
4890
|
}
|
|
4838
4891
|
|
|
4892
|
+
// docx/layout/table-cell-layout.ts
|
|
4893
|
+
function cellParagraphs(cell) {
|
|
4894
|
+
const walk = (blocks) => blocks.flatMap(
|
|
4895
|
+
(block) => block.kind === "paragraph" ? [block] : block.rows.flatMap((row) => row.cells.flatMap(cellParagraphs))
|
|
4896
|
+
);
|
|
4897
|
+
return cell.blocks ? walk(cell.blocks) : cell.paragraphs;
|
|
4898
|
+
}
|
|
4899
|
+
function stackCellBlocks(cell, width, measurer, note, top, starts) {
|
|
4900
|
+
if (!cell.blocks)
|
|
4901
|
+
return stackParagraphs(
|
|
4902
|
+
starts ? cell.paragraphs.filter((p) => starts.has(p.id)) : cell.paragraphs,
|
|
4903
|
+
width,
|
|
4904
|
+
measurer,
|
|
4905
|
+
note,
|
|
4906
|
+
top,
|
|
4907
|
+
starts
|
|
4908
|
+
);
|
|
4909
|
+
let y = top;
|
|
4910
|
+
const boxes = [];
|
|
4911
|
+
for (const block of cell.blocks) {
|
|
4912
|
+
if (block.kind === "paragraph") {
|
|
4913
|
+
if (starts && !starts.has(block.id)) continue;
|
|
4914
|
+
const result = stackParagraphs([block], width, measurer, note, y, starts);
|
|
4915
|
+
boxes.push(...result.boxes);
|
|
4916
|
+
y = result.heightPx;
|
|
4917
|
+
continue;
|
|
4918
|
+
}
|
|
4919
|
+
const tableWidth = block.widthPx ?? width;
|
|
4920
|
+
const x = block.alignment === "center" ? Math.max(0, (width - tableWidth) / 2) : block.alignment === "right" ? Math.max(0, width - tableWidth) : block.indentPx ?? 0;
|
|
4921
|
+
for (const row of block.rows) {
|
|
4922
|
+
if (starts && !row.cells.some((nested) => cellParagraphs(nested).some((p) => starts.has(p.id))))
|
|
4923
|
+
continue;
|
|
4924
|
+
const layout = layoutRow(row, tableWidth, measurer, note, void 0, starts);
|
|
4925
|
+
layout.cells.forEach((paragraphs, index) => {
|
|
4926
|
+
const geometry = layout.geometry[index];
|
|
4927
|
+
for (const paragraph of paragraphs)
|
|
4928
|
+
boxes.push({
|
|
4929
|
+
...paragraph,
|
|
4930
|
+
yPx: y + paragraph.yPx,
|
|
4931
|
+
xPx: x + geometry.xPx + geometry.paddingLeftPx + (paragraph.xPx ?? 0),
|
|
4932
|
+
widthPx: paragraph.widthPx ?? Math.max(1, geometry.widthPx - geometry.paddingLeftPx - geometry.paddingRightPx),
|
|
4933
|
+
readOnly: true
|
|
4934
|
+
});
|
|
4935
|
+
});
|
|
4936
|
+
y += layout.heightPx;
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
boxes.sort((a, b) => a.yPx - b.yPx);
|
|
4940
|
+
return { heightPx: y, boxes };
|
|
4941
|
+
}
|
|
4942
|
+
|
|
4839
4943
|
// docx/layout/table-layout.ts
|
|
4840
4944
|
function stackParagraphs(paragraphs, widthPx, measurer, note, topPx = 0, startTokens) {
|
|
4841
4945
|
let y = topPx;
|
|
@@ -4851,29 +4955,30 @@ function stackParagraphs(paragraphs, widthPx, measurer, note, topPx = 0, startTo
|
|
|
4851
4955
|
);
|
|
4852
4956
|
y += layout.spacingBeforePx;
|
|
4853
4957
|
const top = y;
|
|
4854
|
-
const lines = layout.lines.map((line2) => ({ ...line2
|
|
4958
|
+
const lines = layout.lines.map((line2) => ({ ...line2 }));
|
|
4855
4959
|
boxes.push({
|
|
4856
4960
|
kind: "paragraph",
|
|
4857
4961
|
blockId: paragraph.id,
|
|
4858
4962
|
yPx: top,
|
|
4859
4963
|
heightPx: layout.contentHeightPx,
|
|
4860
|
-
lines
|
|
4964
|
+
lines,
|
|
4965
|
+
...layout.frame ? { frame: layout.frame } : {}
|
|
4861
4966
|
});
|
|
4862
4967
|
y += layout.contentHeightPx + layout.spacingAfterPx;
|
|
4863
4968
|
}
|
|
4864
4969
|
return { heightPx: y, boxes };
|
|
4865
4970
|
}
|
|
4866
|
-
function layoutRow(row, tableWidthPx, measurer, note, remaining) {
|
|
4971
|
+
function layoutRow(row, tableWidthPx, measurer, note, remaining, startTokens) {
|
|
4867
4972
|
const count = row.cells.length || 1;
|
|
4868
4973
|
let x = 0;
|
|
4869
4974
|
const geometry = [];
|
|
4870
4975
|
const laidOut = row.cells.map((cell) => {
|
|
4871
4976
|
const continuation = remaining?.[geometry.length];
|
|
4872
|
-
const starts = continuation ? new Map(continuation.map((box) => [box.blockId, box.lines[0]?.firstToken ?? 0])) :
|
|
4977
|
+
const starts = continuation ? new Map(continuation.map((box) => [box.blockId, box.lines[0]?.firstToken ?? 0])) : startTokens;
|
|
4873
4978
|
const widthPx = cell.widthPx ?? tableWidthPx / count;
|
|
4874
4979
|
const padding = cell.padding ?? { top: 0, right: 0, bottom: 0, left: 0 };
|
|
4875
|
-
const content2 =
|
|
4876
|
-
|
|
4980
|
+
const content2 = stackCellBlocks(
|
|
4981
|
+
cell,
|
|
4877
4982
|
Math.max(1, widthPx - padding.left - padding.right),
|
|
4878
4983
|
measurer,
|
|
4879
4984
|
note,
|
|
@@ -4896,26 +5001,24 @@ function layoutRow(row, tableWidthPx, measurer, note, remaining) {
|
|
|
4896
5001
|
});
|
|
4897
5002
|
const content = Math.max(0, ...laidOut.map((cell) => cell.heightPx));
|
|
4898
5003
|
const heightPx = row.heightPx === void 0 ? content : row.heightRule === "exact" ? row.heightPx : Math.max(content, row.heightPx);
|
|
4899
|
-
return {
|
|
5004
|
+
return {
|
|
5005
|
+
heightPx,
|
|
5006
|
+
cells: laidOut.map((cell) => cell.boxes),
|
|
5007
|
+
geometry,
|
|
5008
|
+
cellPadding: row.cells.map((cell) => ({
|
|
5009
|
+
top: cell.padding?.top ?? 0,
|
|
5010
|
+
bottom: cell.padding?.bottom ?? 0
|
|
5011
|
+
}))
|
|
5012
|
+
};
|
|
4900
5013
|
}
|
|
4901
5014
|
function splitCellAtHeight(boxes, cutHeightPx) {
|
|
4902
5015
|
const before = [];
|
|
4903
5016
|
const after = [];
|
|
4904
|
-
let afterOrigin = null;
|
|
4905
5017
|
let beforeHeightPx = 0;
|
|
4906
5018
|
for (const box of boxes) {
|
|
4907
|
-
if (afterOrigin !== null) {
|
|
4908
|
-
after.push({ ...box, yPx: box.yPx - afterOrigin });
|
|
4909
|
-
continue;
|
|
4910
|
-
}
|
|
4911
5019
|
if (box.yPx + box.heightPx <= cutHeightPx) {
|
|
4912
5020
|
before.push(box);
|
|
4913
|
-
beforeHeightPx = box.yPx + box.heightPx;
|
|
4914
|
-
continue;
|
|
4915
|
-
}
|
|
4916
|
-
if (box.yPx >= cutHeightPx) {
|
|
4917
|
-
afterOrigin = box.yPx;
|
|
4918
|
-
after.push({ ...box, yPx: 0 });
|
|
5021
|
+
beforeHeightPx = Math.max(beforeHeightPx, box.yPx + box.heightPx);
|
|
4919
5022
|
continue;
|
|
4920
5023
|
}
|
|
4921
5024
|
const beforeLines = box.lines.filter(
|
|
@@ -4925,50 +5028,407 @@ function splitCellAtHeight(boxes, cutHeightPx) {
|
|
|
4925
5028
|
if (beforeLines.length) {
|
|
4926
5029
|
const bottom = beforeLines.at(-1).yPx + beforeLines.at(-1).heightPx;
|
|
4927
5030
|
before.push({ ...box, heightPx: bottom, lines: beforeLines });
|
|
4928
|
-
beforeHeightPx = box.yPx + bottom;
|
|
5031
|
+
beforeHeightPx = Math.max(beforeHeightPx, box.yPx + bottom);
|
|
4929
5032
|
}
|
|
4930
5033
|
if (afterLines.length) {
|
|
4931
5034
|
const shift = expectDefined(afterLines[0], "first line after split").yPx;
|
|
4932
|
-
afterOrigin = box.yPx + shift;
|
|
4933
5035
|
after.push({
|
|
4934
5036
|
...box,
|
|
4935
|
-
yPx:
|
|
5037
|
+
yPx: box.yPx + shift,
|
|
4936
5038
|
heightPx: afterLines.at(-1).yPx + afterLines.at(-1).heightPx - shift,
|
|
4937
5039
|
lines: afterLines.map((line2) => ({ ...line2, yPx: line2.yPx - shift }))
|
|
4938
5040
|
});
|
|
4939
|
-
} else {
|
|
4940
|
-
afterOrigin = box.yPx + box.heightPx;
|
|
4941
5041
|
}
|
|
4942
5042
|
}
|
|
5043
|
+
const afterOrigin = Math.min(...after.map((box) => box.yPx));
|
|
5044
|
+
for (const box of after) box.yPx -= afterOrigin;
|
|
4943
5045
|
return { before, after, beforeHeightPx };
|
|
4944
5046
|
}
|
|
4945
|
-
function splitRowAtHeight(row, cutHeightPx) {
|
|
4946
|
-
const splits = row.cells.map((cell) =>
|
|
5047
|
+
function splitRowAtHeight(row, cutHeightPx, cellCuts) {
|
|
5048
|
+
const splits = row.cells.map((cell, index) => {
|
|
5049
|
+
const padding = row.cellPadding?.[index] ?? { top: 0, bottom: 0 };
|
|
5050
|
+
const split = splitCellAtHeight(cell, (cellCuts?.[index] ?? cutHeightPx) - padding.bottom);
|
|
5051
|
+
if (split.before.length) split.beforeHeightPx += padding.bottom;
|
|
5052
|
+
if (split.after.length)
|
|
5053
|
+
split.after = split.after.map((box) => ({ ...box, yPx: box.yPx + padding.top }));
|
|
5054
|
+
return split;
|
|
5055
|
+
});
|
|
4947
5056
|
const anyAfter = splits.some((split) => split.after.length > 0);
|
|
4948
5057
|
const before = {
|
|
4949
5058
|
heightPx: Math.max(0, ...splits.map((split) => split.beforeHeightPx)),
|
|
4950
5059
|
cells: splits.map((split) => split.before),
|
|
4951
|
-
geometry: row.geometry
|
|
5060
|
+
geometry: row.geometry.map((geometry, index) => ({
|
|
5061
|
+
...geometry,
|
|
5062
|
+
contentHeightPx: splits[index].beforeHeightPx
|
|
5063
|
+
})),
|
|
5064
|
+
...row.cellPadding ? { cellPadding: row.cellPadding } : {}
|
|
4952
5065
|
};
|
|
4953
5066
|
if (!anyAfter) return { before, after: null };
|
|
4954
5067
|
const after = {
|
|
4955
5068
|
heightPx: Math.max(
|
|
4956
5069
|
0,
|
|
4957
5070
|
...splits.map(
|
|
4958
|
-
(split) => split.after.
|
|
5071
|
+
(split, index) => split.after.length ? split.after.at(-1).yPx + split.after.at(-1).heightPx + (row.cellPadding?.[index]?.bottom ?? 0) : 0
|
|
4959
5072
|
)
|
|
4960
5073
|
),
|
|
4961
5074
|
cells: splits.map((split) => split.after),
|
|
4962
|
-
geometry: row.geometry
|
|
5075
|
+
geometry: row.geometry.map((geometry, index) => ({
|
|
5076
|
+
...geometry,
|
|
5077
|
+
contentHeightPx: splits[index].after.length ? splits[index].after.at(-1).yPx + splits[index].after.at(-1).heightPx + (row.cellPadding?.[index]?.bottom ?? 0) : 0
|
|
5078
|
+
})),
|
|
5079
|
+
...row.cellPadding ? { cellPadding: row.cellPadding } : {}
|
|
4963
5080
|
};
|
|
4964
5081
|
return { before, after };
|
|
4965
5082
|
}
|
|
4966
5083
|
|
|
4967
|
-
// docx/layout/
|
|
5084
|
+
// docx/layout/footnote-split.ts
|
|
5085
|
+
function splitNote(note, budget) {
|
|
5086
|
+
if (note.heightPx <= budget + 1e-6) return { before: note };
|
|
5087
|
+
const before = [];
|
|
5088
|
+
const after = [];
|
|
5089
|
+
let origin;
|
|
5090
|
+
const sourceTokenStarts = { ...note.sourceTokenStarts };
|
|
5091
|
+
for (const paragraph of note.paragraphs) {
|
|
5092
|
+
if (origin !== void 0) {
|
|
5093
|
+
after.push({ ...paragraph, yPx: paragraph.yPx - origin });
|
|
5094
|
+
continue;
|
|
5095
|
+
}
|
|
5096
|
+
if (paragraph.yPx + paragraph.heightPx <= budget + 1e-6) {
|
|
5097
|
+
before.push(paragraph);
|
|
5098
|
+
continue;
|
|
5099
|
+
}
|
|
5100
|
+
const count = paragraph.lines.filter(
|
|
5101
|
+
(line2) => paragraph.yPx + line2.yPx + line2.heightPx <= budget + 1e-6
|
|
5102
|
+
).length;
|
|
5103
|
+
const head = paragraph.lines.slice(0, count);
|
|
5104
|
+
const tail = paragraph.lines.slice(count);
|
|
5105
|
+
if (head.length) {
|
|
5106
|
+
const bottom = head.at(-1).yPx + head.at(-1).heightPx;
|
|
5107
|
+
before.push({ ...paragraph, heightPx: bottom, lines: head });
|
|
5108
|
+
}
|
|
5109
|
+
const first3 = tail[0];
|
|
5110
|
+
if (head.length)
|
|
5111
|
+
sourceTokenStarts[paragraph.blockId] = head.at(-1).nextToken ?? sourceTokenStarts[paragraph.blockId] ?? 0;
|
|
5112
|
+
origin = paragraph.yPx + (first3?.yPx ?? 0);
|
|
5113
|
+
after.push({
|
|
5114
|
+
...paragraph,
|
|
5115
|
+
yPx: 0,
|
|
5116
|
+
heightPx: Math.max(0, paragraph.heightPx - (first3?.yPx ?? 0)),
|
|
5117
|
+
lines: tail.map((line2) => ({ ...line2, yPx: line2.yPx - (first3?.yPx ?? 0) }))
|
|
5118
|
+
});
|
|
5119
|
+
}
|
|
5120
|
+
if (!before.length) return { after: note };
|
|
5121
|
+
const last = before.at(-1);
|
|
5122
|
+
return {
|
|
5123
|
+
before: { ...note, heightPx: last.yPx + last.heightPx, paragraphs: before },
|
|
5124
|
+
...after.length ? {
|
|
5125
|
+
after: {
|
|
5126
|
+
...note,
|
|
5127
|
+
yPx: 0,
|
|
5128
|
+
heightPx: Math.max(0, note.heightPx - (origin ?? 0)),
|
|
5129
|
+
paragraphs: after,
|
|
5130
|
+
continued: true,
|
|
5131
|
+
sourceTokenStarts
|
|
5132
|
+
}
|
|
5133
|
+
} : {}
|
|
5134
|
+
};
|
|
5135
|
+
}
|
|
5136
|
+
|
|
5137
|
+
// docx/layout/footnote-columns.ts
|
|
5138
|
+
function footnoteColumns(page, columns) {
|
|
5139
|
+
const width = page.widthPx - page.marginLeftPx - page.marginRightPx;
|
|
5140
|
+
const equal = (width - columns.gapPx * (columns.count - 1)) / columns.count;
|
|
5141
|
+
let x = 0;
|
|
5142
|
+
return Array.from({ length: columns.count }, (_, index) => {
|
|
5143
|
+
const own = columns.widths?.[index];
|
|
5144
|
+
const column = { xPx: x, widthPx: Math.max(1, own?.widthPx ?? equal) };
|
|
5145
|
+
x += column.widthPx + (own?.gapPx ?? columns.gapPx);
|
|
5146
|
+
return column;
|
|
5147
|
+
});
|
|
5148
|
+
}
|
|
5149
|
+
function packFootnotes(notes, columns, height, reflow) {
|
|
5150
|
+
const remaining = [...notes], placed = [];
|
|
5151
|
+
let used = 0;
|
|
5152
|
+
for (const [columnIndex, column] of columns.entries()) {
|
|
5153
|
+
let y = 0;
|
|
5154
|
+
while (remaining.length) {
|
|
5155
|
+
const current = reflow(remaining[0], column.widthPx);
|
|
5156
|
+
const split = splitNote(current, Math.max(0, height - y));
|
|
5157
|
+
if (!split.before) break;
|
|
5158
|
+
placed.push({
|
|
5159
|
+
...split.before,
|
|
5160
|
+
yPx: y,
|
|
5161
|
+
xPx: column.xPx,
|
|
5162
|
+
widthPx: column.widthPx,
|
|
5163
|
+
columnIndex
|
|
5164
|
+
});
|
|
5165
|
+
y += split.before.heightPx;
|
|
5166
|
+
used = Math.max(used, y);
|
|
5167
|
+
if (split.after) {
|
|
5168
|
+
remaining[0] = { ...split.after, continued: !!current.continued };
|
|
5169
|
+
break;
|
|
5170
|
+
}
|
|
5171
|
+
remaining.shift();
|
|
5172
|
+
}
|
|
5173
|
+
}
|
|
5174
|
+
return { placed, remaining, heightPx: used };
|
|
5175
|
+
}
|
|
5176
|
+
function balancedFootnotes(notes, columns, limit, reflow) {
|
|
5177
|
+
if (!notes.length) return { placed: [], remaining: [], heightPx: 0 };
|
|
5178
|
+
const full = packFootnotes(notes, columns, limit, reflow);
|
|
5179
|
+
if (full.remaining.length) return full;
|
|
5180
|
+
let lower = 0, upper = limit;
|
|
5181
|
+
for (let step = 0; step < 24 && upper - lower > 5e-3; step++) {
|
|
5182
|
+
const middle = (lower + upper) / 2;
|
|
5183
|
+
if (packFootnotes(notes, columns, middle, reflow).remaining.length) lower = middle;
|
|
5184
|
+
else upper = middle;
|
|
5185
|
+
}
|
|
5186
|
+
return packFootnotes(notes, columns, Math.ceil(upper * 100) / 100, reflow);
|
|
5187
|
+
}
|
|
5188
|
+
function minimumFootnoteHeight(notes, columns, reflow) {
|
|
5189
|
+
const width = columns[0].widthPx;
|
|
5190
|
+
const maximum = notes.reduce((sum, note) => sum + reflow(note, width).heightPx, 0);
|
|
5191
|
+
return balancedFootnotes(notes, columns, maximum, reflow).heightPx;
|
|
5192
|
+
}
|
|
5193
|
+
|
|
5194
|
+
// docx/layout/footnote-flow.ts
|
|
5195
|
+
function firstLineBottom(note) {
|
|
5196
|
+
const first3 = note?.paragraphs[0];
|
|
5197
|
+
return first3 ? first3.yPx + (first3.lines[0]?.yPx ?? 0) + (first3.lines[0]?.heightPx ?? first3.heightPx) : note?.heightPx ?? 0;
|
|
5198
|
+
}
|
|
4968
5199
|
var FOOTNOTE_SEPARATOR_PX = 12;
|
|
5200
|
+
var FootnoteFlow = class {
|
|
5201
|
+
constructor(report, separator, columns, reflow = (note) => note) {
|
|
5202
|
+
this.report = report;
|
|
5203
|
+
this.separator = separator;
|
|
5204
|
+
this.columns = columns;
|
|
5205
|
+
this.reflow = reflow;
|
|
5206
|
+
}
|
|
5207
|
+
report;
|
|
5208
|
+
separator;
|
|
5209
|
+
columns;
|
|
5210
|
+
reflow;
|
|
5211
|
+
pending;
|
|
5212
|
+
remaining = [];
|
|
5213
|
+
sources = /* @__PURE__ */ new WeakMap();
|
|
5214
|
+
separatorHeight(page, notes = this.pending?.notes ?? []) {
|
|
5215
|
+
return (page.footnoteSeparator ?? this.separator?.(page, !!notes[0]?.continued))?.heightPx ?? FOOTNOTE_SEPARATOR_PX;
|
|
5216
|
+
}
|
|
5217
|
+
get hasContinuation() {
|
|
5218
|
+
return this.remaining.length > 0;
|
|
5219
|
+
}
|
|
5220
|
+
hold(blockId, notes, bodyMinimum, freshBodyMinimum = bodyMinimum) {
|
|
5221
|
+
this.pending = notes.length ? { blockId, notes, bodyMinimum, freshBodyMinimum } : void 0;
|
|
5222
|
+
}
|
|
5223
|
+
reserved(page, _columnIndex = 0) {
|
|
5224
|
+
return page.footnotes?.length ? this.separatorHeight(page) + (page.footnoteHeightPx ?? page.footnotes.reduce((sum, note) => sum + note.heightPx, 0)) : 0;
|
|
5225
|
+
}
|
|
5226
|
+
pendingHeight(page, capacity, bodyUsed, _columnIndex = 0) {
|
|
5227
|
+
if (!this.pending) return 0;
|
|
5228
|
+
if (this.columns) {
|
|
5229
|
+
const existing = this.sources.get(page) ?? [];
|
|
5230
|
+
const height = minimumFootnoteHeight(
|
|
5231
|
+
[...existing, ...this.pending.notes],
|
|
5232
|
+
footnoteColumns(page, this.columns),
|
|
5233
|
+
this.reflow
|
|
5234
|
+
) + this.separatorHeight(page);
|
|
5235
|
+
if (height + this.pending.freshBodyMinimum <= capacity)
|
|
5236
|
+
return Math.max(0, height - this.reserved(page));
|
|
5237
|
+
return Math.max(
|
|
5238
|
+
firstLineBottom(this.pending.notes[0]) + (page.footnotes?.length ? 0 : this.separatorHeight(page)),
|
|
5239
|
+
capacity - bodyUsed - this.reserved(page) - this.pending.bodyMinimum
|
|
5240
|
+
);
|
|
5241
|
+
}
|
|
5242
|
+
const total = this.pending.notes.reduce((sum, note) => sum + note.heightPx, 0);
|
|
5243
|
+
const separator = page.footnotes?.length ? 0 : this.separatorHeight(page);
|
|
5244
|
+
if (total + this.separatorHeight(page) + this.pending.freshBodyMinimum <= capacity)
|
|
5245
|
+
return total + separator;
|
|
5246
|
+
return Math.max(
|
|
5247
|
+
firstLineBottom(this.pending.notes[0]) + separator,
|
|
5248
|
+
capacity - bodyUsed - this.reserved(page) - this.pending.bodyMinimum
|
|
5249
|
+
);
|
|
5250
|
+
}
|
|
5251
|
+
/** A later column cannot grow the page-wide note area into body content already placed. */
|
|
5252
|
+
blockedByEarlierColumn(page, capacity, bodyBottom) {
|
|
5253
|
+
if (!this.pending) return false;
|
|
5254
|
+
if (this.columns)
|
|
5255
|
+
return bodyBottom + this.reserved(page) + this.pendingHeight(page, capacity, bodyBottom) > capacity;
|
|
5256
|
+
const total = this.pending.notes.reduce((sum, note) => sum + note.heightPx, 0);
|
|
5257
|
+
const minimum = firstLineBottom(this.pending.notes[0]);
|
|
5258
|
+
const needed = total + this.separatorHeight(page) + this.pending.freshBodyMinimum <= capacity ? total : minimum;
|
|
5259
|
+
return bodyBottom + this.reserved(page) + needed + (page.footnotes?.length ? 0 : this.separatorHeight(page)) > capacity;
|
|
5260
|
+
}
|
|
5261
|
+
commit(blockId, page, available, _columnIndex = 0) {
|
|
5262
|
+
if (this.pending?.blockId !== blockId) return false;
|
|
5263
|
+
const notes = this.pending.notes;
|
|
5264
|
+
this.pending = void 0;
|
|
5265
|
+
this.append(page, notes, available);
|
|
5266
|
+
return true;
|
|
5267
|
+
}
|
|
5268
|
+
resume(page, capacity, _columnIndex, width) {
|
|
5269
|
+
const notes = width === void 0 ? this.remaining : this.remaining.map((note) => this.reflow(note, width));
|
|
5270
|
+
this.remaining = [];
|
|
5271
|
+
this.append(page, notes, capacity);
|
|
5272
|
+
}
|
|
5273
|
+
append(page, notes, available) {
|
|
5274
|
+
if (!page.footnotes?.length && notes.length) {
|
|
5275
|
+
const separator = this.separator?.(page, !!notes[0]?.continued);
|
|
5276
|
+
if (separator) page.footnoteSeparator = separator;
|
|
5277
|
+
}
|
|
5278
|
+
if (this.columns) {
|
|
5279
|
+
const sources = [...this.sources.get(page) ?? [], ...notes];
|
|
5280
|
+
this.sources.set(page, sources);
|
|
5281
|
+
const geometry = footnoteColumns(page, this.columns);
|
|
5282
|
+
const previousHeight = page.footnoteHeightPx ?? 0;
|
|
5283
|
+
const capacity = Math.max(
|
|
5284
|
+
0,
|
|
5285
|
+
available + previousHeight - (page.footnotes?.length ? 0 : this.separatorHeight(page))
|
|
5286
|
+
);
|
|
5287
|
+
let packed = balancedFootnotes(sources, geometry, capacity, this.reflow);
|
|
5288
|
+
if (!packed.placed.length && sources.length) {
|
|
5289
|
+
this.report(
|
|
5290
|
+
"A footnote line was taller than its available page area and was placed without splitting."
|
|
5291
|
+
);
|
|
5292
|
+
packed = balancedFootnotes(
|
|
5293
|
+
sources,
|
|
5294
|
+
geometry,
|
|
5295
|
+
firstLineBottom(this.reflow(sources[0], geometry[0].widthPx)),
|
|
5296
|
+
this.reflow
|
|
5297
|
+
);
|
|
5298
|
+
}
|
|
5299
|
+
page.footnotes = packed.placed;
|
|
5300
|
+
page.footnoteHeightPx = packed.heightPx;
|
|
5301
|
+
this.remaining = packed.remaining.map((note) => ({
|
|
5302
|
+
...note,
|
|
5303
|
+
continued: !!note.continued || packed.placed.some((fragment) => fragment.id === note.id)
|
|
5304
|
+
}));
|
|
5305
|
+
return;
|
|
5306
|
+
}
|
|
5307
|
+
let top = page.footnotes?.reduce((sum, note) => sum + note.heightPx, 0) ?? 0;
|
|
5308
|
+
let budget = Math.max(0, available - (page.footnotes?.length ? 0 : this.separatorHeight(page)));
|
|
5309
|
+
for (let index = 0; index < notes.length; index++) {
|
|
5310
|
+
const note = notes[index];
|
|
5311
|
+
let split = splitNote(note, budget);
|
|
5312
|
+
if (!split.before && !page.footnotes?.length) {
|
|
5313
|
+
split = splitNote(note, firstLineBottom(note));
|
|
5314
|
+
this.report(
|
|
5315
|
+
"A footnote line was taller than its available page area and was placed without splitting."
|
|
5316
|
+
);
|
|
5317
|
+
}
|
|
5318
|
+
if (split.before) {
|
|
5319
|
+
(page.footnotes ??= []).push({ ...split.before, yPx: top });
|
|
5320
|
+
top += split.before.heightPx;
|
|
5321
|
+
budget -= split.before.heightPx;
|
|
5322
|
+
}
|
|
5323
|
+
if (split.after) {
|
|
5324
|
+
this.remaining.push(split.after, ...notes.slice(index + 1));
|
|
5325
|
+
break;
|
|
5326
|
+
}
|
|
5327
|
+
}
|
|
5328
|
+
}
|
|
5329
|
+
};
|
|
5330
|
+
|
|
5331
|
+
// docx/layout/legacy-footnote-flow.ts
|
|
5332
|
+
var LegacyFootnoteFlow = class {
|
|
5333
|
+
flow;
|
|
5334
|
+
views = /* @__PURE__ */ new WeakMap();
|
|
5335
|
+
constructor(report, separator, reflow = (note) => note) {
|
|
5336
|
+
this.flow = new FootnoteFlow(report, separator, void 0, reflow);
|
|
5337
|
+
}
|
|
5338
|
+
view(page, index) {
|
|
5339
|
+
let views = this.views.get(page);
|
|
5340
|
+
if (!views) {
|
|
5341
|
+
views = /* @__PURE__ */ new Map();
|
|
5342
|
+
this.views.set(page, views);
|
|
5343
|
+
}
|
|
5344
|
+
let view = views.get(index);
|
|
5345
|
+
if (!view) {
|
|
5346
|
+
const {
|
|
5347
|
+
footnotes: _notes,
|
|
5348
|
+
footnoteSeparator: _separator,
|
|
5349
|
+
footnoteHeightPx: _height,
|
|
5350
|
+
footnoteColumnAreas: _areas,
|
|
5351
|
+
...geometry
|
|
5352
|
+
} = page;
|
|
5353
|
+
view = {
|
|
5354
|
+
...geometry,
|
|
5355
|
+
widthPx: page.columns[index].widthPx,
|
|
5356
|
+
marginLeftPx: 0,
|
|
5357
|
+
marginRightPx: 0,
|
|
5358
|
+
columns: []
|
|
5359
|
+
};
|
|
5360
|
+
views.set(index, view);
|
|
5361
|
+
}
|
|
5362
|
+
return view;
|
|
5363
|
+
}
|
|
5364
|
+
sync(page) {
|
|
5365
|
+
const views = this.views.get(page);
|
|
5366
|
+
if (!views) return;
|
|
5367
|
+
const areas = [...views].filter(([, view]) => view.footnotes?.length).map(([columnIndex, view]) => {
|
|
5368
|
+
const column = page.columns[columnIndex];
|
|
5369
|
+
return {
|
|
5370
|
+
columnIndex,
|
|
5371
|
+
xPx: column.xPx,
|
|
5372
|
+
widthPx: column.widthPx,
|
|
5373
|
+
heightPx: view.footnotes.reduce((sum, note) => sum + note.heightPx, 0),
|
|
5374
|
+
continued: !!view.footnotes[0]?.continued,
|
|
5375
|
+
...view.footnoteSeparator ? { separator: view.footnoteSeparator } : {},
|
|
5376
|
+
yPx: 0
|
|
5377
|
+
};
|
|
5378
|
+
});
|
|
5379
|
+
const height = Math.max(0, ...areas.map((area) => area.heightPx));
|
|
5380
|
+
for (const area of areas) area.yPx = height - area.heightPx;
|
|
5381
|
+
page.footnoteColumnAreas = areas;
|
|
5382
|
+
page.footnoteHeightPx = height;
|
|
5383
|
+
page.footnotes = areas.flatMap(
|
|
5384
|
+
(area) => this.view(page, area.columnIndex).footnotes.map((note) => ({
|
|
5385
|
+
...note,
|
|
5386
|
+
xPx: area.xPx,
|
|
5387
|
+
widthPx: area.widthPx,
|
|
5388
|
+
columnIndex: area.columnIndex,
|
|
5389
|
+
yPx: area.yPx + note.yPx
|
|
5390
|
+
}))
|
|
5391
|
+
);
|
|
5392
|
+
}
|
|
5393
|
+
get hasContinuation() {
|
|
5394
|
+
return this.flow.hasContinuation;
|
|
5395
|
+
}
|
|
5396
|
+
hold(blockId, notes, bodyMinimum, freshBodyMinimum = bodyMinimum) {
|
|
5397
|
+
this.flow.hold(blockId, notes, bodyMinimum, freshBodyMinimum);
|
|
5398
|
+
}
|
|
5399
|
+
reserved(page, columnIndex = 0) {
|
|
5400
|
+
return this.flow.reserved(this.view(page, columnIndex));
|
|
5401
|
+
}
|
|
5402
|
+
pendingHeight(page, capacity, bodyUsed, columnIndex = 0) {
|
|
5403
|
+
return this.flow.pendingHeight(this.view(page, columnIndex), capacity, bodyUsed);
|
|
5404
|
+
}
|
|
5405
|
+
blockedByEarlierColumn(_page, _capacity, _bodyBottom) {
|
|
5406
|
+
return false;
|
|
5407
|
+
}
|
|
5408
|
+
commit(blockId, page, available, columnIndex = 0) {
|
|
5409
|
+
if (this.flow.commit(blockId, this.view(page, columnIndex), available)) this.sync(page);
|
|
5410
|
+
}
|
|
5411
|
+
resume(page, capacity, columnIndex) {
|
|
5412
|
+
if (!this.flow.hasContinuation) return;
|
|
5413
|
+
const indexes = columnIndex === void 0 ? page.columns.map((_, index) => index) : [columnIndex];
|
|
5414
|
+
for (const index of indexes) {
|
|
5415
|
+
if (!this.flow.hasContinuation) break;
|
|
5416
|
+
const view = this.view(page, index);
|
|
5417
|
+
if (view.footnotes?.length) continue;
|
|
5418
|
+
this.flow.resume(view, capacity, void 0, view.widthPx);
|
|
5419
|
+
}
|
|
5420
|
+
this.sync(page);
|
|
5421
|
+
}
|
|
5422
|
+
};
|
|
5423
|
+
|
|
5424
|
+
// docx/layout/page-cursor.ts
|
|
4969
5425
|
var PageCursor = class {
|
|
4970
|
-
constructor(pages, geometry, columns, sectionIndex = 0, continueAt, balance) {
|
|
5426
|
+
constructor(pages, geometry, columns, sectionIndex = 0, continueAt, balance, report = () => {
|
|
5427
|
+
}, separator, noteColumns, reflow, legacyFootnoteColumns = false) {
|
|
4971
5428
|
this.balance = balance;
|
|
5429
|
+
this.noteColumns = noteColumns;
|
|
5430
|
+
this.legacyFootnoteColumns = legacyFootnoteColumns;
|
|
5431
|
+
this.footnotes = legacyFootnoteColumns ? new LegacyFootnoteFlow(report, separator, reflow) : new FootnoteFlow(report, separator, noteColumns, reflow);
|
|
4972
5432
|
this.sectionIndex = sectionIndex;
|
|
4973
5433
|
this.pages = pages;
|
|
4974
5434
|
this.geometry = geometry;
|
|
@@ -4992,6 +5452,8 @@ var PageCursor = class {
|
|
|
4992
5452
|
}
|
|
4993
5453
|
}
|
|
4994
5454
|
balance;
|
|
5455
|
+
noteColumns;
|
|
5456
|
+
legacyFootnoteColumns;
|
|
4995
5457
|
pages;
|
|
4996
5458
|
equalColumnWidthPx;
|
|
4997
5459
|
activeColumns = [];
|
|
@@ -5002,10 +5464,7 @@ var PageCursor = class {
|
|
|
5002
5464
|
yPx = 0;
|
|
5003
5465
|
sectionIndex;
|
|
5004
5466
|
pageInSection = 0;
|
|
5005
|
-
|
|
5006
|
-
reservedPx = 0;
|
|
5007
|
-
/** Footnotes of the paragraph about to be placed; they join the page its first box lands on. */
|
|
5008
|
-
pending;
|
|
5467
|
+
footnotes;
|
|
5009
5468
|
columnBoxes(offsetPx = 0) {
|
|
5010
5469
|
const columnBoxes = [];
|
|
5011
5470
|
let xPx = offsetPx;
|
|
@@ -5040,7 +5499,7 @@ var PageCursor = class {
|
|
|
5040
5499
|
this.columnIndex = 0;
|
|
5041
5500
|
this.columnTopPx = 0;
|
|
5042
5501
|
this.yPx = 0;
|
|
5043
|
-
this.
|
|
5502
|
+
this.footnotes.resume(this.page, this.physicalColumnHeightPx);
|
|
5044
5503
|
}
|
|
5045
5504
|
get page() {
|
|
5046
5505
|
return this.pages.at(-1);
|
|
@@ -5048,6 +5507,9 @@ var PageCursor = class {
|
|
|
5048
5507
|
get column() {
|
|
5049
5508
|
return expectDefined(this.activeColumns[this.columnIndex], "current page column");
|
|
5050
5509
|
}
|
|
5510
|
+
get noteColumnIndex() {
|
|
5511
|
+
return this.legacyFootnoteColumns ? this.page.columns.indexOf(this.column) : this.columnIndex;
|
|
5512
|
+
}
|
|
5051
5513
|
get columnWidthPx() {
|
|
5052
5514
|
return this.column.widthPx;
|
|
5053
5515
|
}
|
|
@@ -5062,6 +5524,9 @@ var PageCursor = class {
|
|
|
5062
5524
|
endBalance() {
|
|
5063
5525
|
this.balance = void 0;
|
|
5064
5526
|
}
|
|
5527
|
+
get footnoteWidthPx() {
|
|
5528
|
+
return this.noteColumns ? footnoteColumns(this.page, this.noteColumns)[0].widthPx : this.columnWidthPx;
|
|
5529
|
+
}
|
|
5065
5530
|
get y() {
|
|
5066
5531
|
return this.yPx;
|
|
5067
5532
|
}
|
|
@@ -5085,7 +5550,7 @@ var PageCursor = class {
|
|
|
5085
5550
|
);
|
|
5086
5551
|
}
|
|
5087
5552
|
remainingHeightPx() {
|
|
5088
|
-
return this.columnHeightPx - (this.yPx - this.columnTopPx) - this.
|
|
5553
|
+
return this.columnHeightPx - (this.yPx - this.columnTopPx) - this.footnotes.reserved(this.page, this.noteColumnIndex) - this.pendingHeightPx();
|
|
5089
5554
|
}
|
|
5090
5555
|
/** Close this section's column band before another section shares its page. */
|
|
5091
5556
|
finishBand() {
|
|
@@ -5104,16 +5569,41 @@ var PageCursor = class {
|
|
|
5104
5569
|
return bottom;
|
|
5105
5570
|
}
|
|
5106
5571
|
pendingHeightPx() {
|
|
5107
|
-
|
|
5108
|
-
|
|
5572
|
+
return this.footnotes.pendingHeight(
|
|
5573
|
+
this.page,
|
|
5574
|
+
this.columnHeightPx,
|
|
5575
|
+
this.usedColumnHeightPx,
|
|
5576
|
+
this.noteColumnIndex
|
|
5577
|
+
);
|
|
5109
5578
|
}
|
|
5110
5579
|
/**
|
|
5111
5580
|
* Reserves room for a paragraph's footnotes on whichever page its first box is placed, so the
|
|
5112
5581
|
* notes print on the same page as their reference, as Word does.
|
|
5113
5582
|
*/
|
|
5114
|
-
holdFootnotes(blockId, notes) {
|
|
5115
|
-
|
|
5116
|
-
|
|
5583
|
+
holdFootnotes(blockId, notes, bodyMinimum = 0, freshBodyMinimum = bodyMinimum) {
|
|
5584
|
+
this.footnotes.hold(blockId, notes, bodyMinimum, freshBodyMinimum);
|
|
5585
|
+
}
|
|
5586
|
+
/** Finish long notes even when the section has no more body paragraphs. */
|
|
5587
|
+
finishFootnotes() {
|
|
5588
|
+
while (this.footnotes.hasContinuation) {
|
|
5589
|
+
if (this.legacyFootnoteColumns) this.newColumn();
|
|
5590
|
+
else this.newPage();
|
|
5591
|
+
}
|
|
5592
|
+
}
|
|
5593
|
+
/** Continued notes can occupy an otherwise empty page, before body/table content starts. */
|
|
5594
|
+
advancePastFootnotes(minimumBodyHeight) {
|
|
5595
|
+
while (this.page.footnotes?.length && this.atColumnTop && this.remainingHeightPx() < minimumBodyHeight - 1e-6 || this.columnIndex > 0 && this.footnotes.blockedByEarlierColumn(
|
|
5596
|
+
this.page,
|
|
5597
|
+
this.columnHeightPx,
|
|
5598
|
+
Math.max(
|
|
5599
|
+
0,
|
|
5600
|
+
...this.activeColumns.slice(0, this.columnIndex).flatMap(
|
|
5601
|
+
(column) => column.blocks.map((block) => block.yPx + block.heightPx - this.columnTopPx)
|
|
5602
|
+
)
|
|
5603
|
+
)
|
|
5604
|
+
))
|
|
5605
|
+
if (this.legacyFootnoteColumns) this.newColumn();
|
|
5606
|
+
else this.newPage();
|
|
5117
5607
|
}
|
|
5118
5608
|
newPage() {
|
|
5119
5609
|
this.pushPage();
|
|
@@ -5123,6 +5613,8 @@ var PageCursor = class {
|
|
|
5123
5613
|
if (this.columnIndex + 1 < this.columns.count) {
|
|
5124
5614
|
this.columnIndex++;
|
|
5125
5615
|
this.yPx = this.columnTopPx;
|
|
5616
|
+
if (this.legacyFootnoteColumns)
|
|
5617
|
+
this.footnotes.resume(this.page, this.physicalColumnHeightPx, this.noteColumnIndex);
|
|
5126
5618
|
} else {
|
|
5127
5619
|
this.pushPage();
|
|
5128
5620
|
}
|
|
@@ -5136,25 +5628,54 @@ var PageCursor = class {
|
|
|
5136
5628
|
box.yPx = this.yPx;
|
|
5137
5629
|
this.column.blocks.push(box);
|
|
5138
5630
|
this.yPx += advancePx;
|
|
5139
|
-
|
|
5140
|
-
this.
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
this.
|
|
5148
|
-
|
|
5631
|
+
const bodyBottom = this.legacyFootnoteColumns ? this.yPx : Math.max(
|
|
5632
|
+
this.yPx,
|
|
5633
|
+
...this.activeColumns.flatMap(
|
|
5634
|
+
(column) => column.blocks.map((block) => block.yPx + block.heightPx)
|
|
5635
|
+
)
|
|
5636
|
+
);
|
|
5637
|
+
this.footnotes.commit(
|
|
5638
|
+
box.blockId,
|
|
5639
|
+
this.page,
|
|
5640
|
+
this.columnHeightPx - (bodyBottom - this.columnTopPx) - this.footnotes.reserved(this.page, this.noteColumnIndex),
|
|
5641
|
+
this.noteColumnIndex
|
|
5642
|
+
);
|
|
5149
5643
|
}
|
|
5150
5644
|
};
|
|
5151
5645
|
|
|
5152
5646
|
// docx/layout/flow-paragraph.ts
|
|
5153
5647
|
function placeParagraph(cursor, placement, note) {
|
|
5154
5648
|
const { paragraph, spacingBeforePx, requiredTogetherPx, reflow } = placement;
|
|
5155
|
-
|
|
5649
|
+
const trailingBreakLine = (result) => {
|
|
5650
|
+
const last = result.lines.at(-1);
|
|
5651
|
+
if (!placement.trimLeadingColumnBreak || !last || !result.columnBreakAfterLine.has(result.lines.length - 1))
|
|
5652
|
+
return result;
|
|
5653
|
+
return {
|
|
5654
|
+
...result,
|
|
5655
|
+
contentHeightPx: result.contentHeightPx + last.heightPx,
|
|
5656
|
+
lines: [
|
|
5657
|
+
...result.lines,
|
|
5658
|
+
{
|
|
5659
|
+
...last,
|
|
5660
|
+
yPx: last.yPx + last.heightPx,
|
|
5661
|
+
fragments: [],
|
|
5662
|
+
sourceStart: last.sourceEnd,
|
|
5663
|
+
sourceEnd: last.sourceEnd
|
|
5664
|
+
}
|
|
5665
|
+
]
|
|
5666
|
+
};
|
|
5667
|
+
};
|
|
5668
|
+
let layout = trailingBreakLine(placement.layout);
|
|
5156
5669
|
let width = cursor.columnWidthPx;
|
|
5157
5670
|
if (paragraph.pageBreakBefore && cursor.hasPageContent) cursor.newPage();
|
|
5671
|
+
if (requiredTogetherPx > 0 && placement.footnotes) {
|
|
5672
|
+
cursor.holdFootnotes(
|
|
5673
|
+
paragraph.id,
|
|
5674
|
+
placement.footnotes(layout.lines, true),
|
|
5675
|
+
requiredTogetherPx,
|
|
5676
|
+
layout.lines[0]?.heightPx ?? 0
|
|
5677
|
+
);
|
|
5678
|
+
}
|
|
5158
5679
|
if (requiredTogetherPx > 0 && requiredTogetherPx <= cursor.columnHeightPx && requiredTogetherPx > cursor.remainingHeightPx() && !cursor.atColumnTop) {
|
|
5159
5680
|
cursor.newColumn();
|
|
5160
5681
|
}
|
|
@@ -5162,9 +5683,23 @@ function placeParagraph(cursor, placement, note) {
|
|
|
5162
5683
|
let lineCursor = 0;
|
|
5163
5684
|
let nextToken = 0;
|
|
5164
5685
|
let firstSegment = true;
|
|
5686
|
+
const lineHeight = (line2, index) => placement.trimLeadingColumnBreak && layout.columnBreakAfterLine.has(index) && line2.fragments.every((fragment) => !fragment.text && !fragment.object) ? 0 : line2.heightPx;
|
|
5687
|
+
const placedNotes = /* @__PURE__ */ new Set();
|
|
5688
|
+
const notesFor = (lines) => (placement.footnotes?.(lines, firstSegment) ?? []).filter((item) => !placedNotes.has(item.id));
|
|
5689
|
+
const hold = (lines, bodyMinimum) => {
|
|
5690
|
+
const notes = notesFor(lines);
|
|
5691
|
+
if (placement.footnotes)
|
|
5692
|
+
cursor.holdFootnotes(
|
|
5693
|
+
paragraph.id,
|
|
5694
|
+
notes,
|
|
5695
|
+
bodyMinimum,
|
|
5696
|
+
Math.max(0, ...lines.map((line2) => line2.heightPx))
|
|
5697
|
+
);
|
|
5698
|
+
return notes;
|
|
5699
|
+
};
|
|
5165
5700
|
const reflowIfNeeded = () => {
|
|
5166
5701
|
if (!reflow || cursor.columnWidthPx === width) return;
|
|
5167
|
-
layout = reflow(nextToken);
|
|
5702
|
+
layout = trailingBreakLine(reflow(nextToken));
|
|
5168
5703
|
lineCursor = 0;
|
|
5169
5704
|
width = cursor.columnWidthPx;
|
|
5170
5705
|
};
|
|
@@ -5178,15 +5713,27 @@ function placeParagraph(cursor, placement, note) {
|
|
|
5178
5713
|
}
|
|
5179
5714
|
while (lineCursor < layout.lines.length) {
|
|
5180
5715
|
reflowIfNeeded();
|
|
5181
|
-
|
|
5716
|
+
hold(
|
|
5717
|
+
layout.lines.slice(lineCursor, lineCursor + 1),
|
|
5718
|
+
layout.lines[lineCursor] ? lineHeight(layout.lines[lineCursor], lineCursor) : 0
|
|
5719
|
+
);
|
|
5720
|
+
cursor.advancePastFootnotes(
|
|
5721
|
+
layout.lines[lineCursor] ? lineHeight(layout.lines[lineCursor], lineCursor) : 0
|
|
5722
|
+
);
|
|
5723
|
+
reflowIfNeeded();
|
|
5182
5724
|
let cumulative = 0;
|
|
5183
5725
|
let end = lineCursor;
|
|
5184
5726
|
let forced;
|
|
5185
5727
|
for (let i = lineCursor; i < layout.lines.length; i++) {
|
|
5186
5728
|
const line2 = expectDefined(layout.lines[i], "paragraph line index");
|
|
5187
5729
|
const gap = i === lineCursor && !firstSegment ? 0 : line2.gapBeforePx ?? 0;
|
|
5188
|
-
const height = line2
|
|
5189
|
-
|
|
5730
|
+
const height = lineHeight(line2, i) + gap;
|
|
5731
|
+
hold(
|
|
5732
|
+
layout.lines.slice(lineCursor, i + 1),
|
|
5733
|
+
cumulative + height + (firstSegment ? spacingBeforePx : 0)
|
|
5734
|
+
);
|
|
5735
|
+
const budget = cursor.remainingHeightPx() - (firstSegment ? spacingBeforePx : 0);
|
|
5736
|
+
if (cumulative + height > budget + 1e-6 && (end > lineCursor || !cursor.atColumnTop)) break;
|
|
5190
5737
|
cumulative += height;
|
|
5191
5738
|
end = i + 1;
|
|
5192
5739
|
if (layout.pageBreakAfterLine.has(i)) {
|
|
@@ -5211,9 +5758,17 @@ function placeParagraph(cursor, placement, note) {
|
|
|
5211
5758
|
);
|
|
5212
5759
|
placedCount = Math.max(1, end - lineCursor);
|
|
5213
5760
|
}
|
|
5761
|
+
const committedNotes = hold(
|
|
5762
|
+
layout.lines.slice(lineCursor, lineCursor + placedCount),
|
|
5763
|
+
cumulative + (firstSegment ? spacingBeforePx : 0)
|
|
5764
|
+
);
|
|
5214
5765
|
const first3 = expectDefined(layout.lines[lineCursor], "first line of paragraph segment");
|
|
5215
5766
|
const origin = first3.yPx - (firstSegment ? (first3.gapBeforePx ?? 0) + layout.insetTopPx : 0);
|
|
5216
|
-
const segmentLines = layout.lines.slice(lineCursor, lineCursor + placedCount).map((line2) => ({
|
|
5767
|
+
const segmentLines = layout.lines.slice(lineCursor, lineCursor + placedCount).map((line2, index) => ({
|
|
5768
|
+
...line2,
|
|
5769
|
+
yPx: line2.yPx - origin,
|
|
5770
|
+
heightPx: lineHeight(line2, lineCursor + index)
|
|
5771
|
+
}));
|
|
5217
5772
|
const isFinal = lineCursor + placedCount >= layout.lines.length;
|
|
5218
5773
|
const lastLine = segmentLines.at(-1);
|
|
5219
5774
|
const isLastSegment = lineCursor + placedCount >= layout.lines.length;
|
|
@@ -5228,6 +5783,7 @@ function placeParagraph(cursor, placement, note) {
|
|
|
5228
5783
|
};
|
|
5229
5784
|
const advance = (firstSegment ? spacingBeforePx : 0) + segmentHeight + (isFinal ? layout.spacingAfterPx : 0);
|
|
5230
5785
|
cursor.place(box, advance);
|
|
5786
|
+
for (const item of committedNotes) placedNotes.add(item.id);
|
|
5231
5787
|
nextToken = layout.lines[lineCursor + placedCount - 1]?.nextToken ?? nextToken;
|
|
5232
5788
|
lineCursor += placedCount;
|
|
5233
5789
|
firstSegment = false;
|
|
@@ -5237,8 +5793,170 @@ function placeParagraph(cursor, placement, note) {
|
|
|
5237
5793
|
}
|
|
5238
5794
|
}
|
|
5239
5795
|
|
|
5796
|
+
// docx/layout/table-footnotes.ts
|
|
5797
|
+
function prefix(row, cut, cellCuts) {
|
|
5798
|
+
const cells = row.cells.map((cell, index) => {
|
|
5799
|
+
const contentCut = (cellCuts?.[index] ?? cut) - (row.cellPadding?.[index]?.bottom ?? 0);
|
|
5800
|
+
const boxes = [];
|
|
5801
|
+
for (const box of cell) {
|
|
5802
|
+
if (box.yPx >= contentCut + 1e-6) break;
|
|
5803
|
+
if (box.yPx + box.heightPx <= contentCut + 1e-6) {
|
|
5804
|
+
boxes.push(box);
|
|
5805
|
+
continue;
|
|
5806
|
+
}
|
|
5807
|
+
const lines = [];
|
|
5808
|
+
for (const line2 of box.lines) {
|
|
5809
|
+
if (box.yPx + line2.yPx + line2.heightPx > contentCut + 1e-6) break;
|
|
5810
|
+
lines.push(line2);
|
|
5811
|
+
}
|
|
5812
|
+
if (lines.length)
|
|
5813
|
+
boxes.push({ ...box, lines, heightPx: lines.at(-1).yPx + lines.at(-1).heightPx });
|
|
5814
|
+
continue;
|
|
5815
|
+
}
|
|
5816
|
+
return boxes;
|
|
5817
|
+
});
|
|
5818
|
+
if (cells.every(
|
|
5819
|
+
(cell, index) => cell.length === row.cells[index].length && cell.every(
|
|
5820
|
+
(box, boxIndex) => box.lines.length === row.cells[index][boxIndex].lines.length
|
|
5821
|
+
)
|
|
5822
|
+
))
|
|
5823
|
+
return row;
|
|
5824
|
+
return {
|
|
5825
|
+
...row,
|
|
5826
|
+
cells,
|
|
5827
|
+
heightPx: Math.max(
|
|
5828
|
+
0,
|
|
5829
|
+
...cells.flatMap(
|
|
5830
|
+
(cell, index) => cell.map((box) => box.yPx + box.heightPx + (row.cellPadding?.[index]?.bottom ?? 0))
|
|
5831
|
+
)
|
|
5832
|
+
)
|
|
5833
|
+
};
|
|
5834
|
+
}
|
|
5835
|
+
var TableFootnotes = class {
|
|
5836
|
+
constructor(cursor, table, height, resolve) {
|
|
5837
|
+
this.cursor = cursor;
|
|
5838
|
+
this.table = table;
|
|
5839
|
+
this.height = height;
|
|
5840
|
+
this.resolve = resolve;
|
|
5841
|
+
for (const row of table.rows)
|
|
5842
|
+
for (const cell of row.cells)
|
|
5843
|
+
for (const paragraph of cellParagraphs(cell))
|
|
5844
|
+
if (paragraph.footnotes?.length) this.paragraphs.set(paragraph.id, paragraph);
|
|
5845
|
+
}
|
|
5846
|
+
cursor;
|
|
5847
|
+
table;
|
|
5848
|
+
height;
|
|
5849
|
+
resolve;
|
|
5850
|
+
paragraphs = /* @__PURE__ */ new Map();
|
|
5851
|
+
placed = /* @__PURE__ */ new Set();
|
|
5852
|
+
fragment = /* @__PURE__ */ new Map();
|
|
5853
|
+
references(row) {
|
|
5854
|
+
const refs = /* @__PURE__ */ new Map();
|
|
5855
|
+
for (const cell of row.cells)
|
|
5856
|
+
for (const box of cell) {
|
|
5857
|
+
const source = this.paragraphs.get(box.blockId);
|
|
5858
|
+
if (!source) continue;
|
|
5859
|
+
for (const note of this.resolve(
|
|
5860
|
+
source,
|
|
5861
|
+
box.lines,
|
|
5862
|
+
(box.lines[0]?.sourceStart ?? 0) === 0
|
|
5863
|
+
)) {
|
|
5864
|
+
if (this.placed.has(note.id)) continue;
|
|
5865
|
+
const line2 = box.lines.find(
|
|
5866
|
+
(line3) => line3.fragments.some(
|
|
5867
|
+
(fragment) => source.runs[fragment.runIndex]?.footnoteReferenceId === note.id
|
|
5868
|
+
)
|
|
5869
|
+
) ?? box.lines[0];
|
|
5870
|
+
const bottom = Math.min(
|
|
5871
|
+
row.heightPx,
|
|
5872
|
+
box.yPx + (line2?.yPx ?? 0) + (line2?.heightPx ?? box.heightPx)
|
|
5873
|
+
);
|
|
5874
|
+
const prior = refs.get(note.id);
|
|
5875
|
+
if (!prior || bottom < prior.bottom) refs.set(note.id, { note, bottom });
|
|
5876
|
+
}
|
|
5877
|
+
}
|
|
5878
|
+
return [...refs.values()];
|
|
5879
|
+
}
|
|
5880
|
+
hold(refs, minimumBody = 0) {
|
|
5881
|
+
const referenceBottom = Math.max(0, ...[...refs.values()].map((ref) => ref.bottom));
|
|
5882
|
+
const bodyHeight = Math.max(referenceBottom, minimumBody);
|
|
5883
|
+
this.cursor.holdFootnotes(
|
|
5884
|
+
this.table.id,
|
|
5885
|
+
[...refs.values()].map((ref) => ref.note),
|
|
5886
|
+
bodyHeight,
|
|
5887
|
+
this.cursor.usedColumnHeightPx + referenceBottom
|
|
5888
|
+
);
|
|
5889
|
+
}
|
|
5890
|
+
holdCandidate(row) {
|
|
5891
|
+
const refs = new Map(this.fragment);
|
|
5892
|
+
for (const ref of this.references(row))
|
|
5893
|
+
if (!refs.has(ref.note.id))
|
|
5894
|
+
refs.set(ref.note.id, { ...ref, bottom: this.height() + ref.bottom });
|
|
5895
|
+
const referenceBottom = Math.max(0, ...[...refs.values()].map((ref) => ref.bottom));
|
|
5896
|
+
const contentBottom = this.height() + Math.max(0, ...row.cells.flatMap((cell) => cell.map((box) => box.yPx + box.heightPx)));
|
|
5897
|
+
const paddingBottom = Math.max(0, ...(row.cellPadding ?? []).map((padding) => padding.bottom));
|
|
5898
|
+
this.hold(
|
|
5899
|
+
refs,
|
|
5900
|
+
contentBottom <= referenceBottom + 1e-6 ? this.height() + row.heightPx : referenceBottom + paddingBottom
|
|
5901
|
+
);
|
|
5902
|
+
}
|
|
5903
|
+
/** Largest complete prefix that keeps each new marker with available note content. */
|
|
5904
|
+
choose(row, atomic) {
|
|
5905
|
+
this.cursor.holdFootnotes(this.table.id, [], 0);
|
|
5906
|
+
const available = this.cursor.remainingHeightPx() - this.height();
|
|
5907
|
+
if (row.heightPx <= available + 1e-6) {
|
|
5908
|
+
this.holdCandidate(row);
|
|
5909
|
+
if (row.heightPx <= this.cursor.remainingHeightPx() - this.height() + 1e-6)
|
|
5910
|
+
return { layout: row, cut: row.heightPx };
|
|
5911
|
+
}
|
|
5912
|
+
if (!atomic) {
|
|
5913
|
+
const cuts = /* @__PURE__ */ new Set();
|
|
5914
|
+
for (const [index, cell] of row.cells.entries())
|
|
5915
|
+
for (const box of cell) {
|
|
5916
|
+
if (box.yPx > available + 1e-6) break;
|
|
5917
|
+
for (const line2 of box.lines) {
|
|
5918
|
+
const bottom = box.yPx + line2.yPx + line2.heightPx + (row.cellPadding?.[index]?.bottom ?? 0);
|
|
5919
|
+
if (bottom > available + 1e-6) break;
|
|
5920
|
+
if (bottom > 0) cuts.add(bottom);
|
|
5921
|
+
}
|
|
5922
|
+
}
|
|
5923
|
+
for (const cut of [...cuts].sort((a, b) => b - a)) {
|
|
5924
|
+
const candidate = prefix(row, cut);
|
|
5925
|
+
this.holdCandidate(candidate);
|
|
5926
|
+
if (candidate.heightPx <= this.cursor.remainingHeightPx() - this.height() + 1e-6) {
|
|
5927
|
+
const space = this.cursor.remainingHeightPx() - this.height();
|
|
5928
|
+
const cellCuts = row.cells.map(
|
|
5929
|
+
(cell) => cell.some((box) => this.paragraphs.has(box.blockId)) ? cut : space
|
|
5930
|
+
);
|
|
5931
|
+
const expanded = prefix(row, cut, cellCuts);
|
|
5932
|
+
this.holdCandidate(expanded);
|
|
5933
|
+
if (expanded.heightPx <= this.cursor.remainingHeightPx() - this.height() + 1e-6)
|
|
5934
|
+
return { layout: expanded, cut, cellCuts };
|
|
5935
|
+
this.holdCandidate(candidate);
|
|
5936
|
+
return { layout: candidate, cut };
|
|
5937
|
+
}
|
|
5938
|
+
}
|
|
5939
|
+
}
|
|
5940
|
+
this.holdFragment();
|
|
5941
|
+
return void 0;
|
|
5942
|
+
}
|
|
5943
|
+
add(row, repeated) {
|
|
5944
|
+
if (repeated) return;
|
|
5945
|
+
for (const ref of this.references(row))
|
|
5946
|
+
if (!this.fragment.has(ref.note.id))
|
|
5947
|
+
this.fragment.set(ref.note.id, { ...ref, bottom: this.height() + ref.bottom });
|
|
5948
|
+
}
|
|
5949
|
+
holdFragment() {
|
|
5950
|
+
this.hold(this.fragment);
|
|
5951
|
+
}
|
|
5952
|
+
flushed() {
|
|
5953
|
+
for (const id of this.fragment.keys()) this.placed.add(id);
|
|
5954
|
+
this.fragment.clear();
|
|
5955
|
+
}
|
|
5956
|
+
};
|
|
5957
|
+
|
|
5240
5958
|
// docx/layout/flow-table.ts
|
|
5241
|
-
function placeTable(cursor, table, measurer, note) {
|
|
5959
|
+
function placeTable(cursor, table, measurer, note, resolveFootnotes) {
|
|
5242
5960
|
const firstBodyRow = table.rows.findIndex((row) => !row.isHeader);
|
|
5243
5961
|
const headerRows = table.rows.slice(0, firstBodyRow < 0 ? table.rows.length : firstBodyRow);
|
|
5244
5962
|
const xPosition = () => {
|
|
@@ -5247,7 +5965,9 @@ function placeTable(cursor, table, measurer, note) {
|
|
|
5247
5965
|
};
|
|
5248
5966
|
let fragmentRows = [];
|
|
5249
5967
|
let fragmentHeight = 0;
|
|
5968
|
+
const footnotes = resolveFootnotes ? new TableFootnotes(cursor, table, () => fragmentHeight, resolveFootnotes) : void 0;
|
|
5250
5969
|
const toRowBox = (layout, repeated) => {
|
|
5970
|
+
footnotes?.add(layout, repeated);
|
|
5251
5971
|
const box = {
|
|
5252
5972
|
yPx: fragmentHeight,
|
|
5253
5973
|
heightPx: layout.heightPx,
|
|
@@ -5259,7 +5979,10 @@ function placeTable(cursor, table, measurer, note) {
|
|
|
5259
5979
|
return box;
|
|
5260
5980
|
};
|
|
5261
5981
|
function flushFragment() {
|
|
5262
|
-
if (!fragmentRows.length)
|
|
5982
|
+
if (!fragmentRows.length) {
|
|
5983
|
+
footnotes?.holdFragment();
|
|
5984
|
+
return;
|
|
5985
|
+
}
|
|
5263
5986
|
const box = {
|
|
5264
5987
|
kind: "table",
|
|
5265
5988
|
blockId: table.id,
|
|
@@ -5268,19 +5991,89 @@ function placeTable(cursor, table, measurer, note) {
|
|
|
5268
5991
|
heightPx: fragmentHeight,
|
|
5269
5992
|
rows: fragmentRows
|
|
5270
5993
|
};
|
|
5994
|
+
footnotes?.holdFragment();
|
|
5271
5995
|
cursor.place(box, fragmentHeight);
|
|
5996
|
+
footnotes?.flushed();
|
|
5272
5997
|
fragmentRows = [];
|
|
5273
5998
|
fragmentHeight = 0;
|
|
5274
5999
|
}
|
|
5275
6000
|
function startNewFragment() {
|
|
5276
6001
|
flushFragment();
|
|
5277
6002
|
cursor.newColumn();
|
|
6003
|
+
addHeaders();
|
|
6004
|
+
}
|
|
6005
|
+
function addHeaders() {
|
|
5278
6006
|
for (const header of headerRows)
|
|
5279
6007
|
fragmentRows.push(toRowBox(layoutRow(header, cursor.columnWidthPx, measurer, note), true));
|
|
5280
6008
|
}
|
|
5281
6009
|
function placeRow(row, initial, cantSplit) {
|
|
5282
6010
|
let remainingRow = initial;
|
|
5283
6011
|
while (remainingRow) {
|
|
6012
|
+
const minimum = cantSplit ? Math.min(remainingRow.heightPx, cursor.columnHeightPx) : Math.min(
|
|
6013
|
+
...remainingRow.cells.flatMap(
|
|
6014
|
+
(cell) => cell.map(
|
|
6015
|
+
(paragraph) => paragraph.yPx + (paragraph.lines[0]?.yPx ?? 0) + (paragraph.lines[0]?.heightPx ?? 0)
|
|
6016
|
+
)
|
|
6017
|
+
)
|
|
6018
|
+
);
|
|
6019
|
+
if (fragmentRows.every((item) => item.repeated)) {
|
|
6020
|
+
const width = cursor.columnWidthPx;
|
|
6021
|
+
cursor.advancePastFootnotes(fragmentHeight + (Number.isFinite(minimum) ? minimum : 0));
|
|
6022
|
+
if (width !== cursor.columnWidthPx) {
|
|
6023
|
+
remainingRow = layoutRow(
|
|
6024
|
+
remainingRow === initial ? row : { ...row, heightPx: 0, heightRule: "atLeast" },
|
|
6025
|
+
cursor.columnWidthPx,
|
|
6026
|
+
measurer,
|
|
6027
|
+
note,
|
|
6028
|
+
remainingRow.cells
|
|
6029
|
+
);
|
|
6030
|
+
if (fragmentRows.length) {
|
|
6031
|
+
fragmentRows = [];
|
|
6032
|
+
fragmentHeight = 0;
|
|
6033
|
+
addHeaders();
|
|
6034
|
+
}
|
|
6035
|
+
continue;
|
|
6036
|
+
}
|
|
6037
|
+
}
|
|
6038
|
+
if (footnotes) {
|
|
6039
|
+
const selected = footnotes.choose(remainingRow, cantSplit);
|
|
6040
|
+
if (selected) {
|
|
6041
|
+
if (selected.layout === remainingRow) {
|
|
6042
|
+
fragmentRows.push(toRowBox(remainingRow, false));
|
|
6043
|
+
remainingRow = null;
|
|
6044
|
+
continue;
|
|
6045
|
+
}
|
|
6046
|
+
const { before: before2, after: after2 } = splitRowAtHeight(
|
|
6047
|
+
remainingRow,
|
|
6048
|
+
selected.cut + 1e-6,
|
|
6049
|
+
selected.cellCuts?.map((cut) => cut + 1e-6)
|
|
6050
|
+
);
|
|
6051
|
+
fragmentRows.push(toRowBox(before2, false));
|
|
6052
|
+
const previousWidth2 = cursor.columnWidthPx;
|
|
6053
|
+
startNewFragment();
|
|
6054
|
+
remainingRow = after2 && previousWidth2 !== cursor.columnWidthPx ? layoutRow(
|
|
6055
|
+
{ ...row, heightPx: 0, heightRule: "atLeast" },
|
|
6056
|
+
cursor.columnWidthPx,
|
|
6057
|
+
measurer,
|
|
6058
|
+
note,
|
|
6059
|
+
after2.cells
|
|
6060
|
+
) : after2;
|
|
6061
|
+
continue;
|
|
6062
|
+
}
|
|
6063
|
+
if (fragmentRows.length || !cursor.atColumnTop) {
|
|
6064
|
+
const previousWidth2 = cursor.columnWidthPx;
|
|
6065
|
+
startNewFragment();
|
|
6066
|
+
if (previousWidth2 !== cursor.columnWidthPx)
|
|
6067
|
+
remainingRow = layoutRow(
|
|
6068
|
+
remainingRow === initial ? row : { ...row, heightPx: 0, heightRule: "atLeast" },
|
|
6069
|
+
cursor.columnWidthPx,
|
|
6070
|
+
measurer,
|
|
6071
|
+
note,
|
|
6072
|
+
remainingRow === initial ? void 0 : remainingRow.cells
|
|
6073
|
+
);
|
|
6074
|
+
continue;
|
|
6075
|
+
}
|
|
6076
|
+
}
|
|
5284
6077
|
const remaining = cursor.remainingHeightPx() - fragmentHeight;
|
|
5285
6078
|
if (remainingRow.heightPx <= remaining) {
|
|
5286
6079
|
fragmentRows.push(toRowBox(remainingRow, false));
|
|
@@ -5292,6 +6085,18 @@ function placeTable(cursor, table, measurer, note) {
|
|
|
5292
6085
|
startNewFragment();
|
|
5293
6086
|
remainingRow = layoutRow(row, cursor.columnWidthPx, measurer, note);
|
|
5294
6087
|
}
|
|
6088
|
+
const noteWidth = cursor.columnWidthPx;
|
|
6089
|
+
cursor.advancePastFootnotes(
|
|
6090
|
+
fragmentHeight + Math.min(remainingRow.heightPx, cursor.columnHeightPx)
|
|
6091
|
+
);
|
|
6092
|
+
if (noteWidth !== cursor.columnWidthPx) {
|
|
6093
|
+
remainingRow = layoutRow(row, cursor.columnWidthPx, measurer, note);
|
|
6094
|
+
if (fragmentRows.length) {
|
|
6095
|
+
fragmentRows = [];
|
|
6096
|
+
fragmentHeight = 0;
|
|
6097
|
+
addHeaders();
|
|
6098
|
+
}
|
|
6099
|
+
}
|
|
5295
6100
|
const freshRemaining = cursor.remainingHeightPx() - fragmentHeight;
|
|
5296
6101
|
if (remainingRow.heightPx > freshRemaining)
|
|
5297
6102
|
note('A table row marked "keep row together" is taller than an empty page/column.');
|
|
@@ -5322,11 +6127,37 @@ function placeTable(cursor, table, measurer, note) {
|
|
|
5322
6127
|
}
|
|
5323
6128
|
for (const row of table.rows) {
|
|
5324
6129
|
const layout = layoutRow(row, cursor.columnWidthPx, measurer, note);
|
|
5325
|
-
placeRow(
|
|
6130
|
+
placeRow(
|
|
6131
|
+
row,
|
|
6132
|
+
layout,
|
|
6133
|
+
Boolean(row.cantSplit) || headerRows.includes(row) || !!footnotes && row.heightRule === "exact"
|
|
6134
|
+
);
|
|
5326
6135
|
}
|
|
5327
6136
|
flushFragment();
|
|
5328
6137
|
}
|
|
5329
6138
|
|
|
6139
|
+
// docx/layout/reference-footnotes.ts
|
|
6140
|
+
function createReferenceFootnotes(width, measurer, report) {
|
|
6141
|
+
const cache = /* @__PURE__ */ new Map();
|
|
6142
|
+
return (paragraph, lines, includeUnanchored) => {
|
|
6143
|
+
const selected = new Set(
|
|
6144
|
+
lines.flatMap(
|
|
6145
|
+
(line2) => line2.fragments.map((fragment) => paragraph.runs[fragment.runIndex]?.footnoteReferenceId)
|
|
6146
|
+
)
|
|
6147
|
+
);
|
|
6148
|
+
const anchored = new Set(paragraph.runs.map((run) => run.footnoteReferenceId));
|
|
6149
|
+
return (paragraph.footnotes ?? []).filter((note) => selected.has(note.id) || includeUnanchored && !anchored.has(note.id)).map((note) => {
|
|
6150
|
+
const key = `${note.id}:${width()}`;
|
|
6151
|
+
const prior = cache.get(key);
|
|
6152
|
+
if (prior) return prior;
|
|
6153
|
+
const stacked = stackParagraphs(note.paragraphs, width(), measurer, report);
|
|
6154
|
+
const box = { id: note.id, yPx: 0, heightPx: stacked.heightPx, paragraphs: stacked.boxes };
|
|
6155
|
+
cache.set(key, box);
|
|
6156
|
+
return box;
|
|
6157
|
+
});
|
|
6158
|
+
};
|
|
6159
|
+
}
|
|
6160
|
+
|
|
5330
6161
|
// docx/layout/wrap.ts
|
|
5331
6162
|
var SIDE_DISTANCE_PX = 12;
|
|
5332
6163
|
var MIN_SIDE_WIDTH_PX = 48;
|
|
@@ -5380,20 +6211,117 @@ function lineBoxesFor(exclusions, topPx, columnLeftPx, columnWidthPx) {
|
|
|
5380
6211
|
// docx/layout/section-flow.ts
|
|
5381
6212
|
var SectionFlow = class {
|
|
5382
6213
|
constructor(section, pages, measurer, note, sectionIndex = 0, exclusions, continueAt, balance) {
|
|
6214
|
+
this.section = section;
|
|
5383
6215
|
this.exclusions = exclusions;
|
|
5384
6216
|
this.balance = balance;
|
|
6217
|
+
const noteColumns = section.footnoteColumns ?? (section.modernFootnoteSeparator ? section.columns ?? { count: 1, gapPx: 0 } : void 0);
|
|
6218
|
+
if (!noteColumns && !section.legacyFootnoteColumns && (section.columns?.count ?? 1) > 1 && section.blocks.some(
|
|
6219
|
+
(block) => block.kind === "paragraph" ? !!block.footnotes?.length : block.rows.some(
|
|
6220
|
+
(row) => row.cells.some(
|
|
6221
|
+
(cell) => cellParagraphs(cell).some((paragraph) => !!paragraph.footnotes?.length)
|
|
6222
|
+
)
|
|
6223
|
+
)
|
|
6224
|
+
))
|
|
6225
|
+
note(
|
|
6226
|
+
"Multi-column footnotes use a page-wide area; native per-column footnote balancing is not yet modeled."
|
|
6227
|
+
);
|
|
6228
|
+
const sources = /* @__PURE__ */ new Map();
|
|
6229
|
+
for (const block of section.blocks) {
|
|
6230
|
+
const paragraphs = block.kind === "paragraph" ? [block] : block.rows.flatMap((row) => row.cells.flatMap(cellParagraphs));
|
|
6231
|
+
for (const paragraph of paragraphs)
|
|
6232
|
+
for (const source of paragraph.footnotes ?? []) sources.set(source.id, source);
|
|
6233
|
+
}
|
|
6234
|
+
const reflowCache = /* @__PURE__ */ new Map();
|
|
6235
|
+
const reflow = (box, width) => {
|
|
6236
|
+
const source = sources.get(box.id);
|
|
6237
|
+
if (!source) return box;
|
|
6238
|
+
const ids = new Set(box.paragraphs.map((paragraph) => paragraph.blockId));
|
|
6239
|
+
const key = JSON.stringify([box.id, width, [...ids], box.sourceTokenStarts]);
|
|
6240
|
+
const cached = reflowCache.get(key);
|
|
6241
|
+
if (cached) return { ...cached, continued: !!box.continued };
|
|
6242
|
+
const paragraphs = source.paragraphs.filter((paragraph) => ids.has(paragraph.id)).map(
|
|
6243
|
+
(paragraph) => box.sourceTokenStarts?.[paragraph.id] ? { ...paragraph, spacingBeforeTwips: NO_TWIPS } : paragraph
|
|
6244
|
+
);
|
|
6245
|
+
const stacked = stackParagraphs(
|
|
6246
|
+
paragraphs,
|
|
6247
|
+
width,
|
|
6248
|
+
measurer,
|
|
6249
|
+
note,
|
|
6250
|
+
0,
|
|
6251
|
+
new Map(Object.entries(box.sourceTokenStarts ?? {}))
|
|
6252
|
+
);
|
|
6253
|
+
const result = { ...box, yPx: 0, heightPx: stacked.heightPx, paragraphs: stacked.boxes };
|
|
6254
|
+
reflowCache.set(key, result);
|
|
6255
|
+
return result;
|
|
6256
|
+
};
|
|
5385
6257
|
this.blocks = section.blocks;
|
|
5386
6258
|
this.measurer = measurer;
|
|
5387
6259
|
this.note = note;
|
|
6260
|
+
const separatorCache = /* @__PURE__ */ new Map();
|
|
5388
6261
|
this.cursor = new PageCursor(
|
|
5389
6262
|
pages,
|
|
5390
6263
|
section.page,
|
|
5391
6264
|
section.columns ?? { count: 1, gapPx: 0 },
|
|
5392
6265
|
sectionIndex,
|
|
5393
6266
|
continueAt,
|
|
5394
|
-
balance
|
|
6267
|
+
balance,
|
|
6268
|
+
note,
|
|
6269
|
+
(page, continued) => {
|
|
6270
|
+
const paragraphs = section.footnoteSeparators?.[continued && !section.modernFootnoteSeparator ? "continuationSeparator" : "separator"];
|
|
6271
|
+
if (!paragraphs) return void 0;
|
|
6272
|
+
const width = page.widthPx - page.marginLeftPx - page.marginRightPx;
|
|
6273
|
+
const key = `${width}:${continued}`;
|
|
6274
|
+
const cached = separatorCache.get(key);
|
|
6275
|
+
if (cached) return cached;
|
|
6276
|
+
const adapted = paragraphs.map((paragraph) => {
|
|
6277
|
+
const probe = section.legacyFootnoteColumns ? layoutParagraph(
|
|
6278
|
+
{
|
|
6279
|
+
...paragraph,
|
|
6280
|
+
runs: paragraph.runs.map(
|
|
6281
|
+
(run) => run.object?.noteSeparator ? { ...run, object: { ...run.object, widthPx: 0 } } : run
|
|
6282
|
+
)
|
|
6283
|
+
},
|
|
6284
|
+
width,
|
|
6285
|
+
measurer,
|
|
6286
|
+
note
|
|
6287
|
+
) : void 0;
|
|
6288
|
+
return {
|
|
6289
|
+
...paragraph,
|
|
6290
|
+
runs: paragraph.runs.map(
|
|
6291
|
+
(run, index) => run.object?.noteSeparator ? {
|
|
6292
|
+
...run,
|
|
6293
|
+
object: {
|
|
6294
|
+
...run.object,
|
|
6295
|
+
widthPx: section.legacyFootnoteColumns ? Math.min(
|
|
6296
|
+
run.object.noteSeparator === "continuationSeparator" ? width : 192,
|
|
6297
|
+
Math.max(
|
|
6298
|
+
0,
|
|
6299
|
+
width - (probe?.lines.flatMap((line2) => line2.fragments).find(
|
|
6300
|
+
(fragment) => fragment.runIndex === index && fragment.object?.noteSeparator
|
|
6301
|
+
)?.xPx ?? 0)
|
|
6302
|
+
)
|
|
6303
|
+
) : run.object.noteSeparator === "continuationSeparator" ? width : Math.min(192, width)
|
|
6304
|
+
}
|
|
6305
|
+
} : run
|
|
6306
|
+
)
|
|
6307
|
+
};
|
|
6308
|
+
});
|
|
6309
|
+
const stacked = stackParagraphs(adapted, width, measurer, note);
|
|
6310
|
+
const result = { heightPx: stacked.heightPx, paragraphs: stacked.boxes };
|
|
6311
|
+
separatorCache.set(key, result);
|
|
6312
|
+
return result;
|
|
6313
|
+
},
|
|
6314
|
+
noteColumns,
|
|
6315
|
+
reflow,
|
|
6316
|
+
section.legacyFootnoteColumns
|
|
6317
|
+
);
|
|
6318
|
+
this.referenceFootnotes = createReferenceFootnotes(
|
|
6319
|
+
() => this.cursor.footnoteWidthPx,
|
|
6320
|
+
measurer,
|
|
6321
|
+
note
|
|
5395
6322
|
);
|
|
5396
6323
|
}
|
|
6324
|
+
section;
|
|
5397
6325
|
exclusions;
|
|
5398
6326
|
balance;
|
|
5399
6327
|
cursor;
|
|
@@ -5403,6 +6331,7 @@ var SectionFlow = class {
|
|
|
5403
6331
|
measurer;
|
|
5404
6332
|
note;
|
|
5405
6333
|
paragraphCache = /* @__PURE__ */ new Map();
|
|
6334
|
+
referenceFootnotes;
|
|
5406
6335
|
firstRowHeightCache = /* @__PURE__ */ new Map();
|
|
5407
6336
|
paragraphLayout(index) {
|
|
5408
6337
|
const key = `${index}:${this.cursor.columnWidthPx}`;
|
|
@@ -5477,7 +6406,17 @@ var SectionFlow = class {
|
|
|
5477
6406
|
for (let index = 0; index < this.blocks.length; index++) {
|
|
5478
6407
|
const block = expectDefined(this.blocks[index], "flow block index");
|
|
5479
6408
|
if (block.kind === "table") {
|
|
5480
|
-
placeTable(
|
|
6409
|
+
placeTable(
|
|
6410
|
+
this.cursor,
|
|
6411
|
+
block,
|
|
6412
|
+
this.measurer,
|
|
6413
|
+
this.note,
|
|
6414
|
+
block.rows.some(
|
|
6415
|
+
(row) => row.cells.some(
|
|
6416
|
+
(cell) => cellParagraphs(cell).some((paragraph) => paragraph.footnotes?.length)
|
|
6417
|
+
)
|
|
6418
|
+
) ? this.referenceFootnotes : void 0
|
|
6419
|
+
);
|
|
5481
6420
|
if (this.balance?.pageIndex === this.cursor.page.index && !this.cursor.columnContentFits)
|
|
5482
6421
|
this.balanceValid = false;
|
|
5483
6422
|
continue;
|
|
@@ -5485,19 +6424,7 @@ var SectionFlow = class {
|
|
|
5485
6424
|
if (block.afterTableSectionBreak) this.cursor.endBalance();
|
|
5486
6425
|
const spacingBeforePx = this.spacingBeforeFor(index);
|
|
5487
6426
|
const layout = this.wrappedLayout(index, spacingBeforePx) ?? this.paragraphLayout(index);
|
|
5488
|
-
|
|
5489
|
-
this.cursor.holdFootnotes(
|
|
5490
|
-
block.id,
|
|
5491
|
-
block.footnotes.map((note) => {
|
|
5492
|
-
const stacked = stackParagraphs(
|
|
5493
|
-
note.paragraphs,
|
|
5494
|
-
this.cursor.columnWidthPx,
|
|
5495
|
-
this.measurer,
|
|
5496
|
-
this.note
|
|
5497
|
-
);
|
|
5498
|
-
return { id: note.id, yPx: 0, heightPx: stacked.heightPx, paragraphs: stacked.boxes };
|
|
5499
|
-
})
|
|
5500
|
-
);
|
|
6427
|
+
const footnotes = (lines, includeUnanchored) => this.referenceFootnotes(block, lines, includeUnanchored);
|
|
5501
6428
|
const requiredTogetherPx = block.keepNext ? this.requiredKeepHeight(index) : block.keepLines ? spacingBeforePx + layout.contentHeightPx + layout.spacingAfterPx : 0;
|
|
5502
6429
|
if (requiredTogetherPx > this.cursor.columnHeightPx && requiredTogetherPx <= this.cursor.physicalColumnHeightPx)
|
|
5503
6430
|
this.balanceValid = false;
|
|
@@ -5506,7 +6433,9 @@ var SectionFlow = class {
|
|
|
5506
6433
|
{
|
|
5507
6434
|
paragraph: block,
|
|
5508
6435
|
layout,
|
|
6436
|
+
footnotes,
|
|
5509
6437
|
spacingBeforePx,
|
|
6438
|
+
...this.section.modernFootnoteSeparator || this.section.legacyFootnoteColumns ? { trimLeadingColumnBreak: true } : {},
|
|
5510
6439
|
requiredTogetherPx,
|
|
5511
6440
|
reflow: (token) => layoutParagraph(
|
|
5512
6441
|
block,
|
|
@@ -5522,6 +6451,7 @@ var SectionFlow = class {
|
|
|
5522
6451
|
if (this.balance?.pageIndex === this.cursor.page.index && this.cursor.usedColumnHeightPx > this.cursor.columnHeightPx)
|
|
5523
6452
|
this.balanceValid = false;
|
|
5524
6453
|
}
|
|
6454
|
+
this.cursor.finishFootnotes();
|
|
5525
6455
|
}
|
|
5526
6456
|
};
|
|
5527
6457
|
|
|
@@ -5564,8 +6494,16 @@ function insertParityBlank(pages, section) {
|
|
|
5564
6494
|
const nextNumber = pages.length + 1;
|
|
5565
6495
|
const wanted = section.break === "evenPage" ? 0 : 1;
|
|
5566
6496
|
if (nextNumber % 2 === wanted) return;
|
|
6497
|
+
const {
|
|
6498
|
+
footnotes: _footnotes,
|
|
6499
|
+
footnoteSeparator: _separator,
|
|
6500
|
+
footnoteHeightPx: _noteHeight,
|
|
6501
|
+
footnoteColumnAreas: _noteColumnAreas,
|
|
6502
|
+
floats: _floats,
|
|
6503
|
+
...geometry
|
|
6504
|
+
} = previous;
|
|
5567
6505
|
pages.push({
|
|
5568
|
-
...
|
|
6506
|
+
...geometry,
|
|
5569
6507
|
index: pages.length,
|
|
5570
6508
|
pageInSection: previous.pageInSection + 1,
|
|
5571
6509
|
columns: previous.columns.map((column) => ({ ...column, blocks: [] }))
|
|
@@ -5579,7 +6517,12 @@ function alignVertically(pages, section, note) {
|
|
|
5579
6517
|
return;
|
|
5580
6518
|
}
|
|
5581
6519
|
for (const page of pages) {
|
|
5582
|
-
const
|
|
6520
|
+
const footnoteHeight = page.footnoteColumnAreas?.length ? Math.max(
|
|
6521
|
+
...page.footnoteColumnAreas.map(
|
|
6522
|
+
(area) => area.heightPx + (area.separator?.heightPx ?? FOOTNOTE_SEPARATOR_PX)
|
|
6523
|
+
)
|
|
6524
|
+
) : page.footnotes?.length ? (page.footnoteSeparator?.heightPx ?? FOOTNOTE_SEPARATOR_PX) + (page.footnoteHeightPx ?? page.footnotes.reduce((sum, footnote) => sum + footnote.heightPx, 0)) : 0;
|
|
6525
|
+
const available = page.heightPx - page.marginTopPx - page.marginBottomPx - footnoteHeight;
|
|
5583
6526
|
const used = Math.max(
|
|
5584
6527
|
0,
|
|
5585
6528
|
...page.columns.flatMap((column) => column.blocks.map((block) => block.yPx + block.heightPx))
|
|
@@ -5772,6 +6715,11 @@ function adaptTable(table, model, adaptParagraph) {
|
|
|
5772
6715
|
const fill = cssHex(visuals.shadingFill);
|
|
5773
6716
|
return {
|
|
5774
6717
|
paragraphs: cell.paragraphs.map(adaptParagraph),
|
|
6718
|
+
...cell.sourceBlocks ? {
|
|
6719
|
+
blocks: cellSourceBlocks(cell).map(
|
|
6720
|
+
(block) => block.type === "paragraph" ? adaptParagraph(block) : adaptTable(block, model, adaptParagraph)
|
|
6721
|
+
)
|
|
6722
|
+
} : {},
|
|
5775
6723
|
...width !== void 0 ? { widthPx: width } : {},
|
|
5776
6724
|
...grid && xPx !== void 0 ? { xPx } : {},
|
|
5777
6725
|
padding,
|
|
@@ -5951,7 +6899,13 @@ function adaptDocumentModel(model, note = () => {
|
|
|
5951
6899
|
const script = formatting.verticalAlign === "superscript" || noteText !== void 0 && formatting.verticalAlign === void 0 ? "super" : formatting.verticalAlign === "subscript" ? "sub" : void 0;
|
|
5952
6900
|
const image = run.image;
|
|
5953
6901
|
if (image?.unsupported === "Text box") reportOnce(TEXT_BOX_NOTE);
|
|
5954
|
-
const object =
|
|
6902
|
+
const object = run.noteSeparator ? {
|
|
6903
|
+
partName: "",
|
|
6904
|
+
contentType: "",
|
|
6905
|
+
widthPx: 192,
|
|
6906
|
+
heightPx: 1,
|
|
6907
|
+
noteSeparator: run.noteSeparator
|
|
6908
|
+
} : image && !image.anchored ? {
|
|
5955
6909
|
partName: image.partName,
|
|
5956
6910
|
contentType: image.contentType,
|
|
5957
6911
|
widthPx: image.widthPx,
|
|
@@ -5959,8 +6913,10 @@ function adaptDocumentModel(model, note = () => {
|
|
|
5959
6913
|
...image.chart ? { chart: docxChartPaint(image.chart, image.widthPx, image.heightPx, theme) } : {}
|
|
5960
6914
|
} : void 0;
|
|
5961
6915
|
return {
|
|
6916
|
+
sourceLength: reviewSourceLength(run),
|
|
5962
6917
|
// Hidden text (`w:vanish`) takes no space when printed, as in Word by default.
|
|
5963
6918
|
text: image || formatting.vanish ? "" : formatting.caps ? text2.toUpperCase() : text2,
|
|
6919
|
+
...run.noteReference?.kind === "footnote" ? { footnoteReferenceId: run.noteReference.id } : {},
|
|
5964
6920
|
...object ? { object } : {},
|
|
5965
6921
|
...definedProps({
|
|
5966
6922
|
bold: formatting.bold,
|
|
@@ -6059,6 +7015,10 @@ function adaptDocumentModel(model, note = () => {
|
|
|
6059
7015
|
if (block.type === "paragraph") return adaptParagraph(block);
|
|
6060
7016
|
reportOnce(TABLE_ROW_NOTE);
|
|
6061
7017
|
reportOnce(VERTICAL_MERGE_NOTE);
|
|
7018
|
+
if (block.rows.some((row) => row.some((cell) => cell.nestedTables?.length)))
|
|
7019
|
+
reportOnce(
|
|
7020
|
+
"Nested tables are projected as read-only cell paragraphs in Print Layout; their borders, shading, vertical merge and repeated header geometry are not rendered."
|
|
7021
|
+
);
|
|
6062
7022
|
return adaptTable(block, model, adaptParagraph);
|
|
6063
7023
|
}
|
|
6064
7024
|
const blocks = [
|
|
@@ -6068,7 +7028,25 @@ function adaptDocumentModel(model, note = () => {
|
|
|
6068
7028
|
groupParagraphBorders(blocks, betweenBorders);
|
|
6069
7029
|
const folded = foldDropCaps(model.blocks, blocks);
|
|
6070
7030
|
if (folded.size) reportOnce(DROP_CAP_NOTE);
|
|
7031
|
+
if (Object.values(model.footnoteSeparators ?? {}).some(
|
|
7032
|
+
(note2) => note2.blocks.some((block) => block.type === "table")
|
|
7033
|
+
))
|
|
7034
|
+
reportOnce(
|
|
7035
|
+
"Tables in custom footnote separators are preserved but are not rendered in Print Layout."
|
|
7036
|
+
);
|
|
7037
|
+
const footnoteSeparators = model.footnoteSeparators ? Object.fromEntries(
|
|
7038
|
+
Object.entries(model.footnoteSeparators).map(([kind, note2]) => [
|
|
7039
|
+
kind,
|
|
7040
|
+
note2.blocks.filter((block) => block.type === "paragraph").map((paragraph) => adaptParagraph(paragraph))
|
|
7041
|
+
])
|
|
7042
|
+
) : void 0;
|
|
6071
7043
|
const sections = model.sections;
|
|
7044
|
+
const modernFootnoteSeparator = model.compatibilityMode === 15;
|
|
7045
|
+
const legacyFootnoteColumns = model.compatibilityMode === 12 || model.compatibilityMode === 14;
|
|
7046
|
+
if (!modernFootnoteSeparator && !legacyFootnoteColumns && model.sections?.some((section) => section.footnoteColumns !== void 0))
|
|
7047
|
+
reportOnce(
|
|
7048
|
+
"Footnote column settings are preserved, but this compatibility mode has not been verified against native Word; Print Layout uses the existing page-wide fallback."
|
|
7049
|
+
);
|
|
6072
7050
|
if (!sections || !sections.length) {
|
|
6073
7051
|
return {
|
|
6074
7052
|
sections: [
|
|
@@ -6081,6 +7059,9 @@ function adaptDocumentModel(model, note = () => {
|
|
|
6081
7059
|
marginBottomPx: model.page.marginBottom,
|
|
6082
7060
|
marginLeftPx: model.page.marginLeft
|
|
6083
7061
|
},
|
|
7062
|
+
...footnoteSeparators ? { footnoteSeparators } : {},
|
|
7063
|
+
...modernFootnoteSeparator ? { modernFootnoteSeparator: true } : {},
|
|
7064
|
+
...legacyFootnoteColumns ? { legacyFootnoteColumns: true } : {},
|
|
6084
7065
|
blocks: blocks.filter((block) => !folded.has(block))
|
|
6085
7066
|
}
|
|
6086
7067
|
]
|
|
@@ -6094,8 +7075,34 @@ function adaptDocumentModel(model, note = () => {
|
|
|
6094
7075
|
const end = Math.max(start, endIndex);
|
|
6095
7076
|
const slice = blocks.slice(start, end);
|
|
6096
7077
|
start = end;
|
|
7078
|
+
if (legacyFootnoteColumns && section.footnoteColumns)
|
|
7079
|
+
reportOnce(
|
|
7080
|
+
"Independent footnote column counts are preserved but ignored in measured compatibility modes 12 and 14; Print Layout attaches notes to body columns."
|
|
7081
|
+
);
|
|
7082
|
+
const footnoteWidth = twipsToPx3(section.pageWidthTwips) - twipsToPx3(section.marginLeftTwips) - twipsToPx3(section.marginRightTwips);
|
|
7083
|
+
if (modernFootnoteSeparator && section.footnoteColumns && (section.footnoteColumns > 45 || footnoteWidth <= 48 * (section.footnoteColumns - 1)))
|
|
7084
|
+
reportOnce(
|
|
7085
|
+
"Footnote columns exceeding the available page width or 45 rendered columns use one column in Print Layout; the saved count is preserved."
|
|
7086
|
+
);
|
|
6097
7087
|
const sectionStart = index === 0 ? void 0 : sectionBreak(section.type, reportOnce);
|
|
6098
7088
|
return {
|
|
7089
|
+
...footnoteSeparators ? { footnoteSeparators } : {},
|
|
7090
|
+
...modernFootnoteSeparator ? { modernFootnoteSeparator: true } : {},
|
|
7091
|
+
...legacyFootnoteColumns ? { legacyFootnoteColumns: true } : {},
|
|
7092
|
+
...section.footnoteColumns !== void 0 && modernFootnoteSeparator ? {
|
|
7093
|
+
footnoteColumns: {
|
|
7094
|
+
count: section.footnoteColumns && (section.footnoteColumns > 45 || footnoteWidth <= 48 * (section.footnoteColumns - 1)) ? 1 : Math.max(1, section.footnoteColumns || section.columns.count),
|
|
7095
|
+
gapPx: section.footnoteColumns ? 48 : twipsToPx3(section.columns.spacingTwips ?? twips(720)),
|
|
7096
|
+
...!section.footnoteColumns && !section.columns.equalWidth && section.columns.widths?.length ? {
|
|
7097
|
+
widths: section.columns.widths.map((column) => ({
|
|
7098
|
+
widthPx: twipsToPx3(column.widthTwips),
|
|
7099
|
+
gapPx: twipsToPx3(
|
|
7100
|
+
column.spacingTwips ?? section.columns.spacingTwips ?? twips(720)
|
|
7101
|
+
)
|
|
7102
|
+
}))
|
|
7103
|
+
} : {}
|
|
7104
|
+
}
|
|
7105
|
+
} : {},
|
|
6099
7106
|
page: {
|
|
6100
7107
|
widthPx: twipsToPx3(section.pageWidthTwips),
|
|
6101
7108
|
heightPx: twipsToPx3(section.pageHeightTwips),
|