@beyondwork/docx-react-component 1.0.102 → 1.0.103
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/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 +5 -5
- package/src/io/ooxml/parse-fields.ts +16 -15
- 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 +18 -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 +835 -833
- package/src/runtime/formatting/document-lookup.ts +3 -2
- package/src/runtime/formatting/formatting-context.ts +66 -25
- package/src/runtime/formatting/index.ts +18 -0
- package/src/runtime/formatting/layout-inputs.ts +256 -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/surface-projection.ts +31 -36
- package/src/session/import/normalize.ts +2 -1
- package/src/session/import/source-package-evidence.ts +612 -1
|
@@ -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");
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* responsibility post-v2.0; this module emits only data.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import type { OleEmbedNode } from "../../model/canonical-document.ts";
|
|
21
|
+
import type { OleEmbedNode, Mutable } from "../../model/canonical-document.ts";
|
|
22
22
|
import type { OpcRelationship } from "./part-manifest.ts";
|
|
23
23
|
import type { XmlElementNode } from "./xml-element.ts";
|
|
24
24
|
import { resolveOleRelationship } from "./parse-ole-relationship.ts";
|
|
@@ -93,13 +93,13 @@ export function parseObject(
|
|
|
93
93
|
|
|
94
94
|
const metadata: OleEmbedNode["metadata"] = {};
|
|
95
95
|
if (resolved.originalFilename) {
|
|
96
|
-
metadata.originalFilename = resolved.originalFilename;
|
|
96
|
+
(metadata as Mutable<typeof metadata>).originalFilename = resolved.originalFilename;
|
|
97
97
|
}
|
|
98
98
|
if (classId) {
|
|
99
|
-
metadata.classId = classId;
|
|
99
|
+
(metadata as Mutable<typeof metadata>).classId = classId;
|
|
100
100
|
}
|
|
101
101
|
if (shapeId) {
|
|
102
|
-
metadata.shapeId = shapeId;
|
|
102
|
+
(metadata as Mutable<typeof metadata>).shapeId = shapeId;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
const id =
|
|
@@ -107,7 +107,7 @@ export function parseObject(
|
|
|
107
107
|
? `ole-embed-${resolved.relationshipId}-${occurrenceIndex}`
|
|
108
108
|
: `ole-embed-${resolved.relationshipId}`;
|
|
109
109
|
|
|
110
|
-
const result: OleEmbedNode = {
|
|
110
|
+
const result: Mutable<OleEmbedNode> = {
|
|
111
111
|
type: "ole_embed",
|
|
112
112
|
id,
|
|
113
113
|
embedType: "oleObject",
|
|
@@ -116,7 +116,7 @@ export function parseObject(
|
|
|
116
116
|
rawXml,
|
|
117
117
|
};
|
|
118
118
|
if (progId) {
|
|
119
|
-
result.progId = progId;
|
|
119
|
+
(result as Mutable<typeof result>).progId = progId;
|
|
120
120
|
}
|
|
121
121
|
return result;
|
|
122
122
|
}
|
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
ParagraphShading,
|
|
15
15
|
ParagraphSpacing,
|
|
16
16
|
TabStop,
|
|
17
|
+
Mutable,
|
|
17
18
|
} from "../../model/canonical-document.ts";
|
|
18
19
|
import { readRunProperties } from "./parse-run-formatting.ts";
|
|
19
20
|
import { findChildOptional, localName, readIntAttr, readIntVal, readOnOff } from "./xml-attr-helpers.ts";
|
|
@@ -87,31 +88,31 @@ const PPR_GRAB_BAG_DESCRIPTOR: PropertyGrabBagDescriptor = {
|
|
|
87
88
|
};
|
|
88
89
|
|
|
89
90
|
function readSpacing(node: XmlElementNode): ParagraphSpacing | undefined {
|
|
90
|
-
const out: ParagraphSpacing = {};
|
|
91
|
+
const out: Mutable<ParagraphSpacing> = {};
|
|
91
92
|
const before = readIntAttr(node, "w:before");
|
|
92
93
|
const after = readIntAttr(node, "w:after");
|
|
93
94
|
const line = readIntAttr(node, "w:line");
|
|
94
95
|
const rule = node.attributes["w:lineRule"] ?? node.attributes.lineRule;
|
|
95
|
-
if (before !== undefined) out.before = before;
|
|
96
|
-
if (after !== undefined) out.after = after;
|
|
96
|
+
if (before !== undefined) (out as Mutable<typeof out>).before = before;
|
|
97
|
+
if (after !== undefined) (out as Mutable<typeof out>).after = after;
|
|
97
98
|
if (line !== undefined) out.line = line;
|
|
98
99
|
if (rule) {
|
|
99
100
|
const n = rule.toLowerCase();
|
|
100
|
-
if (n === "auto" || n === "exact") out.lineRule = n;
|
|
101
|
+
if (n === "auto" || n === "exact") (out as Mutable<typeof out>).lineRule = n;
|
|
101
102
|
else if (n === "atleast") out.lineRule = "atLeast";
|
|
102
103
|
}
|
|
103
104
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
function readIndent(node: XmlElementNode): ParagraphIndentation | undefined {
|
|
107
|
-
const out: ParagraphIndentation = {};
|
|
108
|
+
const out: Mutable<ParagraphIndentation> = {};
|
|
108
109
|
const left = readIntAttr(node, "w:left") ?? readIntAttr(node, "w:start");
|
|
109
110
|
const right = readIntAttr(node, "w:right") ?? readIntAttr(node, "w:end");
|
|
110
111
|
const firstLine = readIntAttr(node, "w:firstLine");
|
|
111
112
|
const hanging = readIntAttr(node, "w:hanging");
|
|
112
|
-
if (left !== undefined) out.left = left;
|
|
113
|
-
if (right !== undefined) out.right = right;
|
|
114
|
-
if (firstLine !== undefined) out.firstLine = firstLine;
|
|
113
|
+
if (left !== undefined) (out as Mutable<typeof out>).left = left;
|
|
114
|
+
if (right !== undefined) (out as Mutable<typeof out>).right = right;
|
|
115
|
+
if (firstLine !== undefined) (out as Mutable<typeof out>).firstLine = firstLine;
|
|
115
116
|
if (hanging !== undefined) out.hanging = hanging;
|
|
116
117
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
117
118
|
}
|
|
@@ -138,7 +139,7 @@ function readTabStops(node: XmlElementNode): TabStop[] | undefined {
|
|
|
138
139
|
}
|
|
139
140
|
|
|
140
141
|
function readBorders(node: XmlElementNode): ParagraphBorders | undefined {
|
|
141
|
-
const out: ParagraphBorders = {};
|
|
142
|
+
const out: Mutable<ParagraphBorders> = {};
|
|
142
143
|
const sides = ["top", "bottom", "left", "right", "between", "bar"] as const;
|
|
143
144
|
for (const side of sides) {
|
|
144
145
|
const child = findChildOptional(node, side);
|
|
@@ -205,7 +206,7 @@ function readShading(node: XmlElementNode): ParagraphShading | undefined {
|
|
|
205
206
|
* text frames, drop-caps); extension attrs are rare in that corpus.
|
|
206
207
|
*/
|
|
207
208
|
export function readFrameProperties(node: XmlElementNode): FrameProperties | undefined {
|
|
208
|
-
const out: FrameProperties = {};
|
|
209
|
+
const out: Mutable<FrameProperties> = {};
|
|
209
210
|
const width = readIntAttr(node, "w:w");
|
|
210
211
|
if (width !== undefined) out.widthTwips = width;
|
|
211
212
|
const height = readIntAttr(node, "w:h");
|
|
@@ -268,7 +269,7 @@ export function readParagraphProperties(
|
|
|
268
269
|
): CanonicalParagraphFormatting | undefined {
|
|
269
270
|
if (!node) return undefined;
|
|
270
271
|
|
|
271
|
-
const out: CanonicalParagraphFormatting = {};
|
|
272
|
+
const out: Mutable<CanonicalParagraphFormatting> = {};
|
|
272
273
|
|
|
273
274
|
const spacingNode = findChildOptional(node, "spacing");
|
|
274
275
|
if (spacingNode) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PictureContent } from "../../model/canonical-document.ts";
|
|
1
|
+
import type { PictureContent, Mutable } from "../../model/canonical-document.ts";
|
|
2
2
|
import {
|
|
3
3
|
type XmlElementNode,
|
|
4
4
|
findFirstChild,
|
|
@@ -100,21 +100,21 @@ export function parsePicture(graphicDataEl: XmlElementNode): PictureContent | nu
|
|
|
100
100
|
const glowEl = effectLst ? findFirstChild(effectLst, "glow") : undefined;
|
|
101
101
|
const glow = glowEl ? parseGlow(glowEl) : undefined;
|
|
102
102
|
|
|
103
|
-
const result: PictureContent = { type: "picture", blipRef };
|
|
104
|
-
if (isLinked) result.isLinked = true;
|
|
103
|
+
const result: Mutable<PictureContent> = { type: "picture", blipRef };
|
|
104
|
+
if (isLinked) (result as Mutable<typeof result>).isLinked = true;
|
|
105
105
|
if (lum && (lum.bright !== undefined || lum.contrast !== undefined)) {
|
|
106
|
-
result.lum = lum;
|
|
106
|
+
(result as Mutable<typeof result>).lum = lum;
|
|
107
107
|
}
|
|
108
|
-
if (srcRect) result.srcRect = srcRect;
|
|
109
|
-
if (stretch !== undefined) result.stretch = stretch;
|
|
108
|
+
if (srcRect) (result as Mutable<typeof result>).srcRect = srcRect;
|
|
109
|
+
if (stretch !== undefined) (result as Mutable<typeof result>).stretch = stretch;
|
|
110
110
|
if (tile !== undefined) result.tile = tile;
|
|
111
|
-
if (rotation !== undefined) result.rotation = rotation;
|
|
112
|
-
if (flipH !== undefined) result.flipH = flipH;
|
|
113
|
-
if (flipV !== undefined) result.flipV = flipV;
|
|
114
|
-
if (presetGeom) result.presetGeom = presetGeom;
|
|
115
|
-
if (softEdgeRadius !== undefined) result.softEdgeRadius = softEdgeRadius;
|
|
116
|
-
if (outerShadow) result.outerShadow = outerShadow;
|
|
117
|
-
if (glow) result.glow = glow;
|
|
111
|
+
if (rotation !== undefined) (result as Mutable<typeof result>).rotation = rotation;
|
|
112
|
+
if (flipH !== undefined) (result as Mutable<typeof result>).flipH = flipH;
|
|
113
|
+
if (flipV !== undefined) (result as Mutable<typeof result>).flipV = flipV;
|
|
114
|
+
if (presetGeom) (result as Mutable<typeof result>).presetGeom = presetGeom;
|
|
115
|
+
if (softEdgeRadius !== undefined) (result as Mutable<typeof result>).softEdgeRadius = softEdgeRadius;
|
|
116
|
+
if (outerShadow) (result as Mutable<typeof result>).outerShadow = outerShadow;
|
|
117
|
+
if (glow) (result as Mutable<typeof result>).glow = glow;
|
|
118
118
|
return result;
|
|
119
119
|
}
|
|
120
120
|
|
|
@@ -172,13 +172,13 @@ function readTileAttrs(
|
|
|
172
172
|
const v = tileEl.attributes[key];
|
|
173
173
|
if (v !== undefined) {
|
|
174
174
|
const n = parseInt(v, 10);
|
|
175
|
-
if (Number.isFinite(n)) result[key] = n;
|
|
175
|
+
if (Number.isFinite(n)) (result as Mutable<typeof result>)[key] = n;
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
const flip = tileEl.attributes.flip;
|
|
179
|
-
if (flip === "x" || flip === "y" || flip === "xy") result.flip = flip;
|
|
179
|
+
if (flip === "x" || flip === "y" || flip === "xy") (result as Mutable<typeof result>).flip = flip;
|
|
180
180
|
const algn = tileEl.attributes.algn;
|
|
181
|
-
if (algn) result.algn = algn;
|
|
181
|
+
if (algn) (result as Mutable<typeof result>).algn = algn;
|
|
182
182
|
return Object.keys(result).length > 0 ? result : {};
|
|
183
183
|
}
|
|
184
184
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
CanonicalRunFormatting,
|
|
3
3
|
ThemeFontSlot,
|
|
4
|
+
Mutable,
|
|
4
5
|
} from "../../model/canonical-document.ts";
|
|
5
6
|
import { findChildOptional, readIntVal, readOnOff, readStringAttr } from "./xml-attr-helpers.ts";
|
|
6
7
|
import type { XmlElementNode } from "./xml-element.ts";
|
|
@@ -58,7 +59,7 @@ export function readRunProperties(
|
|
|
58
59
|
): CanonicalRunFormatting | undefined {
|
|
59
60
|
if (!node) return undefined;
|
|
60
61
|
|
|
61
|
-
const rPr: CanonicalRunFormatting = {};
|
|
62
|
+
const rPr: Mutable<CanonicalRunFormatting> = {};
|
|
62
63
|
|
|
63
64
|
const bold = readOnOff(findChildOptional(node, "b"));
|
|
64
65
|
if (bold !== undefined) rPr.bold = bold;
|
|
@@ -121,9 +122,9 @@ export function readRunProperties(
|
|
|
121
122
|
const hAnsi = rFonts.attributes["w:hAnsi"] ?? rFonts.attributes.hAnsi;
|
|
122
123
|
const eastAsia = rFonts.attributes["w:eastAsia"] ?? rFonts.attributes.eastAsia;
|
|
123
124
|
const cs = rFonts.attributes["w:cs"] ?? rFonts.attributes.cs;
|
|
124
|
-
if (ascii) rPr.fontFamilyAscii = ascii;
|
|
125
|
-
if (hAnsi) rPr.fontFamilyHAnsi = hAnsi;
|
|
126
|
-
if (eastAsia) rPr.fontFamilyEastAsia = eastAsia;
|
|
125
|
+
if (ascii) (rPr as Mutable<typeof rPr>).fontFamilyAscii = ascii;
|
|
126
|
+
if (hAnsi) (rPr as Mutable<typeof rPr>).fontFamilyHAnsi = hAnsi;
|
|
127
|
+
if (eastAsia) (rPr as Mutable<typeof rPr>).fontFamilyEastAsia = eastAsia;
|
|
127
128
|
if (cs) rPr.fontFamilyCs = cs;
|
|
128
129
|
const primary = ascii ?? hAnsi ?? eastAsia ?? cs;
|
|
129
130
|
if (primary) rPr.fontFamily = primary;
|
|
@@ -150,9 +151,9 @@ export function readRunProperties(
|
|
|
150
151
|
rFonts.attributes["w:csTheme"] ??
|
|
151
152
|
rFonts.attributes.csTheme,
|
|
152
153
|
);
|
|
153
|
-
if (asciiTheme) rPr.asciiTheme = asciiTheme;
|
|
154
|
-
if (hAnsiTheme) rPr.hAnsiTheme = hAnsiTheme;
|
|
155
|
-
if (eastAsiaTheme) rPr.eastAsiaTheme = eastAsiaTheme;
|
|
154
|
+
if (asciiTheme) (rPr as Mutable<typeof rPr>).asciiTheme = asciiTheme;
|
|
155
|
+
if (hAnsiTheme) (rPr as Mutable<typeof rPr>).hAnsiTheme = hAnsiTheme;
|
|
156
|
+
if (eastAsiaTheme) (rPr as Mutable<typeof rPr>).eastAsiaTheme = eastAsiaTheme;
|
|
156
157
|
if (csTheme) rPr.csTheme = csTheme;
|
|
157
158
|
}
|
|
158
159
|
|
|
@@ -171,9 +172,9 @@ export function readRunProperties(
|
|
|
171
172
|
color.attributes["w:themeTint"] ?? color.attributes["themeTint"];
|
|
172
173
|
const shade =
|
|
173
174
|
color.attributes["w:themeShade"] ?? color.attributes["themeShade"];
|
|
174
|
-
if (val) rPr.colorHex = val;
|
|
175
|
-
if (theme) rPr.colorThemeSlot = theme;
|
|
176
|
-
if (tint) rPr.colorThemeTint = tint;
|
|
175
|
+
if (val) (rPr as Mutable<typeof rPr>).colorHex = val;
|
|
176
|
+
if (theme) (rPr as Mutable<typeof rPr>).colorThemeSlot = theme;
|
|
177
|
+
if (tint) (rPr as Mutable<typeof rPr>).colorThemeTint = tint;
|
|
177
178
|
if (shade) rPr.colorThemeShade = shade;
|
|
178
179
|
}
|
|
179
180
|
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
DocumentSettings,
|
|
6
6
|
FootnoteProperties,
|
|
7
7
|
ThemeColorSlot,
|
|
8
|
+
Mutable,
|
|
8
9
|
} from "../../model/canonical-document.ts";
|
|
9
10
|
import { parseXml } from "./xml-parser.ts";
|
|
10
11
|
import { localName } from "./xml-attr-helpers.ts";
|
|
@@ -160,7 +161,7 @@ function readFootnoteLikeProperties(
|
|
|
160
161
|
): FootnoteProperties | undefined {
|
|
161
162
|
if (!element) return undefined;
|
|
162
163
|
|
|
163
|
-
const result: FootnoteProperties = {};
|
|
164
|
+
const result: Mutable<FootnoteProperties> = {};
|
|
164
165
|
for (const child of element.children) {
|
|
165
166
|
if (child.type !== "element") continue;
|
|
166
167
|
const name = localName(child.name);
|
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
BlockNode,
|
|
15
15
|
ShapeContent,
|
|
16
16
|
TextBoxBodyProperties,
|
|
17
|
+
Mutable,
|
|
17
18
|
} from "../../model/canonical-document.ts";
|
|
18
19
|
import { parseFill } from "./parse-fill.ts";
|
|
19
20
|
import {
|
|
@@ -46,7 +47,7 @@ export interface ParsedWpsShape {
|
|
|
46
47
|
* shape-textbox paragraphs). Same shape + semantics as
|
|
47
48
|
* `ShapeContent.txbxBlocks` on the drawing-frame path.
|
|
48
49
|
*/
|
|
49
|
-
txbxBlocks?:
|
|
50
|
+
txbxBlocks?: BlockNode[];
|
|
50
51
|
/** DrawML geometry preset, e.g. "rect", "roundRect". */
|
|
51
52
|
geometry?: string;
|
|
52
53
|
/** Original drawing XML for lossless round-trip export. */
|
|
@@ -129,7 +130,7 @@ export function parseShapeXml(
|
|
|
129
130
|
// content (CCEP "Copyright CCEP STRICTLY CONFIDENTIAL" footer band)
|
|
130
131
|
// is reachable only via the `.text` summary string — L03 cascade +
|
|
131
132
|
// L11 render can't walk runs/marks.
|
|
132
|
-
let txbxBlocks:
|
|
133
|
+
let txbxBlocks: BlockNode[] | undefined;
|
|
133
134
|
if (txbxContentXml && blockParser) {
|
|
134
135
|
try {
|
|
135
136
|
// The `blockParser` callback is supplied by parse-main-document.ts
|
|
@@ -142,7 +143,7 @@ export function parseShapeXml(
|
|
|
142
143
|
// canonical; a structural `as unknown as BlockNode[]` preserves
|
|
143
144
|
// type safety at every consumer site (L03 cascade, L11 render,
|
|
144
145
|
// validator walk).
|
|
145
|
-
txbxBlocks = blockParser(txbxContentXml) as unknown as
|
|
146
|
+
txbxBlocks = blockParser(txbxContentXml) as unknown as BlockNode[];
|
|
146
147
|
} catch {
|
|
147
148
|
txbxBlocks = undefined;
|
|
148
149
|
}
|
|
@@ -271,7 +272,7 @@ export function parseShapeContent(
|
|
|
271
272
|
const txbxContentXml = txbxContent ? extractRawXml(txbxContent) : undefined;
|
|
272
273
|
const text = txbxContent ? extractAllText(txbxContent).trim() || undefined : undefined;
|
|
273
274
|
|
|
274
|
-
let txbxBlocks:
|
|
275
|
+
let txbxBlocks: BlockNode[] | undefined;
|
|
275
276
|
if (txbxContentXml && blockParser) {
|
|
276
277
|
try {
|
|
277
278
|
// See `TxbxBlockParser` doc above: runtime output is canonical
|
|
@@ -279,7 +280,7 @@ export function parseShapeContent(
|
|
|
279
280
|
// footer fixture 2026-04-24). Cast at the assembly seam so
|
|
280
281
|
// downstream consumers (L03, L11, validator) get canonical types
|
|
281
282
|
// without local `as unknown` ceremony.
|
|
282
|
-
txbxBlocks = blockParser(txbxContentXml) as unknown as
|
|
283
|
+
txbxBlocks = blockParser(txbxContentXml) as unknown as BlockNode[];
|
|
283
284
|
} catch {
|
|
284
285
|
// Preserve-only fallback: keep txbxContentXml for serialization; leave
|
|
285
286
|
// txbxBlocks undefined so consumers know recursion did not succeed.
|
|
@@ -294,15 +295,15 @@ export function parseShapeContent(
|
|
|
294
295
|
// roundRect text boxes + callout/ellipse shapes as non-text.
|
|
295
296
|
const isTextBox = Boolean(txbxContent);
|
|
296
297
|
|
|
297
|
-
const result: ShapeContent = { type: "shape", rawXml: drawingRawXml };
|
|
298
|
-
if (geometry) result.geometry = geometry;
|
|
298
|
+
const result: Mutable<ShapeContent> = { type: "shape", rawXml: drawingRawXml };
|
|
299
|
+
if (geometry) (result as Mutable<typeof result>).geometry = geometry;
|
|
299
300
|
if (text) result.text = text;
|
|
300
|
-
if (fill) result.fill = fill;
|
|
301
|
-
if (line) result.line = line;
|
|
302
|
-
if (isTextBox) result.isTextBox = true;
|
|
303
|
-
if (textBoxBody) result.textBoxBody = textBoxBody;
|
|
304
|
-
if (txbxContentXml) result.txbxContentXml = txbxContentXml;
|
|
305
|
-
if (txbxBlocks && txbxBlocks.length > 0) result.txbxBlocks = txbxBlocks;
|
|
301
|
+
if (fill) (result as Mutable<typeof result>).fill = fill;
|
|
302
|
+
if (line) (result as Mutable<typeof result>).line = line;
|
|
303
|
+
if (isTextBox) (result as Mutable<typeof result>).isTextBox = true;
|
|
304
|
+
if (textBoxBody) (result as Mutable<typeof result>).textBoxBody = textBoxBody;
|
|
305
|
+
if (txbxContentXml) (result as Mutable<typeof result>).txbxContentXml = txbxContentXml;
|
|
306
|
+
if (txbxBlocks && txbxBlocks.length > 0) (result as Mutable<typeof result>).txbxBlocks = txbxBlocks;
|
|
306
307
|
return result;
|
|
307
308
|
}
|
|
308
309
|
|
|
@@ -310,7 +311,7 @@ function readTextBoxBody(wsp: XmlElementNode): TextBoxBodyProperties | undefined
|
|
|
310
311
|
const bodyPr = findFirstChild(wsp, "bodyPr");
|
|
311
312
|
if (!bodyPr) return undefined;
|
|
312
313
|
|
|
313
|
-
const result: TextBoxBodyProperties = {};
|
|
314
|
+
const result: Mutable<TextBoxBodyProperties> = {};
|
|
314
315
|
const anchor = bodyPr.attributes.anchor;
|
|
315
316
|
if (anchor === "t" || anchor === "ctr" || anchor === "b") {
|
|
316
317
|
result.anchor = anchor;
|
|
@@ -319,9 +320,9 @@ function readTextBoxBody(wsp: XmlElementNode): TextBoxBodyProperties | undefined
|
|
|
319
320
|
const top = readIntAttr(bodyPr, "tIns");
|
|
320
321
|
const right = readIntAttr(bodyPr, "rIns");
|
|
321
322
|
const bottom = readIntAttr(bodyPr, "bIns");
|
|
322
|
-
if (left !== undefined) result.insetLeftEmu = left;
|
|
323
|
-
if (top !== undefined) result.insetTopEmu = top;
|
|
324
|
-
if (right !== undefined) result.insetRightEmu = right;
|
|
323
|
+
if (left !== undefined) (result as Mutable<typeof result>).insetLeftEmu = left;
|
|
324
|
+
if (top !== undefined) (result as Mutable<typeof result>).insetTopEmu = top;
|
|
325
|
+
if (right !== undefined) (result as Mutable<typeof result>).insetRightEmu = right;
|
|
325
326
|
if (bottom !== undefined) result.insetBottomEmu = bottom;
|
|
326
327
|
|
|
327
328
|
return Object.keys(result).length > 0 ? result : undefined;
|