@docx4j/core-ts 0.1.0 → 0.1.2
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/README.md +410 -10
- package/dist/model/content/Body.d.mts +109 -4
- package/dist/model/content/Body.mjs +300 -29
- package/dist/model/content/Comment.d.mts +78 -0
- package/dist/model/content/Comment.mjs +429 -0
- package/dist/model/content/ContentControl.d.mts +173 -0
- package/dist/model/content/ContentControl.mjs +638 -0
- package/dist/model/content/Font.d.mts +48 -8
- package/dist/model/content/Font.mjs +55 -13
- package/dist/model/content/InlinePicture.d.mts +103 -0
- package/dist/model/content/InlinePicture.mjs +361 -0
- package/dist/model/content/List.d.mts +253 -0
- package/dist/model/content/List.mjs +778 -0
- package/dist/model/content/Paragraph.d.mts +213 -16
- package/dist/model/content/Paragraph.mjs +611 -57
- package/dist/model/content/Range.d.mts +48 -4
- package/dist/model/content/Range.mjs +161 -4
- package/dist/model/content/Table.d.mts +130 -0
- package/dist/model/content/Table.mjs +429 -0
- package/dist/model/content/TrackedChange.d.mts +96 -0
- package/dist/model/content/TrackedChange.mjs +352 -0
- package/dist/model/content/comments.d.mts +122 -0
- package/dist/model/content/comments.mjs +248 -0
- package/dist/model/content/index.d.mts +13 -3
- package/dist/model/content/index.mjs +15 -3
- package/dist/model/content/ooxml.d.mts +17 -0
- package/dist/model/content/ooxml.mjs +214 -0
- package/dist/model/content/styles.d.mts +21 -0
- package/dist/model/content/styles.mjs +86 -0
- package/dist/model/content/tracking.d.mts +104 -0
- package/dist/model/content/tracking.mjs +313 -0
- package/dist/model/content/tree.d.mts +56 -9
- package/dist/model/content/tree.mjs +104 -31
- package/dist/model/customxml/CustomXmlPart.d.mts +158 -0
- package/dist/model/customxml/CustomXmlPart.mjs +415 -0
- package/dist/model/customxml/CustomXmlPartCollection.d.mts +68 -0
- package/dist/model/customxml/CustomXmlPartCollection.mjs +183 -0
- package/dist/model/customxml/XmlMapping.d.mts +46 -0
- package/dist/model/customxml/XmlMapping.mjs +98 -0
- package/dist/model/customxml/bindings.d.mts +41 -0
- package/dist/model/customxml/bindings.mjs +230 -0
- package/dist/model/customxml/index.d.mts +7 -0
- package/dist/model/customxml/index.mjs +9 -0
- package/dist/model/customxml/insert.d.mts +20 -0
- package/dist/model/customxml/insert.mjs +22 -0
- package/dist/model/customxml/kinds.d.mts +103 -0
- package/dist/model/customxml/kinds.mjs +267 -0
- package/dist/model/customxml/xpath.d.mts +52 -0
- package/dist/model/customxml/xpath.mjs +205 -0
- package/dist/model/fonts/CJKToEnglish.d.mts +2 -0
- package/dist/model/fonts/CJKToEnglish.mjs +16 -0
- package/dist/model/fonts/FontFallback.d.mts +58 -0
- package/dist/model/fonts/FontFallback.mjs +219 -0
- package/dist/model/fonts/IdentityPlusMapper.d.mts +7 -0
- package/dist/model/fonts/IdentityPlusMapper.mjs +19 -0
- package/dist/model/fonts/LanguageTagToScriptMapping.d.mts +7 -0
- package/dist/model/fonts/LanguageTagToScriptMapping.mjs +67 -0
- package/dist/model/fonts/Mapper.d.mts +190 -0
- package/dist/model/fonts/Mapper.mjs +481 -0
- package/dist/model/fonts/PhysicalFont.d.mts +34 -0
- package/dist/model/fonts/PhysicalFont.mjs +62 -0
- package/dist/model/fonts/RunFontSelector.d.mts +194 -0
- package/dist/model/fonts/RunFontSelector.mjs +441 -0
- package/dist/model/fonts/ThemeFonts.d.mts +17 -0
- package/dist/model/fonts/ThemeFonts.mjs +76 -0
- package/dist/model/fonts/defaultTheme.d.mts +37 -0
- package/dist/model/fonts/defaultTheme.mjs +57 -0
- package/dist/model/fonts/families.generated.d.mts +11 -0
- package/dist/model/fonts/families.generated.mjs +17 -0
- package/dist/model/fonts/fontsInUse.d.mts +39 -0
- package/dist/model/fonts/fontsInUse.mjs +183 -0
- package/dist/model/fonts/index.d.mts +14 -0
- package/dist/model/fonts/index.mjs +29 -0
- package/dist/model/fonts/lookup.d.mts +5 -0
- package/dist/model/fonts/lookup.mjs +12 -0
- package/dist/model/fonts/registry.d.mts +31 -0
- package/dist/model/fonts/registry.mjs +103 -0
- package/dist/model/fonts/scripts.d.mts +2 -0
- package/dist/model/fonts/scripts.mjs +78 -0
- package/dist/model/fonts/substitutions.generated.d.mts +30 -0
- package/dist/model/fonts/substitutions.generated.mjs +12 -0
- package/dist/model/fonts/themes.generated.d.mts +6 -0
- package/dist/model/fonts/themes.generated.mjs +11 -0
- package/dist/model/index.d.mts +5 -0
- package/dist/model/index.mjs +13 -1
- package/dist/model/listnumbering/Emulator.d.mts +187 -0
- package/dist/model/listnumbering/Emulator.mjs +332 -0
- package/dist/model/listnumbering/definitions.d.mts +251 -0
- package/dist/model/listnumbering/definitions.mjs +571 -0
- package/dist/model/listnumbering/formats.d.mts +25 -0
- package/dist/model/listnumbering/formats.mjs +320 -0
- package/dist/model/listnumbering/index.d.mts +4 -0
- package/dist/model/listnumbering/index.mjs +15 -0
- package/dist/model/listnumbering/state.d.mts +97 -0
- package/dist/model/listnumbering/state.mjs +179 -0
- package/dist/model/properties/PropertyResolver.d.mts +216 -0
- package/dist/model/properties/PropertyResolver.mjs +524 -0
- package/dist/model/properties/catalogue.d.mts +179 -0
- package/dist/model/properties/catalogue.mjs +860 -0
- package/dist/model/properties/index.d.mts +4 -0
- package/dist/model/properties/index.mjs +9 -0
- package/dist/model/properties/log.d.mts +7 -0
- package/dist/model/properties/log.mjs +25 -0
- package/dist/model/properties/styleUtil.d.mts +112 -0
- package/dist/model/properties/styleUtil.mjs +359 -0
- package/dist/node/index.d.mts +1 -0
- package/dist/node/index.mjs +12 -0
- package/dist/office-js/document.d.mts +111 -0
- package/dist/office-js/document.mjs +267 -0
- package/dist/office-js/enums.d.mts +187 -0
- package/dist/office-js/enums.mjs +176 -0
- package/dist/office-js/errors.d.mts +29 -0
- package/dist/office-js/errors.mjs +39 -0
- package/dist/office-js/extras.d.mts +5 -0
- package/dist/office-js/extras.mjs +29 -0
- package/dist/office-js/fragment.d.mts +10 -0
- package/dist/office-js/fragment.mjs +23 -0
- package/dist/office-js/index.d.mts +183 -0
- package/dist/office-js/index.mjs +54 -0
- package/dist/office-js/proxy.d.mts +72 -0
- package/dist/office-js/proxy.mjs +279 -0
- package/dist/office-js/run.d.mts +32 -0
- package/dist/office-js/run.mjs +66 -0
- package/dist/office-js/supported.d.mts +7 -0
- package/dist/office-js/supported.generated.d.mts +1 -0
- package/dist/office-js/supported.generated.mjs +235 -0
- package/dist/office-js/supported.mjs +53 -0
- package/dist/office-js/toApiScript.d.mts +25 -0
- package/dist/office-js/toApiScript.mjs +394 -0
- package/dist/opc/ContentTypes.d.mts +11 -0
- package/dist/opc/ContentTypes.mjs +14 -0
- package/dist/opc/DirectoryPartStore.d.mts +47 -0
- package/dist/opc/DirectoryPartStore.mjs +123 -0
- package/dist/opc/exceptions.d.mts +30 -0
- package/dist/opc/exceptions.mjs +38 -0
- package/dist/opc/index.d.mts +1 -1
- package/dist/opc/index.mjs +1 -1
- package/dist/packages/OpcPackage.d.mts +19 -1
- package/dist/packages/OpcPackage.mjs +29 -0
- package/dist/packages/PresentationMLPackage.d.mts +71 -1
- package/dist/packages/PresentationMLPackage.mjs +179 -0
- package/dist/packages/SpreadsheetMLPackage.d.mts +30 -1
- package/dist/packages/SpreadsheetMLPackage.mjs +78 -0
- package/dist/packages/WordprocessingMLPackage.d.mts +124 -2
- package/dist/packages/WordprocessingMLPackage.mjs +309 -2
- package/dist/packages/index.d.mts +1 -1
- package/dist/packages/index.mjs +1 -1
- package/dist/parts/DefaultXmlPart.d.mts +18 -0
- package/dist/parts/DefaultXmlPart.mjs +34 -5
- package/dist/parts/Namespaces.d.mts +18 -0
- package/dist/parts/Namespaces.mjs +20 -0
- package/dist/parts/Part.d.mts +6 -0
- package/dist/parts/Part.mjs +13 -0
- package/dist/parts/PartRegistry.mjs +13 -1
- package/dist/parts/XmlPart.d.mts +33 -0
- package/dist/parts/XmlPart.mjs +105 -2
- package/dist/parts/pml/defaults.d.mts +6 -0
- package/dist/parts/pml/defaults.mjs +53 -0
- package/dist/parts/pml/index.d.mts +66 -3
- package/dist/parts/pml/index.mjs +206 -7
- package/dist/parts/pml/placeholders.d.mts +71 -0
- package/dist/parts/pml/placeholders.mjs +141 -0
- package/dist/parts/sml/index.d.mts +80 -1
- package/dist/parts/sml/index.mjs +154 -1
- package/dist/parts/wml/comments.d.mts +1 -0
- package/dist/parts/wml/comments.mjs +179 -0
- package/dist/parts/wml/defaultNumbering.d.mts +1 -0
- package/dist/parts/wml/defaultNumbering.mjs +216 -0
- package/dist/parts/wml/index.d.mts +121 -0
- package/dist/parts/wml/index.mjs +291 -0
- package/dist/xml/dom.mjs +1 -2
- package/package.json +25 -4
|
@@ -0,0 +1,860 @@
|
|
|
1
|
+
// ---------------------------------------------------------------- copying
|
|
2
|
+
/**
|
|
3
|
+
* A structural copy of a leaf value, without its `PARENT` link: what the merges store, so
|
|
4
|
+
* that nothing in an effective `w:pPr` or `w:rPr` is a styles-part object.
|
|
5
|
+
*/
|
|
6
|
+
export function copyLeaf(value) {
|
|
7
|
+
if (value === null || typeof value !== 'object')
|
|
8
|
+
return value;
|
|
9
|
+
if (Array.isArray(value))
|
|
10
|
+
return value.map((item) => copyLeaf(item));
|
|
11
|
+
const out = {};
|
|
12
|
+
for (const key of Object.keys(value)) {
|
|
13
|
+
if (key === 'PARENT')
|
|
14
|
+
continue;
|
|
15
|
+
out[key] = copyLeaf(value[key]);
|
|
16
|
+
}
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
19
|
+
// ---------------------------------------------------------------- emptiness of scalars
|
|
20
|
+
/** docx4j `StyleUtil.isEmpty(String)`: null or the empty string. */
|
|
21
|
+
function emptyString(value) {
|
|
22
|
+
return value === undefined || value === '';
|
|
23
|
+
}
|
|
24
|
+
/** docx4j `StyleUtil.isEmpty(STThemeColor)`: null or `none`. */
|
|
25
|
+
function emptyThemeColor(value) {
|
|
26
|
+
return value === undefined || value === 'none';
|
|
27
|
+
}
|
|
28
|
+
/** docx4j `StyleUtil.apply(String, String)` and friends: the source where it states one. */
|
|
29
|
+
function attr(source, destination) {
|
|
30
|
+
return source === undefined ? destination : source;
|
|
31
|
+
}
|
|
32
|
+
/** docx4j `StyleUtil.apply(STThemeColor, STThemeColor)`: `none` does not override. */
|
|
33
|
+
function themeColor(source, destination) {
|
|
34
|
+
return emptyThemeColor(source) ? destination : source;
|
|
35
|
+
}
|
|
36
|
+
/** A merge with no per-attribute rule: a copy of the source where it has one, else the inherited. */
|
|
37
|
+
export function mergeReplace(source, destination) {
|
|
38
|
+
return source === undefined ? destination : copyLeaf(source);
|
|
39
|
+
}
|
|
40
|
+
/** Never carried: docx4j's `apply` for the owning element does not mention this member. */
|
|
41
|
+
function notCarried(_source, destination) {
|
|
42
|
+
return destination;
|
|
43
|
+
}
|
|
44
|
+
/** Never empty in itself: `undefined` only. */
|
|
45
|
+
function isNull(value) {
|
|
46
|
+
return value === undefined;
|
|
47
|
+
}
|
|
48
|
+
// ---------------------------------------------------------------- leaf emptiness
|
|
49
|
+
/** `<w:b/>` and `<w:b w:val="0"/>` both count: an explicit false is applied. */
|
|
50
|
+
export function isEmptyBool(value) {
|
|
51
|
+
return value === undefined;
|
|
52
|
+
}
|
|
53
|
+
/** A `BooleanDefaultTrue`'s value: absent `w:val` means true (docx4j `isVal()`). */
|
|
54
|
+
export function isTrue(value) {
|
|
55
|
+
return value !== undefined && value.val !== false;
|
|
56
|
+
}
|
|
57
|
+
function isEmptyVal(value) {
|
|
58
|
+
return value === undefined || value.val === undefined;
|
|
59
|
+
}
|
|
60
|
+
function isEmptyStringVal(value) {
|
|
61
|
+
return value === undefined || emptyString(value.val);
|
|
62
|
+
}
|
|
63
|
+
export function isEmptyRStyle(value) {
|
|
64
|
+
return isEmptyStringVal(value);
|
|
65
|
+
}
|
|
66
|
+
/** docx4j `isEmpty(RFonts)`: insensitive to a `w:hint` (which `apply` still carries). */
|
|
67
|
+
export function isEmptyRFonts(value) {
|
|
68
|
+
return value === undefined
|
|
69
|
+
|| (emptyString(value.ascii) && value.asciiTheme === undefined
|
|
70
|
+
&& emptyString(value.cs) && value.cstheme === undefined
|
|
71
|
+
&& emptyString(value.eastAsia) && value.eastAsiaTheme === undefined
|
|
72
|
+
&& emptyString(value.hAnsi) && value.hAnsiTheme === undefined);
|
|
73
|
+
}
|
|
74
|
+
export function isEmptyColor(value) {
|
|
75
|
+
return value === undefined || emptyString(value.val);
|
|
76
|
+
}
|
|
77
|
+
export function isEmptyU(value) {
|
|
78
|
+
return value === undefined || (value.val === undefined && emptyString(value.color));
|
|
79
|
+
}
|
|
80
|
+
export function isEmptyHighlight(value) {
|
|
81
|
+
return value === undefined || emptyString(value.val);
|
|
82
|
+
}
|
|
83
|
+
/** @since CR-015 phase 1: a style stating only `w:lang` used to count as empty and was never applied. */
|
|
84
|
+
export function isEmptyLang(value) {
|
|
85
|
+
return value === undefined || (emptyString(value.val) && emptyString(value.eastAsia) && emptyString(value.bidi));
|
|
86
|
+
}
|
|
87
|
+
export function isEmptyShd(value) {
|
|
88
|
+
return value === undefined
|
|
89
|
+
|| (emptyString(value.color) && emptyString(value.themeTint) && emptyString(value.themeShade)
|
|
90
|
+
&& emptyString(value.fill) && emptyString(value.themeFillTint) && emptyString(value.themeFillShade)
|
|
91
|
+
&& value.themeColor === undefined && value.themeFill === undefined && value.val === undefined);
|
|
92
|
+
}
|
|
93
|
+
export function isEmptyBorder(value) {
|
|
94
|
+
return value === undefined
|
|
95
|
+
|| (emptyString(value.color) && value.space === undefined && value.sz === undefined
|
|
96
|
+
&& value.themeColor === undefined && emptyString(value.themeShade) && emptyString(value.themeTint)
|
|
97
|
+
&& value.val === undefined);
|
|
98
|
+
}
|
|
99
|
+
export function isEmptyPBdr(value) {
|
|
100
|
+
return value === undefined
|
|
101
|
+
|| (isEmptyBorder(value.top) && isEmptyBorder(value.left) && isEmptyBorder(value.bottom)
|
|
102
|
+
&& isEmptyBorder(value.right) && isEmptyBorder(value.between) && isEmptyBorder(value.bar));
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* docx4j `isEmpty(Ind)`: `w:start`/`w:end` (the strict-conformance spellings) count too
|
|
106
|
+
* (17.0.5); dropping them lost them in style resolution.
|
|
107
|
+
*/
|
|
108
|
+
export function isEmptyInd(value) {
|
|
109
|
+
return value === undefined
|
|
110
|
+
|| (value.firstLine === undefined && value.firstLineChars === undefined
|
|
111
|
+
&& value.hanging === undefined && value.hangingChars === undefined
|
|
112
|
+
&& value.left === undefined && value.leftChars === undefined
|
|
113
|
+
&& value.right === undefined && value.rightChars === undefined
|
|
114
|
+
&& value.start === undefined && value.startChars === undefined
|
|
115
|
+
&& value.end === undefined && value.endChars === undefined);
|
|
116
|
+
}
|
|
117
|
+
/** An explicit `w:beforeAutospacing`/`w:afterAutospacing` of either value is a statement too. */
|
|
118
|
+
export function isEmptySpacing(value) {
|
|
119
|
+
return value === undefined
|
|
120
|
+
|| (value.after === undefined && value.afterLines === undefined
|
|
121
|
+
&& value.before === undefined && value.beforeLines === undefined
|
|
122
|
+
&& value.line === undefined && value.lineRule === undefined
|
|
123
|
+
&& value.beforeAutospacing === undefined && value.afterAutospacing === undefined);
|
|
124
|
+
}
|
|
125
|
+
function isEmptyTabStop(value) {
|
|
126
|
+
return value === undefined || (value.pos === undefined && value.val === undefined && value.leader === undefined);
|
|
127
|
+
}
|
|
128
|
+
export function isEmptyTabs(value) {
|
|
129
|
+
if (value === undefined || value.tab === undefined || value.tab.length === 0)
|
|
130
|
+
return true;
|
|
131
|
+
return !value.tab.some((stop) => !isEmptyTabStop(stop));
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* A `w:numPr` is empty only when it states neither `w:numId` nor `w:ilvl`: each inherits on
|
|
135
|
+
* its own (CR-015 probe styles-numpr-ilvl-only).
|
|
136
|
+
*/
|
|
137
|
+
export function isEmptyNumPr(value) {
|
|
138
|
+
return value === undefined
|
|
139
|
+
|| ((value.numId === undefined || value.numId.val === undefined)
|
|
140
|
+
&& (value.ilvl === undefined || value.ilvl.val === undefined));
|
|
141
|
+
}
|
|
142
|
+
/** `w:anchorLock` defaults to true, so only an explicit `w:anchorLock="0"` makes a frame non-empty by itself. */
|
|
143
|
+
export function isEmptyFramePr(value) {
|
|
144
|
+
var _a;
|
|
145
|
+
return value === undefined
|
|
146
|
+
|| (value.dropCap === undefined && value.lines === undefined && value.w === undefined
|
|
147
|
+
&& value.h === undefined && value.vSpace === undefined && value.hSpace === undefined
|
|
148
|
+
&& value.wrap === undefined && value.hAnchor === undefined && value.vAnchor === undefined
|
|
149
|
+
&& value.x === undefined && value.xAlign === undefined
|
|
150
|
+
&& value.y === undefined && value.yAlign === undefined && value.hRule === undefined
|
|
151
|
+
&& ((_a = value.anchorLock) !== null && _a !== void 0 ? _a : true));
|
|
152
|
+
}
|
|
153
|
+
function isEmptyTblWidth(value) {
|
|
154
|
+
// @w:type is ignored, as docx4j does
|
|
155
|
+
return value === undefined || value.w === undefined;
|
|
156
|
+
}
|
|
157
|
+
function isEmptyTblCellMar(value) {
|
|
158
|
+
// w:start/w:end are not read, as docx4j's isEmpty/apply pair does not read them
|
|
159
|
+
return value === undefined
|
|
160
|
+
|| (isEmptyTblWidth(value.bottom) && isEmptyTblWidth(value.left)
|
|
161
|
+
&& isEmptyTblWidth(value.right) && isEmptyTblWidth(value.top));
|
|
162
|
+
}
|
|
163
|
+
function isEmptyTblBorders(value) {
|
|
164
|
+
return value === undefined
|
|
165
|
+
|| (isEmptyBorder(value.bottom) && isEmptyBorder(value.left) && isEmptyBorder(value.right)
|
|
166
|
+
&& isEmptyBorder(value.top) && isEmptyBorder(value.insideH) && isEmptyBorder(value.insideV));
|
|
167
|
+
}
|
|
168
|
+
function isEmptyTcBorders(value) {
|
|
169
|
+
return value === undefined
|
|
170
|
+
|| (isEmptyBorder(value.bottom) && isEmptyBorder(value.left) && isEmptyBorder(value.right)
|
|
171
|
+
&& isEmptyBorder(value.top) && isEmptyBorder(value.insideH) && isEmptyBorder(value.insideV)
|
|
172
|
+
&& isEmptyBorder(value.tl2Br) && isEmptyBorder(value.tr2Bl));
|
|
173
|
+
}
|
|
174
|
+
function isEmptyTcMar(value) {
|
|
175
|
+
return value === undefined
|
|
176
|
+
|| (isEmptyTblWidth(value.bottom) && isEmptyTblWidth(value.left)
|
|
177
|
+
&& isEmptyTblWidth(value.right) && isEmptyTblWidth(value.top));
|
|
178
|
+
}
|
|
179
|
+
function isEmptyTblLook(value) {
|
|
180
|
+
return value === undefined
|
|
181
|
+
|| (value.firstColumn === undefined && value.firstRow === undefined
|
|
182
|
+
&& value.lastColumn === undefined && value.lastRow === undefined
|
|
183
|
+
&& value.noHBand === undefined && value.noVBand === undefined && value.val === undefined);
|
|
184
|
+
}
|
|
185
|
+
function isEmptyTblPPr(value) {
|
|
186
|
+
return value === undefined
|
|
187
|
+
|| (value.leftFromText === undefined && value.rightFromText === undefined
|
|
188
|
+
&& value.topFromText === undefined && value.bottomFromText === undefined
|
|
189
|
+
&& value.vertAnchor === undefined && value.horzAnchor === undefined
|
|
190
|
+
&& value.tblpXSpec === undefined && value.tblpX === undefined
|
|
191
|
+
&& value.tblpYSpec === undefined && value.tblpY === undefined);
|
|
192
|
+
}
|
|
193
|
+
function isEmptyCnf(value) {
|
|
194
|
+
return isEmptyStringVal(value);
|
|
195
|
+
}
|
|
196
|
+
// ---------------------------------------------------------------- leaf merges
|
|
197
|
+
/** docx4j `apply(BooleanDefaultTrue, BooleanDefaultTrue)`: a copy of the source where it states one. */
|
|
198
|
+
export function mergeBool(source, destination) {
|
|
199
|
+
return source === undefined ? destination : copyLeaf(source);
|
|
200
|
+
}
|
|
201
|
+
/** A leaf whose only content is `w:val`, taken whole when the source states it. */
|
|
202
|
+
function mergeVal(isEmptyOf) {
|
|
203
|
+
return (source, destination) => {
|
|
204
|
+
if (source === undefined || isEmptyOf(source))
|
|
205
|
+
return destination;
|
|
206
|
+
const out = (destination !== null && destination !== void 0 ? destination : {});
|
|
207
|
+
out.val = source.val;
|
|
208
|
+
return out;
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
export const mergeRStyle = mergeVal(isEmptyRStyle);
|
|
212
|
+
export const mergeHighlight = mergeVal(isEmptyHighlight);
|
|
213
|
+
export const mergeEm = mergeVal(isEmptyVal);
|
|
214
|
+
export const mergeVertAlign = mergeVal(isEmptyVal);
|
|
215
|
+
export const mergeEffect = mergeVal(isEmptyVal);
|
|
216
|
+
export const mergeHps = mergeVal(isEmptyVal);
|
|
217
|
+
export const mergeSignedHps = mergeVal(isEmptyVal);
|
|
218
|
+
export const mergeSignedTwips = mergeVal(isEmptyVal);
|
|
219
|
+
export const mergeTextScale = mergeVal(isEmptyVal);
|
|
220
|
+
export const mergeJc = mergeVal(isEmptyVal);
|
|
221
|
+
export const mergeOutlineLvl = mergeVal(isEmptyVal);
|
|
222
|
+
export const mergeTextAlignment = mergeVal(isEmptyVal);
|
|
223
|
+
export const mergeTextDirection = mergeVal(isEmptyVal);
|
|
224
|
+
export const mergeTextboxTightWrap = mergeVal(isEmptyVal);
|
|
225
|
+
export const mergeCnf = mergeVal(isEmptyCnf);
|
|
226
|
+
export const mergePStyle = mergeVal(isEmptyStringVal);
|
|
227
|
+
const mergeTblStyle = mergeVal(isEmptyStringVal);
|
|
228
|
+
const mergeRowBandSize = mergeVal(isEmptyVal);
|
|
229
|
+
const mergeColBandSize = mergeVal(isEmptyVal);
|
|
230
|
+
const mergeTblOverlap = mergeVal(isEmptyVal);
|
|
231
|
+
const mergeVAlign = mergeVal(isEmptyVal);
|
|
232
|
+
const mergeGridSpan = mergeVal(isEmptyVal);
|
|
233
|
+
const mergeHMerge = mergeVal(isEmptyStringVal);
|
|
234
|
+
const mergeVMerge = mergeVal(isEmptyStringVal);
|
|
235
|
+
const mergeTblLayout = (source, destination) => {
|
|
236
|
+
if (source === undefined || source.type === undefined)
|
|
237
|
+
return destination;
|
|
238
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
239
|
+
out.type = source.type;
|
|
240
|
+
return out;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* `w:rFonts`: a theme reference trumps an explicit face within one element, and a source with
|
|
244
|
+
* only a `w:hint` still says something. A null source leaves the destination alone (until
|
|
245
|
+
* CR-015 phase 1 it was given an empty `w:rFonts`, so every merged `w:rPr` read as directly
|
|
246
|
+
* formatted).
|
|
247
|
+
*/
|
|
248
|
+
export const mergeRFonts = (source, destination) => {
|
|
249
|
+
if (source === undefined)
|
|
250
|
+
return destination;
|
|
251
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
252
|
+
if (isEmptyRFonts(source)) {
|
|
253
|
+
if (source.hint !== undefined)
|
|
254
|
+
out.hint = source.hint;
|
|
255
|
+
// else: keep the (possibly empty) element, which RunFontSelector relies on
|
|
256
|
+
return out;
|
|
257
|
+
}
|
|
258
|
+
if (source.ascii !== undefined) {
|
|
259
|
+
out.ascii = source.ascii;
|
|
260
|
+
delete out.asciiTheme;
|
|
261
|
+
}
|
|
262
|
+
if (source.cs !== undefined) {
|
|
263
|
+
out.cs = source.cs;
|
|
264
|
+
delete out.cstheme;
|
|
265
|
+
}
|
|
266
|
+
if (source.eastAsia !== undefined) {
|
|
267
|
+
out.eastAsia = source.eastAsia;
|
|
268
|
+
delete out.eastAsiaTheme;
|
|
269
|
+
}
|
|
270
|
+
if (source.hAnsi !== undefined) {
|
|
271
|
+
out.hAnsi = source.hAnsi;
|
|
272
|
+
delete out.hAnsiTheme;
|
|
273
|
+
}
|
|
274
|
+
if (source.asciiTheme !== undefined) {
|
|
275
|
+
out.asciiTheme = source.asciiTheme;
|
|
276
|
+
delete out.ascii;
|
|
277
|
+
}
|
|
278
|
+
if (source.cstheme !== undefined) {
|
|
279
|
+
out.cstheme = source.cstheme;
|
|
280
|
+
delete out.cs;
|
|
281
|
+
}
|
|
282
|
+
if (source.eastAsiaTheme !== undefined) {
|
|
283
|
+
out.eastAsiaTheme = source.eastAsiaTheme;
|
|
284
|
+
delete out.eastAsia;
|
|
285
|
+
}
|
|
286
|
+
if (source.hAnsiTheme !== undefined) {
|
|
287
|
+
out.hAnsiTheme = source.hAnsiTheme;
|
|
288
|
+
delete out.hAnsi;
|
|
289
|
+
}
|
|
290
|
+
if (source.hint !== undefined)
|
|
291
|
+
out.hint = source.hint;
|
|
292
|
+
return out;
|
|
293
|
+
};
|
|
294
|
+
export const mergeColor = (source, destination) => {
|
|
295
|
+
if (isEmptyColor(source))
|
|
296
|
+
return destination;
|
|
297
|
+
const s = source;
|
|
298
|
+
const out = (destination !== null && destination !== void 0 ? destination : {});
|
|
299
|
+
out.themeColor = themeColor(s.themeColor, out.themeColor);
|
|
300
|
+
out.themeShade = attr(s.themeShade, out.themeShade);
|
|
301
|
+
out.themeTint = attr(s.themeTint, out.themeTint);
|
|
302
|
+
out.val = attr(s.val, out.val);
|
|
303
|
+
return out;
|
|
304
|
+
};
|
|
305
|
+
/** `w:val` and the colour attributes each inherit on their own (CR-015 phase 1). */
|
|
306
|
+
export const mergeU = (source, destination) => {
|
|
307
|
+
if (isEmptyU(source))
|
|
308
|
+
return destination;
|
|
309
|
+
const s = source;
|
|
310
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
311
|
+
out.val = attr(s.val, out.val);
|
|
312
|
+
out.color = attr(s.color, out.color);
|
|
313
|
+
out.themeColor = themeColor(s.themeColor, out.themeColor);
|
|
314
|
+
out.themeTint = attr(s.themeTint, out.themeTint);
|
|
315
|
+
out.themeShade = attr(s.themeShade, out.themeShade);
|
|
316
|
+
return out;
|
|
317
|
+
};
|
|
318
|
+
/** `w:val`, `w:eastAsia` and `w:bidi` each name the language of one script range and each inherits. */
|
|
319
|
+
export const mergeLang = (source, destination) => {
|
|
320
|
+
if (isEmptyLang(source))
|
|
321
|
+
return destination;
|
|
322
|
+
const s = source;
|
|
323
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
324
|
+
out.val = attr(s.val, out.val);
|
|
325
|
+
out.eastAsia = attr(s.eastAsia, out.eastAsia);
|
|
326
|
+
out.bidi = attr(s.bidi, out.bidi);
|
|
327
|
+
return out;
|
|
328
|
+
};
|
|
329
|
+
export const mergeShd = (source, destination) => {
|
|
330
|
+
if (isEmptyShd(source))
|
|
331
|
+
return destination;
|
|
332
|
+
const s = source;
|
|
333
|
+
const out = (destination !== null && destination !== void 0 ? destination : {});
|
|
334
|
+
out.color = attr(s.color, out.color);
|
|
335
|
+
out.fill = attr(s.fill, out.fill);
|
|
336
|
+
out.val = attr(s.val, out.val);
|
|
337
|
+
out.themeTint = attr(s.themeTint, out.themeTint);
|
|
338
|
+
out.themeShade = attr(s.themeShade, out.themeShade);
|
|
339
|
+
out.themeFillTint = attr(s.themeFillTint, out.themeFillTint);
|
|
340
|
+
out.themeFillShade = attr(s.themeFillShade, out.themeFillShade);
|
|
341
|
+
// the enums only when the source states them (until CR-015 a null source cleared them)
|
|
342
|
+
out.themeColor = themeColor(s.themeColor, out.themeColor);
|
|
343
|
+
out.themeFill = themeColor(s.themeFill, out.themeFill);
|
|
344
|
+
return out;
|
|
345
|
+
};
|
|
346
|
+
export const mergeBorder = (source, destination) => {
|
|
347
|
+
if (isEmptyBorder(source))
|
|
348
|
+
return destination;
|
|
349
|
+
const s = source;
|
|
350
|
+
const out = (destination !== null && destination !== void 0 ? destination : {});
|
|
351
|
+
out.color = attr(s.color, out.color);
|
|
352
|
+
out.space = attr(s.space, out.space);
|
|
353
|
+
out.sz = attr(s.sz, out.sz);
|
|
354
|
+
out.themeColor = themeColor(s.themeColor, out.themeColor);
|
|
355
|
+
out.themeShade = attr(s.themeShade, out.themeShade);
|
|
356
|
+
out.themeTint = attr(s.themeTint, out.themeTint);
|
|
357
|
+
out.val = attr(s.val, out.val);
|
|
358
|
+
return out;
|
|
359
|
+
};
|
|
360
|
+
export const mergePBdr = (source, destination) => {
|
|
361
|
+
if (isEmptyPBdr(source))
|
|
362
|
+
return destination;
|
|
363
|
+
const s = source;
|
|
364
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
365
|
+
out.top = mergeBorder(s.top, out.top);
|
|
366
|
+
out.left = mergeBorder(s.left, out.left);
|
|
367
|
+
out.bottom = mergeBorder(s.bottom, out.bottom);
|
|
368
|
+
out.right = mergeBorder(s.right, out.right);
|
|
369
|
+
out.between = mergeBorder(s.between, out.between);
|
|
370
|
+
out.bar = mergeBorder(s.bar, out.bar);
|
|
371
|
+
return out;
|
|
372
|
+
};
|
|
373
|
+
/** `w:numId` and `w:ilvl` each inherit on their own; see {@link isEmptyNumPr}. */
|
|
374
|
+
export const mergeNumPr = (source, destination) => {
|
|
375
|
+
if (isEmptyNumPr(source))
|
|
376
|
+
return destination;
|
|
377
|
+
const s = source;
|
|
378
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
379
|
+
if (s.numId !== undefined && s.numId.val !== undefined)
|
|
380
|
+
out.numId = copyLeaf(s.numId);
|
|
381
|
+
if (s.ilvl !== undefined && s.ilvl.val !== undefined)
|
|
382
|
+
out.ilvl = copyLeaf(s.ilvl);
|
|
383
|
+
return out;
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* `w:ind`: `w:firstLine` and `w:hanging` are two spellings of one property (ECMA-376
|
|
387
|
+
* 17.3.1.12), so whichever of the two the more specific `w:ind` states replaces both; the
|
|
388
|
+
* rest inherit per attribute.
|
|
389
|
+
*/
|
|
390
|
+
export const mergeInd = (source, destination) => {
|
|
391
|
+
if (isEmptyInd(source))
|
|
392
|
+
return destination;
|
|
393
|
+
const s = source;
|
|
394
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
395
|
+
const sourceFirstLine = s.firstLine !== undefined || s.firstLineChars !== undefined;
|
|
396
|
+
const sourceHanging = s.hanging !== undefined || s.hangingChars !== undefined;
|
|
397
|
+
if (sourceFirstLine && !sourceHanging) {
|
|
398
|
+
delete out.hanging;
|
|
399
|
+
delete out.hangingChars;
|
|
400
|
+
}
|
|
401
|
+
else if (sourceHanging && !sourceFirstLine) {
|
|
402
|
+
delete out.firstLine;
|
|
403
|
+
delete out.firstLineChars;
|
|
404
|
+
}
|
|
405
|
+
out.firstLine = attr(s.firstLine, out.firstLine);
|
|
406
|
+
out.firstLineChars = attr(s.firstLineChars, out.firstLineChars);
|
|
407
|
+
out.hanging = attr(s.hanging, out.hanging);
|
|
408
|
+
out.hangingChars = attr(s.hangingChars, out.hangingChars);
|
|
409
|
+
out.left = attr(s.left, out.left);
|
|
410
|
+
out.leftChars = attr(s.leftChars, out.leftChars);
|
|
411
|
+
out.right = attr(s.right, out.right);
|
|
412
|
+
out.rightChars = attr(s.rightChars, out.rightChars);
|
|
413
|
+
out.start = attr(s.start, out.start);
|
|
414
|
+
out.startChars = attr(s.startChars, out.startChars);
|
|
415
|
+
out.end = attr(s.end, out.end);
|
|
416
|
+
out.endChars = attr(s.endChars, out.endChars);
|
|
417
|
+
return out;
|
|
418
|
+
};
|
|
419
|
+
/**
|
|
420
|
+
* `w:spacing`: the autospacing attributes survive the merge, and `w:lineRule` qualifies
|
|
421
|
+
* `w:line` - a source stating `w:line` states a rule too (auto when it names none), and a
|
|
422
|
+
* source stating no `w:line` leaves both inherited (CR-015 probe styles-linerule).
|
|
423
|
+
*/
|
|
424
|
+
export const mergeSpacing = (source, destination) => {
|
|
425
|
+
var _a;
|
|
426
|
+
if (source === undefined)
|
|
427
|
+
return destination;
|
|
428
|
+
let out = destination;
|
|
429
|
+
if (source.beforeAutospacing !== undefined || source.afterAutospacing !== undefined) {
|
|
430
|
+
out !== null && out !== void 0 ? out : (out = {});
|
|
431
|
+
if (source.beforeAutospacing !== undefined)
|
|
432
|
+
out.beforeAutospacing = source.beforeAutospacing;
|
|
433
|
+
if (source.afterAutospacing !== undefined)
|
|
434
|
+
out.afterAutospacing = source.afterAutospacing;
|
|
435
|
+
}
|
|
436
|
+
if (!isEmptySpacing(source)) {
|
|
437
|
+
out !== null && out !== void 0 ? out : (out = {});
|
|
438
|
+
out.after = attr(source.after, out.after);
|
|
439
|
+
out.afterLines = attr(source.afterLines, out.afterLines);
|
|
440
|
+
out.before = attr(source.before, out.before);
|
|
441
|
+
out.beforeLines = attr(source.beforeLines, out.beforeLines);
|
|
442
|
+
if (source.line !== undefined) {
|
|
443
|
+
out.line = source.line;
|
|
444
|
+
out.lineRule = (_a = source.lineRule) !== null && _a !== void 0 ? _a : 'auto';
|
|
445
|
+
}
|
|
446
|
+
else if (source.lineRule !== undefined) {
|
|
447
|
+
out.lineRule = source.lineRule;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
return out;
|
|
451
|
+
};
|
|
452
|
+
/**
|
|
453
|
+
* `w:tabs`: the custom tab stops are the union of those declared and those inherited, a stop
|
|
454
|
+
* at the same position replaces the inherited one, and `w:val="clear"` only removes
|
|
455
|
+
* (ECMA-376 17.3.1.38, 17.3.1.37). Word holds them in ascending position order.
|
|
456
|
+
*/
|
|
457
|
+
export const mergeTabs = (source, destination) => {
|
|
458
|
+
var _a;
|
|
459
|
+
if (isEmptyTabs(source))
|
|
460
|
+
return destination;
|
|
461
|
+
const out = destination !== null && destination !== void 0 ? destination : { tab: [] };
|
|
462
|
+
(_a = out.tab) !== null && _a !== void 0 ? _a : (out.tab = []);
|
|
463
|
+
for (const stop of source.tab) {
|
|
464
|
+
const pos = stop.pos;
|
|
465
|
+
if (pos !== undefined) {
|
|
466
|
+
for (let i = out.tab.length - 1; i >= 0; i--) {
|
|
467
|
+
if (out.tab[i].pos === pos)
|
|
468
|
+
out.tab.splice(i, 1);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (stop.val === 'clear')
|
|
472
|
+
continue;
|
|
473
|
+
out.tab.push({ leader: stop.leader, pos, val: stop.val });
|
|
474
|
+
}
|
|
475
|
+
out.tab.sort((a, b) => {
|
|
476
|
+
if (a.pos === undefined)
|
|
477
|
+
return b.pos === undefined ? 0 : -1;
|
|
478
|
+
if (b.pos === undefined)
|
|
479
|
+
return 1;
|
|
480
|
+
return a.pos - b.pos;
|
|
481
|
+
});
|
|
482
|
+
return out;
|
|
483
|
+
};
|
|
484
|
+
/**
|
|
485
|
+
* `w:framePr`'s attributes each inherit on their own: a paragraph whose direct `w:framePr`
|
|
486
|
+
* gives only `w:x`/`w:y` keeps the anchors its style states. `w:anchorLock` defaults to true,
|
|
487
|
+
* and docx4j's merge writes that default out explicitly.
|
|
488
|
+
*/
|
|
489
|
+
export const mergeFramePr = (source, destination) => {
|
|
490
|
+
var _a;
|
|
491
|
+
if (isEmptyFramePr(source))
|
|
492
|
+
return destination;
|
|
493
|
+
const s = source;
|
|
494
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
495
|
+
out.dropCap = attr(s.dropCap, out.dropCap);
|
|
496
|
+
out.lines = attr(s.lines, out.lines);
|
|
497
|
+
out.w = attr(s.w, out.w);
|
|
498
|
+
out.h = attr(s.h, out.h);
|
|
499
|
+
out.vSpace = attr(s.vSpace, out.vSpace);
|
|
500
|
+
out.hSpace = attr(s.hSpace, out.hSpace);
|
|
501
|
+
out.wrap = attr(s.wrap, out.wrap);
|
|
502
|
+
out.hAnchor = attr(s.hAnchor, out.hAnchor);
|
|
503
|
+
out.vAnchor = attr(s.vAnchor, out.vAnchor);
|
|
504
|
+
out.x = attr(s.x, out.x);
|
|
505
|
+
out.xAlign = attr(s.xAlign, out.xAlign);
|
|
506
|
+
out.y = attr(s.y, out.y);
|
|
507
|
+
out.yAlign = attr(s.yAlign, out.yAlign);
|
|
508
|
+
out.hRule = attr(s.hRule, out.hRule);
|
|
509
|
+
// docx4j reads this through isAnchorLock(), which answers true when the attribute is absent
|
|
510
|
+
out.anchorLock = (_a = s.anchorLock) !== null && _a !== void 0 ? _a : true;
|
|
511
|
+
return out;
|
|
512
|
+
};
|
|
513
|
+
const mergeTblWidth = (source, destination) => {
|
|
514
|
+
if (source === undefined || source.w === undefined)
|
|
515
|
+
return destination;
|
|
516
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
517
|
+
out.w = source.w;
|
|
518
|
+
// "if @w:type is omitted, its value shall be assumed to be dxa"
|
|
519
|
+
out.type = source.type;
|
|
520
|
+
return out;
|
|
521
|
+
};
|
|
522
|
+
const mergeTblCellMar = (source, destination) => {
|
|
523
|
+
if (isEmptyTblCellMar(source))
|
|
524
|
+
return destination;
|
|
525
|
+
const s = source;
|
|
526
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
527
|
+
out.bottom = mergeTblWidth(s.bottom, out.bottom);
|
|
528
|
+
out.left = mergeTblWidth(s.left, out.left);
|
|
529
|
+
out.right = mergeTblWidth(s.right, out.right);
|
|
530
|
+
out.top = mergeTblWidth(s.top, out.top);
|
|
531
|
+
return out;
|
|
532
|
+
};
|
|
533
|
+
const mergeTblBorders = (source, destination) => {
|
|
534
|
+
if (isEmptyTblBorders(source))
|
|
535
|
+
return destination;
|
|
536
|
+
const s = source;
|
|
537
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
538
|
+
out.bottom = mergeBorder(s.bottom, out.bottom);
|
|
539
|
+
out.left = mergeBorder(s.left, out.left);
|
|
540
|
+
out.right = mergeBorder(s.right, out.right);
|
|
541
|
+
out.top = mergeBorder(s.top, out.top);
|
|
542
|
+
out.insideH = mergeBorder(s.insideH, out.insideH);
|
|
543
|
+
out.insideV = mergeBorder(s.insideV, out.insideV);
|
|
544
|
+
return out;
|
|
545
|
+
};
|
|
546
|
+
const mergeTcBorders = (source, destination) => {
|
|
547
|
+
if (isEmptyTcBorders(source))
|
|
548
|
+
return destination;
|
|
549
|
+
const s = source;
|
|
550
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
551
|
+
out.bottom = mergeBorder(s.bottom, out.bottom);
|
|
552
|
+
out.left = mergeBorder(s.left, out.left);
|
|
553
|
+
out.right = mergeBorder(s.right, out.right);
|
|
554
|
+
out.top = mergeBorder(s.top, out.top);
|
|
555
|
+
out.insideH = mergeBorder(s.insideH, out.insideH);
|
|
556
|
+
out.insideV = mergeBorder(s.insideV, out.insideV);
|
|
557
|
+
out.tl2Br = mergeBorder(s.tl2Br, out.tl2Br);
|
|
558
|
+
out.tr2Bl = mergeBorder(s.tr2Bl, out.tr2Bl);
|
|
559
|
+
return out;
|
|
560
|
+
};
|
|
561
|
+
const mergeTcMar = (source, destination) => {
|
|
562
|
+
if (isEmptyTcMar(source))
|
|
563
|
+
return destination;
|
|
564
|
+
const s = source;
|
|
565
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
566
|
+
out.bottom = mergeTblWidth(s.bottom, out.bottom);
|
|
567
|
+
out.left = mergeTblWidth(s.left, out.left);
|
|
568
|
+
out.right = mergeTblWidth(s.right, out.right);
|
|
569
|
+
out.top = mergeTblWidth(s.top, out.top);
|
|
570
|
+
return out;
|
|
571
|
+
};
|
|
572
|
+
const mergeTblLook = (source, destination) => {
|
|
573
|
+
if (isEmptyTblLook(source))
|
|
574
|
+
return destination;
|
|
575
|
+
const s = source;
|
|
576
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
577
|
+
out.firstColumn = attr(s.firstColumn, out.firstColumn);
|
|
578
|
+
out.firstRow = attr(s.firstRow, out.firstRow);
|
|
579
|
+
out.lastColumn = attr(s.lastColumn, out.lastColumn);
|
|
580
|
+
out.lastRow = attr(s.lastRow, out.lastRow);
|
|
581
|
+
out.noHBand = attr(s.noHBand, out.noHBand);
|
|
582
|
+
out.noVBand = attr(s.noVBand, out.noVBand);
|
|
583
|
+
out.val = attr(s.val, out.val);
|
|
584
|
+
return out;
|
|
585
|
+
};
|
|
586
|
+
/**
|
|
587
|
+
* `w:tblpPr`: the anchors and the `*Spec` enums only when the source states them - a
|
|
588
|
+
* `w:tblpPr` stating only `w:tblpX` keeps its inherited anchors in Word.
|
|
589
|
+
*/
|
|
590
|
+
const mergeTblPPr = (source, destination) => {
|
|
591
|
+
if (isEmptyTblPPr(source))
|
|
592
|
+
return destination;
|
|
593
|
+
const s = source;
|
|
594
|
+
const out = destination !== null && destination !== void 0 ? destination : {};
|
|
595
|
+
out.leftFromText = attr(s.leftFromText, out.leftFromText);
|
|
596
|
+
out.rightFromText = attr(s.rightFromText, out.rightFromText);
|
|
597
|
+
out.topFromText = attr(s.topFromText, out.topFromText);
|
|
598
|
+
out.bottomFromText = attr(s.bottomFromText, out.bottomFromText);
|
|
599
|
+
if (s.vertAnchor !== undefined)
|
|
600
|
+
out.vertAnchor = s.vertAnchor;
|
|
601
|
+
if (s.horzAnchor !== undefined)
|
|
602
|
+
out.horzAnchor = s.horzAnchor;
|
|
603
|
+
if (s.tblpXSpec !== undefined)
|
|
604
|
+
out.tblpXSpec = s.tblpXSpec;
|
|
605
|
+
out.tblpX = attr(s.tblpX, out.tblpX);
|
|
606
|
+
if (s.tblpYSpec !== undefined)
|
|
607
|
+
out.tblpYSpec = s.tblpYSpec;
|
|
608
|
+
out.tblpY = attr(s.tblpY, out.tblpY);
|
|
609
|
+
return out;
|
|
610
|
+
};
|
|
611
|
+
/**
|
|
612
|
+
* One entry. The accessors are by member name, which is the same on `RPr` and `ParaRPr`
|
|
613
|
+
* (docx4j needs an accessor pair per class there; here the two generated interfaces have the
|
|
614
|
+
* same members, so one pair serves both).
|
|
615
|
+
*/
|
|
616
|
+
function prop(name, merge, isEmpty, copyOf, options) {
|
|
617
|
+
var _a, _b;
|
|
618
|
+
return {
|
|
619
|
+
name,
|
|
620
|
+
isFormatting: (_a = options === null || options === void 0 ? void 0 : options.formatting) !== null && _a !== void 0 ? _a : true,
|
|
621
|
+
countsEmpty: (_b = options === null || options === void 0 ? void 0 : options.countsEmpty) !== null && _b !== void 0 ? _b : true,
|
|
622
|
+
get: (owner) => owner[name],
|
|
623
|
+
set: (owner, value) => {
|
|
624
|
+
const record = owner;
|
|
625
|
+
if (value === undefined)
|
|
626
|
+
delete record[name];
|
|
627
|
+
else
|
|
628
|
+
record[name] = value;
|
|
629
|
+
},
|
|
630
|
+
merge,
|
|
631
|
+
isEmpty,
|
|
632
|
+
copyOf,
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
/** A `BooleanDefaultTrue` member. */
|
|
636
|
+
function bool(name, options) {
|
|
637
|
+
return prop(name, mergeBool, isEmptyBool, copyLeaf, options);
|
|
638
|
+
}
|
|
639
|
+
/** A w14 member (Office 2010 text effects and OpenType features): replaced whole. */
|
|
640
|
+
function w14(name) {
|
|
641
|
+
return prop(name, mergeReplace, isNull, copyLeaf);
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* The members of `w:rPr` (17.3.2) and of the paragraph mark's `w:pPr/w:rPr`, in schema order,
|
|
645
|
+
* plus the w14 extensions the generated interfaces carry. Not listed: `w:rPrChange` and the
|
|
646
|
+
* paragraph mark's `w:ins`/`w:del`/`w:moveFrom`/`w:moveTo`, which record revisions and are
|
|
647
|
+
* never inherited.
|
|
648
|
+
*/
|
|
649
|
+
export const RUN = [
|
|
650
|
+
prop('rStyle', mergeRStyle, isEmptyRStyle, copyLeaf, { formatting: false }),
|
|
651
|
+
prop('rFonts', mergeRFonts, isEmptyRFonts, copyLeaf),
|
|
652
|
+
bool('b'),
|
|
653
|
+
bool('bCs'),
|
|
654
|
+
bool('i'),
|
|
655
|
+
bool('iCs'),
|
|
656
|
+
bool('caps'),
|
|
657
|
+
bool('smallCaps'),
|
|
658
|
+
bool('strike'),
|
|
659
|
+
bool('dstrike'),
|
|
660
|
+
bool('outline'),
|
|
661
|
+
bool('shadow'),
|
|
662
|
+
bool('emboss'),
|
|
663
|
+
bool('imprint'),
|
|
664
|
+
bool('noProof'),
|
|
665
|
+
bool('snapToGrid'),
|
|
666
|
+
bool('vanish'),
|
|
667
|
+
bool('webHidden'),
|
|
668
|
+
prop('color', mergeColor, isEmptyColor, copyLeaf),
|
|
669
|
+
prop('spacing', mergeSignedTwips, isEmptyVal, copyLeaf),
|
|
670
|
+
prop('w', mergeTextScale, isEmptyVal, copyLeaf),
|
|
671
|
+
prop('kern', mergeHps, isEmptyVal, copyLeaf),
|
|
672
|
+
prop('position', mergeSignedHps, isEmptyVal, copyLeaf),
|
|
673
|
+
prop('sz', mergeHps, isEmptyVal, copyLeaf),
|
|
674
|
+
prop('szCs', mergeHps, isEmptyVal, copyLeaf),
|
|
675
|
+
prop('highlight', mergeHighlight, isEmptyHighlight, copyLeaf),
|
|
676
|
+
prop('u', mergeU, isEmptyU, copyLeaf),
|
|
677
|
+
prop('effect', mergeEffect, isEmptyVal, copyLeaf),
|
|
678
|
+
prop('bdr', mergeBorder, isEmptyBorder, copyLeaf),
|
|
679
|
+
prop('shd', mergeShd, isEmptyShd, copyLeaf),
|
|
680
|
+
prop('fitText', mergeReplace, isNull, copyLeaf),
|
|
681
|
+
prop('vertAlign', mergeVertAlign, isEmptyVal, copyLeaf),
|
|
682
|
+
bool('rtl'),
|
|
683
|
+
bool('cs'),
|
|
684
|
+
prop('em', mergeEm, isEmptyVal, copyLeaf),
|
|
685
|
+
prop('lang', mergeLang, isEmptyLang, copyLeaf),
|
|
686
|
+
prop('eastAsianLayout', mergeReplace, isNull, copyLeaf),
|
|
687
|
+
bool('specVanish'),
|
|
688
|
+
bool('oMath'),
|
|
689
|
+
// w14 (Office 2010 text effects and OpenType features)
|
|
690
|
+
w14('glow'),
|
|
691
|
+
w14('shadow14'),
|
|
692
|
+
w14('reflection'),
|
|
693
|
+
w14('textOutline'),
|
|
694
|
+
w14('textFill'),
|
|
695
|
+
w14('scene3D'),
|
|
696
|
+
w14('props3D'),
|
|
697
|
+
w14('ligatures'),
|
|
698
|
+
w14('numForm'),
|
|
699
|
+
w14('numSpacing'),
|
|
700
|
+
w14('stylisticSets'),
|
|
701
|
+
w14('cntxtAlts'),
|
|
702
|
+
];
|
|
703
|
+
/** Members of `w:rPr` and `w:pPr/w:rPr` that are not in {@link RUN} (revision records). */
|
|
704
|
+
export const RUN_EXCLUDED = ['rPrChange', 'ins', 'del', 'moveFrom', 'moveTo'];
|
|
705
|
+
/**
|
|
706
|
+
* The names of the **toggle properties** of `w:rPr`, in the order ECMA-376-1 §17.7.3 lists
|
|
707
|
+
* them. Twelve, and no more: `w:dstrike`, `w:noProof`, `w:snapToGrid`, `w:webHidden`,
|
|
708
|
+
* `w:rtl`, `w:cs`, `w:specVanish` and `w:oMath` are Boolean but are not toggles.
|
|
709
|
+
*/
|
|
710
|
+
export const TOGGLE_NAMES = new Set([
|
|
711
|
+
'b', 'bCs', 'caps', 'emboss', 'i', 'iCs', 'imprint', 'outline',
|
|
712
|
+
'shadow', 'smallCaps', 'strike', 'vanish',
|
|
713
|
+
]);
|
|
714
|
+
/** {@link TOGGLE_NAMES} as members of {@link RUN}. */
|
|
715
|
+
export const TOGGLES = [...TOGGLE_NAMES].map((name) => {
|
|
716
|
+
const found = RUN.find((p) => p.name === name);
|
|
717
|
+
if (!found)
|
|
718
|
+
throw new Error(`no w:rPr member named ${name}`);
|
|
719
|
+
return found;
|
|
720
|
+
});
|
|
721
|
+
/** The `w:ind` member's name: the paragraph merge applies it last, after the numbering level's. */
|
|
722
|
+
export const IND = 'ind';
|
|
723
|
+
/**
|
|
724
|
+
* The members of `w:pPr` shared with a style's `w:pPr` (`PPrBase`, 17.3.1), in schema order.
|
|
725
|
+
* Not formatting: `w:pStyle` (the style reference), `w:divId` (an HTML import artefact),
|
|
726
|
+
* `w:cnfStyle` (Word's cache of the table conditions that apply) and `w14:collapsed` (the
|
|
727
|
+
* outline view's state). A `w:pPr`'s own `w:rPr` (the paragraph mark) and `w:sectPr` are
|
|
728
|
+
* outside `PPrBase` and outside this list.
|
|
729
|
+
*/
|
|
730
|
+
export const PARAGRAPH = [
|
|
731
|
+
prop('pStyle', mergePStyle, isEmptyStringVal, copyLeaf, { formatting: false }),
|
|
732
|
+
bool('keepNext'),
|
|
733
|
+
bool('keepLines'),
|
|
734
|
+
bool('pageBreakBefore'),
|
|
735
|
+
prop('framePr', mergeFramePr, isEmptyFramePr, copyLeaf),
|
|
736
|
+
bool('widowControl'),
|
|
737
|
+
prop('numPr', mergeNumPr, isEmptyNumPr, copyLeaf),
|
|
738
|
+
bool('suppressLineNumbers'),
|
|
739
|
+
prop('pBdr', mergePBdr, isEmptyPBdr, copyLeaf),
|
|
740
|
+
prop('shd', mergeShd, isEmptyShd, copyLeaf),
|
|
741
|
+
prop('tabs', mergeTabs, isEmptyTabs, copyLeaf),
|
|
742
|
+
bool('suppressAutoHyphens'),
|
|
743
|
+
bool('kinsoku'),
|
|
744
|
+
bool('wordWrap'),
|
|
745
|
+
bool('overflowPunct'),
|
|
746
|
+
bool('topLinePunct'),
|
|
747
|
+
bool('autoSpaceDE'),
|
|
748
|
+
bool('autoSpaceDN'),
|
|
749
|
+
bool('bidi'),
|
|
750
|
+
bool('adjustRightInd'),
|
|
751
|
+
bool('snapToGrid'),
|
|
752
|
+
prop('spacing', mergeSpacing, isEmptySpacing, copyLeaf),
|
|
753
|
+
prop(IND, mergeInd, isEmptyInd, copyLeaf),
|
|
754
|
+
bool('contextualSpacing'),
|
|
755
|
+
bool('mirrorIndents'),
|
|
756
|
+
bool('suppressOverlap'),
|
|
757
|
+
prop('jc', mergeJc, isEmptyVal, copyLeaf),
|
|
758
|
+
prop('textDirection', mergeTextDirection, isEmptyVal, copyLeaf),
|
|
759
|
+
prop('textAlignment', mergeTextAlignment, isEmptyVal, copyLeaf),
|
|
760
|
+
prop('textboxTightWrap', mergeTextboxTightWrap, isEmptyVal, copyLeaf),
|
|
761
|
+
prop('outlineLvl', mergeOutlineLvl, isEmptyVal, copyLeaf),
|
|
762
|
+
prop('divId', mergeReplace, isNull, copyLeaf, { formatting: false }),
|
|
763
|
+
prop('cnfStyle', mergeCnf, isEmptyCnf, copyLeaf, { formatting: false }),
|
|
764
|
+
bool('collapsed', { formatting: false }),
|
|
765
|
+
];
|
|
766
|
+
/** Members of `w:pPr` that are not in {@link PARAGRAPH}: the mark, the section, the revision. */
|
|
767
|
+
export const PARAGRAPH_EXCLUDED = ['rPr', 'sectPr', 'pPrChange'];
|
|
768
|
+
/**
|
|
769
|
+
* The members of `w:tblPr` (`CTTblPrBase`, 17.4.60), in schema order.
|
|
770
|
+
*
|
|
771
|
+
* Three quirks of docx4j's hand-written pair are reproduced and flagged: `w:bidiVisual` is
|
|
772
|
+
* applied but not counted by `isEmpty`, and `w:tblCaption` and `w:tblDescription` are neither
|
|
773
|
+
* applied nor counted (they are a table's accessibility text, not formatting a style carries).
|
|
774
|
+
*/
|
|
775
|
+
export const TABLE = [
|
|
776
|
+
prop('tblStyle', mergeTblStyle, isEmptyStringVal, copyLeaf, { formatting: false }),
|
|
777
|
+
prop('tblpPr', mergeTblPPr, isEmptyTblPPr, copyLeaf),
|
|
778
|
+
prop('tblOverlap', mergeTblOverlap, isEmptyVal, copyLeaf),
|
|
779
|
+
bool('bidiVisual', { countsEmpty: false }),
|
|
780
|
+
prop('tblStyleRowBandSize', mergeRowBandSize, isEmptyVal, copyLeaf),
|
|
781
|
+
prop('tblStyleColBandSize', mergeColBandSize, isEmptyVal, copyLeaf),
|
|
782
|
+
prop('tblW', mergeTblWidth, isEmptyTblWidth, copyLeaf),
|
|
783
|
+
prop('jc', mergeJc, isEmptyVal, copyLeaf),
|
|
784
|
+
prop('tblCellSpacing', mergeTblWidth, isEmptyTblWidth, copyLeaf),
|
|
785
|
+
prop('tblInd', mergeTblWidth, isEmptyTblWidth, copyLeaf),
|
|
786
|
+
prop('tblBorders', mergeTblBorders, isEmptyTblBorders, copyLeaf),
|
|
787
|
+
prop('shd', mergeShd, isEmptyShd, copyLeaf),
|
|
788
|
+
prop('tblLayout', mergeTblLayout, (v) => v === undefined || v.type === undefined, copyLeaf),
|
|
789
|
+
prop('tblCellMar', mergeTblCellMar, isEmptyTblCellMar, copyLeaf),
|
|
790
|
+
prop('tblLook', mergeTblLook, isEmptyTblLook, copyLeaf),
|
|
791
|
+
prop('tblCaption', notCarried, isNull, copyLeaf, { countsEmpty: false }),
|
|
792
|
+
prop('tblDescription', notCarried, isNull, copyLeaf, { countsEmpty: false }),
|
|
793
|
+
];
|
|
794
|
+
export const TABLE_EXCLUDED = ['tblPrChange'];
|
|
795
|
+
/**
|
|
796
|
+
* The members of `w:tcPr` (`TcPr`, 17.4.68), in schema order. `w:cellIns`, `w:cellDel`,
|
|
797
|
+
* `w:cellMerge` and `w:tcPrChange` record revisions and are excluded.
|
|
798
|
+
*/
|
|
799
|
+
export const CELL = [
|
|
800
|
+
prop('cnfStyle', mergeCnf, isEmptyCnf, copyLeaf, { formatting: false }),
|
|
801
|
+
prop('tcW', mergeTblWidth, isEmptyTblWidth, copyLeaf),
|
|
802
|
+
prop('gridSpan', mergeGridSpan, isEmptyVal, copyLeaf),
|
|
803
|
+
prop('hMerge', mergeHMerge, isEmptyStringVal, copyLeaf),
|
|
804
|
+
prop('vMerge', mergeVMerge, isEmptyStringVal, copyLeaf),
|
|
805
|
+
prop('tcBorders', mergeTcBorders, isEmptyTcBorders, copyLeaf),
|
|
806
|
+
prop('shd', mergeShd, isEmptyShd, copyLeaf),
|
|
807
|
+
bool('noWrap'),
|
|
808
|
+
prop('tcMar', mergeTcMar, isEmptyTcMar, copyLeaf),
|
|
809
|
+
prop('textDirection', mergeTextDirection, isEmptyVal, copyLeaf),
|
|
810
|
+
bool('tcFitText'),
|
|
811
|
+
prop('vAlign', mergeVAlign, isEmptyVal, copyLeaf),
|
|
812
|
+
bool('hideMark'),
|
|
813
|
+
];
|
|
814
|
+
export const CELL_EXCLUDED = ['cellIns', 'cellDel', 'cellMerge', 'tcPrChange'];
|
|
815
|
+
// ---------------------------------------------------------------- generic operations
|
|
816
|
+
/** The member of that name, or undefined. */
|
|
817
|
+
export function namedProperty(catalogue, name) {
|
|
818
|
+
return catalogue.find((p) => p.name === name);
|
|
819
|
+
}
|
|
820
|
+
/** Whether every member of `owner` is empty. */
|
|
821
|
+
export function isEmptyOf(catalogue, owner) {
|
|
822
|
+
if (owner === undefined || owner === null)
|
|
823
|
+
return true;
|
|
824
|
+
for (const p of catalogue) {
|
|
825
|
+
if (!p.countsEmpty)
|
|
826
|
+
continue;
|
|
827
|
+
if (!p.isEmpty(p.get(owner)))
|
|
828
|
+
return false;
|
|
829
|
+
}
|
|
830
|
+
return true;
|
|
831
|
+
}
|
|
832
|
+
/** Whether any formatting member is present (an element that is there, even with no attributes, counts: it was stated). */
|
|
833
|
+
export function hasDirectFormattingOf(catalogue, owner) {
|
|
834
|
+
if (owner === undefined || owner === null)
|
|
835
|
+
return false;
|
|
836
|
+
for (const p of catalogue) {
|
|
837
|
+
if (p.isFormatting && p.get(owner) !== undefined)
|
|
838
|
+
return true;
|
|
839
|
+
}
|
|
840
|
+
return false;
|
|
841
|
+
}
|
|
842
|
+
/** Apply every member of `source` over `destination`, in place, except those named. */
|
|
843
|
+
export function applyCatalogue(catalogue, source, destination, except) {
|
|
844
|
+
for (const p of catalogue) {
|
|
845
|
+
if (except === null || except === void 0 ? void 0 : except.has(p.name))
|
|
846
|
+
continue;
|
|
847
|
+
applyProperty(p, source, destination);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
/** Apply one member of `source` over `destination`. */
|
|
851
|
+
export function applyProperty(p, source, destination) {
|
|
852
|
+
p.set(destination, p.merge(p.get(source), p.get(destination)));
|
|
853
|
+
}
|
|
854
|
+
/** Unset in `destination` every member that `source` states. */
|
|
855
|
+
export function unsetCatalogue(catalogue, source, destination) {
|
|
856
|
+
for (const p of catalogue) {
|
|
857
|
+
if (p.get(source) !== undefined)
|
|
858
|
+
p.set(destination, undefined);
|
|
859
|
+
}
|
|
860
|
+
}
|