@stll/folio-core 0.47.7 → 0.49.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/ai-edits/apply.js +565 -121
- package/dist/ai-edits/minimal-replacement.d.ts +64 -0
- package/dist/ai-edits/minimal-replacement.js +282 -0
- package/dist/controller/fontReadiness.js +3 -3
- package/dist/controller/hyphenationReadiness.d.ts +19 -0
- package/dist/controller/hyphenationReadiness.js +47 -0
- package/dist/controller/layoutPipeline.d.ts +3 -0
- package/dist/controller/layoutPipeline.js +70 -18
- package/dist/display-list/build/buildDisplayList.js +39 -12
- package/dist/display-list/build/pageFurniture.d.ts +7 -1
- package/dist/display-list/build/pageFurniture.js +21 -8
- package/dist/display-list/build/paragraphPrimitives.js +68 -11
- package/dist/display-list/build/tablePrimitives.js +10 -6
- package/dist/display-list/build/textBoxPrimitives.js +1 -1
- package/dist/display-list/build/unsupported.d.ts +2 -2
- package/dist/display-list/build/unsupported.js +0 -0
- package/dist/display-list/dom/renderDisplayListToDom.js +0 -1
- package/dist/docx/attributeRemainder.js +10 -2
- package/dist/docx/blockContentParser.d.ts +2 -0
- package/dist/docx/blockContentParser.js +79 -64
- package/dist/docx/bulletMarkers.d.ts +18 -2
- package/dist/docx/bulletMarkers.js +27 -2
- package/dist/docx/commentParser.d.ts +2 -1
- package/dist/docx/commentParser.js +57 -45
- package/dist/docx/containerChildren.d.ts +21 -8
- package/dist/docx/containerChildren.js +39 -9
- package/dist/docx/documentParser.d.ts +5 -1
- package/dist/docx/documentParser.js +8 -5
- package/dist/docx/documentSectionFacts.d.ts +22 -0
- package/dist/docx/documentSectionFacts.js +43 -0
- package/dist/docx/drawingGroupChildren.d.ts +60 -0
- package/dist/docx/drawingGroupChildren.js +176 -0
- package/dist/docx/drawingUtils.js +3 -0
- package/dist/docx/fieldParser.d.ts +8 -1
- package/dist/docx/fieldParser.js +47 -3
- package/dist/docx/fontTableParser.js +34 -27
- package/dist/docx/footnoteParser.d.ts +3 -2
- package/dist/docx/footnoteParser.js +15 -12
- package/dist/docx/groupDrawingParser.d.ts +9 -2
- package/dist/docx/groupDrawingParser.js +125 -37
- package/dist/docx/headerFooterParser.d.ts +7 -2
- package/dist/docx/headerFooterParser.js +15 -5
- package/dist/docx/hyperlinkParser.d.ts +48 -36
- package/dist/docx/hyperlinkParser.js +97 -82
- package/dist/docx/numberingParser.js +108 -84
- package/dist/docx/packageParts.d.ts +45 -1
- package/dist/docx/packageParts.js +93 -2
- package/dist/docx/paraIdAttribute.d.ts +3 -2
- package/dist/docx/paragraphParser.d.ts +5 -1
- package/dist/docx/paragraphParser.js +468 -365
- package/dist/docx/paragraphProperties.js +123 -109
- package/dist/docx/paragraphPropertySource.d.ts +6 -1
- package/dist/docx/paragraphPropertySource.js +9 -1
- package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
- package/dist/docx/paragraphTextBoxEnrichment.js +143 -10
- package/dist/docx/parser.d.ts +7 -1
- package/dist/docx/parser.js +33 -16
- package/dist/docx/previewBudget.d.ts +55 -33
- package/dist/docx/previewBudget.js +59 -65
- package/dist/docx/rezip.js +41 -58
- package/dist/docx/runParser.d.ts +4 -1
- package/dist/docx/runParser.js +182 -184
- package/dist/docx/sdtProperties.js +87 -84
- package/dist/docx/sectionParser.js +169 -160
- package/dist/docx/selectiveSaveFlags.d.ts +10 -3
- package/dist/docx/selectiveSaveFlags.js +1 -1
- package/dist/docx/selectiveXmlPatch.d.ts +56 -34
- package/dist/docx/selectiveXmlPatch.js +222 -115
- package/dist/docx/serializer/groupTextBoxWriteBack.d.ts +12 -0
- package/dist/docx/serializer/groupTextBoxWriteBack.js +101 -0
- package/dist/docx/serializer/paragraphSerializer.js +47 -42
- package/dist/docx/serializer/runSerializer.d.ts +5 -1
- package/dist/docx/serializer/runSerializer.js +4 -3
- package/dist/docx/serializer/settingsSerializer.js +19 -1
- package/dist/docx/settingsParser.js +8 -0
- package/dist/docx/shapeAlternateContent.d.ts +25 -0
- package/dist/docx/shapeAlternateContent.js +52 -0
- package/dist/docx/streamingXmlParser.d.ts +6 -2
- package/dist/docx/streamingXmlParser.js +12 -7
- package/dist/docx/styleParser.js +34 -8
- package/dist/docx/tableParser.d.ts +21 -12
- package/dist/docx/tableParser.js +518 -441
- package/dist/docx/textBoxParser.d.ts +18 -5
- package/dist/docx/textBoxParser.js +12 -6
- package/dist/docx/verbatimCapture.d.ts +10 -8
- package/dist/docx/verbatimCapture.js +45 -2
- package/dist/docx/vmlImageParser.d.ts +15 -13
- package/dist/docx/vmlImageParser.js +75 -60
- package/dist/docx/vmlPreview.d.ts +3 -3
- package/dist/docx/vmlPreview.js +3 -4
- package/dist/docx/xmlNamespaceContext.d.ts +9 -0
- package/dist/docx/xmlNamespaceContext.js +54 -0
- package/dist/docx/xmlParser.d.ts +6 -3
- package/dist/docx/xmlParser.js +11 -41
- package/dist/docx/xmlResourceLimits.d.ts +2 -1
- package/dist/docx/xmlResourceLimits.js +4 -1
- package/dist/fonts/headlessMeasure.js +0 -0
- package/dist/headless-layout.d.ts +11 -2
- package/dist/headless-layout.js +153 -107
- package/dist/internal/headlessRevisionResolution.js +50 -13
- package/dist/internal/paragraphFormattingSerialization.js +3 -3
- package/dist/layout-bridge/convert/endnoteLayout.d.ts +65 -0
- package/dist/layout-bridge/convert/endnoteLayout.js +227 -0
- package/dist/layout-bridge/convert/footnoteLayout.d.ts +19 -3
- package/dist/layout-bridge/convert/footnoteLayout.js +40 -31
- package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -7
- package/dist/layout-bridge/convert/headerFooterLayout.js +5 -20
- package/dist/layout-bridge/convert/paragraphMarkFormatting.d.ts +10 -0
- package/dist/layout-bridge/convert/paragraphMarkFormatting.js +59 -0
- package/dist/layout-bridge/convert/toFlowBlocks.d.ts +29 -1
- package/dist/layout-bridge/convert/toFlowBlocks.js +284 -39
- package/dist/layout-bridge/engine/hitTest.js +5 -3
- package/dist/layout-bridge/engine/selectionRects.js +5 -3
- package/dist/layout-engine/anchorLayoutInCellCompatibility.d.ts +10 -0
- package/dist/layout-engine/anchorLayoutInCellCompatibility.js +22 -0
- package/dist/layout-engine/index.d.ts +2 -2
- package/dist/layout-engine/index.js +102 -14
- package/dist/layout-engine/justificationCompatibility.d.ts +1 -1
- package/dist/layout-engine/justificationCompatibility.js +9 -5
- package/dist/layout-engine/keep-together.d.ts +15 -6
- package/dist/layout-engine/keep-together.js +43 -16
- package/dist/layout-engine/layoutInstrumentation.d.ts +8 -2
- package/dist/layout-engine/layoutInstrumentation.js +8 -1
- package/dist/layout-engine/measure/advanceComposition.js +50 -7
- package/dist/layout-engine/measure/hyphenationDictionaries.d.ts +74 -0
- package/dist/layout-engine/measure/hyphenationDictionaries.js +138 -0
- package/dist/layout-engine/measure/hyphenationPreload.d.ts +11 -0
- package/dist/layout-engine/measure/hyphenationPreload.js +24 -0
- package/dist/layout-engine/measure/lineBreakProvider.d.ts +12 -2
- package/dist/layout-engine/measure/lineBreakProvider.js +30 -30
- package/dist/layout-engine/measure/lineBreaks.d.ts +6 -1
- package/dist/layout-engine/measure/lineBreaks.js +10 -3
- package/dist/layout-engine/measure/listMarkerWidth.d.ts +9 -6
- package/dist/layout-engine/measure/listMarkerWidth.js +20 -22
- package/dist/layout-engine/measure/measureBlocks.js +46 -10
- package/dist/layout-engine/measure/measureContainer.js +51 -8
- package/dist/layout-engine/measure/measureHelpers.d.ts +15 -3
- package/dist/layout-engine/measure/measureHelpers.js +34 -8
- package/dist/layout-engine/measure/measureParagraph.js +143 -101
- package/dist/layout-engine/measure/measureTypes.d.ts +5 -0
- package/dist/layout-engine/measure/smallCapsCasing.d.ts +56 -0
- package/dist/layout-engine/measure/smallCapsCasing.js +88 -0
- package/dist/layout-engine/measure/tabCalculator.d.ts +2 -0
- package/dist/layout-engine/measure/tabCalculator.js +2 -1
- package/dist/layout-engine/measure/tableCellFloating.d.ts +2 -0
- package/dist/layout-engine/measure/tableCellFloating.js +51 -19
- package/dist/layout-engine/measure/tableCellGrid.d.ts +28 -3
- package/dist/layout-engine/measure/tableCellGrid.js +45 -5
- package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
- package/dist/layout-engine/noteAreaFlow.d.ts +19 -0
- package/dist/layout-engine/noteAreaFlow.js +83 -0
- package/dist/layout-engine/paginator.d.ts +12 -1
- package/dist/layout-engine/paginator.js +18 -2
- package/dist/layout-engine/paragraphSpacing.d.ts +4 -2
- package/dist/layout-engine/paragraphSpacing.js +2 -1
- package/dist/layout-engine/tableRowBreak.d.ts +8 -1
- package/dist/layout-engine/tableRowBreak.js +25 -2
- package/dist/layout-engine/types.d.ts +108 -3
- package/dist/layout-engine/types.js +96 -1
- package/dist/layout-painter/index.d.ts +3 -0
- package/dist/layout-painter/renderPage.js +32 -83
- package/dist/layout-painter/renderParagraph.d.ts +6 -1
- package/dist/layout-painter/renderParagraph.js +75 -26
- package/dist/layout-painter/renderTable.js +26 -13
- package/dist/layout-painter/renderTextBox.d.ts +12 -2
- package/dist/layout-painter/renderTextBox.js +26 -2
- package/dist/prosemirror/alternateContentAttrs.d.ts +9 -0
- package/dist/prosemirror/alternateContentAttrs.js +35 -0
- package/dist/prosemirror/attrs/index.d.ts +9 -9
- package/dist/prosemirror/attrs/index.js +133 -11
- package/dist/prosemirror/commands/comments.js +51 -41
- package/dist/prosemirror/contentControlRevisions.d.ts +43 -0
- package/dist/prosemirror/contentControlRevisions.js +84 -0
- package/dist/prosemirror/conversion/fromProseDoc.js +54 -23
- package/dist/prosemirror/conversion/markInterner.d.ts +21 -0
- package/dist/prosemirror/conversion/markInterner.js +90 -0
- package/dist/prosemirror/conversion/toProseDoc.js +117 -58
- package/dist/prosemirror/extensions/core/DocExtension.js +2 -1
- package/dist/prosemirror/extensions/core/ParagraphExtension.js +1 -0
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.d.ts +7 -7
- package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -7
- package/dist/prosemirror/extensions/marks/markUtils.d.ts +6 -2
- package/dist/prosemirror/extensions/marks/markUtils.js +39 -51
- package/dist/prosemirror/extensions/nodes/FieldExtension.js +6 -3
- package/dist/prosemirror/extensions/nodes/SdtExtension.js +9 -2
- package/dist/prosemirror/extensions/nodes/ShapeExtension.js +1 -0
- package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +5 -1
- package/dist/prosemirror/listMarker.d.ts +1 -0
- package/dist/prosemirror/listMarker.js +4 -2
- package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
- package/dist/prosemirror/listRenderingAttrs.js +3 -0
- package/dist/prosemirror/paragraphDirection.d.ts +29 -2
- package/dist/prosemirror/paragraphDirection.js +21 -2
- package/dist/prosemirror/plugins/suggestionMode.js +37 -8
- package/dist/prosemirror/rejoinRunCarriers.d.ts +27 -0
- package/dist/prosemirror/rejoinRunCarriers.js +66 -0
- package/dist/prosemirror/runIdentityAcrossRevisions.d.ts +10 -0
- package/dist/prosemirror/runIdentityAcrossRevisions.js +90 -0
- package/dist/prosemirror/schema/nodes.d.ts +50 -6
- package/dist/prosemirror/textBoxHostParagraph.d.ts +13 -0
- package/dist/prosemirror/textBoxHostParagraph.js +21 -0
- package/dist/prosemirror/validation.js +91 -80
- package/dist/types/content.d.ts +2 -2
- package/dist/utils/createDocument.js +10 -1
- package/dist/utils/scriptSegments.d.ts +33 -4
- package/dist/utils/scriptSegments.js +39 -6
- package/dist/utils/textFormattingMerge.d.ts +17 -3
- package/dist/utils/textFormattingMerge.js +18 -12
- package/dist/utils/trailingText.d.ts +22 -0
- package/dist/utils/trailingText.js +32 -0
- package/package.json +2 -2
- package/dist/layout-engine/justifiedLineFit.d.ts +0 -7
- package/dist/layout-engine/justifiedLineFit.js +0 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { emuToPixels } from "../utils/units.js";
|
|
2
|
+
import { collectGroupTextBoxes, readTransform } from "./drawingGroupChildren.js";
|
|
2
3
|
import { parseImage, resolveImageData } from "./imageParser.js";
|
|
3
|
-
import { PREVIEW_KINDS } from "./previewBudget.js";
|
|
4
4
|
import { findAllDeep, findChildByLocalName, findChildrenByLocalName, getAttribute, getChildElements, getLocalName, getTextContent, parseNumericAttribute } from "./xmlParser.js";
|
|
5
5
|
import { escapeXmlAttribute, escapeXmlText } from "@stll/docx-core";
|
|
6
6
|
//#region src/docx/groupDrawingParser.ts
|
|
@@ -10,6 +10,7 @@ const DEFAULT_FONT_HALF_POINTS = 22;
|
|
|
10
10
|
const DEFAULT_LINE_WIDTH_EMU = 9525;
|
|
11
11
|
const HALF_POINT_TO_EMU = 6350;
|
|
12
12
|
const MAX_GROUP_SHAPES = 256;
|
|
13
|
+
const MAX_GROUP_DEPTH = 16;
|
|
13
14
|
const CROP_SCALE = 1e5;
|
|
14
15
|
const MAX_PATH_COMMANDS = 1e4;
|
|
15
16
|
const MAX_TEXT_CHARACTERS = 2e4;
|
|
@@ -80,34 +81,66 @@ const pathData = (path) => {
|
|
|
80
81
|
}
|
|
81
82
|
return commands.join(" ");
|
|
82
83
|
};
|
|
83
|
-
|
|
84
|
+
/**
|
|
85
|
+
* A child's own `a:xfrm` rotation and flips, applied about its centre in the
|
|
86
|
+
* coordinate space it is drawn in (ECMA-376 §20.1.7.6).
|
|
87
|
+
*/
|
|
88
|
+
const withChildTransform = (element, piece) => {
|
|
89
|
+
if (!piece) return piece;
|
|
90
|
+
const transform = readTransform(findChildByLocalName(findChildByLocalName(element, "spPr"), "xfrm"));
|
|
91
|
+
return wrapTransformed(transform, piece);
|
|
92
|
+
};
|
|
93
|
+
const wrapTransformed = (transform, piece) => {
|
|
94
|
+
if (transform.rotation === 0 && !transform.flipH && !transform.flipV) return piece;
|
|
95
|
+
const centerX = transform.x + transform.width / 2;
|
|
96
|
+
const centerY = transform.y + transform.height / 2;
|
|
97
|
+
const operations = [];
|
|
98
|
+
if (transform.rotation !== 0) operations.push(`rotate(${transform.rotation} ${centerX} ${centerY})`);
|
|
99
|
+
if (transform.flipH || transform.flipV) operations.push(`translate(${centerX} ${centerY}) scale(${transform.flipH ? -1 : 1} ${transform.flipV ? -1 : 1}) translate(${-centerX} ${-centerY})`);
|
|
100
|
+
return `<g transform="${operations.join(" ")}">${piece}</g>`;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* `unitScale` is how many EMUs one unit of the child coordinate space spans.
|
|
104
|
+
* Line widths are authored in EMUs, so they are divided by it to be drawn in
|
|
105
|
+
* the space the geometry is in.
|
|
106
|
+
*/
|
|
107
|
+
const renderGeometry = (wsp, unitScale) => {
|
|
84
108
|
const { x, y, width, height } = childTransform(wsp);
|
|
85
|
-
if (width <= 0 || height <= 0) return "";
|
|
86
109
|
const spPr = findChildByLocalName(wsp, "spPr");
|
|
87
110
|
const style = findChildByLocalName(wsp, "style");
|
|
88
111
|
const styleStroke = colorFrom(findChildByLocalName(style, "lnRef"), "none");
|
|
89
112
|
const fill = colorFrom(spPr, "none");
|
|
90
113
|
const line = findChildByLocalName(spPr, "ln");
|
|
91
114
|
const stroke = colorFrom(line, styleStroke);
|
|
92
|
-
const strokeWidth = line ? parseNumericAttribute(line, null, "w") ?? DEFAULT_LINE_WIDTH_EMU : 0;
|
|
115
|
+
const strokeWidth = (line ? parseNumericAttribute(line, null, "w") ?? DEFAULT_LINE_WIDTH_EMU : 0) / unitScale;
|
|
116
|
+
const strokeColor = stroke === "none" ? "none" : `#${stroke}`;
|
|
117
|
+
if (width <= 0 || height <= 0) {
|
|
118
|
+
if (width < 0 || height < 0 || width === 0 && height === 0 || strokeColor === "none") return "";
|
|
119
|
+
return `<line x1="${x}" y1="${y}" x2="${x + width}" y2="${y + height}" stroke="${strokeColor}" stroke-width="${strokeWidth}"/>`;
|
|
120
|
+
}
|
|
93
121
|
const paths = findAllDeep(findChildByLocalName(spPr, "custGeom"), "a", "path");
|
|
94
|
-
if (paths.length === 0) return `<rect x="${x}" y="${y}" width="${width}" height="${height}" fill="${fill === "none" ? "none" : `#${fill}`}" stroke="${
|
|
122
|
+
if (paths.length === 0) return `<rect x="${x}" y="${y}" width="${width}" height="${height}" fill="${fill === "none" ? "none" : `#${fill}`}" stroke="${strokeColor}" stroke-width="${strokeWidth}"/>`;
|
|
95
123
|
return paths.map((path) => {
|
|
96
124
|
const viewWidth = numericAttr(path, "w") || width;
|
|
97
125
|
const viewHeight = numericAttr(path, "h") || height;
|
|
98
126
|
const d = pathData(path);
|
|
99
127
|
if (!d) return "";
|
|
100
|
-
return `<path d="${d}" transform="translate(${x} ${y}) scale(${width / viewWidth} ${height / viewHeight})" fill="${fill === "none" ? "none" : `#${fill}`}" stroke="${
|
|
128
|
+
return `<path d="${d}" transform="translate(${x} ${y}) scale(${width / viewWidth} ${height / viewHeight})" fill="${fill === "none" ? "none" : `#${fill}`}" stroke="${strokeColor}" stroke-width="${strokeWidth}"/>`;
|
|
101
129
|
}).join("");
|
|
102
130
|
};
|
|
103
|
-
|
|
131
|
+
/**
|
|
132
|
+
* An approximate rendering of a text box the layout does not host (an inline
|
|
133
|
+
* group, or one placed by alignment rather than offset). Font sizes are in
|
|
134
|
+
* EMUs and the drawing is in child units, hence `unitScale`.
|
|
135
|
+
*/
|
|
136
|
+
const renderTextBox = (wsp, unitScale) => {
|
|
104
137
|
const { x, y, width, height } = childTransform(wsp);
|
|
105
138
|
if (width <= 0 || height <= 0) return "";
|
|
106
139
|
const paragraphs = findAllDeep(wsp, "w", "p");
|
|
107
140
|
const firstSize = findAllDeep(wsp, "w", "sz").at(0);
|
|
108
141
|
const halfPoints = numericAttr(firstSize ?? null, "val") || DEFAULT_FONT_HALF_POINTS;
|
|
109
142
|
const color = colorFrom(findAllDeep(wsp, "w", "color").at(0) ?? null, DEFAULT_TEXT_COLOR);
|
|
110
|
-
const fontSize = halfPoints * HALF_POINT_TO_EMU;
|
|
143
|
+
const fontSize = halfPoints * HALF_POINT_TO_EMU / unitScale;
|
|
111
144
|
const maxCharacters = Math.max(1, Math.floor(width / (fontSize * .38)));
|
|
112
145
|
const lines = paragraphs.flatMap((paragraph) => wrapLine(getTextContent(paragraph).slice(0, MAX_TEXT_CHARACTERS), maxCharacters)).map(escapeXmlText);
|
|
113
146
|
if (lines.length === 0) return "";
|
|
@@ -138,55 +171,110 @@ const renderPicture = (picture, index, rels, media) => {
|
|
|
138
171
|
return `<defs><clipPath id="${clipId}"><rect x="${x}" y="${y}" width="${width}" height="${height}"/></clipPath></defs><g clip-path="url(#${clipId})">${image}</g>`;
|
|
139
172
|
};
|
|
140
173
|
const groupViewBox = (group, width, height) => {
|
|
141
|
-
const transform = findChildByLocalName(findChildByLocalName(group, "grpSpPr"), "xfrm");
|
|
142
|
-
const childOffset = findChildByLocalName(transform, "chOff");
|
|
143
|
-
const childExtent = findChildByLocalName(transform, "chExt");
|
|
144
|
-
const childWidth = numericAttr(childExtent, "cx");
|
|
145
|
-
const childHeight = numericAttr(childExtent, "cy");
|
|
174
|
+
const transform = readTransform(findChildByLocalName(findChildByLocalName(group, "grpSpPr"), "xfrm"));
|
|
146
175
|
return {
|
|
147
|
-
x:
|
|
148
|
-
y:
|
|
149
|
-
width: childWidth > 0 ? childWidth : width,
|
|
150
|
-
height: childHeight > 0 ? childHeight : height
|
|
176
|
+
x: transform.childX,
|
|
177
|
+
y: transform.childY,
|
|
178
|
+
width: transform.childWidth > 0 ? transform.childWidth : width,
|
|
179
|
+
height: transform.childHeight > 0 ? transform.childHeight : height
|
|
151
180
|
};
|
|
152
181
|
};
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
182
|
+
/**
|
|
183
|
+
* A nested group's child space drawn inside its frame in the parent's space,
|
|
184
|
+
* then turned by the group's own rotation and flips.
|
|
185
|
+
*/
|
|
186
|
+
const nestedGroupTransform = (transform) => {
|
|
187
|
+
const scaleX = transform.childWidth > 0 ? transform.width / transform.childWidth : 1;
|
|
188
|
+
const scaleY = transform.childHeight > 0 ? transform.height / transform.childHeight : 1;
|
|
189
|
+
return `translate(${transform.x} ${transform.y}) scale(${scaleX} ${scaleY}) translate(${-transform.childX} ${-transform.childY})`;
|
|
190
|
+
};
|
|
191
|
+
const averageScale = (scale) => (scale.x + scale.y) / 2 || 1;
|
|
192
|
+
const createSvg = (group, width, height, rels, media, hostedTextBoxes) => {
|
|
193
|
+
let total = 0;
|
|
194
|
+
let shapes = 0;
|
|
195
|
+
let serial = 0;
|
|
196
|
+
/** One container's markup, or null once the budget is spent. */
|
|
197
|
+
const render = (container, scale, depth) => {
|
|
198
|
+
let content = "";
|
|
199
|
+
for (const child of getChildElements(container)) {
|
|
200
|
+
const index = serial;
|
|
201
|
+
serial += 1;
|
|
202
|
+
if (shapes >= MAX_GROUP_SHAPES) break;
|
|
203
|
+
const localName = getLocalName(child.name ?? "");
|
|
204
|
+
let piece;
|
|
205
|
+
if (localName === "pic") {
|
|
206
|
+
shapes += 1;
|
|
207
|
+
piece = withChildTransform(child, renderPicture(child, index, rels, media));
|
|
208
|
+
} else if (localName === "wsp") {
|
|
209
|
+
shapes += 1;
|
|
210
|
+
if (hostedTextBoxes.has(child)) continue;
|
|
211
|
+
const unitScale = averageScale(scale);
|
|
212
|
+
piece = withChildTransform(child, findChildByLocalName(child, "txbx") ? `${renderGeometry(child, unitScale)}${renderTextBox(child, unitScale)}` : renderGeometry(child, unitScale));
|
|
213
|
+
} else if (localName === "grpSp" && depth < MAX_GROUP_DEPTH) {
|
|
214
|
+
const transform = readTransform(findChildByLocalName(findChildByLocalName(child, "grpSpPr"), "xfrm"));
|
|
215
|
+
const scaleX = transform.childWidth > 0 ? transform.width / transform.childWidth : 1;
|
|
216
|
+
const scaleY = transform.childHeight > 0 ? transform.height / transform.childHeight : 1;
|
|
217
|
+
const nested = render(child, {
|
|
218
|
+
x: scale.x * scaleX,
|
|
219
|
+
y: scale.y * scaleY
|
|
220
|
+
}, depth + 1);
|
|
221
|
+
if (nested === null) return null;
|
|
222
|
+
piece = nested ? wrapTransformed(transform, `<g transform="${nestedGroupTransform(transform)}">${nested}</g>`) : "";
|
|
223
|
+
total -= nested.length;
|
|
224
|
+
} else continue;
|
|
225
|
+
content += piece;
|
|
226
|
+
total += piece.length;
|
|
227
|
+
if (total > MAX_SVG_CHARACTERS) return null;
|
|
228
|
+
}
|
|
229
|
+
return content;
|
|
230
|
+
};
|
|
166
231
|
const viewBox = groupViewBox(group, width, height);
|
|
232
|
+
const content = render(group, {
|
|
233
|
+
x: width / viewBox.width,
|
|
234
|
+
y: height / viewBox.height
|
|
235
|
+
}, 0);
|
|
236
|
+
if (content === null || !content && hostedTextBoxes.size === 0) return null;
|
|
167
237
|
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}" width="${emuToPixels(width)}" height="${emuToPixels(height)}">${content}</svg>`;
|
|
168
238
|
};
|
|
169
239
|
const groupElement = (drawing) => {
|
|
170
240
|
return findChildByLocalName(findAllDeep(drawing, "a", "graphicData").at(0) ?? null, "wgp");
|
|
171
241
|
};
|
|
172
242
|
/**
|
|
243
|
+
* Whether the layout can place the group's text boxes itself. A floating group
|
|
244
|
+
* positioned by offsets on both axes puts each child at the group's offset
|
|
245
|
+
* plus the child's frame, which a text box anchored beside the group can state
|
|
246
|
+
* exactly; an inline group or one placed by alignment has no such offset.
|
|
247
|
+
*/
|
|
248
|
+
const hostsTextBoxes = (image) => {
|
|
249
|
+
const position = image.position;
|
|
250
|
+
return image.wrap.type !== "inline" && image.anchor?.useSimplePosition !== true && position !== void 0 && position.horizontal.alignment === void 0 && position.horizontal.posOffset !== void 0 && position.vertical.alignment === void 0 && position.vertical.posOffset !== void 0;
|
|
251
|
+
};
|
|
252
|
+
/** The text boxes each group preview leaves to the layout, keyed by the preview. */
|
|
253
|
+
const hostedTextBoxFrames = /* @__PURE__ */ new WeakMap();
|
|
254
|
+
/**
|
|
255
|
+
* The text boxes a group preview does not draw, which the paragraph parser
|
|
256
|
+
* lifts out as text boxes of their own. Undefined for any other image.
|
|
257
|
+
*/
|
|
258
|
+
const groupPreviewTextBoxes = (image) => hostedTextBoxFrames.get(image);
|
|
259
|
+
/**
|
|
173
260
|
* Whether a `w:drawing` carries a WordprocessingGroup payload. A group this
|
|
174
261
|
* module declines to rasterize has no editable projection either — the shape
|
|
175
262
|
* model holds one shape, not a group — so the caller must preserve it raw.
|
|
176
263
|
*/
|
|
177
264
|
const isGroupDrawing = (drawing) => groupElement(drawing) !== null;
|
|
178
265
|
/** Parse a WordprocessingGroup drawing into a safe SVG-backed image preview. */
|
|
179
|
-
const parseGroupDrawing = (drawing, rels, media) => {
|
|
266
|
+
const parseGroupDrawing = (drawing, previews, rels, media) => {
|
|
180
267
|
const group = groupElement(drawing);
|
|
181
268
|
if (!group) return null;
|
|
182
269
|
const image = parseImage(drawing, void 0, void 0);
|
|
183
270
|
if (!image || image.size.width <= 0 || image.size.height <= 0) return null;
|
|
184
|
-
const
|
|
271
|
+
const hosted = hostsTextBoxes(image) ? collectGroupTextBoxes(group, image.size.width, image.size.height) : [];
|
|
272
|
+
const svg = createSvg(group, image.size.width, image.size.height, rels, media, new Set(hosted.map(({ wsp }) => wsp)));
|
|
185
273
|
if (!svg || svg.length > MAX_SVG_CHARACTERS) return null;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return
|
|
274
|
+
const { rId: _rId, src: _src, mimeType: _mimeType, filename: _filename, ...frame } = image;
|
|
275
|
+
const preview = previews.svgImage("wpGroup", svg, frame);
|
|
276
|
+
if (hosted.length > 0) hostedTextBoxFrames.set(preview, hosted);
|
|
277
|
+
return preview;
|
|
190
278
|
};
|
|
191
279
|
//#endregion
|
|
192
|
-
export { isGroupDrawing, parseGroupDrawing };
|
|
280
|
+
export { groupPreviewTextBoxes, isGroupDrawing, parseGroupDrawing };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
import { NumberingMap } from "./numberingParser.js";
|
|
3
|
+
import { PreviewLedger } from "./previewBudget.js";
|
|
3
4
|
import { StyleMap } from "./styleParser.js";
|
|
4
5
|
import { parseFooterReference, parseFooterReferences, parseHeaderReference, parseHeaderReferences } from "./headerFooterRefParser.js";
|
|
5
6
|
//#region src/docx/headerFooterParser.d.ts
|
|
@@ -28,9 +29,11 @@ type HeaderFooterMap = {
|
|
|
28
29
|
* @param numbering - Parsed numbering definitions for lists
|
|
29
30
|
* @param rels - Relationships for resolving hyperlinks/images
|
|
30
31
|
* @param media - Media files for images
|
|
32
|
+
* @param previews - The ledger of the package this part belongs to; a part
|
|
33
|
+
* read on its own charges its previews to no package
|
|
31
34
|
* @returns HeaderFooter object
|
|
32
35
|
*/
|
|
33
|
-
declare function parseHeader(headerXml: string, hdrFtrType?: document_d_exports.HeaderFooterType, styles?: StyleMap | null, theme?: document_d_exports.Theme | null, numbering?: NumberingMap | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null): document_d_exports.HeaderFooter;
|
|
36
|
+
declare function parseHeader(headerXml: string, hdrFtrType?: document_d_exports.HeaderFooterType, styles?: StyleMap | null, theme?: document_d_exports.Theme | null, numbering?: NumberingMap | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null, previews?: PreviewLedger): document_d_exports.HeaderFooter;
|
|
34
37
|
/**
|
|
35
38
|
* Parse a footer XML file (word/footer*.xml)
|
|
36
39
|
*
|
|
@@ -41,9 +44,11 @@ declare function parseHeader(headerXml: string, hdrFtrType?: document_d_exports.
|
|
|
41
44
|
* @param numbering - Parsed numbering definitions for lists
|
|
42
45
|
* @param rels - Relationships for resolving hyperlinks/images
|
|
43
46
|
* @param media - Media files for images
|
|
47
|
+
* @param previews - The ledger of the package this part belongs to; a part
|
|
48
|
+
* read on its own charges its previews to no package
|
|
44
49
|
* @returns HeaderFooter object
|
|
45
50
|
*/
|
|
46
|
-
declare function parseFooter(footerXml: string, hdrFtrType?: document_d_exports.HeaderFooterType, styles?: StyleMap | null, theme?: document_d_exports.Theme | null, numbering?: NumberingMap | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null): document_d_exports.HeaderFooter;
|
|
51
|
+
declare function parseFooter(footerXml: string, hdrFtrType?: document_d_exports.HeaderFooterType, styles?: StyleMap | null, theme?: document_d_exports.Theme | null, numbering?: NumberingMap | null, rels?: document_d_exports.RelationshipMap | null, media?: Map<string, document_d_exports.MediaFile> | null, previews?: PreviewLedger): document_d_exports.HeaderFooter;
|
|
47
52
|
/**
|
|
48
53
|
* Generic function to parse either header or footer
|
|
49
54
|
*
|
|
@@ -3,6 +3,7 @@ import { blockPlainText } from "./blockPlainText.js";
|
|
|
3
3
|
import { parseFooterReference, parseFooterReferences, parseHeaderReference, parseHeaderReferences } from "./headerFooterRefParser.js";
|
|
4
4
|
import { assignHeaderFooterVerbatimXml } from "./headerFooterVerbatim.js";
|
|
5
5
|
import { cloneParagraphWithPropertySource } from "./paragraphPropertySource.js";
|
|
6
|
+
import { standalonePreviewLedger } from "./previewBudget.js";
|
|
6
7
|
import { parseWatermark } from "./watermarkParser.js";
|
|
7
8
|
import { collectXmlnsDeclarations, parseXml } from "./xmlParser.js";
|
|
8
9
|
//#region src/docx/headerFooterParser.ts
|
|
@@ -16,9 +17,11 @@ import { collectXmlnsDeclarations, parseXml } from "./xmlParser.js";
|
|
|
16
17
|
* @param numbering - Parsed numbering definitions for lists
|
|
17
18
|
* @param rels - Relationships for resolving hyperlinks/images
|
|
18
19
|
* @param media - Media files for images
|
|
20
|
+
* @param previews - The ledger of the package this part belongs to; a part
|
|
21
|
+
* read on its own charges its previews to no package
|
|
19
22
|
* @returns HeaderFooter object
|
|
20
23
|
*/
|
|
21
|
-
function parseHeader(headerXml, hdrFtrType = "default", styles = null, theme = null, numbering = null, rels = null, media = null) {
|
|
24
|
+
function parseHeader(headerXml, hdrFtrType = "default", styles = null, theme = null, numbering = null, rels = null, media = null, previews = standalonePreviewLedger()) {
|
|
22
25
|
const result = {
|
|
23
26
|
type: "header",
|
|
24
27
|
hdrFtrType,
|
|
@@ -35,11 +38,15 @@ function parseHeader(headerXml, hdrFtrType = "default", styles = null, theme = n
|
|
|
35
38
|
}
|
|
36
39
|
result.content = parseBlockContent(rootElement, styles, theme, numbering, rels, media, {
|
|
37
40
|
inHeaderFooter: true,
|
|
38
|
-
rootXmlns: collectXmlnsDeclarations(rootElement)
|
|
41
|
+
rootXmlns: collectXmlnsDeclarations(rootElement),
|
|
42
|
+
previews
|
|
39
43
|
});
|
|
40
44
|
if (watermarkResult) {
|
|
41
45
|
const host = result.content.at(watermarkResult.blockIndex);
|
|
42
|
-
if (host?.type === "paragraph")
|
|
46
|
+
if (host?.type === "paragraph") {
|
|
47
|
+
previews.release(host.content);
|
|
48
|
+
result.content[watermarkResult.blockIndex] = cloneParagraphWithPropertySource(host, { content: [] });
|
|
49
|
+
}
|
|
43
50
|
}
|
|
44
51
|
assignHeaderFooterVerbatimXml(result, headerXml);
|
|
45
52
|
return result;
|
|
@@ -54,9 +61,11 @@ function parseHeader(headerXml, hdrFtrType = "default", styles = null, theme = n
|
|
|
54
61
|
* @param numbering - Parsed numbering definitions for lists
|
|
55
62
|
* @param rels - Relationships for resolving hyperlinks/images
|
|
56
63
|
* @param media - Media files for images
|
|
64
|
+
* @param previews - The ledger of the package this part belongs to; a part
|
|
65
|
+
* read on its own charges its previews to no package
|
|
57
66
|
* @returns HeaderFooter object
|
|
58
67
|
*/
|
|
59
|
-
function parseFooter(footerXml, hdrFtrType = "default", styles = null, theme = null, numbering = null, rels = null, media = null) {
|
|
68
|
+
function parseFooter(footerXml, hdrFtrType = "default", styles = null, theme = null, numbering = null, rels = null, media = null, previews = standalonePreviewLedger()) {
|
|
60
69
|
const result = {
|
|
61
70
|
type: "footer",
|
|
62
71
|
hdrFtrType,
|
|
@@ -67,7 +76,8 @@ function parseFooter(footerXml, hdrFtrType = "default", styles = null, theme = n
|
|
|
67
76
|
if (!rootElement) return result;
|
|
68
77
|
result.content = parseBlockContent(rootElement, styles, theme, numbering, rels, media, {
|
|
69
78
|
inHeaderFooter: true,
|
|
70
|
-
rootXmlns: collectXmlnsDeclarations(rootElement)
|
|
79
|
+
rootXmlns: collectXmlnsDeclarations(rootElement),
|
|
80
|
+
previews
|
|
71
81
|
});
|
|
72
82
|
assignHeaderFooterVerbatimXml(result, footerXml);
|
|
73
83
|
return result;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
import { XmlElement } from "./xmlParser.js";
|
|
3
|
+
import { PreviewLedger } from "./previewBudget.js";
|
|
3
4
|
import { StyleMap } from "./styleParser.js";
|
|
5
|
+
import { ChildReader } from "./containerChildren.js";
|
|
4
6
|
//#region src/docx/hyperlinkParser.d.ts
|
|
5
7
|
/**
|
|
6
8
|
* Parse a hyperlink element (w:hyperlink)
|
|
@@ -13,10 +15,19 @@ import { StyleMap } from "./styleParser.js";
|
|
|
13
15
|
* @param styles - Style map for resolving run styles
|
|
14
16
|
* @param theme - Theme for resolving colors/fonts
|
|
15
17
|
* @param media - Media files map for image data
|
|
18
|
+
* @param previews - The ledger of the package this link belongs to; a link
|
|
19
|
+
* read on its own charges its previews to no package
|
|
16
20
|
* @returns Parsed Hyperlink object
|
|
17
21
|
*/
|
|
18
|
-
declare function parseHyperlink(node: XmlElement, rels: document_d_exports.RelationshipMap | null, styles?: StyleMap | null, theme?: document_d_exports.Theme | null, media?: Map<string, document_d_exports.MediaFile> | null, rootXmlns?: Record<string, string
|
|
19
|
-
/**
|
|
22
|
+
declare function parseHyperlink(node: XmlElement, rels: document_d_exports.RelationshipMap | null, styles?: StyleMap | null, theme?: document_d_exports.Theme | null, media?: Map<string, document_d_exports.MediaFile> | null, rootXmlns?: Record<string, string>, previews?: PreviewLedger): document_d_exports.Hyperlink;
|
|
23
|
+
/**
|
|
24
|
+
* A `w:hyperlink`'s own attributes as a link with no children yet.
|
|
25
|
+
*
|
|
26
|
+
* The paragraph parser's revision-segmenting walk reads the children itself,
|
|
27
|
+
* so it takes the shell rather than a link whose children it would discard.
|
|
28
|
+
*/
|
|
29
|
+
declare function parseHyperlinkShell(node: XmlElement, rels: document_d_exports.RelationshipMap | null): document_d_exports.Hyperlink;
|
|
30
|
+
/** What {@link HYPERLINK_CHILD_HANDLERS} needs to read one child of a link. */
|
|
20
31
|
type HyperlinkChildContext = {
|
|
21
32
|
/** Where a parsed or captured child lands, in source order. */
|
|
22
33
|
push: (child: document_d_exports.Hyperlink["children"][number]) => void;
|
|
@@ -24,6 +35,7 @@ type HyperlinkChildContext = {
|
|
|
24
35
|
theme: document_d_exports.Theme | null;
|
|
25
36
|
rels: document_d_exports.RelationshipMap | null;
|
|
26
37
|
media: Map<string, document_d_exports.MediaFile> | null;
|
|
38
|
+
previews: PreviewLedger;
|
|
27
39
|
inScopeXmlns: Record<string, string>;
|
|
28
40
|
};
|
|
29
41
|
/**
|
|
@@ -43,39 +55,39 @@ type HyperlinkChildContext = {
|
|
|
43
55
|
* recognising is recognised by all of them rather than by whichever list
|
|
44
56
|
* somebody remembered to update.
|
|
45
57
|
*/
|
|
46
|
-
declare const
|
|
47
|
-
r: (child: XmlElement) => void;
|
|
48
|
-
bookmarkStart: (child: XmlElement) => void;
|
|
49
|
-
bookmarkEnd: (child: XmlElement) => void;
|
|
50
|
-
bdo:
|
|
51
|
-
dir:
|
|
52
|
-
customXml:
|
|
53
|
-
smartTag:
|
|
54
|
-
del: "capture";
|
|
55
|
-
ins: "capture";
|
|
56
|
-
moveFrom: "capture";
|
|
57
|
-
moveTo: "capture";
|
|
58
|
-
commentRangeEnd: "capture";
|
|
59
|
-
commentRangeStart: "capture";
|
|
60
|
-
customXmlDelRangeEnd: "capture";
|
|
61
|
-
customXmlDelRangeStart: "capture";
|
|
62
|
-
customXmlInsRangeEnd: "capture";
|
|
63
|
-
customXmlInsRangeStart: "capture";
|
|
64
|
-
customXmlMoveFromRangeEnd: "capture";
|
|
65
|
-
customXmlMoveFromRangeStart: "capture";
|
|
66
|
-
customXmlMoveToRangeEnd: "capture";
|
|
67
|
-
customXmlMoveToRangeStart: "capture";
|
|
68
|
-
fldSimple: (child: XmlElement) => void;
|
|
69
|
-
hyperlink: (child: XmlElement) => void;
|
|
70
|
-
moveFromRangeEnd: "capture";
|
|
71
|
-
moveFromRangeStart: "capture";
|
|
72
|
-
moveToRangeEnd: "capture";
|
|
73
|
-
moveToRangeStart: "capture";
|
|
74
|
-
permEnd: "capture";
|
|
75
|
-
permStart: "capture";
|
|
76
|
-
proofErr: "capture";
|
|
77
|
-
sdt: "capture";
|
|
78
|
-
subDoc: "capture";
|
|
58
|
+
declare const HYPERLINK_CHILD_HANDLERS: {
|
|
59
|
+
readonly r: (child: XmlElement, { push, styles, theme, rels, media, previews, inScopeXmlns }: HyperlinkChildContext) => void;
|
|
60
|
+
readonly bookmarkStart: (child: XmlElement, { push }: HyperlinkChildContext) => void;
|
|
61
|
+
readonly bookmarkEnd: (child: XmlElement, { push }: HyperlinkChildContext) => void;
|
|
62
|
+
readonly bdo: ChildReader<HyperlinkChildContext>;
|
|
63
|
+
readonly dir: ChildReader<HyperlinkChildContext>;
|
|
64
|
+
readonly customXml: ChildReader<HyperlinkChildContext>;
|
|
65
|
+
readonly smartTag: ChildReader<HyperlinkChildContext>;
|
|
66
|
+
readonly del: "capture";
|
|
67
|
+
readonly ins: "capture";
|
|
68
|
+
readonly moveFrom: "capture";
|
|
69
|
+
readonly moveTo: "capture";
|
|
70
|
+
readonly commentRangeEnd: "capture";
|
|
71
|
+
readonly commentRangeStart: "capture";
|
|
72
|
+
readonly customXmlDelRangeEnd: "capture";
|
|
73
|
+
readonly customXmlDelRangeStart: "capture";
|
|
74
|
+
readonly customXmlInsRangeEnd: "capture";
|
|
75
|
+
readonly customXmlInsRangeStart: "capture";
|
|
76
|
+
readonly customXmlMoveFromRangeEnd: "capture";
|
|
77
|
+
readonly customXmlMoveFromRangeStart: "capture";
|
|
78
|
+
readonly customXmlMoveToRangeEnd: "capture";
|
|
79
|
+
readonly customXmlMoveToRangeStart: "capture";
|
|
80
|
+
readonly fldSimple: (child: XmlElement, { push }: HyperlinkChildContext) => void;
|
|
81
|
+
readonly hyperlink: (child: XmlElement, { push }: HyperlinkChildContext) => void;
|
|
82
|
+
readonly moveFromRangeEnd: "capture";
|
|
83
|
+
readonly moveFromRangeStart: "capture";
|
|
84
|
+
readonly moveToRangeEnd: "capture";
|
|
85
|
+
readonly moveToRangeStart: "capture";
|
|
86
|
+
readonly permEnd: "capture";
|
|
87
|
+
readonly permStart: "capture";
|
|
88
|
+
readonly proofErr: "capture";
|
|
89
|
+
readonly sdt: "capture";
|
|
90
|
+
readonly subDoc: "capture";
|
|
79
91
|
};
|
|
80
92
|
/**
|
|
81
93
|
* Get the display text of a hyperlink
|
|
@@ -169,4 +181,4 @@ declare function createExternalHyperlink(url: string, children: document_d_expor
|
|
|
169
181
|
target?: string;
|
|
170
182
|
}): document_d_exports.Hyperlink;
|
|
171
183
|
//#endregion
|
|
172
|
-
export { HyperlinkChildContext, createExternalHyperlink, createInternalHyperlink, getHyperlinkRuns, getHyperlinkText, getHyperlinkUrl, hasContent,
|
|
184
|
+
export { HYPERLINK_CHILD_HANDLERS, HyperlinkChildContext, createExternalHyperlink, createInternalHyperlink, getHyperlinkRuns, getHyperlinkText, getHyperlinkUrl, hasContent, isExternalLink, isInternalLink, parseHyperlink, parseHyperlinkShell, resolveHyperlinkUrl };
|