@beyondwork/docx-react-component 1.0.102 → 1.0.104
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/package.json +1 -1
- package/src/api/public-types.ts +63 -1
- package/src/api/v3/_runtime-handle.ts +2 -0
- package/src/api/v3/ai/outline.ts +2 -7
- package/src/api/v3/runtime/geometry.ts +79 -0
- package/src/core/commands/formatting-commands.ts +8 -7
- package/src/core/commands/paragraph-layout-commands.ts +11 -10
- package/src/core/commands/section-layout-commands.ts +7 -6
- package/src/core/commands/style-commands.ts +3 -2
- package/src/io/normalize/normalize-text.ts +6 -5
- package/src/io/ooxml/parse-anchor.ts +15 -15
- package/src/io/ooxml/parse-drawing.ts +103 -5
- package/src/io/ooxml/parse-fields.ts +43 -21
- package/src/io/ooxml/parse-font-table.ts +2 -1
- package/src/io/ooxml/parse-footnotes.ts +3 -2
- package/src/io/ooxml/parse-headers-footers.ts +7 -6
- package/src/io/ooxml/parse-main-document.ts +41 -40
- package/src/io/ooxml/parse-numbering.ts +3 -2
- package/src/io/ooxml/parse-object.ts +6 -6
- package/src/io/ooxml/parse-paragraph-formatting.ts +12 -11
- package/src/io/ooxml/parse-picture.ts +16 -16
- package/src/io/ooxml/parse-run-formatting.ts +11 -10
- package/src/io/ooxml/parse-settings.ts +2 -1
- package/src/io/ooxml/parse-shapes.ts +148 -17
- package/src/io/ooxml/parse-styles.ts +16 -16
- package/src/io/ooxml/parse-theme.ts +5 -4
- package/src/model/canonical-document.ts +869 -836
- package/src/model/canonical-layout-inputs.ts +979 -0
- package/src/model/layout/index.ts +6 -0
- package/src/model/layout/page-graph-types.ts +61 -0
- package/src/model/layout/runtime-page-graph-types.ts +10 -0
- package/src/runtime/collab/runtime-collab-sync.ts +3 -3
- package/src/runtime/debug/build-debug-inspector-snapshot.ts +17 -4
- package/src/runtime/document-runtime.ts +30 -14
- package/src/runtime/event-refresh-hints.ts +3 -0
- package/src/runtime/formatting/document-lookup.ts +3 -2
- package/src/runtime/formatting/formatting-context.ts +176 -34
- package/src/runtime/formatting/index.ts +20 -0
- package/src/runtime/formatting/layout-inputs.ts +320 -0
- package/src/runtime/formatting/numbering/geometry.ts +13 -12
- package/src/runtime/formatting/style-cascade.ts +2 -1
- package/src/runtime/formatting/table-style-resolver.ts +8 -7
- package/src/runtime/geometry/caret-geometry.ts +82 -10
- package/src/runtime/geometry/geometry-facet.ts +36 -0
- package/src/runtime/geometry/geometry-index.ts +891 -0
- package/src/runtime/geometry/geometry-types.ts +221 -1
- package/src/runtime/geometry/index.ts +26 -0
- package/src/runtime/geometry/inert-geometry-facet.ts +3 -0
- package/src/runtime/geometry/replacement-envelope.ts +41 -2
- package/src/runtime/layout/layout-engine-version.ts +16 -1
- package/src/runtime/layout/page-graph.ts +191 -1
- package/src/runtime/prerender/graph-canonicalize.ts +30 -0
- package/src/runtime/surface-projection.ts +74 -39
- package/src/runtime/workflow/coordinator.ts +57 -11
- package/src/session/import/normalize.ts +2 -1
- package/src/session/import/source-package-evidence.ts +612 -1
- package/src/ui-tailwind/chrome-overlay/tw-page-stack-overlay-layer.tsx +3 -0
|
@@ -2,7 +2,12 @@ import type { OpcRelationship } from "./part-manifest.ts";
|
|
|
2
2
|
import { normalizePartPath, resolveRelationshipTarget } from "./part-manifest.ts";
|
|
3
3
|
import type { InlineMediaPart } from "./parse-inline-media.ts";
|
|
4
4
|
import type { ChartPartLookup } from "./parse-complex-content.ts";
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
AnchorGeometry,
|
|
7
|
+
DrawingFrameNode,
|
|
8
|
+
Mutable,
|
|
9
|
+
PreserveOnlyObjectSizing,
|
|
10
|
+
} from "../../model/canonical-document.ts";
|
|
6
11
|
import { parseAnchorGeometry } from "./parse-anchor.ts";
|
|
7
12
|
import { parsePicture } from "./parse-picture.ts";
|
|
8
13
|
import { parseShapeContent, type TxbxBlockParser } from "./parse-shapes.ts";
|
|
@@ -144,6 +149,13 @@ function resolveFromBranch(
|
|
|
144
149
|
if (uri === WPS_SHAPE_GRAPHIC_URI && isWordArtGraphicData(graphicData)) return null;
|
|
145
150
|
|
|
146
151
|
const content = resolveContent(uri, graphicData, outerRawXml, opts);
|
|
152
|
+
attachPreserveOnlyObjectSizing(content, {
|
|
153
|
+
anchor: geometry,
|
|
154
|
+
container,
|
|
155
|
+
fallbackHint: fallbackHintForContent(content, geometry),
|
|
156
|
+
rawXml: outerRawXml,
|
|
157
|
+
sourcePartPath: opts.sourcePartPath,
|
|
158
|
+
});
|
|
147
159
|
return { type: "drawing_frame", anchor: geometry, content };
|
|
148
160
|
}
|
|
149
161
|
|
|
@@ -190,14 +202,14 @@ function resolveContent(
|
|
|
190
202
|
resolveRelationshipTarget(opts.sourcePartPath ?? "/word/document.xml", rel),
|
|
191
203
|
);
|
|
192
204
|
const mediaPart = opts.mediaParts?.get(partPath);
|
|
193
|
-
pic.packagePartName = partPath;
|
|
194
|
-
pic.mediaId = `media:${partPath.slice(1)}`;
|
|
205
|
+
(pic as Mutable<typeof pic>).packagePartName = partPath;
|
|
206
|
+
(pic as Mutable<typeof pic>).mediaId = `media:${partPath.slice(1)}`;
|
|
195
207
|
if (mediaPart?.contentType) {
|
|
196
|
-
pic.contentType = mediaPart.contentType;
|
|
208
|
+
(pic as Mutable<typeof pic>).contentType = mediaPart.contentType;
|
|
197
209
|
}
|
|
198
210
|
}
|
|
199
211
|
// F4.1 — preserve outer drawing XML for lossless round-trip serialization
|
|
200
|
-
pic.rawXml = rawXml;
|
|
212
|
+
(pic as Mutable<typeof pic>).rawXml = rawXml;
|
|
201
213
|
return pic;
|
|
202
214
|
}
|
|
203
215
|
}
|
|
@@ -231,6 +243,92 @@ function resolveContent(
|
|
|
231
243
|
return { type: "opaque", rawXml };
|
|
232
244
|
}
|
|
233
245
|
|
|
246
|
+
function attachPreserveOnlyObjectSizing(
|
|
247
|
+
content: DrawingFrameNode["content"],
|
|
248
|
+
context: {
|
|
249
|
+
anchor: AnchorGeometry;
|
|
250
|
+
container: XmlElementNode;
|
|
251
|
+
fallbackHint: PreserveOnlyObjectSizing["fallbackHint"] | null;
|
|
252
|
+
rawXml: string;
|
|
253
|
+
sourcePartPath: string | undefined;
|
|
254
|
+
},
|
|
255
|
+
): void {
|
|
256
|
+
if (content.type === "picture" || context.fallbackHint === null) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
(content as Mutable<typeof content>).preserveOnlyObject = {
|
|
261
|
+
sourceId: createPreserveOnlyObjectSourceId(
|
|
262
|
+
context.sourcePartPath,
|
|
263
|
+
context.anchor,
|
|
264
|
+
context.rawXml,
|
|
265
|
+
),
|
|
266
|
+
display: context.anchor.display,
|
|
267
|
+
extentEmu: {
|
|
268
|
+
widthEmu: context.anchor.extent.widthEmu,
|
|
269
|
+
heightEmu: context.anchor.extent.heightEmu,
|
|
270
|
+
},
|
|
271
|
+
fallbackHint: context.fallbackHint,
|
|
272
|
+
relationshipIds: collectRelationshipIds(context.container),
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function fallbackHintForContent(
|
|
277
|
+
content: DrawingFrameNode["content"],
|
|
278
|
+
anchor: AnchorGeometry,
|
|
279
|
+
): PreserveOnlyObjectSizing["fallbackHint"] | null {
|
|
280
|
+
switch (content.type) {
|
|
281
|
+
case "picture":
|
|
282
|
+
return null;
|
|
283
|
+
case "chart_preview":
|
|
284
|
+
return "chart";
|
|
285
|
+
case "smartart_preview":
|
|
286
|
+
return "smartart";
|
|
287
|
+
case "shape":
|
|
288
|
+
return "shape";
|
|
289
|
+
case "opaque":
|
|
290
|
+
return anchor.display === "floating" ? "drawing-floating" : "drawing-inline";
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function createPreserveOnlyObjectSourceId(
|
|
295
|
+
sourcePartPath: string | undefined,
|
|
296
|
+
anchor: AnchorGeometry,
|
|
297
|
+
rawXml: string,
|
|
298
|
+
): string {
|
|
299
|
+
const part = sourcePartPath ?? "/word/document.xml";
|
|
300
|
+
const docPrId = anchor.docPr?.id;
|
|
301
|
+
if (docPrId) return `part:${part}#drawing-docPr:${docPrId}`;
|
|
302
|
+
return `part:${part}#drawing:${hashString(rawXml)}`;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function collectRelationshipIds(node: XmlElementNode): string[] {
|
|
306
|
+
const ids = new Set<string>();
|
|
307
|
+
const visit = (current: XmlElementNode): void => {
|
|
308
|
+
const id =
|
|
309
|
+
current.attributes["r:id"] ??
|
|
310
|
+
current.attributes["r:embed"] ??
|
|
311
|
+
current.attributes.embed ??
|
|
312
|
+
current.attributes["r:link"] ??
|
|
313
|
+
current.attributes.link;
|
|
314
|
+
if (id) ids.add(id);
|
|
315
|
+
for (const child of current.children) {
|
|
316
|
+
if (child.type === "element") visit(child);
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
visit(node);
|
|
320
|
+
return [...ids].sort();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function hashString(value: string): string {
|
|
324
|
+
let hash = 2166136261;
|
|
325
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
326
|
+
hash ^= value.charCodeAt(index);
|
|
327
|
+
hash = Math.imul(hash, 16777619);
|
|
328
|
+
}
|
|
329
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
330
|
+
}
|
|
331
|
+
|
|
234
332
|
function extractChartRelId(graphicData: XmlElementNode | undefined): string | null {
|
|
235
333
|
if (!graphicData) return null;
|
|
236
334
|
const chart = findFirstDescendant(graphicData, "chart");
|
|
@@ -328,7 +328,13 @@ import type {
|
|
|
328
328
|
TocInstructionModel,
|
|
329
329
|
TocRegion,
|
|
330
330
|
TocStructure,
|
|
331
|
+
Mutable,
|
|
331
332
|
} from "../../model/canonical-document.ts";
|
|
333
|
+
import {
|
|
334
|
+
MAIN_STORY_KEY,
|
|
335
|
+
createHeaderFooterStoryKey,
|
|
336
|
+
createNoteStoryKey,
|
|
337
|
+
} from "../../model/canonical-layout-inputs.ts";
|
|
332
338
|
import { parseFieldSwitches } from "./parse-field-switches.ts";
|
|
333
339
|
|
|
334
340
|
const FIELD_FAMILY_PATTERN =
|
|
@@ -379,14 +385,14 @@ export function classifyFieldInstruction(instruction: string): {
|
|
|
379
385
|
let switches: FieldNode["switches"] | undefined;
|
|
380
386
|
if (family === "REF" || family === "PAGEREF" || family === "NOTEREF" || family === "TOC") {
|
|
381
387
|
const raw = parseFieldSwitches(trimmed);
|
|
382
|
-
const sw: FieldNode["switches"] = {};
|
|
383
|
-
if (raw.hyperlink) sw.hyperlink = true;
|
|
384
|
-
if (raw.relativePosition) sw.relativePosition = true;
|
|
385
|
-
if (raw.numericRef) sw.numericRef = true;
|
|
386
|
-
if (raw.recursive) sw.recursive = true;
|
|
387
|
-
if (raw.suppressNonDelimiter) sw.suppressNonDelimiter = true;
|
|
388
|
-
if (raw.includeNumbering) sw.includeNumbering = true;
|
|
389
|
-
if (raw.includeLevel) sw.includeLevel = true;
|
|
388
|
+
const sw: Mutable<NonNullable<FieldNode["switches"]>> = {};
|
|
389
|
+
if (raw.hyperlink) (sw as Mutable<typeof sw>).hyperlink = true;
|
|
390
|
+
if (raw.relativePosition) (sw as Mutable<typeof sw>).relativePosition = true;
|
|
391
|
+
if (raw.numericRef) (sw as Mutable<typeof sw>).numericRef = true;
|
|
392
|
+
if (raw.recursive) (sw as Mutable<typeof sw>).recursive = true;
|
|
393
|
+
if (raw.suppressNonDelimiter) (sw as Mutable<typeof sw>).suppressNonDelimiter = true;
|
|
394
|
+
if (raw.includeNumbering) (sw as Mutable<typeof sw>).includeNumbering = true;
|
|
395
|
+
if (raw.includeLevel) (sw as Mutable<typeof sw>).includeLevel = true;
|
|
390
396
|
if (Object.keys(sw).length > 0) {
|
|
391
397
|
switches = sw;
|
|
392
398
|
}
|
|
@@ -430,7 +436,7 @@ export function buildFieldRegistry(
|
|
|
430
436
|
? { family: node.fieldFamily, supported: isSupportedFieldFamily(node.fieldFamily), target: node.fieldTarget, switches: node.switches }
|
|
431
437
|
: classifyFieldInstruction(node.instruction);
|
|
432
438
|
const displayText = flattenFieldText(node.children);
|
|
433
|
-
const entry: FieldRegistryEntry = {
|
|
439
|
+
const entry: Mutable<FieldRegistryEntry> = {
|
|
434
440
|
fieldIndex,
|
|
435
441
|
fieldFamily: classification.family,
|
|
436
442
|
supported: classification.supported,
|
|
@@ -438,6 +444,7 @@ export function buildFieldRegistry(
|
|
|
438
444
|
...(classification.target ? { fieldTarget: classification.target } : {}),
|
|
439
445
|
displayText,
|
|
440
446
|
paragraphIndex,
|
|
447
|
+
storyKey: MAIN_STORY_KEY,
|
|
441
448
|
refreshStatus: node.refreshStatus ?? (classification.supported ? "stale" : "preserve-only"),
|
|
442
449
|
...(classification.switches ? { switches: classification.switches } : {}),
|
|
443
450
|
};
|
|
@@ -453,14 +460,14 @@ export function buildFieldRegistry(
|
|
|
453
460
|
}
|
|
454
461
|
});
|
|
455
462
|
if (document.subParts) {
|
|
456
|
-
walkSubPartFields(document.subParts, (node, pIdx) => {
|
|
463
|
+
walkSubPartFields(document.subParts, (node, pIdx, storyKey) => {
|
|
457
464
|
paragraphIndex = pIdx;
|
|
458
465
|
if (node.type === "field") {
|
|
459
466
|
const classification = node.fieldFamily
|
|
460
467
|
? { family: node.fieldFamily, supported: isSupportedFieldFamily(node.fieldFamily), target: node.fieldTarget, switches: node.switches }
|
|
461
468
|
: classifyFieldInstruction(node.instruction);
|
|
462
469
|
const displayText = flattenFieldText(node.children);
|
|
463
|
-
const entry: FieldRegistryEntry = {
|
|
470
|
+
const entry: Mutable<FieldRegistryEntry> = {
|
|
464
471
|
fieldIndex,
|
|
465
472
|
fieldFamily: classification.family,
|
|
466
473
|
supported: classification.supported,
|
|
@@ -468,6 +475,7 @@ export function buildFieldRegistry(
|
|
|
468
475
|
...(classification.target ? { fieldTarget: classification.target } : {}),
|
|
469
476
|
displayText,
|
|
470
477
|
paragraphIndex,
|
|
478
|
+
storyKey,
|
|
471
479
|
refreshStatus: node.refreshStatus ?? (classification.supported ? "stale" : "preserve-only"),
|
|
472
480
|
...(classification.switches ? { switches: classification.switches } : {}),
|
|
473
481
|
};
|
|
@@ -512,7 +520,7 @@ export function parseTocLevelRange(instruction: string): { from: number; to: num
|
|
|
512
520
|
}
|
|
513
521
|
|
|
514
522
|
export function parseTocInstruction(instruction: string): TocInstructionModel {
|
|
515
|
-
const model: TocInstructionModel = {
|
|
523
|
+
const model: Mutable<TocInstructionModel> = {
|
|
516
524
|
raw: instruction,
|
|
517
525
|
outlineRange: { from: 1, to: 9 },
|
|
518
526
|
};
|
|
@@ -867,7 +875,7 @@ function tocLevelFromStyle(styleId: string | undefined): number {
|
|
|
867
875
|
}
|
|
868
876
|
|
|
869
877
|
function extractCachedTocEntry(
|
|
870
|
-
paragraph: ParagraphNode
|
|
878
|
+
paragraph: Mutable<ParagraphNode>,
|
|
871
879
|
paragraphIndexByNode: WeakMap<ParagraphNode, number>,
|
|
872
880
|
): TocCachedEntry | undefined {
|
|
873
881
|
if (!isTocParagraphStyle(paragraph.styleId)) {
|
|
@@ -1004,7 +1012,7 @@ export function resolveRefFieldText(
|
|
|
1004
1012
|
* applies these to the live document.
|
|
1005
1013
|
*/
|
|
1006
1014
|
export function refreshFieldRegistry(
|
|
1007
|
-
registry: FieldRegistry
|
|
1015
|
+
registry: Mutable<FieldRegistry>,
|
|
1008
1016
|
bookmarkNameMap: Map<string, { bookmarkId: string; paragraphIndex: number }>,
|
|
1009
1017
|
): FieldRegistry {
|
|
1010
1018
|
const refreshed: FieldRegistryEntry[] = registry.supported.map((entry) => {
|
|
@@ -1060,28 +1068,42 @@ function walkFieldDocument(
|
|
|
1060
1068
|
}
|
|
1061
1069
|
|
|
1062
1070
|
function walkSubPartFields(
|
|
1063
|
-
subParts: SubPartsCatalog
|
|
1064
|
-
visit: (node: DocumentNode, paragraphIndex: number) => void,
|
|
1071
|
+
subParts: Mutable<SubPartsCatalog>,
|
|
1072
|
+
visit: (node: DocumentNode, paragraphIndex: number, storyKey: string) => void,
|
|
1065
1073
|
): void {
|
|
1066
1074
|
for (const header of subParts.headers) {
|
|
1075
|
+
const storyKey = createHeaderFooterStoryKey({
|
|
1076
|
+
kind: "header",
|
|
1077
|
+
relationshipId: header.relationshipId,
|
|
1078
|
+
variant: header.variant,
|
|
1079
|
+
...(header.sectionIndex !== undefined ? { sectionIndex: header.sectionIndex } : {}),
|
|
1080
|
+
});
|
|
1067
1081
|
for (const block of header.blocks) {
|
|
1068
|
-
walkFieldDocument(block, visit);
|
|
1082
|
+
walkFieldDocument(block, (node, paragraphIndex) => visit(node, paragraphIndex, storyKey));
|
|
1069
1083
|
}
|
|
1070
1084
|
}
|
|
1071
1085
|
for (const footer of subParts.footers) {
|
|
1086
|
+
const storyKey = createHeaderFooterStoryKey({
|
|
1087
|
+
kind: "footer",
|
|
1088
|
+
relationshipId: footer.relationshipId,
|
|
1089
|
+
variant: footer.variant,
|
|
1090
|
+
...(footer.sectionIndex !== undefined ? { sectionIndex: footer.sectionIndex } : {}),
|
|
1091
|
+
});
|
|
1072
1092
|
for (const block of footer.blocks) {
|
|
1073
|
-
walkFieldDocument(block, visit);
|
|
1093
|
+
walkFieldDocument(block, (node, paragraphIndex) => visit(node, paragraphIndex, storyKey));
|
|
1074
1094
|
}
|
|
1075
1095
|
}
|
|
1076
1096
|
if (subParts.footnoteCollection) {
|
|
1077
1097
|
for (const note of Object.values(subParts.footnoteCollection.footnotes)) {
|
|
1098
|
+
const storyKey = createNoteStoryKey("footnote", note.noteId);
|
|
1078
1099
|
for (const block of note.blocks) {
|
|
1079
|
-
walkFieldDocument(block, visit);
|
|
1100
|
+
walkFieldDocument(block, (node, paragraphIndex) => visit(node, paragraphIndex, storyKey));
|
|
1080
1101
|
}
|
|
1081
1102
|
}
|
|
1082
1103
|
for (const note of Object.values(subParts.footnoteCollection.endnotes)) {
|
|
1104
|
+
const storyKey = createNoteStoryKey("endnote", note.noteId);
|
|
1083
1105
|
for (const block of note.blocks) {
|
|
1084
|
-
walkFieldDocument(block, visit);
|
|
1106
|
+
walkFieldDocument(block, (node, paragraphIndex) => visit(node, paragraphIndex, storyKey));
|
|
1085
1107
|
}
|
|
1086
1108
|
}
|
|
1087
1109
|
}
|
|
@@ -1112,7 +1134,7 @@ function flattenParagraphInlineText(children: InlineNode[]): string {
|
|
|
1112
1134
|
}
|
|
1113
1135
|
|
|
1114
1136
|
function flattenBookmarkContent(
|
|
1115
|
-
paragraph: ParagraphNode
|
|
1137
|
+
paragraph: Mutable<ParagraphNode>,
|
|
1116
1138
|
bookmarkId: string,
|
|
1117
1139
|
): string {
|
|
1118
1140
|
let inside = false;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import type {
|
|
14
14
|
CanonicalFontEntry,
|
|
15
15
|
CanonicalFontTable,
|
|
16
|
+
Mutable,
|
|
16
17
|
} from "../../model/canonical-document.ts";
|
|
17
18
|
import type { XmlElementNode } from "./xml-element.ts";
|
|
18
19
|
import { parseXml } from "./xml-parser.ts";
|
|
@@ -32,7 +33,7 @@ export function parseFontTable(xml: string): CanonicalFontTable {
|
|
|
32
33
|
const name = child.attributes["w:name"] ?? child.attributes["name"];
|
|
33
34
|
if (!name) continue;
|
|
34
35
|
|
|
35
|
-
const entry: CanonicalFontEntry = { name };
|
|
36
|
+
const entry: Mutable<CanonicalFontEntry> = { name };
|
|
36
37
|
|
|
37
38
|
for (const sub of child.children) {
|
|
38
39
|
if (sub.type !== "element") continue;
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
TableNode,
|
|
12
12
|
TableRowNode,
|
|
13
13
|
TextMark,
|
|
14
|
+
Mutable,
|
|
14
15
|
} from "../../model/canonical-document.ts";
|
|
15
16
|
import { classifyFieldInstruction } from "./parse-fields.ts";
|
|
16
17
|
import { isSafeTableFieldInstruction } from "./table-opaque-preservation.ts";
|
|
@@ -644,7 +645,7 @@ function parseRunProperties(rElement: XmlElementNode): TextMark[] {
|
|
|
644
645
|
function readParagraphSpacing(pPr: XmlElementNode): ParagraphSpacing | undefined {
|
|
645
646
|
const spacingNode = findChildElementOptional(pPr, "spacing");
|
|
646
647
|
if (!spacingNode) return undefined;
|
|
647
|
-
const result: ParagraphSpacing = {};
|
|
648
|
+
const result: Mutable<ParagraphSpacing> = {};
|
|
648
649
|
const before = readStringAttr(spacingNode, "w:before");
|
|
649
650
|
if (before) result.before = Number.parseInt(before, 10);
|
|
650
651
|
const after = readStringAttr(spacingNode, "w:after");
|
|
@@ -661,7 +662,7 @@ function readParagraphSpacing(pPr: XmlElementNode): ParagraphSpacing | undefined
|
|
|
661
662
|
function readParagraphIndentation(pPr: XmlElementNode): ParagraphIndentation | undefined {
|
|
662
663
|
const indNode = findChildElementOptional(pPr, "ind");
|
|
663
664
|
if (!indNode) return undefined;
|
|
664
|
-
const result: ParagraphIndentation = {};
|
|
665
|
+
const result: Mutable<ParagraphIndentation> = {};
|
|
665
666
|
const left = readStringAttr(indNode, "w:left");
|
|
666
667
|
if (left) result.left = Number.parseInt(left, 10);
|
|
667
668
|
const right = readStringAttr(indNode, "w:right");
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
TableNode,
|
|
12
12
|
TableRowNode,
|
|
13
13
|
TextMark,
|
|
14
|
+
Mutable,
|
|
14
15
|
} from "../../model/canonical-document.ts";
|
|
15
16
|
import type { LegacyFormFieldNode } from "../../model/canonical-document.ts";
|
|
16
17
|
import { resolveHighlightColor } from "./highlight-colors.ts";
|
|
@@ -500,7 +501,7 @@ function parseRunElement(
|
|
|
500
501
|
const noteId =
|
|
501
502
|
readStringAttr(child, "w:id") ?? "";
|
|
502
503
|
if (noteId) {
|
|
503
|
-
const ref: FootnoteRefNode = {
|
|
504
|
+
const ref: Mutable<FootnoteRefNode> = {
|
|
504
505
|
type: "footnote_ref",
|
|
505
506
|
noteId,
|
|
506
507
|
noteKind: "footnote",
|
|
@@ -511,7 +512,7 @@ function parseRunElement(
|
|
|
511
512
|
const noteId =
|
|
512
513
|
readStringAttr(child, "w:id") ?? "";
|
|
513
514
|
if (noteId) {
|
|
514
|
-
const ref: FootnoteRefNode = {
|
|
515
|
+
const ref: Mutable<FootnoteRefNode> = {
|
|
515
516
|
type: "footnote_ref",
|
|
516
517
|
noteId,
|
|
517
518
|
noteKind: "endnote",
|
|
@@ -594,7 +595,7 @@ function parseRunChildNode(
|
|
|
594
595
|
const noteId =
|
|
595
596
|
readStringAttr(child, "w:id") ?? "";
|
|
596
597
|
if (noteId) {
|
|
597
|
-
const ref: FootnoteRefNode = {
|
|
598
|
+
const ref: Mutable<FootnoteRefNode> = {
|
|
598
599
|
type: "footnote_ref",
|
|
599
600
|
noteId,
|
|
600
601
|
noteKind: "footnote",
|
|
@@ -607,7 +608,7 @@ function parseRunChildNode(
|
|
|
607
608
|
const noteId =
|
|
608
609
|
readStringAttr(child, "w:id") ?? "";
|
|
609
610
|
if (noteId) {
|
|
610
|
-
const ref: FootnoteRefNode = {
|
|
611
|
+
const ref: Mutable<FootnoteRefNode> = {
|
|
611
612
|
type: "footnote_ref",
|
|
612
613
|
noteId,
|
|
613
614
|
noteKind: "endnote",
|
|
@@ -970,7 +971,7 @@ function parseRunProperties(rElement: XmlElementNode): TextMark[] {
|
|
|
970
971
|
function readParagraphSpacing(pPr: XmlElementNode): ParagraphSpacing | undefined {
|
|
971
972
|
const spacingNode = findChildElementOptional(pPr, "spacing");
|
|
972
973
|
if (!spacingNode) return undefined;
|
|
973
|
-
const result: ParagraphSpacing = {};
|
|
974
|
+
const result: Mutable<ParagraphSpacing> = {};
|
|
974
975
|
const before = readStringAttr(spacingNode, "w:before");
|
|
975
976
|
if (before) result.before = Number.parseInt(before, 10);
|
|
976
977
|
const after = readStringAttr(spacingNode, "w:after");
|
|
@@ -987,7 +988,7 @@ function readParagraphSpacing(pPr: XmlElementNode): ParagraphSpacing | undefined
|
|
|
987
988
|
function readParagraphIndentation(pPr: XmlElementNode): ParagraphIndentation | undefined {
|
|
988
989
|
const indNode = findChildElementOptional(pPr, "ind");
|
|
989
990
|
if (!indNode) return undefined;
|
|
990
|
-
const result: ParagraphIndentation = {};
|
|
991
|
+
const result: Mutable<ParagraphIndentation> = {};
|
|
991
992
|
const left = readStringAttr(indNode, "w:left");
|
|
992
993
|
if (left) result.left = Number.parseInt(left, 10);
|
|
993
994
|
const right = readStringAttr(indNode, "w:right");
|
|
@@ -26,6 +26,7 @@ import type {
|
|
|
26
26
|
SectionPageBorders,
|
|
27
27
|
DrawingFrameNode,
|
|
28
28
|
UnknownPropertyChild,
|
|
29
|
+
Mutable,
|
|
29
30
|
} from "../../model/canonical-document.ts";
|
|
30
31
|
import type { OpcRelationship } from "./part-manifest.ts";
|
|
31
32
|
import { SCOPE_MARKER_BOOKMARK_PREFIX } from "./parse-scope-markers.ts";
|
|
@@ -2288,7 +2289,7 @@ function readParagraphSpacing(node: XmlElementNode): ParagraphSpacing | undefine
|
|
|
2288
2289
|
);
|
|
2289
2290
|
if (!spacingNode) return undefined;
|
|
2290
2291
|
|
|
2291
|
-
const spacing: ParagraphSpacing = {};
|
|
2292
|
+
const spacing: Mutable<ParagraphSpacing> = {};
|
|
2292
2293
|
const before = spacingNode.attributes["w:before"] ?? spacingNode.attributes.before;
|
|
2293
2294
|
const after = spacingNode.attributes["w:after"] ?? spacingNode.attributes.after;
|
|
2294
2295
|
const line = spacingNode.attributes["w:line"] ?? spacingNode.attributes.line;
|
|
@@ -2332,7 +2333,7 @@ function readParagraphIndentation(node: XmlElementNode): ParagraphIndentation |
|
|
|
2332
2333
|
);
|
|
2333
2334
|
if (!indNode) return undefined;
|
|
2334
2335
|
|
|
2335
|
-
const indentation: ParagraphIndentation = {};
|
|
2336
|
+
const indentation: Mutable<ParagraphIndentation> = {};
|
|
2336
2337
|
const left = indNode.attributes["w:left"] ?? indNode.attributes.left;
|
|
2337
2338
|
const right = indNode.attributes["w:right"] ?? indNode.attributes.right;
|
|
2338
2339
|
const firstLine = indNode.attributes["w:firstLine"] ?? indNode.attributes.firstLine;
|
|
@@ -2450,7 +2451,7 @@ function readParagraphBorders(node: XmlElementNode): ParagraphBorders | undefine
|
|
|
2450
2451
|
return undefined;
|
|
2451
2452
|
}
|
|
2452
2453
|
|
|
2453
|
-
const borders: ParagraphBorders = {};
|
|
2454
|
+
const borders: Mutable<ParagraphBorders> = {};
|
|
2454
2455
|
for (const [name, key] of [
|
|
2455
2456
|
["top", "top"],
|
|
2456
2457
|
["left", "left"],
|
|
@@ -2481,7 +2482,7 @@ function readParagraphShading(node: XmlElementNode): ParagraphShading | undefine
|
|
|
2481
2482
|
return undefined;
|
|
2482
2483
|
}
|
|
2483
2484
|
|
|
2484
|
-
const shading: ParagraphShading = {};
|
|
2485
|
+
const shading: Mutable<ParagraphShading> = {};
|
|
2485
2486
|
const fill = shadingNode.attributes["w:fill"] ?? shadingNode.attributes.fill;
|
|
2486
2487
|
const color = shadingNode.attributes["w:color"] ?? shadingNode.attributes.color;
|
|
2487
2488
|
const val = shadingNode.attributes["w:val"] ?? shadingNode.attributes.val;
|
|
@@ -2491,14 +2492,14 @@ function readParagraphShading(node: XmlElementNode): ParagraphShading | undefine
|
|
|
2491
2492
|
const themeColor = shadingNode.attributes["w:themeColor"] ?? shadingNode.attributes.themeColor;
|
|
2492
2493
|
const themeColorTint = shadingNode.attributes["w:themeColorTint"] ?? shadingNode.attributes.themeColorTint;
|
|
2493
2494
|
const themeColorShade = shadingNode.attributes["w:themeColorShade"] ?? shadingNode.attributes.themeColorShade;
|
|
2494
|
-
if (fill) shading.fill = fill;
|
|
2495
|
-
if (color) shading.color = color;
|
|
2496
|
-
if (val) shading.val = val;
|
|
2497
|
-
if (themeFill) shading.themeFill = themeFill;
|
|
2498
|
-
if (themeFillTint) shading.themeFillTint = themeFillTint;
|
|
2499
|
-
if (themeFillShade) shading.themeFillShade = themeFillShade;
|
|
2500
|
-
if (themeColor) shading.themeColor = themeColor;
|
|
2501
|
-
if (themeColorTint) shading.themeColorTint = themeColorTint;
|
|
2495
|
+
if (fill) (shading as Mutable<typeof shading>).fill = fill;
|
|
2496
|
+
if (color) (shading as Mutable<typeof shading>).color = color;
|
|
2497
|
+
if (val) (shading as Mutable<typeof shading>).val = val;
|
|
2498
|
+
if (themeFill) (shading as Mutable<typeof shading>).themeFill = themeFill;
|
|
2499
|
+
if (themeFillTint) (shading as Mutable<typeof shading>).themeFillTint = themeFillTint;
|
|
2500
|
+
if (themeFillShade) (shading as Mutable<typeof shading>).themeFillShade = themeFillShade;
|
|
2501
|
+
if (themeColor) (shading as Mutable<typeof shading>).themeColor = themeColor;
|
|
2502
|
+
if (themeColorTint) (shading as Mutable<typeof shading>).themeColorTint = themeColorTint;
|
|
2502
2503
|
if (themeColorShade) shading.themeColorShade = themeColorShade;
|
|
2503
2504
|
return Object.keys(shading).length > 0 ? shading : undefined;
|
|
2504
2505
|
}
|
|
@@ -2511,7 +2512,7 @@ function readParagraphCnfStyle(node: XmlElementNode): string | undefined {
|
|
|
2511
2512
|
}
|
|
2512
2513
|
|
|
2513
2514
|
function readBorder(node: XmlElementNode): ParagraphBorders[keyof ParagraphBorders] {
|
|
2514
|
-
const border: NonNullable<ParagraphBorders[keyof ParagraphBorders]
|
|
2515
|
+
const border: Mutable<NonNullable<ParagraphBorders[keyof ParagraphBorders]>> = {};
|
|
2515
2516
|
const value = node.attributes["w:val"] ?? node.attributes.val;
|
|
2516
2517
|
const size = node.attributes["w:sz"] ?? node.attributes.sz;
|
|
2517
2518
|
const space = node.attributes["w:space"] ?? node.attributes.space;
|
|
@@ -3632,7 +3633,7 @@ function readSectionPropertiesXmlFromPPr(
|
|
|
3632
3633
|
export function parseSectionPropertiesFromElement(
|
|
3633
3634
|
node: XmlElementNode,
|
|
3634
3635
|
): SectionProperties {
|
|
3635
|
-
const props: SectionProperties = {};
|
|
3636
|
+
const props: Mutable<SectionProperties> = {};
|
|
3636
3637
|
|
|
3637
3638
|
for (const child of node.children) {
|
|
3638
3639
|
if (child.type !== "element") continue;
|
|
@@ -3643,7 +3644,7 @@ export function parseSectionPropertiesFromElement(
|
|
|
3643
3644
|
const w = safeParseInt(child.attributes["w:w"]);
|
|
3644
3645
|
const h = safeParseInt(child.attributes["w:h"]);
|
|
3645
3646
|
if (w !== undefined && h !== undefined) {
|
|
3646
|
-
const pageSize: PageSize = { width: w, height: h };
|
|
3647
|
+
const pageSize: Mutable<PageSize> = { width: w, height: h };
|
|
3647
3648
|
const orient = child.attributes["w:orient"];
|
|
3648
3649
|
if (orient === "landscape" || orient === "portrait") {
|
|
3649
3650
|
pageSize.orientation = orient;
|
|
@@ -3658,26 +3659,26 @@ export function parseSectionPropertiesFromElement(
|
|
|
3658
3659
|
const bottom = safeParseInt(child.attributes["w:bottom"]);
|
|
3659
3660
|
const left = safeParseInt(child.attributes["w:left"]);
|
|
3660
3661
|
if (top !== undefined && right !== undefined && bottom !== undefined && left !== undefined) {
|
|
3661
|
-
const margins: PageMargins = { top, right, bottom, left };
|
|
3662
|
+
const margins: Mutable<PageMargins> = { top, right, bottom, left };
|
|
3662
3663
|
const header = safeParseInt(child.attributes["w:header"]);
|
|
3663
3664
|
const footer = safeParseInt(child.attributes["w:footer"]);
|
|
3664
3665
|
const gutter = safeParseInt(child.attributes["w:gutter"]);
|
|
3665
|
-
if (header !== undefined) margins.header = header;
|
|
3666
|
-
if (footer !== undefined) margins.footer = footer;
|
|
3667
|
-
if (gutter !== undefined) margins.gutter = gutter;
|
|
3666
|
+
if (header !== undefined) (margins as Mutable<typeof margins>).header = header;
|
|
3667
|
+
if (footer !== undefined) (margins as Mutable<typeof margins>).footer = footer;
|
|
3668
|
+
if (gutter !== undefined) (margins as Mutable<typeof margins>).gutter = gutter;
|
|
3668
3669
|
props.pageMargins = margins;
|
|
3669
3670
|
}
|
|
3670
3671
|
break;
|
|
3671
3672
|
}
|
|
3672
3673
|
case "cols": {
|
|
3673
|
-
const columns: ColumnProperties = {};
|
|
3674
|
+
const columns: Mutable<ColumnProperties> = {};
|
|
3674
3675
|
const num = safeParseInt(child.attributes["w:num"]);
|
|
3675
3676
|
const space = safeParseInt(child.attributes["w:space"]);
|
|
3676
3677
|
const equalWidth = child.attributes["w:equalWidth"];
|
|
3677
3678
|
const sep = child.attributes["w:sep"];
|
|
3678
|
-
if (num !== undefined) columns.count = num;
|
|
3679
|
-
if (space !== undefined) columns.space = space;
|
|
3680
|
-
if (equalWidth !== undefined) columns.equalWidth = equalWidth !== "0" && equalWidth !== "false";
|
|
3679
|
+
if (num !== undefined) (columns as Mutable<typeof columns>).count = num;
|
|
3680
|
+
if (space !== undefined) (columns as Mutable<typeof columns>).space = space;
|
|
3681
|
+
if (equalWidth !== undefined) (columns as Mutable<typeof columns>).equalWidth = equalWidth !== "0" && equalWidth !== "false";
|
|
3681
3682
|
if (sep === "1" || sep === "true") columns.separator = true;
|
|
3682
3683
|
const colDefs: Array<{ width: number; space?: number }> = [];
|
|
3683
3684
|
for (const colChild of child.children) {
|
|
@@ -3689,31 +3690,31 @@ export function parseSectionPropertiesFromElement(
|
|
|
3689
3690
|
}
|
|
3690
3691
|
}
|
|
3691
3692
|
}
|
|
3692
|
-
if (colDefs.length > 0) columns.columns = colDefs;
|
|
3693
|
+
if (colDefs.length > 0) (columns as Mutable<typeof columns>).columns = colDefs;
|
|
3693
3694
|
if (Object.keys(columns).length > 0) props.columns = columns;
|
|
3694
3695
|
break;
|
|
3695
3696
|
}
|
|
3696
3697
|
case "pgNumType": {
|
|
3697
|
-
const numbering: PageNumbering = {};
|
|
3698
|
+
const numbering: Mutable<PageNumbering> = {};
|
|
3698
3699
|
const fmt = child.attributes["w:fmt"];
|
|
3699
3700
|
const start = safeParseInt(child.attributes["w:start"]);
|
|
3700
3701
|
const chapStyle = child.attributes["w:chapStyle"];
|
|
3701
3702
|
const chapSep = child.attributes["w:chapSep"];
|
|
3702
|
-
if (fmt) numbering.format = fmt;
|
|
3703
|
-
if (start !== undefined) numbering.start = start;
|
|
3704
|
-
if (chapStyle) numbering.chapStyle = chapStyle;
|
|
3705
|
-
if (chapSep) numbering.chapSep = chapSep;
|
|
3703
|
+
if (fmt) (numbering as Mutable<typeof numbering>).format = fmt;
|
|
3704
|
+
if (start !== undefined) (numbering as Mutable<typeof numbering>).start = start;
|
|
3705
|
+
if (chapStyle) (numbering as Mutable<typeof numbering>).chapStyle = chapStyle;
|
|
3706
|
+
if (chapSep) (numbering as Mutable<typeof numbering>).chapSep = chapSep;
|
|
3706
3707
|
if (Object.keys(numbering).length > 0) props.pageNumbering = numbering;
|
|
3707
3708
|
break;
|
|
3708
3709
|
}
|
|
3709
3710
|
case "lnNumType": {
|
|
3710
|
-
const lineNumbering: SectionLineNumbering = {};
|
|
3711
|
+
const lineNumbering: Mutable<SectionLineNumbering> = {};
|
|
3711
3712
|
const countBy = safeParseInt(child.attributes["w:countBy"]);
|
|
3712
3713
|
const start = safeParseInt(child.attributes["w:start"]);
|
|
3713
3714
|
const distance = safeParseInt(child.attributes["w:distance"]);
|
|
3714
3715
|
const restart = child.attributes["w:restart"];
|
|
3715
|
-
if (countBy !== undefined) lineNumbering.countBy = countBy;
|
|
3716
|
-
if (start !== undefined) lineNumbering.start = start;
|
|
3716
|
+
if (countBy !== undefined) (lineNumbering as Mutable<typeof lineNumbering>).countBy = countBy;
|
|
3717
|
+
if (start !== undefined) (lineNumbering as Mutable<typeof lineNumbering>).start = start;
|
|
3717
3718
|
if (distance !== undefined) lineNumbering.distance = distance;
|
|
3718
3719
|
if (
|
|
3719
3720
|
restart === "newPage" ||
|
|
@@ -3728,7 +3729,7 @@ export function parseSectionPropertiesFromElement(
|
|
|
3728
3729
|
break;
|
|
3729
3730
|
}
|
|
3730
3731
|
case "pgBorders": {
|
|
3731
|
-
const pageBorders: SectionPageBorders = {};
|
|
3732
|
+
const pageBorders: Mutable<SectionPageBorders> = {};
|
|
3732
3733
|
const offsetFrom = child.attributes["w:offsetFrom"];
|
|
3733
3734
|
const display = child.attributes["w:display"];
|
|
3734
3735
|
const zOrder = child.attributes["w:zOrder"];
|
|
@@ -3765,7 +3766,7 @@ export function parseSectionPropertiesFromElement(
|
|
|
3765
3766
|
break;
|
|
3766
3767
|
}
|
|
3767
3768
|
case "docGrid": {
|
|
3768
|
-
const documentGrid: SectionDocumentGrid = {};
|
|
3769
|
+
const documentGrid: Mutable<SectionDocumentGrid> = {};
|
|
3769
3770
|
const type = child.attributes["w:type"];
|
|
3770
3771
|
const linePitch = safeParseInt(child.attributes["w:linePitch"]);
|
|
3771
3772
|
const charSpace = safeParseInt(child.attributes["w:charSpace"]);
|
|
@@ -3777,7 +3778,7 @@ export function parseSectionPropertiesFromElement(
|
|
|
3777
3778
|
) {
|
|
3778
3779
|
documentGrid.type = type;
|
|
3779
3780
|
}
|
|
3780
|
-
if (linePitch !== undefined) documentGrid.linePitch = linePitch;
|
|
3781
|
+
if (linePitch !== undefined) (documentGrid as Mutable<typeof documentGrid>).linePitch = linePitch;
|
|
3781
3782
|
if (charSpace !== undefined) documentGrid.charSpace = charSpace;
|
|
3782
3783
|
if (Object.keys(documentGrid).length > 0) {
|
|
3783
3784
|
props.documentGrid = documentGrid;
|
|
@@ -3856,7 +3857,7 @@ function safeParseInt(value: string | undefined): number | undefined {
|
|
|
3856
3857
|
function readFootnoteLikeProperties(
|
|
3857
3858
|
node: XmlElementNode,
|
|
3858
3859
|
): FootnoteProperties | undefined {
|
|
3859
|
-
const result: FootnoteProperties = {};
|
|
3860
|
+
const result: Mutable<FootnoteProperties> = {};
|
|
3860
3861
|
|
|
3861
3862
|
for (const child of node.children) {
|
|
3862
3863
|
if (child.type !== "element") continue;
|
|
@@ -3902,15 +3903,15 @@ function readFootnoteLikeProperties(
|
|
|
3902
3903
|
}
|
|
3903
3904
|
|
|
3904
3905
|
function parseBorderSpec(node: XmlElementNode): BorderSpec | undefined {
|
|
3905
|
-
const border: BorderSpec = {};
|
|
3906
|
+
const border: Mutable<BorderSpec> = {};
|
|
3906
3907
|
const value = node.attributes["w:val"];
|
|
3907
3908
|
const size = safeParseInt(node.attributes["w:sz"]);
|
|
3908
3909
|
const space = safeParseInt(node.attributes["w:space"]);
|
|
3909
3910
|
const color = node.attributes["w:color"];
|
|
3910
3911
|
|
|
3911
|
-
if (value) border.value = value;
|
|
3912
|
-
if (size !== undefined) border.size = size;
|
|
3913
|
-
if (space !== undefined) border.space = space;
|
|
3912
|
+
if (value) (border as Mutable<typeof border>).value = value;
|
|
3913
|
+
if (size !== undefined) (border as Mutable<typeof border>).size = size;
|
|
3914
|
+
if (space !== undefined) (border as Mutable<typeof border>).space = space;
|
|
3914
3915
|
if (color) border.color = color;
|
|
3915
3916
|
|
|
3916
3917
|
return Object.keys(border).length > 0 ? border : undefined;
|
|
@@ -8,6 +8,7 @@ import type {
|
|
|
8
8
|
ParagraphSpacing,
|
|
9
9
|
ParagraphIndentation,
|
|
10
10
|
TabStop,
|
|
11
|
+
Mutable,
|
|
11
12
|
} from "../../model/canonical-document.ts";
|
|
12
13
|
import { readRunProperties } from "./parse-run-formatting.ts";
|
|
13
14
|
import type { OpcRelationship } from "./part-manifest.ts";
|
|
@@ -519,7 +520,7 @@ function readParagraphIndentation(node: XmlElementNode): ParagraphIndentation |
|
|
|
519
520
|
return undefined;
|
|
520
521
|
}
|
|
521
522
|
|
|
522
|
-
const indentation: ParagraphIndentation = {};
|
|
523
|
+
const indentation: Mutable<ParagraphIndentation> = {};
|
|
523
524
|
const left = readStringAttr(indNode, "w:start") ?? readStringAttr(indNode, "w:left");
|
|
524
525
|
const right = readStringAttr(indNode, "w:end") ?? readStringAttr(indNode, "w:right");
|
|
525
526
|
const firstLine = readStringAttr(indNode, "w:firstLine");
|
|
@@ -560,7 +561,7 @@ function readParagraphSpacing(node: XmlElementNode): ParagraphSpacing | undefine
|
|
|
560
561
|
return undefined;
|
|
561
562
|
}
|
|
562
563
|
|
|
563
|
-
const spacing: ParagraphSpacing = {};
|
|
564
|
+
const spacing: Mutable<ParagraphSpacing> = {};
|
|
564
565
|
const before = readStringAttr(spacingNode, "w:before");
|
|
565
566
|
const after = readStringAttr(spacingNode, "w:after");
|
|
566
567
|
const line = readStringAttr(spacingNode, "w:line");
|