@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
|
@@ -28,10 +28,35 @@ const SYMBOL_BULLET_MAP = {
|
|
|
28
28
|
62: ">",
|
|
29
29
|
45: "-"
|
|
30
30
|
};
|
|
31
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Fonts whose single-byte codes name pictographs rather than Latin letters.
|
|
33
|
+
* A `w:lvlText` character below U+0100 only means a symbol glyph when the
|
|
34
|
+
* numbering level's `w:rFonts` selects one of these faces.
|
|
35
|
+
*/
|
|
36
|
+
const SYMBOL_ENCODED_FONTS = /* @__PURE__ */ new Set([
|
|
37
|
+
"symbol",
|
|
38
|
+
"wingdings",
|
|
39
|
+
"wingdings 2",
|
|
40
|
+
"wingdings 3",
|
|
41
|
+
"webdings"
|
|
42
|
+
]);
|
|
43
|
+
/** The face a bullet level's `w:rFonts` names for its (Latin-range) marker character. */
|
|
44
|
+
const bulletMarkerFontName = (formatting) => formatting?.fontFamily?.ascii ?? formatting?.fontFamily?.hAnsi;
|
|
45
|
+
/** A printable Latin-1 character in a named, non-symbol face paints as itself. */
|
|
46
|
+
const isTextFontCharacter = (charCode, fontName) => fontName !== void 0 && (charCode >= 32 && charCode < 127 || charCode >= 160 && charCode < 256) && !SYMBOL_ENCODED_FONTS.has(fontName.trim().toLowerCase());
|
|
47
|
+
/**
|
|
48
|
+
* Map a bullet level's `w:lvlText` to the character painted for it.
|
|
49
|
+
*
|
|
50
|
+
* `fontName` is the level's own `w:rFonts` face. When it is an ordinary text
|
|
51
|
+
* font, a Latin-range character is the letter itself (the common `o` bullet
|
|
52
|
+
* in a monospace face); without a named face the character is read as a
|
|
53
|
+
* symbol-font code.
|
|
54
|
+
*/
|
|
55
|
+
const convertBulletToUnicode = (bulletChar, fontName) => {
|
|
32
56
|
if (!bulletChar || bulletChar.trim() === "") return "•";
|
|
33
57
|
const charCode = bulletChar.codePointAt(0);
|
|
34
58
|
if (charCode === void 0) return "•";
|
|
59
|
+
if (isTextFontCharacter(charCode, fontName)) return bulletChar;
|
|
35
60
|
const mapped = SYMBOL_BULLET_MAP[charCode];
|
|
36
61
|
if (mapped !== void 0) return mapped;
|
|
37
62
|
if (charCode >= 57344 && charCode <= 63743) return "•";
|
|
@@ -39,4 +64,4 @@ const convertBulletToUnicode = (bulletChar) => {
|
|
|
39
64
|
return bulletChar;
|
|
40
65
|
};
|
|
41
66
|
//#endregion
|
|
42
|
-
export { convertBulletToUnicode };
|
|
67
|
+
export { bulletMarkerFontName, convertBulletToUnicode };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
import { ParseContext } from "./parseContext.js";
|
|
3
|
+
import { PreviewLedger } from "./previewBudget.js";
|
|
3
4
|
import { StyleMap } from "./styleParser.js";
|
|
4
5
|
//#region src/docx/commentParser.d.ts
|
|
5
6
|
type CommentExtendedInfo = {
|
|
@@ -29,6 +30,6 @@ declare function parseCommentsExtended(xml: string): Map<string, CommentExtended
|
|
|
29
30
|
* local time. If `commentsExtendedXml` is provided, reply-thread
|
|
30
31
|
* parent links (`parentId`) and resolved state (`done`) are populated.
|
|
31
32
|
*/
|
|
32
|
-
declare function parseComments(commentsXml: string | null, styles: StyleMap | null, theme: document_d_exports.Theme | null, rels: document_d_exports.RelationshipMap, media: Map<string, document_d_exports.MediaFile>, commentsExtensibleXml?: string | null, commentsExtendedXml?: string | null, context?: ParseContext): document_d_exports.Comment[];
|
|
33
|
+
declare function parseComments(commentsXml: string | null, styles: StyleMap | null, theme: document_d_exports.Theme | null, rels: document_d_exports.RelationshipMap, media: Map<string, document_d_exports.MediaFile>, commentsExtensibleXml?: string | null, commentsExtendedXml?: string | null, context?: ParseContext, previews?: PreviewLedger): document_d_exports.Comment[];
|
|
33
34
|
//#endregion
|
|
34
35
|
export { CommentExtendedInfo, parseComments, parseCommentsExtended };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { commentThreadParaId } from "./commentThreadKey.js";
|
|
2
|
-
import { CAPTURE,
|
|
2
|
+
import { CAPTURE, dispatchChildrenWithContext } from "./containerChildren.js";
|
|
3
3
|
import { PARA_ID_NAMESPACE_URIS, paraIdAttribute, paraIdParentAttribute } from "./paraIdAttribute.js";
|
|
4
4
|
import { parseParagraph } from "./paragraphParser.js";
|
|
5
5
|
import { cloneParagraphWithPropertySource } from "./paragraphPropertySource.js";
|
|
6
|
+
import { standalonePreviewLedger } from "./previewBudget.js";
|
|
6
7
|
import { RUN_PROPERTY_OWNERS, parseRunProperties } from "./runParser.js";
|
|
7
8
|
import { findChild, getAttribute, getAttributeByNamespaceUri, getChildElements, getLocalName, parseOnOffValue, parseXml } from "./xmlParser.js";
|
|
8
9
|
import { PARSE_WARNING_CODES } from "@stll/docx-core/model";
|
|
@@ -97,6 +98,46 @@ function parseCommentsExtended(xml) {
|
|
|
97
98
|
}
|
|
98
99
|
return infoByParaId;
|
|
99
100
|
}
|
|
101
|
+
const COMMENT_BODY_HANDLERS = {
|
|
102
|
+
p: (contentChild, walk) => {
|
|
103
|
+
const { styles, theme, rels, media, previews, paragraphs } = walk;
|
|
104
|
+
const paragraph = parseParagraph(contentChild, styles, theme, null, rels, media, { previews });
|
|
105
|
+
if (paragraphs.length > 0) {
|
|
106
|
+
paragraphs.push(paragraph);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const normalized = normalizeFirstCommentParagraph(contentChild, paragraph, theme);
|
|
110
|
+
walk.annotationReferenceFormatting = normalized.annotationReferenceFormatting;
|
|
111
|
+
paragraphs.push(normalized.paragraph);
|
|
112
|
+
},
|
|
113
|
+
altChunk: CAPTURE,
|
|
114
|
+
bookmarkEnd: CAPTURE,
|
|
115
|
+
bookmarkStart: CAPTURE,
|
|
116
|
+
commentRangeEnd: CAPTURE,
|
|
117
|
+
commentRangeStart: CAPTURE,
|
|
118
|
+
customXml: CAPTURE,
|
|
119
|
+
customXmlDelRangeEnd: CAPTURE,
|
|
120
|
+
customXmlDelRangeStart: CAPTURE,
|
|
121
|
+
customXmlInsRangeEnd: CAPTURE,
|
|
122
|
+
customXmlInsRangeStart: CAPTURE,
|
|
123
|
+
customXmlMoveFromRangeEnd: CAPTURE,
|
|
124
|
+
customXmlMoveFromRangeStart: CAPTURE,
|
|
125
|
+
customXmlMoveToRangeEnd: CAPTURE,
|
|
126
|
+
customXmlMoveToRangeStart: CAPTURE,
|
|
127
|
+
del: CAPTURE,
|
|
128
|
+
ins: CAPTURE,
|
|
129
|
+
moveFrom: CAPTURE,
|
|
130
|
+
moveFromRangeEnd: CAPTURE,
|
|
131
|
+
moveFromRangeStart: CAPTURE,
|
|
132
|
+
moveTo: CAPTURE,
|
|
133
|
+
moveToRangeEnd: CAPTURE,
|
|
134
|
+
moveToRangeStart: CAPTURE,
|
|
135
|
+
permEnd: CAPTURE,
|
|
136
|
+
permStart: CAPTURE,
|
|
137
|
+
proofErr: CAPTURE,
|
|
138
|
+
sdt: CAPTURE,
|
|
139
|
+
tbl: CAPTURE
|
|
140
|
+
};
|
|
100
141
|
/**
|
|
101
142
|
* Parse comments.xml into an array of Comment objects.
|
|
102
143
|
*
|
|
@@ -105,7 +146,7 @@ function parseCommentsExtended(xml) {
|
|
|
105
146
|
* local time. If `commentsExtendedXml` is provided, reply-thread
|
|
106
147
|
* parent links (`parentId`) and resolved state (`done`) are populated.
|
|
107
148
|
*/
|
|
108
|
-
function parseComments(commentsXml, styles, theme, rels, media, commentsExtensibleXml, commentsExtendedXml, context) {
|
|
149
|
+
function parseComments(commentsXml, styles, theme, rels, media, commentsExtensibleXml, commentsExtendedXml, context, previews = standalonePreviewLedger()) {
|
|
109
150
|
if (!commentsXml) return [];
|
|
110
151
|
const root = parseXml(commentsXml);
|
|
111
152
|
const dateUtcByParaId = commentsExtensibleXml ? parseCommentsExtensible(commentsExtensibleXml) : /* @__PURE__ */ new Map();
|
|
@@ -135,52 +176,23 @@ function parseComments(commentsXml, styles, theme, rels, media, commentsExtensib
|
|
|
135
176
|
const paraId = rawParaId ? String(rawParaId).toUpperCase() : null;
|
|
136
177
|
const date = (paraId ? dateUtcByParaId.get(paraId) : void 0) ?? localDate;
|
|
137
178
|
const done = (paraId ? extendedByParaId.get(paraId) : void 0)?.done;
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
179
|
+
const walk = {
|
|
180
|
+
styles,
|
|
181
|
+
theme,
|
|
182
|
+
rels,
|
|
183
|
+
media,
|
|
184
|
+
previews,
|
|
185
|
+
paragraphs: [],
|
|
186
|
+
annotationReferenceFormatting: void 0
|
|
187
|
+
};
|
|
188
|
+
const preserved = dispatchChildrenWithContext({
|
|
141
189
|
element: child,
|
|
142
190
|
container: "w:comment",
|
|
143
|
-
capturePosition: () => paragraphs.length,
|
|
144
|
-
handlers:
|
|
145
|
-
|
|
146
|
-
const paragraph = parseParagraph(contentChild, styles, theme, null, rels, media);
|
|
147
|
-
if (paragraphs.length > 0) {
|
|
148
|
-
paragraphs.push(paragraph);
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
const normalized = normalizeFirstCommentParagraph(contentChild, paragraph, theme);
|
|
152
|
-
annotationReferenceFormatting = normalized.annotationReferenceFormatting;
|
|
153
|
-
paragraphs.push(normalized.paragraph);
|
|
154
|
-
},
|
|
155
|
-
altChunk: CAPTURE,
|
|
156
|
-
bookmarkEnd: CAPTURE,
|
|
157
|
-
bookmarkStart: CAPTURE,
|
|
158
|
-
commentRangeEnd: CAPTURE,
|
|
159
|
-
commentRangeStart: CAPTURE,
|
|
160
|
-
customXml: CAPTURE,
|
|
161
|
-
customXmlDelRangeEnd: CAPTURE,
|
|
162
|
-
customXmlDelRangeStart: CAPTURE,
|
|
163
|
-
customXmlInsRangeEnd: CAPTURE,
|
|
164
|
-
customXmlInsRangeStart: CAPTURE,
|
|
165
|
-
customXmlMoveFromRangeEnd: CAPTURE,
|
|
166
|
-
customXmlMoveFromRangeStart: CAPTURE,
|
|
167
|
-
customXmlMoveToRangeEnd: CAPTURE,
|
|
168
|
-
customXmlMoveToRangeStart: CAPTURE,
|
|
169
|
-
del: CAPTURE,
|
|
170
|
-
ins: CAPTURE,
|
|
171
|
-
moveFrom: CAPTURE,
|
|
172
|
-
moveFromRangeEnd: CAPTURE,
|
|
173
|
-
moveFromRangeStart: CAPTURE,
|
|
174
|
-
moveTo: CAPTURE,
|
|
175
|
-
moveToRangeEnd: CAPTURE,
|
|
176
|
-
moveToRangeStart: CAPTURE,
|
|
177
|
-
permEnd: CAPTURE,
|
|
178
|
-
permStart: CAPTURE,
|
|
179
|
-
proofErr: CAPTURE,
|
|
180
|
-
sdt: CAPTURE,
|
|
181
|
-
tbl: CAPTURE
|
|
182
|
-
}
|
|
191
|
+
capturePosition: () => walk.paragraphs.length,
|
|
192
|
+
handlers: COMMENT_BODY_HANDLERS,
|
|
193
|
+
context: walk
|
|
183
194
|
});
|
|
195
|
+
const { paragraphs, annotationReferenceFormatting } = walk;
|
|
184
196
|
if (paraId && !commentIdByParaId.has(paraId)) commentIdByParaId.set(paraId, id);
|
|
185
197
|
parsed.push({
|
|
186
198
|
comment: {
|
|
@@ -83,6 +83,12 @@ declare const ownedElsewhere: <Container extends DispatchedContainer, Child exte
|
|
|
83
83
|
* difference between this and a `default` that says nothing.
|
|
84
84
|
*/
|
|
85
85
|
declare const DROPPED_WITH_ITS_WRAPPER = "dropped-with-its-wrapper";
|
|
86
|
+
/**
|
|
87
|
+
* A handler that reads one child. `context` is the value the walk was given
|
|
88
|
+
* (see {@link dispatchChildrenWithContext}), so a handler table can be built
|
|
89
|
+
* once per module rather than as closures per element.
|
|
90
|
+
*/
|
|
91
|
+
type ChildReader<Context = undefined> = (child: XmlElement, context: Context) => typeof CAPTURE | void;
|
|
86
92
|
/**
|
|
87
93
|
* What a container does with one declared child.
|
|
88
94
|
*
|
|
@@ -94,7 +100,7 @@ declare const DROPPED_WITH_ITS_WRAPPER = "dropped-with-its-wrapper";
|
|
|
94
100
|
* it by the outcome rather than by the name is what makes the decision total:
|
|
95
101
|
* the map cannot list the values a reader will refuse.
|
|
96
102
|
*/
|
|
97
|
-
type ChildDisposition<Container extends DispatchedContainer = DispatchedContainer, Child extends string = string
|
|
103
|
+
type ChildDisposition<Container extends DispatchedContainer = DispatchedContainer, Child extends string = string, Context = undefined> = ChildReader<Context> | typeof CAPTURE | typeof DROPPED_WITH_ITS_WRAPPER | OwnedElsewhere<Container, Child>;
|
|
98
104
|
/**
|
|
99
105
|
* A total decision per declared child.
|
|
100
106
|
*
|
|
@@ -103,13 +109,13 @@ type ChildDisposition<Container extends DispatchedContainer = DispatchedContaine
|
|
|
103
109
|
* type is keyed by the child it is filed under, so an {@link ownedElsewhere}
|
|
104
110
|
* entry cannot name a different child than the one it decides.
|
|
105
111
|
*/
|
|
106
|
-
type ChildHandlers<Container extends DispatchedContainer> = Readonly<{ [Child in DeclaredChild<Container>]: ChildDisposition<Container, Child>; }>;
|
|
107
|
-
type DispatchChildrenOptions<Container extends DispatchedContainer> = {
|
|
112
|
+
type ChildHandlers<Container extends DispatchedContainer, Context = undefined> = Readonly<{ [Child in DeclaredChild<Container>]: ChildDisposition<Container, Child, Context>; }>;
|
|
113
|
+
type DispatchChildrenOptions<Container extends DispatchedContainer, Context = undefined> = {
|
|
108
114
|
/** The container element, as the source wrote it. */
|
|
109
115
|
element: XmlElement;
|
|
110
116
|
/** Which container's declared-child set the handler map must be total over. */
|
|
111
117
|
container: Container;
|
|
112
|
-
handlers: ChildHandlers<Container>;
|
|
118
|
+
handlers: ChildHandlers<Container, Context>;
|
|
113
119
|
/**
|
|
114
120
|
* Where a capture belongs among the caller's children, called once per
|
|
115
121
|
* captured child.
|
|
@@ -135,7 +141,7 @@ type DispatchChildrenOptions<Container extends DispatchedContainer> = {
|
|
|
135
141
|
*
|
|
136
142
|
* Each entry is a claim that folio reads this name in this container.
|
|
137
143
|
*/
|
|
138
|
-
undeclared?: Readonly<Record<string, ChildDisposition
|
|
144
|
+
undeclared?: Readonly<Record<string, ChildDisposition<DispatchedContainer, string, Context>>>;
|
|
139
145
|
/**
|
|
140
146
|
* Dispositions for whole namespaces the declared set does not cover, by
|
|
141
147
|
* namespace URI, consulted after {@link undeclared} and before the sink.
|
|
@@ -148,7 +154,7 @@ type DispatchChildrenOptions<Container extends DispatchedContainer> = {
|
|
|
148
154
|
* not a `default` in disguise: a child from any *other* namespace still goes
|
|
149
155
|
* to the sink, which is the branch a hand-written `default` gets wrong.
|
|
150
156
|
*/
|
|
151
|
-
undeclaredNamespaces?: Readonly<Record<string, ChildDisposition
|
|
157
|
+
undeclaredNamespaces?: Readonly<Record<string, ChildDisposition<DispatchedContainer, string, Context>>>;
|
|
152
158
|
};
|
|
153
159
|
/**
|
|
154
160
|
* The Transitional spelling of a namespace, so one disposition covers both.
|
|
@@ -171,7 +177,14 @@ declare const transitionalNamespaceOf: (namespace: string) => string;
|
|
|
171
177
|
* none — an empty record is never written, so a fully modelled container
|
|
172
178
|
* stays byte-identical in the model.
|
|
173
179
|
*/
|
|
174
|
-
declare const dispatchChildren: <Container extends DispatchedContainer>(
|
|
180
|
+
declare const dispatchChildren: <Container extends DispatchedContainer>(options: DispatchChildrenOptions<Container>) => PreservedMarkup | undefined;
|
|
181
|
+
/**
|
|
182
|
+
* {@link dispatchChildren} for a handler table that reads into a value it is
|
|
183
|
+
* handed rather than one it closes over, so the table is built once.
|
|
184
|
+
*/
|
|
185
|
+
declare const dispatchChildrenWithContext: <Container extends DispatchedContainer, Context>({ element, handlers, capturePosition, undeclared, undeclaredNamespaces, context }: DispatchChildrenOptions<Container, Context> & {
|
|
186
|
+
context: Context;
|
|
187
|
+
}) => PreservedMarkup | undefined;
|
|
175
188
|
/**
|
|
176
189
|
* Put a container's modelled children back with its preserved ones between
|
|
177
190
|
* them, in source position.
|
|
@@ -205,4 +218,4 @@ declare const serializeWithPreservedChildren: (modelled: readonly string[], pres
|
|
|
205
218
|
*/
|
|
206
219
|
declare const sequencePositions: <Container extends SequenceContainer>(container: Container, element: XmlElement) => ((child: XmlElement) => number);
|
|
207
220
|
//#endregion
|
|
208
|
-
export { CAPTURE, ChildDisposition, ChildHandlers, ChildOwnerClaim, ChildOwnerRef, DROPPED_WITH_ITS_WRAPPER, OwnedElsewhere, dispatchChildren, keptUnless, ownedElsewhere, ownedElsewhereClaims, sequencePositions, serializeWithPreservedChildren, transitionalNamespaceOf, withPreservedChildren };
|
|
221
|
+
export { CAPTURE, ChildDisposition, ChildHandlers, ChildOwnerClaim, ChildOwnerRef, ChildReader, DROPPED_WITH_ITS_WRAPPER, OwnedElsewhere, dispatchChildren, dispatchChildrenWithContext, keptUnless, ownedElsewhere, ownedElsewhereClaims, sequencePositions, serializeWithPreservedChildren, transitionalNamespaceOf, withPreservedChildren };
|
|
@@ -59,6 +59,13 @@ const DROPPED_WITH_ITS_WRAPPER = "dropped-with-its-wrapper";
|
|
|
59
59
|
*/
|
|
60
60
|
const transitionalNamespaceOf = (namespace) => TRANSITIONAL_NAMESPACE_BY_STRICT_URI.get(namespace) ?? namespace;
|
|
61
61
|
/**
|
|
62
|
+
* A table's own entry for `key`. Read directly rather than copied into a `Map`
|
|
63
|
+
* per container: the tables are rebuilt per element, and the copy dominated the
|
|
64
|
+
* walk. `Object.hasOwn` keeps a name such as `constructor` from resolving to a
|
|
65
|
+
* prototype member.
|
|
66
|
+
*/
|
|
67
|
+
const ownDisposition = (table, key) => table !== void 0 && Object.hasOwn(table, key) ? table[key] : void 0;
|
|
68
|
+
/**
|
|
62
69
|
* Walk a container's children, handing each to its handler and the rest to the
|
|
63
70
|
* sink.
|
|
64
71
|
*
|
|
@@ -66,7 +73,15 @@ const transitionalNamespaceOf = (namespace) => TRANSITIONAL_NAMESPACE_BY_STRICT_
|
|
|
66
73
|
* none — an empty record is never written, so a fully modelled container
|
|
67
74
|
* stays byte-identical in the model.
|
|
68
75
|
*/
|
|
69
|
-
const dispatchChildren = (
|
|
76
|
+
const dispatchChildren = (options) => dispatchChildrenWithContext({
|
|
77
|
+
...options,
|
|
78
|
+
context: void 0
|
|
79
|
+
});
|
|
80
|
+
/**
|
|
81
|
+
* {@link dispatchChildren} for a handler table that reads into a value it is
|
|
82
|
+
* handed rather than one it closes over, so the table is built once.
|
|
83
|
+
*/
|
|
84
|
+
const dispatchChildrenWithContext = ({ element, handlers, capturePosition, undeclared, undeclaredNamespaces, context }) => {
|
|
70
85
|
const children = [];
|
|
71
86
|
const capture = (child) => {
|
|
72
87
|
children.push({
|
|
@@ -74,19 +89,17 @@ const dispatchChildren = ({ element, handlers, capturePosition, undeclared, unde
|
|
|
74
89
|
xml: captureVerbatimXml(child)
|
|
75
90
|
});
|
|
76
91
|
};
|
|
77
|
-
const declared =
|
|
78
|
-
const byName = new Map(Object.entries(undeclared ?? {}));
|
|
79
|
-
const byNamespace = new Map(Object.entries(undeclaredNamespaces ?? {}));
|
|
92
|
+
const declared = handlers;
|
|
80
93
|
for (const child of getChildElements(element)) {
|
|
81
94
|
const localName = getLocalName(child.name);
|
|
82
95
|
const namespace = getNamespaceUri(child);
|
|
83
|
-
const disposition = namespace === void 0 || WORDPROCESSINGML_NAMESPACE_URIS.has(namespace) ? declared
|
|
96
|
+
const disposition = namespace === void 0 || WORDPROCESSINGML_NAMESPACE_URIS.has(namespace) ? ownDisposition(declared, localName) ?? ownDisposition(undeclared, localName) : ownDisposition(undeclared, localName) ?? ownDisposition(undeclaredNamespaces, transitionalNamespaceOf(namespace));
|
|
84
97
|
if (disposition === void 0 || disposition === "capture") {
|
|
85
98
|
capture(child);
|
|
86
99
|
continue;
|
|
87
100
|
}
|
|
88
101
|
if (typeof disposition !== "function") continue;
|
|
89
|
-
if (disposition(child) === "capture") capture(child);
|
|
102
|
+
if (disposition(child, context) === "capture") capture(child);
|
|
90
103
|
}
|
|
91
104
|
return children.length === 0 ? void 0 : { children };
|
|
92
105
|
};
|
|
@@ -138,16 +151,33 @@ const serializeWithPreservedChildren = (modelled, preserved) => withPreservedChi
|
|
|
138
151
|
* ahead of the sequence's first slot.
|
|
139
152
|
*/
|
|
140
153
|
const sequencePositions = (container, element) => {
|
|
154
|
+
let positions;
|
|
155
|
+
return (child) => {
|
|
156
|
+
positions ??= computeSequencePositions(container, element);
|
|
157
|
+
return positions.get(child) ?? -1;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
const SEQUENCE_ORDINALS = /* @__PURE__ */ new Map();
|
|
161
|
+
const sequenceOrdinals = (container) => {
|
|
162
|
+
const cached = SEQUENCE_ORDINALS.get(container);
|
|
163
|
+
if (cached !== void 0) return cached;
|
|
164
|
+
const ordinals = /* @__PURE__ */ new Map();
|
|
141
165
|
const declared = SEQUENCE_CHILDREN[container];
|
|
166
|
+
for (const [at, name] of declared.entries()) if (!ordinals.has(name)) ordinals.set(name, at);
|
|
167
|
+
SEQUENCE_ORDINALS.set(container, ordinals);
|
|
168
|
+
return ordinals;
|
|
169
|
+
};
|
|
170
|
+
const computeSequencePositions = (container, element) => {
|
|
171
|
+
const ordinals = sequenceOrdinals(container);
|
|
142
172
|
const positions = /* @__PURE__ */ new Map();
|
|
143
173
|
let previous = -1;
|
|
144
174
|
for (const child of getChildElements(element)) {
|
|
145
175
|
const namespace = getNamespaceUri(child);
|
|
146
|
-
const at = namespace === void 0 || WORDPROCESSINGML_NAMESPACE_URIS.has(namespace) ?
|
|
176
|
+
const at = namespace === void 0 || WORDPROCESSINGML_NAMESPACE_URIS.has(namespace) ? ordinals.get(getLocalName(child.name)) ?? -1 : -1;
|
|
147
177
|
if (at !== -1) previous = at;
|
|
148
178
|
positions.set(child, at === -1 ? previous : at);
|
|
149
179
|
}
|
|
150
|
-
return
|
|
180
|
+
return positions;
|
|
151
181
|
};
|
|
152
182
|
//#endregion
|
|
153
|
-
export { CAPTURE, DROPPED_WITH_ITS_WRAPPER, dispatchChildren, keptUnless, ownedElsewhere, ownedElsewhereClaims, sequencePositions, serializeWithPreservedChildren, transitionalNamespaceOf, withPreservedChildren };
|
|
183
|
+
export { CAPTURE, DROPPED_WITH_ITS_WRAPPER, dispatchChildren, dispatchChildrenWithContext, keptUnless, ownedElsewhere, ownedElsewhereClaims, sequencePositions, serializeWithPreservedChildren, transitionalNamespaceOf, withPreservedChildren };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { document_d_exports } from "../types/document.js";
|
|
2
2
|
import { NumberingMap } from "./numberingParser.js";
|
|
3
3
|
import { ParseContext } from "./parseContext.js";
|
|
4
|
+
import { PreviewLedger } from "./previewBudget.js";
|
|
4
5
|
import { StyleMap } from "./styleParser.js";
|
|
5
6
|
//#region src/docx/documentParser.d.ts
|
|
6
7
|
/**
|
|
@@ -26,9 +27,12 @@ declare function extractAllTemplateVariables(content: document_d_exports.BlockCo
|
|
|
26
27
|
* @param numbering - Parsed numbering definitions
|
|
27
28
|
* @param rels - Document relationships
|
|
28
29
|
* @param media - Media files
|
|
30
|
+
* @param context - Where normalisations are reported
|
|
31
|
+
* @param previews - The ledger of the package this body belongs to; a body
|
|
32
|
+
* read on its own charges its previews to no package
|
|
29
33
|
* @returns DocumentBody with content, sections, and template variables
|
|
30
34
|
*/
|
|
31
|
-
declare function parseDocumentBody(xml: string, 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, context?: ParseContext): document_d_exports.DocumentBody;
|
|
35
|
+
declare function parseDocumentBody(xml: string, 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, context?: ParseContext, previews?: PreviewLedger): document_d_exports.DocumentBody;
|
|
32
36
|
/**
|
|
33
37
|
* Get all paragraphs from document body (flattened)
|
|
34
38
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parseBlockContent } from "./blockContentParser.js";
|
|
2
2
|
import { getParagraphText } from "./paragraphParser.js";
|
|
3
|
+
import { standalonePreviewLedger } from "./previewBudget.js";
|
|
3
4
|
import { getDefaultSectionProperties, parseSectionProperties } from "./sectionParser.js";
|
|
4
|
-
import { parseStreamingXml } from "./streamingXmlParser.js";
|
|
5
5
|
import { parseThemeColorAttribute } from "./themeColorAttribute.js";
|
|
6
6
|
import { captureVerbatimXml } from "./verbatimCapture.js";
|
|
7
7
|
import { WORDPROCESSINGML_NAMESPACE_URIS, collectXmlnsDeclarations, findChild, findChildByNamespaceUri, getAttributeByNamespaceUri, getLocalName, parseXml } from "./xmlParser.js";
|
|
@@ -145,13 +145,15 @@ function parseDocumentBackground(documentEl, context) {
|
|
|
145
145
|
* @param numbering - Parsed numbering definitions
|
|
146
146
|
* @param rels - Document relationships
|
|
147
147
|
* @param media - Media files
|
|
148
|
+
* @param context - Where normalisations are reported
|
|
149
|
+
* @param previews - The ledger of the package this body belongs to; a body
|
|
150
|
+
* read on its own charges its previews to no package
|
|
148
151
|
* @returns DocumentBody with content, sections, and template variables
|
|
149
152
|
*/
|
|
150
|
-
function parseDocumentBody(xml, styles = null, theme = null, numbering = null, rels = null, media = null, context) {
|
|
153
|
+
function parseDocumentBody(xml, styles = null, theme = null, numbering = null, rels = null, media = null, context, previews = standalonePreviewLedger()) {
|
|
151
154
|
const result = { content: [] };
|
|
152
155
|
if (!xml) return result;
|
|
153
|
-
const
|
|
154
|
-
const documentEl = ((streamed.status === "parsed" ? streamed.value : parseXml(xml)).elements ?? []).find((el) => el.type === "element" && (el.name === "w:document" || el.name?.endsWith(":document")));
|
|
156
|
+
const documentEl = (parseXml(xml).elements ?? []).find((el) => el.type === "element" && (el.name === "w:document" || el.name?.endsWith(":document")));
|
|
155
157
|
if (!documentEl) return result;
|
|
156
158
|
const background = parseDocumentBackground(documentEl, context);
|
|
157
159
|
if (background !== void 0) result.background = background;
|
|
@@ -159,7 +161,8 @@ function parseDocumentBody(xml, styles = null, theme = null, numbering = null, r
|
|
|
159
161
|
if (!bodyEl) return result;
|
|
160
162
|
result.content = parseBlockContent(bodyEl, styles, theme, numbering, rels, media, {
|
|
161
163
|
rootXmlns: collectXmlnsDeclarations(documentEl),
|
|
162
|
-
context
|
|
164
|
+
context,
|
|
165
|
+
previews
|
|
163
166
|
});
|
|
164
167
|
const finalSectPr = findChild(bodyEl, "w", "sectPr");
|
|
165
168
|
if (finalSectPr) result.finalSectionProperties = parseSectionProperties(finalSectPr, context);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { document_d_exports } from "../types/document.js";
|
|
2
|
+
import { XmlElement } from "./xmlParser.js";
|
|
3
|
+
//#region src/docx/documentSectionFacts.d.ts
|
|
4
|
+
type HeaderFooterReference = {
|
|
5
|
+
element: "headerReference" | "footerReference";
|
|
6
|
+
/** The parsed `ST_HdrFtr` value, never the raw attribute. */
|
|
7
|
+
type: document_d_exports.HeaderFooterType;
|
|
8
|
+
rId: string;
|
|
9
|
+
};
|
|
10
|
+
/** What a save must not lose from `word/document.xml`. */
|
|
11
|
+
type DocumentSectionFacts = {
|
|
12
|
+
/** `w:sectPr` elements, excluding the prior records inside `w:sectPrChange`. */
|
|
13
|
+
sectionCount: number;
|
|
14
|
+
/** Every header/footer reference, including those inside `w:sectPrChange`. */
|
|
15
|
+
headerFooterReferences: readonly HeaderFooterReference[];
|
|
16
|
+
};
|
|
17
|
+
/** Both facts from one walk of a parsed document tree. */
|
|
18
|
+
declare const collectDocumentSectionFacts: (root: XmlElement) => DocumentSectionFacts;
|
|
19
|
+
/** Read the section facts of a `word/document.xml` string under the shared resource limits. */
|
|
20
|
+
declare const readDocumentSectionFacts: (xml: string) => DocumentSectionFacts;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { DocumentSectionFacts, HeaderFooterReference, collectDocumentSectionFacts, readDocumentSectionFacts };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { parseHeaderFooterType } from "./headerFooterRefParser.js";
|
|
2
|
+
import { OFFICE_RELATIONSHIP_NAMESPACE_URIS, WORDPROCESSINGML_NAMESPACE_URIS, getAttributeByNamespaceUri, getChildElements, getLocalName, getNamespaceUri, parseXml } from "./xmlParser.js";
|
|
3
|
+
import { assertXmlResourceLimits } from "./xmlResourceLimits.js";
|
|
4
|
+
//#region src/docx/documentSectionFacts.ts
|
|
5
|
+
const isWordprocessingElement = (element, localName) => getLocalName(element.name) === localName && WORDPROCESSINGML_NAMESPACE_URIS.has(getNamespaceUri(element) ?? "");
|
|
6
|
+
/** Both facts from one walk of a parsed document tree. */
|
|
7
|
+
const collectDocumentSectionFacts = (root) => {
|
|
8
|
+
let sectionCount = 0;
|
|
9
|
+
const headerFooterReferences = [];
|
|
10
|
+
const pending = [{
|
|
11
|
+
element: root,
|
|
12
|
+
insidePropertyChange: false
|
|
13
|
+
}];
|
|
14
|
+
for (let current = pending.pop(); current !== void 0; current = pending.pop()) {
|
|
15
|
+
const { element, insidePropertyChange } = current;
|
|
16
|
+
const localName = getLocalName(element.name);
|
|
17
|
+
if (!insidePropertyChange && isWordprocessingElement(element, "sectPr")) sectionCount += 1;
|
|
18
|
+
if ((localName === "headerReference" || localName === "footerReference") && isWordprocessingElement(element, localName)) {
|
|
19
|
+
const rId = getAttributeByNamespaceUri(element, OFFICE_RELATIONSHIP_NAMESPACE_URIS, "id");
|
|
20
|
+
if (rId) headerFooterReferences.push({
|
|
21
|
+
element: localName,
|
|
22
|
+
type: parseHeaderFooterType(getAttributeByNamespaceUri(element, WORDPROCESSINGML_NAMESPACE_URIS, "type")),
|
|
23
|
+
rId
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const childrenInsidePropertyChange = insidePropertyChange || isWordprocessingElement(element, "sectPrChange");
|
|
27
|
+
for (const child of getChildElements(element)) pending.push({
|
|
28
|
+
element: child,
|
|
29
|
+
insidePropertyChange: childrenInsidePropertyChange
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
sectionCount,
|
|
34
|
+
headerFooterReferences
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
/** Read the section facts of a `word/document.xml` string under the shared resource limits. */
|
|
38
|
+
const readDocumentSectionFacts = (xml) => {
|
|
39
|
+
assertXmlResourceLimits({ xml });
|
|
40
|
+
return collectDocumentSectionFacts(parseXml(xml));
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
export { collectDocumentSectionFacts, readDocumentSectionFacts };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { XmlElement } from "./xmlParser.js";
|
|
2
|
+
//#region src/docx/drawingGroupChildren.d.ts
|
|
3
|
+
type GroupTextBoxFrame = {
|
|
4
|
+
/** Element indices from the `wpg:wgp` down to the `wps:wsp`. */
|
|
5
|
+
path: number[];
|
|
6
|
+
wsp: XmlElement;
|
|
7
|
+
/** EMUs from the group's top-left corner. */
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
/** Degrees clockwise. */
|
|
13
|
+
rotation: number;
|
|
14
|
+
flipH: boolean;
|
|
15
|
+
flipV: boolean;
|
|
16
|
+
};
|
|
17
|
+
type Transform2D = {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
childX: number;
|
|
23
|
+
childY: number;
|
|
24
|
+
childWidth: number;
|
|
25
|
+
childHeight: number;
|
|
26
|
+
rotation: number;
|
|
27
|
+
flipH: boolean;
|
|
28
|
+
flipV: boolean;
|
|
29
|
+
};
|
|
30
|
+
/** A `CT_GroupTransform2D` or `CT_Transform2D`; absent children read as zero. */
|
|
31
|
+
declare const readTransform: (xfrm: XmlElement | null) => Transform2D;
|
|
32
|
+
/**
|
|
33
|
+
* Every `wps:wsp` with a text box in the group, nested groups included, with
|
|
34
|
+
* its frame in EMUs from the group's top-left corner.
|
|
35
|
+
*
|
|
36
|
+
* A nested group that is rotated or flipped turns its children's frames into
|
|
37
|
+
* something other than a rectangle in the drawing's axes, so its text boxes
|
|
38
|
+
* are left out and stay with the preview.
|
|
39
|
+
*/
|
|
40
|
+
declare const collectGroupTextBoxes: (group: XmlElement, width: number, height: number) => GroupTextBoxFrame[];
|
|
41
|
+
/** Identity of a group drawing's authored XML. */
|
|
42
|
+
declare const groupXmlFingerprint: (rawXml: string) => string;
|
|
43
|
+
/** Identity of a text box's content, compared on save to tell an edit. */
|
|
44
|
+
declare const groupTextContentFingerprint: (content: unknown) => string;
|
|
45
|
+
type GroupTextBoxEdit = {
|
|
46
|
+
path: readonly number[];
|
|
47
|
+
/** Serialized `w:txbxContent` children. */
|
|
48
|
+
contentXml: string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* The captured group XML with each edited text box's content replaced, or
|
|
52
|
+
* undefined when an edit names no text box in it.
|
|
53
|
+
*
|
|
54
|
+
* The replacement is written as a placeholder element and substituted after
|
|
55
|
+
* the tree is serialized, so the new content is never reparsed and the rest
|
|
56
|
+
* of the capture is written exactly as it was read.
|
|
57
|
+
*/
|
|
58
|
+
declare const replaceGroupTextBoxContent: (rawXml: string, edits: readonly GroupTextBoxEdit[]) => string | undefined;
|
|
59
|
+
//#endregion
|
|
60
|
+
export { GroupTextBoxEdit, GroupTextBoxFrame, collectGroupTextBoxes, groupTextContentFingerprint, groupXmlFingerprint, readTransform, replaceGroupTextBoxContent };
|