@bnsights/bbsf-utilities 1.0.36 → 1.0.37
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 +4 -0
- package/bnsights-bbsf-utilities.d.ts +4 -0
- package/bnsights-bbsf-utilities.metadata.json +1 -0
- package/bundles/bnsights-bbsf-utilities.umd.js +4870 -0
- package/bundles/bnsights-bbsf-utilities.umd.js.map +1 -0
- package/esm2015/bnsights-bbsf-utilities.js +5 -0
- package/esm2015/lib/bbsf-utilities.module.js +52 -0
- package/esm2015/lib/shared/authentication/auth.service.js +234 -0
- package/esm2015/lib/shared/config/environment.js +12 -0
- package/esm2015/lib/shared/config/word/constants.js +105 -0
- package/esm2015/lib/shared/config/word/docx-document.js +351 -0
- package/esm2015/lib/shared/config/word/helpers/index.js +4 -0
- package/esm2015/lib/shared/config/word/helpers/render-document-file.js +278 -0
- package/esm2015/lib/shared/config/word/helpers/xml-builder.js +1765 -0
- package/esm2015/lib/shared/config/word/html-to-docx.js +195 -0
- package/esm2015/lib/shared/config/word/index.js +55 -0
- package/esm2015/lib/shared/config/word/namespaces.js +37 -0
- package/esm2015/lib/shared/config/word/schemas/content-types.js +26 -0
- package/esm2015/lib/shared/config/word/schemas/core.js +29 -0
- package/esm2015/lib/shared/config/word/schemas/document-rels.js +16 -0
- package/esm2015/lib/shared/config/word/schemas/document.template.js +109 -0
- package/esm2015/lib/shared/config/word/schemas/font-table.js +40 -0
- package/esm2015/lib/shared/config/word/schemas/generic-rels.js +11 -0
- package/esm2015/lib/shared/config/word/schemas/index.js +13 -0
- package/esm2015/lib/shared/config/word/schemas/numbering.js +19 -0
- package/esm2015/lib/shared/config/word/schemas/rels.js +11 -0
- package/esm2015/lib/shared/config/word/schemas/settings.js +13 -0
- package/esm2015/lib/shared/config/word/schemas/styles.js +149 -0
- package/esm2015/lib/shared/config/word/schemas/theme.js +200 -0
- package/esm2015/lib/shared/config/word/schemas/web-settings.js +9 -0
- package/esm2015/lib/shared/config/word/utils/color-conversion.js +60 -0
- package/esm2015/lib/shared/config/word/utils/list.js +51 -0
- package/esm2015/lib/shared/config/word/utils/unit-conversion.js +30 -0
- package/esm2015/lib/shared/config/word/utils/url.js +9 -0
- package/esm2015/lib/shared/config/word/utils/vnode.js +3 -0
- package/esm2015/lib/shared/config/word/word-work/templates/documentTemplate.js +54 -0
- package/esm2015/lib/shared/config/word/word-work/templates/index.js +4 -0
- package/esm2015/lib/shared/config/word/word-work/templates/mhtDocumentTemplate.js +22 -0
- package/esm2015/lib/shared/config/word/word-work/templates/mhtPartTemplate.js +10 -0
- package/esm2015/lib/shared/config/word/word-work/utils.js +26 -0
- package/esm2015/lib/shared/models/AreaModel.js +3 -0
- package/esm2015/lib/shared/models/ErrorModel.js +3 -0
- package/esm2015/lib/shared/models/RequestOptionsModel.js +11 -0
- package/esm2015/lib/shared/models/WordDocumentModel.js +8 -0
- package/esm2015/lib/shared/services/AppearanceConfiguration.service.js +37 -0
- package/esm2015/lib/shared/services/configuration.service.js +26 -0
- package/esm2015/lib/shared/services/controlvalidation.service.js +175 -0
- package/esm2015/lib/shared/services/environment.service.js +48 -0
- package/esm2015/lib/shared/services/masterlayout.service.js +96 -0
- package/esm2015/lib/shared/services/requesthandler.service.js +206 -0
- package/esm2015/lib/shared/services/stylesbundle.service.js +56 -0
- package/esm2015/lib/shared/services/translate.service.js +13 -0
- package/esm2015/lib/shared/services/translationresolver.service.js +20 -0
- package/esm2015/lib/shared/services/utility.service.js +96 -0
- package/esm2015/lib/shared/services/word-document.service.js +39 -0
- package/esm2015/public-api.js +20 -0
- package/fesm2015/bnsights-bbsf-utilities.js +4639 -0
- package/fesm2015/bnsights-bbsf-utilities.js.map +1 -0
- package/lib/bbsf-utilities.module.d.ts +6 -0
- package/lib/shared/authentication/auth.service.d.ts +41 -0
- package/lib/shared/config/environment.d.ts +1 -0
- package/lib/shared/config/word/constants.d.ts +124 -0
- package/lib/shared/config/word/docx-document.d.ts +73 -0
- package/lib/shared/config/word/helpers/index.d.ts +1 -0
- package/lib/shared/config/word/helpers/render-document-file.d.ts +4 -0
- package/lib/shared/config/word/helpers/xml-builder.d.ts +14 -0
- package/lib/shared/config/word/html-to-docx.d.ts +1 -0
- package/lib/shared/config/word/index.d.ts +1 -0
- package/lib/shared/config/word/namespaces.d.ts +36 -0
- package/lib/shared/config/word/schemas/content-types.d.ts +1 -0
- package/lib/shared/config/word/schemas/core.d.ts +1 -0
- package/lib/shared/config/word/schemas/document-rels.d.ts +1 -0
- package/lib/shared/config/word/schemas/document.template.d.ts +4 -0
- package/lib/shared/config/word/schemas/font-table.d.ts +1 -0
- package/lib/shared/config/word/schemas/generic-rels.d.ts +1 -0
- package/lib/shared/config/word/schemas/index.d.ts +12 -0
- package/lib/shared/config/word/schemas/numbering.d.ts +1 -0
- package/lib/shared/config/word/schemas/rels.d.ts +1 -0
- package/lib/shared/config/word/schemas/settings.d.ts +1 -0
- package/lib/shared/config/word/schemas/styles.d.ts +1 -0
- package/lib/shared/config/word/schemas/theme.d.ts +1 -0
- package/lib/shared/config/word/schemas/web-settings.d.ts +1 -0
- package/lib/shared/config/word/utils/color-conversion.d.ts +7 -0
- package/lib/shared/config/word/utils/list.d.ts +6 -0
- package/lib/shared/config/word/utils/unit-conversion.d.ts +29 -0
- package/lib/shared/config/word/utils/url.d.ts +1 -0
- package/lib/shared/config/word/utils/vnode.d.ts +1 -0
- package/lib/shared/config/word/word-work/templates/documentTemplate.d.ts +12 -0
- package/lib/shared/config/word/word-work/templates/index.d.ts +3 -0
- package/lib/shared/config/word/word-work/templates/mhtDocumentTemplate.d.ts +1 -0
- package/lib/shared/config/word/word-work/templates/mhtPartTemplate.d.ts +1 -0
- package/lib/shared/config/word/word-work/utils.d.ts +1 -0
- package/lib/shared/models/AreaModel.d.ts +4 -0
- package/{src/lib/shared/models/ErrorModel.ts → lib/shared/models/ErrorModel.d.ts} +2 -5
- package/lib/shared/models/RequestOptionsModel.d.ts +11 -0
- package/lib/shared/models/WordDocumentModel.d.ts +16 -0
- package/lib/shared/services/AppearanceConfiguration.service.d.ts +11 -0
- package/lib/shared/services/configuration.service.d.ts +7 -0
- package/lib/shared/services/controlvalidation.service.d.ts +20 -0
- package/lib/shared/services/environment.service.d.ts +13 -0
- package/lib/shared/services/masterlayout.service.d.ts +24 -0
- package/lib/shared/services/requesthandler.service.d.ts +32 -0
- package/lib/shared/services/stylesbundle.service.d.ts +9 -0
- package/lib/shared/services/translate.service.d.ts +3 -0
- package/lib/shared/services/translationresolver.service.d.ts +8 -0
- package/lib/shared/services/utility.service.d.ts +21 -0
- package/lib/shared/services/word-document.service.d.ts +5 -0
- package/package.json +28 -20
- package/public-api.d.ts +16 -0
- package/karma.conf.js +0 -44
- package/ng-package.json +0 -10
- package/src/lib/bbsf-utilities.module.ts +0 -52
- package/src/lib/shared/authentication/auth.service.ts +0 -242
- package/src/lib/shared/config/environment.ts +0 -16
- package/src/lib/shared/config/word/constants.js +0 -133
- package/src/lib/shared/config/word/docx-document.js +0 -482
- package/src/lib/shared/config/word/helpers/index.js +0 -3
- package/src/lib/shared/config/word/helpers/render-document-file.js +0 -334
- package/src/lib/shared/config/word/helpers/xml-builder.js +0 -2165
- package/src/lib/shared/config/word/html-to-docx.js +0 -259
- package/src/lib/shared/config/word/index.js +0 -63
- package/src/lib/shared/config/word/namespaces.js +0 -40
- package/src/lib/shared/config/word/schemas/content-types.js +0 -26
- package/src/lib/shared/config/word/schemas/core.js +0 -44
- package/src/lib/shared/config/word/schemas/document-rels.js +0 -17
- package/src/lib/shared/config/word/schemas/document.template.js +0 -119
- package/src/lib/shared/config/word/schemas/font-table.js +0 -41
- package/src/lib/shared/config/word/schemas/generic-rels.js +0 -11
- package/src/lib/shared/config/word/schemas/index.js +0 -12
- package/src/lib/shared/config/word/schemas/numbering.js +0 -18
- package/src/lib/shared/config/word/schemas/rels.js +0 -12
- package/src/lib/shared/config/word/schemas/settings.js +0 -14
- package/src/lib/shared/config/word/schemas/styles.js +0 -152
- package/src/lib/shared/config/word/schemas/theme.js +0 -199
- package/src/lib/shared/config/word/schemas/web-settings.js +0 -10
- package/src/lib/shared/config/word/utils/color-conversion.js +0 -60
- package/src/lib/shared/config/word/utils/list.js +0 -55
- package/src/lib/shared/config/word/utils/unit-conversion.js +0 -53
- package/src/lib/shared/config/word/utils/url.js +0 -8
- package/src/lib/shared/config/word/utils/vnode.js +0 -3
- package/src/lib/shared/config/word/word-work/assets/contentTypesXml.ts +0 -1
- package/src/lib/shared/config/word/word-work/assets/documentXmlRels.ts +0 -1
- package/src/lib/shared/config/word/word-work/assets/index.ts +0 -3
- package/src/lib/shared/config/word/word-work/assets/relsXml.ts +0 -1
- package/src/lib/shared/config/word/word-work/index.ts +0 -8
- package/src/lib/shared/config/word/word-work/internal.ts +0 -69
- package/src/lib/shared/config/word/word-work/templates/documentTemplate.ts +0 -58
- package/src/lib/shared/config/word/word-work/templates/index.ts +0 -3
- package/src/lib/shared/config/word/word-work/templates/mhtDocumentTemplate.ts +0 -21
- package/src/lib/shared/config/word/word-work/templates/mhtPartTemplate.ts +0 -14
- package/src/lib/shared/config/word/word-work/utils.ts +0 -27
- package/src/lib/shared/models/AreaModel.ts +0 -5
- package/src/lib/shared/models/RequestOptionsModel.ts +0 -13
- package/src/lib/shared/models/WordDocumentModel.ts +0 -19
- package/src/lib/shared/services/AppearanceConfiguration.service.ts +0 -30
- package/src/lib/shared/services/configuration.service.ts +0 -18
- package/src/lib/shared/services/controlvalidation.service.ts +0 -194
- package/src/lib/shared/services/environment.service.ts +0 -56
- package/src/lib/shared/services/masterlayout.service.ts +0 -89
- package/src/lib/shared/services/requesthandler.service.ts +0 -241
- package/src/lib/shared/services/stylesbundle.service.ts +0 -52
- package/src/lib/shared/services/translate.service.ts +0 -8
- package/src/lib/shared/services/translationresolver.service.ts +0 -16
- package/src/lib/shared/services/utility.service.ts +0 -94
- package/src/lib/shared/services/word-document.service.ts +0 -36
- package/src/public-api.ts +0 -27
- package/src/test.ts +0 -26
- package/tsconfig.lib.json +0 -39
- package/tsconfig.lib.prod.json +0 -11
- package/tsconfig.spec.json +0 -17
- package/tslint.json +0 -17
|
@@ -1,2165 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-await-in-loop */
|
|
2
|
-
/* eslint-disable radix */
|
|
3
|
-
/* eslint-disable no-param-reassign */
|
|
4
|
-
/* eslint-disable no-case-declarations */
|
|
5
|
-
/* eslint-disable no-plusplus */
|
|
6
|
-
/* eslint-disable no-else-return */
|
|
7
|
-
import { fragment } from 'xmlbuilder2';
|
|
8
|
-
import isVNode from 'virtual-dom/vnode/is-vnode';
|
|
9
|
-
import isVText from 'virtual-dom/vnode/is-vtext';
|
|
10
|
-
import colorNames from 'color-name';
|
|
11
|
-
import { cloneDeep } from 'lodash';
|
|
12
|
-
import imageToBase64 from 'image-to-base64';
|
|
13
|
-
import mimeTypes from 'mime-types';
|
|
14
|
-
import sizeOf from 'image-size';
|
|
15
|
-
|
|
16
|
-
import namespaces from '../namespaces';
|
|
17
|
-
import {
|
|
18
|
-
rgbToHex,
|
|
19
|
-
hslToHex,
|
|
20
|
-
hslRegex,
|
|
21
|
-
rgbRegex,
|
|
22
|
-
hexRegex,
|
|
23
|
-
hex3Regex,
|
|
24
|
-
hex3ToHex,
|
|
25
|
-
} from '../utils/color-conversion';
|
|
26
|
-
import {
|
|
27
|
-
pixelToEMU,
|
|
28
|
-
pixelRegex,
|
|
29
|
-
TWIPToEMU,
|
|
30
|
-
percentageRegex,
|
|
31
|
-
pointRegex,
|
|
32
|
-
pointToHIP,
|
|
33
|
-
HIPToTWIP,
|
|
34
|
-
pointToTWIP,
|
|
35
|
-
pixelToHIP,
|
|
36
|
-
pixelToTWIP,
|
|
37
|
-
pixelToEIP,
|
|
38
|
-
pointToEIP,
|
|
39
|
-
cmToTWIP,
|
|
40
|
-
cmRegex,
|
|
41
|
-
inchRegex,
|
|
42
|
-
inchToTWIP,
|
|
43
|
-
} from '../utils/unit-conversion';
|
|
44
|
-
// FIXME: remove the cyclic dependency
|
|
45
|
-
// eslint-disable-next-line import/no-cycle
|
|
46
|
-
import { buildImage, buildList } from './render-document-file';
|
|
47
|
-
import {
|
|
48
|
-
defaultFont,
|
|
49
|
-
hyperlinkType,
|
|
50
|
-
paragraphBordersObject,
|
|
51
|
-
colorlessColors,
|
|
52
|
-
verticalAlignValues,
|
|
53
|
-
imageType,
|
|
54
|
-
internalRelationship,
|
|
55
|
-
} from '../constants';
|
|
56
|
-
import { vNodeHasChildren } from '../utils/vnode';
|
|
57
|
-
import { isValidUrl } from '../utils/url';
|
|
58
|
-
|
|
59
|
-
// eslint-disable-next-line consistent-return
|
|
60
|
-
const fixupColorCode = (colorCodeString) => {
|
|
61
|
-
if (Object.prototype.hasOwnProperty.call(colorNames, colorCodeString.toLowerCase())) {
|
|
62
|
-
const [red, green, blue] = colorNames[colorCodeString.toLowerCase()];
|
|
63
|
-
|
|
64
|
-
return rgbToHex(red, green, blue);
|
|
65
|
-
} else if (rgbRegex.test(colorCodeString)) {
|
|
66
|
-
const matchedParts = colorCodeString.match(rgbRegex);
|
|
67
|
-
const red = matchedParts[1];
|
|
68
|
-
const green = matchedParts[2];
|
|
69
|
-
const blue = matchedParts[3];
|
|
70
|
-
|
|
71
|
-
return rgbToHex(red, green, blue);
|
|
72
|
-
} else if (hslRegex.test(colorCodeString)) {
|
|
73
|
-
const matchedParts = colorCodeString.match(hslRegex);
|
|
74
|
-
const hue = matchedParts[1];
|
|
75
|
-
const saturation = matchedParts[2];
|
|
76
|
-
const luminosity = matchedParts[3];
|
|
77
|
-
|
|
78
|
-
return hslToHex(hue, saturation, luminosity);
|
|
79
|
-
} else if (hexRegex.test(colorCodeString)) {
|
|
80
|
-
const matchedParts = colorCodeString.match(hexRegex);
|
|
81
|
-
|
|
82
|
-
return matchedParts[1];
|
|
83
|
-
} else if (hex3Regex.test(colorCodeString)) {
|
|
84
|
-
const matchedParts = colorCodeString.match(hex3Regex);
|
|
85
|
-
const red = matchedParts[1];
|
|
86
|
-
const green = matchedParts[2];
|
|
87
|
-
const blue = matchedParts[3];
|
|
88
|
-
|
|
89
|
-
return hex3ToHex(red, green, blue);
|
|
90
|
-
} else {
|
|
91
|
-
return '000000';
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const buildRunFontFragment = (fontName = defaultFont) =>
|
|
96
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
97
|
-
.ele('@w', 'rFonts')
|
|
98
|
-
.att('@w', 'ascii', fontName)
|
|
99
|
-
.att('@w', 'hAnsi', fontName)
|
|
100
|
-
.up();
|
|
101
|
-
|
|
102
|
-
const buildRunStyleFragment = (type = 'Hyperlink') =>
|
|
103
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
104
|
-
.ele('@w', 'rStyle')
|
|
105
|
-
.att('@w', 'val', type)
|
|
106
|
-
.up();
|
|
107
|
-
|
|
108
|
-
const buildTableRowHeight = (tableRowHeight) =>
|
|
109
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
110
|
-
.ele('@w', 'trHeight')
|
|
111
|
-
.att('@w', 'val', tableRowHeight)
|
|
112
|
-
.att('@w', 'hRule', 'atLeast')
|
|
113
|
-
.up();
|
|
114
|
-
|
|
115
|
-
const buildVerticalAlignment = (verticalAlignment) => {
|
|
116
|
-
if (verticalAlignment.toLowerCase() === 'middle') {
|
|
117
|
-
verticalAlignment = 'center';
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return fragment({ namespaceAlias: { w: namespaces.w } })
|
|
121
|
-
.ele('@w', 'vAlign')
|
|
122
|
-
.att('@w', 'val', verticalAlignment)
|
|
123
|
-
.up();
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
const buildVerticalMerge = (verticalMerge = 'continue') =>
|
|
127
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
128
|
-
.ele('@w', 'vMerge')
|
|
129
|
-
.att('@w', 'val', verticalMerge)
|
|
130
|
-
.up();
|
|
131
|
-
|
|
132
|
-
const buildColor = (colorCode) =>
|
|
133
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
134
|
-
.ele('@w', 'color')
|
|
135
|
-
.att('@w', 'val', colorCode)
|
|
136
|
-
.up();
|
|
137
|
-
|
|
138
|
-
const buildFontSize = (fontSize) =>
|
|
139
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
140
|
-
.ele('@w', 'sz')
|
|
141
|
-
.att('@w', 'val', fontSize)
|
|
142
|
-
.up();
|
|
143
|
-
|
|
144
|
-
const buildShading = (colorCode) =>
|
|
145
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
146
|
-
.ele('@w', 'shd')
|
|
147
|
-
.att('@w', 'val', 'clear')
|
|
148
|
-
.att('@w', 'fill', colorCode)
|
|
149
|
-
.up();
|
|
150
|
-
|
|
151
|
-
const buildHighlight = (color = 'yellow') =>
|
|
152
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
153
|
-
.ele('@w', 'highlight')
|
|
154
|
-
.att('@w', 'val', color)
|
|
155
|
-
.up();
|
|
156
|
-
|
|
157
|
-
const buildVertAlign = (type = 'baseline') =>
|
|
158
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
159
|
-
.ele('@w', 'vertAlign')
|
|
160
|
-
.att('@w', 'val', type)
|
|
161
|
-
.up();
|
|
162
|
-
|
|
163
|
-
const buildStrike = () =>
|
|
164
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
165
|
-
.ele('@w', 'strike')
|
|
166
|
-
.att('@w', 'val', true)
|
|
167
|
-
.up();
|
|
168
|
-
|
|
169
|
-
const buildBold = () =>
|
|
170
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
171
|
-
.ele('@w', 'b')
|
|
172
|
-
.up();
|
|
173
|
-
|
|
174
|
-
const buildItalics = () =>
|
|
175
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
176
|
-
.ele('@w', 'i')
|
|
177
|
-
.up();
|
|
178
|
-
|
|
179
|
-
const buildUnderline = (type = 'single') =>
|
|
180
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
181
|
-
.ele('@w', 'u')
|
|
182
|
-
.att('@w', 'val', type)
|
|
183
|
-
.up();
|
|
184
|
-
|
|
185
|
-
const buildLineBreak = (type = 'textWrapping') =>
|
|
186
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
187
|
-
.ele('@w', 'br')
|
|
188
|
-
.att('@w', 'type', type)
|
|
189
|
-
.up();
|
|
190
|
-
|
|
191
|
-
const buildBorder = (
|
|
192
|
-
borderSide = 'top',
|
|
193
|
-
borderSize = 0,
|
|
194
|
-
borderSpacing = 0,
|
|
195
|
-
borderColor = fixupColorCode('black'),
|
|
196
|
-
borderStroke = 'single'
|
|
197
|
-
) =>
|
|
198
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
199
|
-
.ele('@w', borderSide)
|
|
200
|
-
.att('@w', 'val', borderStroke)
|
|
201
|
-
.att('@w', 'sz', borderSize)
|
|
202
|
-
.att('@w', 'space', borderSpacing)
|
|
203
|
-
.att('@w', 'color', borderColor)
|
|
204
|
-
.up();
|
|
205
|
-
|
|
206
|
-
const buildTextElement = (text) =>
|
|
207
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
208
|
-
.ele('@w', 't')
|
|
209
|
-
.att('@xml', 'space', 'preserve')
|
|
210
|
-
.txt(text)
|
|
211
|
-
.up();
|
|
212
|
-
|
|
213
|
-
// eslint-disable-next-line consistent-return
|
|
214
|
-
const fixupLineHeight = (lineHeight, fontSize) => {
|
|
215
|
-
// FIXME: If line height is anything other than a number
|
|
216
|
-
// eslint-disable-next-line no-restricted-globals
|
|
217
|
-
if (!isNaN(lineHeight)) {
|
|
218
|
-
if (fontSize) {
|
|
219
|
-
const actualLineHeight = +lineHeight * fontSize;
|
|
220
|
-
|
|
221
|
-
return HIPToTWIP(actualLineHeight);
|
|
222
|
-
} else {
|
|
223
|
-
// 240 TWIP or 12 point is default line height
|
|
224
|
-
return +lineHeight * 240;
|
|
225
|
-
}
|
|
226
|
-
} else {
|
|
227
|
-
// 240 TWIP or 12 point is default line height
|
|
228
|
-
return 240;
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
// eslint-disable-next-line consistent-return
|
|
233
|
-
const fixupFontSize = (fontSizeString) => {
|
|
234
|
-
if (pointRegex.test(fontSizeString)) {
|
|
235
|
-
const matchedParts = fontSizeString.match(pointRegex);
|
|
236
|
-
// convert point to half point
|
|
237
|
-
return pointToHIP(matchedParts[1]);
|
|
238
|
-
} else if (pixelRegex.test(fontSizeString)) {
|
|
239
|
-
const matchedParts = fontSizeString.match(pixelRegex);
|
|
240
|
-
// convert pixels to half point
|
|
241
|
-
return pixelToHIP(matchedParts[1]);
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
// eslint-disable-next-line consistent-return
|
|
246
|
-
const fixupRowHeight = (rowHeightString) => {
|
|
247
|
-
if (pointRegex.test(rowHeightString)) {
|
|
248
|
-
const matchedParts = rowHeightString.match(pointRegex);
|
|
249
|
-
// convert point to half point
|
|
250
|
-
return pointToTWIP(matchedParts[1]);
|
|
251
|
-
} else if (pixelRegex.test(rowHeightString)) {
|
|
252
|
-
const matchedParts = rowHeightString.match(pixelRegex);
|
|
253
|
-
// convert pixels to half point
|
|
254
|
-
return pixelToTWIP(matchedParts[1]);
|
|
255
|
-
} else if (cmRegex.test(rowHeightString)) {
|
|
256
|
-
const matchedParts = rowHeightString.match(cmRegex);
|
|
257
|
-
return cmToTWIP(matchedParts[1]);
|
|
258
|
-
} else if (inchRegex.test(rowHeightString)) {
|
|
259
|
-
const matchedParts = rowHeightString.match(inchRegex);
|
|
260
|
-
return inchToTWIP(matchedParts[1]);
|
|
261
|
-
}
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
// eslint-disable-next-line consistent-return
|
|
265
|
-
const fixupColumnWidth = (columnWidthString) => {
|
|
266
|
-
if (pointRegex.test(columnWidthString)) {
|
|
267
|
-
const matchedParts = columnWidthString.match(pointRegex);
|
|
268
|
-
return pointToTWIP(matchedParts[1]);
|
|
269
|
-
} else if (pixelRegex.test(columnWidthString)) {
|
|
270
|
-
const matchedParts = columnWidthString.match(pixelRegex);
|
|
271
|
-
return pixelToTWIP(matchedParts[1]);
|
|
272
|
-
} else if (cmRegex.test(columnWidthString)) {
|
|
273
|
-
const matchedParts = columnWidthString.match(cmRegex);
|
|
274
|
-
return cmToTWIP(matchedParts[1]);
|
|
275
|
-
} else if (inchRegex.test(columnWidthString)) {
|
|
276
|
-
const matchedParts = columnWidthString.match(inchRegex);
|
|
277
|
-
return inchToTWIP(matchedParts[1]);
|
|
278
|
-
}
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
// eslint-disable-next-line consistent-return
|
|
282
|
-
const fixupMargin = (marginString) => {
|
|
283
|
-
if (pointRegex.test(marginString)) {
|
|
284
|
-
const matchedParts = marginString.match(pointRegex);
|
|
285
|
-
// convert point to half point
|
|
286
|
-
return pointToTWIP(matchedParts[1]);
|
|
287
|
-
} else if (pixelRegex.test(marginString)) {
|
|
288
|
-
const matchedParts = marginString.match(pixelRegex);
|
|
289
|
-
// convert pixels to half point
|
|
290
|
-
return pixelToTWIP(matchedParts[1]);
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
const modifiedStyleAttributesBuilder = (vNode, attributes, options) => {
|
|
295
|
-
const modifiedAttributes = { ...attributes };
|
|
296
|
-
|
|
297
|
-
// styles
|
|
298
|
-
if (isVNode(vNode) && vNode.properties && vNode.properties.style) {
|
|
299
|
-
if (vNode.properties.style.color && !colorlessColors.includes(vNode.properties.style.color)) {
|
|
300
|
-
modifiedAttributes.color = fixupColorCode(vNode.properties.style.color);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (
|
|
304
|
-
vNode.properties.style['background-color'] &&
|
|
305
|
-
!colorlessColors.includes(vNode.properties.style['background-color'])
|
|
306
|
-
) {
|
|
307
|
-
modifiedAttributes.backgroundColor = fixupColorCode(
|
|
308
|
-
vNode.properties.style['background-color']
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
if (
|
|
313
|
-
vNode.properties.style['vertical-align'] &&
|
|
314
|
-
verticalAlignValues.includes(vNode.properties.style['vertical-align'])
|
|
315
|
-
) {
|
|
316
|
-
modifiedAttributes.verticalAlign = vNode.properties.style['vertical-align'];
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
if (
|
|
320
|
-
vNode.properties.style['text-align'] &&
|
|
321
|
-
['left', 'right', 'center', 'justify'].includes(vNode.properties.style['text-align'])
|
|
322
|
-
) {
|
|
323
|
-
modifiedAttributes.textAlign = vNode.properties.style['text-align'];
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// FIXME: remove bold check when other font weights are handled.
|
|
327
|
-
if (vNode.properties.style['font-weight'] && vNode.properties.style['font-weight'] === 'bold') {
|
|
328
|
-
modifiedAttributes.strong = vNode.properties.style['font-weight'];
|
|
329
|
-
}
|
|
330
|
-
if (vNode.properties.style['font-size']) {
|
|
331
|
-
modifiedAttributes.fontSize = fixupFontSize(vNode.properties.style['font-size']);
|
|
332
|
-
}
|
|
333
|
-
if (vNode.properties.style['line-height']) {
|
|
334
|
-
modifiedAttributes.lineHeight = fixupLineHeight(
|
|
335
|
-
vNode.properties.style['line-height'],
|
|
336
|
-
vNode.properties.style['font-size']
|
|
337
|
-
? fixupFontSize(vNode.properties.style['font-size'])
|
|
338
|
-
: null
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
if (vNode.properties.style['margin-left'] || vNode.properties.style['margin-right']) {
|
|
342
|
-
const leftMargin = fixupMargin(vNode.properties.style['margin-left']);
|
|
343
|
-
const rightMargin = fixupMargin(vNode.properties.style['margin-right']);
|
|
344
|
-
const indentation = {};
|
|
345
|
-
if (leftMargin) {
|
|
346
|
-
indentation.left = leftMargin;
|
|
347
|
-
}
|
|
348
|
-
if (rightMargin) {
|
|
349
|
-
indentation.right = rightMargin;
|
|
350
|
-
}
|
|
351
|
-
if (leftMargin || rightMargin) {
|
|
352
|
-
modifiedAttributes.indentation = indentation;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
if (vNode.properties.style.display) {
|
|
356
|
-
modifiedAttributes.display = vNode.properties.style.display;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
if (vNode.properties.style.width) {
|
|
360
|
-
modifiedAttributes.width = vNode.properties.style.width;
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// paragraph only
|
|
365
|
-
if (options && options.isParagraph) {
|
|
366
|
-
if (isVNode(vNode) && vNode.tagName === 'blockquote') {
|
|
367
|
-
modifiedAttributes.indentation = { left: 284 };
|
|
368
|
-
modifiedAttributes.textAlign = 'justify';
|
|
369
|
-
} else if (isVNode(vNode) && vNode.tagName === 'code') {
|
|
370
|
-
modifiedAttributes.highlightColor = 'lightGray';
|
|
371
|
-
} else if (isVNode(vNode) && vNode.tagName === 'pre') {
|
|
372
|
-
modifiedAttributes.font = 'Courier';
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
return modifiedAttributes;
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
// html tag to formatting function
|
|
380
|
-
// options are passed to the formatting function if needed
|
|
381
|
-
const buildFormatting = (htmlTag, options) => {
|
|
382
|
-
switch (htmlTag) {
|
|
383
|
-
case 'strong':
|
|
384
|
-
case 'b':
|
|
385
|
-
return buildBold();
|
|
386
|
-
case 'em':
|
|
387
|
-
case 'i':
|
|
388
|
-
return buildItalics();
|
|
389
|
-
case 'ins':
|
|
390
|
-
case 'u':
|
|
391
|
-
return buildUnderline();
|
|
392
|
-
case 'strike':
|
|
393
|
-
case 'del':
|
|
394
|
-
case 's':
|
|
395
|
-
return buildStrike();
|
|
396
|
-
case 'sub':
|
|
397
|
-
return buildVertAlign('subscript');
|
|
398
|
-
case 'sup':
|
|
399
|
-
return buildVertAlign('superscript');
|
|
400
|
-
case 'mark':
|
|
401
|
-
return buildHighlight();
|
|
402
|
-
case 'code':
|
|
403
|
-
return buildHighlight('lightGray');
|
|
404
|
-
case 'highlightColor':
|
|
405
|
-
return buildHighlight(options && options.color ? options.color : 'lightGray');
|
|
406
|
-
case 'font':
|
|
407
|
-
case 'pre':
|
|
408
|
-
return buildRunFontFragment('Courier');
|
|
409
|
-
case 'color':
|
|
410
|
-
return buildColor(options && options.color ? options.color : 'black');
|
|
411
|
-
case 'backgroundColor':
|
|
412
|
-
return buildShading(options && options.color ? options.color : 'black');
|
|
413
|
-
case 'fontSize':
|
|
414
|
-
// does this need a unit of measure?
|
|
415
|
-
return buildFontSize(options && options.fontSize ? options.fontSize : 10);
|
|
416
|
-
case 'hyperlink':
|
|
417
|
-
return buildRunStyleFragment('Hyperlink');
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
return null;
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
const buildRunProperties = (attributes) => {
|
|
424
|
-
const runPropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'rPr');
|
|
425
|
-
if (attributes && attributes.constructor === Object) {
|
|
426
|
-
Object.keys(attributes).forEach((key) => {
|
|
427
|
-
const options = {};
|
|
428
|
-
if (key === 'color' || key === 'backgroundColor' || key === 'highlightColor') {
|
|
429
|
-
options.color = attributes[key];
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
if (key === 'fontSize') {
|
|
433
|
-
options.fontSize = attributes[key];
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
const formattingFragment = buildFormatting(key, options);
|
|
437
|
-
if (formattingFragment) {
|
|
438
|
-
runPropertiesFragment.import(formattingFragment);
|
|
439
|
-
}
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
runPropertiesFragment.up();
|
|
443
|
-
|
|
444
|
-
return runPropertiesFragment;
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
const buildRun = async (vNode, attributes, docxDocumentInstance) => {
|
|
448
|
-
const runFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'r');
|
|
449
|
-
const runPropertiesFragment = buildRunProperties(cloneDeep(attributes));
|
|
450
|
-
|
|
451
|
-
// case where we have recursive spans representing font changes
|
|
452
|
-
if (isVNode(vNode) && vNode.tagName === 'span') {
|
|
453
|
-
// eslint-disable-next-line no-use-before-define
|
|
454
|
-
return buildRunOrRuns(vNode, attributes, docxDocumentInstance);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
if (
|
|
458
|
-
isVNode(vNode) &&
|
|
459
|
-
[
|
|
460
|
-
'strong',
|
|
461
|
-
'b',
|
|
462
|
-
'em',
|
|
463
|
-
'i',
|
|
464
|
-
'u',
|
|
465
|
-
'ins',
|
|
466
|
-
'strike',
|
|
467
|
-
'del',
|
|
468
|
-
's',
|
|
469
|
-
'sub',
|
|
470
|
-
'sup',
|
|
471
|
-
'mark',
|
|
472
|
-
'blockquote',
|
|
473
|
-
'code',
|
|
474
|
-
'pre',
|
|
475
|
-
].includes(vNode.tagName)
|
|
476
|
-
) {
|
|
477
|
-
const runFragmentsArray = [];
|
|
478
|
-
|
|
479
|
-
let vNodes = [vNode];
|
|
480
|
-
// create temp run fragments to split the paragraph into different runs
|
|
481
|
-
let tempAttributes = cloneDeep(attributes);
|
|
482
|
-
let tempRunFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'r');
|
|
483
|
-
while (vNodes.length) {
|
|
484
|
-
const tempVNode = vNodes.shift();
|
|
485
|
-
if (isVText(tempVNode)) {
|
|
486
|
-
const textFragment = buildTextElement(tempVNode.text);
|
|
487
|
-
const tempRunPropertiesFragment = buildRunProperties({ ...attributes, ...tempAttributes });
|
|
488
|
-
tempRunFragment.import(tempRunPropertiesFragment);
|
|
489
|
-
tempRunFragment.import(textFragment);
|
|
490
|
-
runFragmentsArray.push(tempRunFragment);
|
|
491
|
-
|
|
492
|
-
// re initialize temp run fragments with new fragment
|
|
493
|
-
tempAttributes = cloneDeep(attributes);
|
|
494
|
-
tempRunFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'r');
|
|
495
|
-
} else if (isVNode(tempVNode)) {
|
|
496
|
-
if (
|
|
497
|
-
[
|
|
498
|
-
'strong',
|
|
499
|
-
'b',
|
|
500
|
-
'em',
|
|
501
|
-
'i',
|
|
502
|
-
'u',
|
|
503
|
-
'ins',
|
|
504
|
-
'strike',
|
|
505
|
-
'del',
|
|
506
|
-
's',
|
|
507
|
-
'sub',
|
|
508
|
-
'sup',
|
|
509
|
-
'mark',
|
|
510
|
-
'code',
|
|
511
|
-
'pre',
|
|
512
|
-
].includes(tempVNode.tagName)
|
|
513
|
-
) {
|
|
514
|
-
tempAttributes = {};
|
|
515
|
-
switch (tempVNode.tagName) {
|
|
516
|
-
case 'strong':
|
|
517
|
-
case 'b':
|
|
518
|
-
tempAttributes.strong = true;
|
|
519
|
-
break;
|
|
520
|
-
case 'i':
|
|
521
|
-
tempAttributes.i = true;
|
|
522
|
-
break;
|
|
523
|
-
case 'u':
|
|
524
|
-
tempAttributes.u = true;
|
|
525
|
-
break;
|
|
526
|
-
case 'sub':
|
|
527
|
-
tempAttributes.sub = true;
|
|
528
|
-
break;
|
|
529
|
-
case 'sup':
|
|
530
|
-
tempAttributes.sup = true;
|
|
531
|
-
break;
|
|
532
|
-
}
|
|
533
|
-
const formattingFragment = buildFormatting(tempVNode);
|
|
534
|
-
|
|
535
|
-
if (formattingFragment) {
|
|
536
|
-
runPropertiesFragment.import(formattingFragment);
|
|
537
|
-
}
|
|
538
|
-
// go a layer deeper if there is a span somewhere in the children
|
|
539
|
-
} else if (tempVNode.tagName === 'span') {
|
|
540
|
-
// eslint-disable-next-line no-use-before-define
|
|
541
|
-
const spanFragment = await buildRunOrRuns(
|
|
542
|
-
tempVNode,
|
|
543
|
-
{ ...attributes, ...tempAttributes },
|
|
544
|
-
docxDocumentInstance
|
|
545
|
-
);
|
|
546
|
-
|
|
547
|
-
// if spanFragment is an array, we need to add each fragment to the runFragmentsArray. If the fragment is an array, perform a depth first search on the array to add each fragment to the runFragmentsArray
|
|
548
|
-
if (Array.isArray(spanFragment)) {
|
|
549
|
-
spanFragment.flat(Infinity);
|
|
550
|
-
runFragmentsArray.push(...spanFragment);
|
|
551
|
-
} else {
|
|
552
|
-
runFragmentsArray.push(spanFragment);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
// do not slice and concat children since this is already accounted for in the buildRunOrRuns function
|
|
556
|
-
// eslint-disable-next-line no-continue
|
|
557
|
-
continue;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
if (tempVNode.children && tempVNode.children.length) {
|
|
562
|
-
if (tempVNode.children.length > 1) {
|
|
563
|
-
attributes = { ...attributes, ...tempAttributes };
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
vNodes = tempVNode.children.slice().concat(vNodes);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
if (runFragmentsArray.length) {
|
|
570
|
-
return runFragmentsArray;
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
runFragment.import(runPropertiesFragment);
|
|
575
|
-
if (isVText(vNode)) {
|
|
576
|
-
const textFragment = buildTextElement(vNode.text);
|
|
577
|
-
runFragment.import(textFragment);
|
|
578
|
-
} else if (attributes && attributes.type === 'picture') {
|
|
579
|
-
let response = null;
|
|
580
|
-
|
|
581
|
-
const base64Uri = decodeURIComponent(vNode.properties.src);
|
|
582
|
-
if (base64Uri) {
|
|
583
|
-
response = docxDocumentInstance.createMediaFile(base64Uri);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
if (response) {
|
|
587
|
-
docxDocumentInstance.zip
|
|
588
|
-
.folder('word')
|
|
589
|
-
.folder('media')
|
|
590
|
-
.file(response.fileNameWithExtension, Buffer.from(response.fileContent, 'base64'), {
|
|
591
|
-
createFolders: false,
|
|
592
|
-
});
|
|
593
|
-
|
|
594
|
-
const documentRelsId = docxDocumentInstance.createDocumentRelationships(
|
|
595
|
-
docxDocumentInstance.relationshipFilename,
|
|
596
|
-
imageType,
|
|
597
|
-
`media/${response.fileNameWithExtension}`,
|
|
598
|
-
internalRelationship
|
|
599
|
-
);
|
|
600
|
-
|
|
601
|
-
attributes.inlineOrAnchored = true;
|
|
602
|
-
attributes.relationshipId = documentRelsId;
|
|
603
|
-
attributes.id = response.id;
|
|
604
|
-
attributes.fileContent = response.fileContent;
|
|
605
|
-
attributes.fileNameWithExtension = response.fileNameWithExtension;
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
const { type, inlineOrAnchored, ...otherAttributes } = attributes;
|
|
609
|
-
// eslint-disable-next-line no-use-before-define
|
|
610
|
-
const imageFragment = buildDrawing(inlineOrAnchored, type, otherAttributes);
|
|
611
|
-
runFragment.import(imageFragment);
|
|
612
|
-
} else if (isVNode(vNode) && vNode.tagName === 'br') {
|
|
613
|
-
const lineBreakFragment = buildLineBreak();
|
|
614
|
-
runFragment.import(lineBreakFragment);
|
|
615
|
-
}
|
|
616
|
-
runFragment.up();
|
|
617
|
-
|
|
618
|
-
return runFragment;
|
|
619
|
-
};
|
|
620
|
-
|
|
621
|
-
const buildRunOrRuns = async (vNode, attributes, docxDocumentInstance) => {
|
|
622
|
-
if (isVNode(vNode) && vNode.tagName === 'span') {
|
|
623
|
-
let runFragments = [];
|
|
624
|
-
|
|
625
|
-
for (let index = 0; index < vNode.children.length; index++) {
|
|
626
|
-
const childVNode = vNode.children[index];
|
|
627
|
-
const modifiedAttributes = modifiedStyleAttributesBuilder(vNode, attributes);
|
|
628
|
-
const tempRunFragments = await buildRun(childVNode, modifiedAttributes, docxDocumentInstance);
|
|
629
|
-
runFragments = runFragments.concat(
|
|
630
|
-
Array.isArray(tempRunFragments) ? tempRunFragments : [tempRunFragments]
|
|
631
|
-
);
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
return runFragments;
|
|
635
|
-
} else {
|
|
636
|
-
const tempRunFragments = await buildRun(vNode, attributes, docxDocumentInstance);
|
|
637
|
-
return tempRunFragments;
|
|
638
|
-
}
|
|
639
|
-
};
|
|
640
|
-
|
|
641
|
-
const buildRunOrHyperLink = async (vNode, attributes, docxDocumentInstance) => {
|
|
642
|
-
if (isVNode(vNode) && vNode.tagName === 'a') {
|
|
643
|
-
const relationshipId = docxDocumentInstance.createDocumentRelationships(
|
|
644
|
-
docxDocumentInstance.relationshipFilename,
|
|
645
|
-
hyperlinkType,
|
|
646
|
-
vNode.properties && vNode.properties.href ? vNode.properties.href : ''
|
|
647
|
-
);
|
|
648
|
-
const hyperlinkFragment = fragment({ namespaceAlias: { w: namespaces.w, r: namespaces.r } })
|
|
649
|
-
.ele('@w', 'hyperlink')
|
|
650
|
-
.att('@r', 'id', `rId${relationshipId}`);
|
|
651
|
-
|
|
652
|
-
const modifiedAttributes = { ...attributes };
|
|
653
|
-
modifiedAttributes.hyperlink = true;
|
|
654
|
-
|
|
655
|
-
const runFragments = await buildRunOrRuns(
|
|
656
|
-
vNode.children[0],
|
|
657
|
-
modifiedAttributes,
|
|
658
|
-
docxDocumentInstance
|
|
659
|
-
);
|
|
660
|
-
if (Array.isArray(runFragments)) {
|
|
661
|
-
for (let index = 0; index < runFragments.length; index++) {
|
|
662
|
-
const runFragment = runFragments[index];
|
|
663
|
-
|
|
664
|
-
hyperlinkFragment.import(runFragment);
|
|
665
|
-
}
|
|
666
|
-
} else {
|
|
667
|
-
hyperlinkFragment.import(runFragments);
|
|
668
|
-
}
|
|
669
|
-
hyperlinkFragment.up();
|
|
670
|
-
|
|
671
|
-
return hyperlinkFragment;
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
const runFragments = await buildRunOrRuns(vNode, attributes, docxDocumentInstance);
|
|
675
|
-
|
|
676
|
-
return runFragments;
|
|
677
|
-
};
|
|
678
|
-
|
|
679
|
-
const buildNumberingProperties = (levelId, numberingId) =>
|
|
680
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
681
|
-
.ele('@w', 'numPr')
|
|
682
|
-
.ele('@w', 'ilvl')
|
|
683
|
-
.att('@w', 'val', String(levelId))
|
|
684
|
-
.up()
|
|
685
|
-
.ele('@w', 'numId')
|
|
686
|
-
.att('@w', 'val', String(numberingId))
|
|
687
|
-
.up()
|
|
688
|
-
.up();
|
|
689
|
-
|
|
690
|
-
const buildNumberingInstances = () =>
|
|
691
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
692
|
-
.ele('@w', 'num')
|
|
693
|
-
.ele('@w', 'abstractNumId')
|
|
694
|
-
.up()
|
|
695
|
-
.up();
|
|
696
|
-
|
|
697
|
-
const buildSpacing = (lineSpacing, beforeSpacing, afterSpacing) => {
|
|
698
|
-
const spacingFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'spacing');
|
|
699
|
-
|
|
700
|
-
if (lineSpacing) {
|
|
701
|
-
spacingFragment.att('@w', 'line', lineSpacing);
|
|
702
|
-
}
|
|
703
|
-
if (beforeSpacing) {
|
|
704
|
-
spacingFragment.att('@w', 'before', beforeSpacing);
|
|
705
|
-
}
|
|
706
|
-
if (afterSpacing) {
|
|
707
|
-
spacingFragment.att('@w', 'after', afterSpacing);
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
spacingFragment.att('@w', 'lineRule', 'auto').up();
|
|
711
|
-
|
|
712
|
-
return spacingFragment;
|
|
713
|
-
};
|
|
714
|
-
|
|
715
|
-
const buildIndentation = ({ left, right }) => {
|
|
716
|
-
const indentationFragment = fragment({
|
|
717
|
-
namespaceAlias: { w: namespaces.w },
|
|
718
|
-
}).ele('@w', 'ind');
|
|
719
|
-
|
|
720
|
-
if (left) {
|
|
721
|
-
indentationFragment.att('@w', 'left', left);
|
|
722
|
-
}
|
|
723
|
-
if (right) {
|
|
724
|
-
indentationFragment.att('@w', 'right', right);
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
indentationFragment.up();
|
|
728
|
-
|
|
729
|
-
return indentationFragment;
|
|
730
|
-
};
|
|
731
|
-
|
|
732
|
-
const buildPStyle = (style = 'Normal') =>
|
|
733
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
734
|
-
.ele('@w', 'pStyle')
|
|
735
|
-
.att('@w', 'val', style)
|
|
736
|
-
.up();
|
|
737
|
-
|
|
738
|
-
const buildHorizontalAlignment = (horizontalAlignment) => {
|
|
739
|
-
if (horizontalAlignment === 'justify') {
|
|
740
|
-
horizontalAlignment = 'both';
|
|
741
|
-
}
|
|
742
|
-
return fragment({ namespaceAlias: { w: namespaces.w } })
|
|
743
|
-
.ele('@w', 'jc')
|
|
744
|
-
.att('@w', 'val', horizontalAlignment)
|
|
745
|
-
.up();
|
|
746
|
-
};
|
|
747
|
-
|
|
748
|
-
const buildParagraphBorder = () => {
|
|
749
|
-
const paragraphBorderFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele(
|
|
750
|
-
'@w',
|
|
751
|
-
'pBdr'
|
|
752
|
-
);
|
|
753
|
-
const bordersObject = cloneDeep(paragraphBordersObject);
|
|
754
|
-
|
|
755
|
-
Object.keys(bordersObject).forEach((borderName) => {
|
|
756
|
-
if (bordersObject[borderName]) {
|
|
757
|
-
const { size, spacing, color } = bordersObject[borderName];
|
|
758
|
-
|
|
759
|
-
const borderFragment = buildBorder(borderName, size, spacing, color);
|
|
760
|
-
paragraphBorderFragment.import(borderFragment);
|
|
761
|
-
}
|
|
762
|
-
});
|
|
763
|
-
|
|
764
|
-
paragraphBorderFragment.up();
|
|
765
|
-
|
|
766
|
-
return paragraphBorderFragment;
|
|
767
|
-
};
|
|
768
|
-
|
|
769
|
-
const buildParagraphProperties = (attributes) => {
|
|
770
|
-
const paragraphPropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele(
|
|
771
|
-
'@w',
|
|
772
|
-
'pPr'
|
|
773
|
-
);
|
|
774
|
-
if (attributes && attributes.constructor === Object) {
|
|
775
|
-
Object.keys(attributes).forEach((key) => {
|
|
776
|
-
switch (key) {
|
|
777
|
-
case 'numbering':
|
|
778
|
-
const { levelId, numberingId } = attributes[key];
|
|
779
|
-
const numberingPropertiesFragment = buildNumberingProperties(levelId, numberingId);
|
|
780
|
-
paragraphPropertiesFragment.import(numberingPropertiesFragment);
|
|
781
|
-
// eslint-disable-next-line no-param-reassign
|
|
782
|
-
delete attributes.numbering;
|
|
783
|
-
break;
|
|
784
|
-
case 'textAlign':
|
|
785
|
-
const horizontalAlignmentFragment = buildHorizontalAlignment(attributes[key]);
|
|
786
|
-
paragraphPropertiesFragment.import(horizontalAlignmentFragment);
|
|
787
|
-
// eslint-disable-next-line no-param-reassign
|
|
788
|
-
delete attributes.textAlign;
|
|
789
|
-
break;
|
|
790
|
-
case 'backgroundColor':
|
|
791
|
-
// Add shading to Paragraph Properties only if display is block
|
|
792
|
-
// Essentially if background color needs to be across the row
|
|
793
|
-
if (attributes.display === 'block') {
|
|
794
|
-
const shadingFragment = buildShading(attributes[key]);
|
|
795
|
-
paragraphPropertiesFragment.import(shadingFragment);
|
|
796
|
-
// FIXME: Inner padding in case of shaded paragraphs.
|
|
797
|
-
const paragraphBorderFragment = buildParagraphBorder();
|
|
798
|
-
paragraphPropertiesFragment.import(paragraphBorderFragment);
|
|
799
|
-
// eslint-disable-next-line no-param-reassign
|
|
800
|
-
delete attributes.backgroundColor;
|
|
801
|
-
}
|
|
802
|
-
break;
|
|
803
|
-
case 'paragraphStyle':
|
|
804
|
-
const pStyleFragment = buildPStyle(attributes.paragraphStyle);
|
|
805
|
-
paragraphPropertiesFragment.import(pStyleFragment);
|
|
806
|
-
delete attributes.paragraphStyle;
|
|
807
|
-
break;
|
|
808
|
-
case 'indentation':
|
|
809
|
-
const indentationFragment = buildIndentation(attributes[key]);
|
|
810
|
-
paragraphPropertiesFragment.import(indentationFragment);
|
|
811
|
-
// eslint-disable-next-line no-param-reassign
|
|
812
|
-
delete attributes.indentation;
|
|
813
|
-
break;
|
|
814
|
-
}
|
|
815
|
-
});
|
|
816
|
-
|
|
817
|
-
const spacingFragment = buildSpacing(
|
|
818
|
-
attributes.lineHeight,
|
|
819
|
-
attributes.beforeSpacing,
|
|
820
|
-
attributes.afterSpacing
|
|
821
|
-
);
|
|
822
|
-
// eslint-disable-next-line no-param-reassign
|
|
823
|
-
delete attributes.lineHeight;
|
|
824
|
-
// eslint-disable-next-line no-param-reassign
|
|
825
|
-
delete attributes.beforeSpacing;
|
|
826
|
-
// eslint-disable-next-line no-param-reassign
|
|
827
|
-
delete attributes.afterSpacing;
|
|
828
|
-
|
|
829
|
-
paragraphPropertiesFragment.import(spacingFragment);
|
|
830
|
-
}
|
|
831
|
-
paragraphPropertiesFragment.up();
|
|
832
|
-
|
|
833
|
-
return paragraphPropertiesFragment;
|
|
834
|
-
};
|
|
835
|
-
|
|
836
|
-
const computeImageDimensions = (vNode, attributes) => {
|
|
837
|
-
const { maximumWidth, originalWidth, originalHeight } = attributes;
|
|
838
|
-
const aspectRatio = originalWidth / originalHeight;
|
|
839
|
-
const maximumWidthInEMU = TWIPToEMU(maximumWidth);
|
|
840
|
-
let originalWidthInEMU = pixelToEMU(originalWidth);
|
|
841
|
-
let originalHeightInEMU = pixelToEMU(originalHeight);
|
|
842
|
-
if (originalWidthInEMU > maximumWidthInEMU) {
|
|
843
|
-
originalWidthInEMU = maximumWidthInEMU;
|
|
844
|
-
originalHeightInEMU = Math.round(originalWidthInEMU / aspectRatio);
|
|
845
|
-
}
|
|
846
|
-
let modifiedHeight;
|
|
847
|
-
let modifiedWidth;
|
|
848
|
-
|
|
849
|
-
if (vNode.properties && vNode.properties.style) {
|
|
850
|
-
if (vNode.properties.style.width) {
|
|
851
|
-
if (vNode.properties.style.width !== 'auto') {
|
|
852
|
-
if (pixelRegex.test(vNode.properties.style.width)) {
|
|
853
|
-
modifiedWidth = pixelToEMU(vNode.properties.style.width.match(pixelRegex)[1]);
|
|
854
|
-
} else if (percentageRegex.test(vNode.properties.style.width)) {
|
|
855
|
-
const percentageValue = vNode.properties.style.width.match(percentageRegex)[1];
|
|
856
|
-
|
|
857
|
-
modifiedWidth = Math.round((percentageValue / 100) * originalWidthInEMU);
|
|
858
|
-
}
|
|
859
|
-
} else {
|
|
860
|
-
// eslint-disable-next-line no-lonely-if
|
|
861
|
-
if (vNode.properties.style.height && vNode.properties.style.height === 'auto') {
|
|
862
|
-
modifiedWidth = originalWidthInEMU;
|
|
863
|
-
modifiedHeight = originalHeightInEMU;
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
if (vNode.properties.style.height) {
|
|
868
|
-
if (vNode.properties.style.height !== 'auto') {
|
|
869
|
-
if (pixelRegex.test(vNode.properties.style.height)) {
|
|
870
|
-
modifiedHeight = pixelToEMU(vNode.properties.style.height.match(pixelRegex)[1]);
|
|
871
|
-
} else if (percentageRegex.test(vNode.properties.style.height)) {
|
|
872
|
-
const percentageValue = vNode.properties.style.width.match(percentageRegex)[1];
|
|
873
|
-
|
|
874
|
-
modifiedHeight = Math.round((percentageValue / 100) * originalHeightInEMU);
|
|
875
|
-
if (!modifiedWidth) {
|
|
876
|
-
modifiedWidth = Math.round(modifiedHeight * aspectRatio);
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
} else {
|
|
880
|
-
// eslint-disable-next-line no-lonely-if
|
|
881
|
-
if (modifiedWidth) {
|
|
882
|
-
if (!modifiedHeight) {
|
|
883
|
-
modifiedHeight = Math.round(modifiedWidth / aspectRatio);
|
|
884
|
-
}
|
|
885
|
-
} else {
|
|
886
|
-
modifiedHeight = originalHeightInEMU;
|
|
887
|
-
modifiedWidth = originalWidthInEMU;
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
if (modifiedWidth && !modifiedHeight) {
|
|
892
|
-
modifiedHeight = Math.round(modifiedWidth / aspectRatio);
|
|
893
|
-
} else if (modifiedHeight && !modifiedWidth) {
|
|
894
|
-
modifiedWidth = Math.round(modifiedHeight * aspectRatio);
|
|
895
|
-
}
|
|
896
|
-
} else {
|
|
897
|
-
modifiedWidth = originalWidthInEMU;
|
|
898
|
-
modifiedHeight = originalHeightInEMU;
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
// eslint-disable-next-line no-param-reassign
|
|
902
|
-
attributes.width = modifiedWidth;
|
|
903
|
-
// eslint-disable-next-line no-param-reassign
|
|
904
|
-
attributes.height = modifiedHeight;
|
|
905
|
-
};
|
|
906
|
-
|
|
907
|
-
const buildParagraph = async (vNode, attributes, docxDocumentInstance) => {
|
|
908
|
-
const paragraphFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'p');
|
|
909
|
-
const modifiedAttributes = modifiedStyleAttributesBuilder(vNode, attributes, {
|
|
910
|
-
isParagraph: true,
|
|
911
|
-
});
|
|
912
|
-
const paragraphPropertiesFragment = buildParagraphProperties(modifiedAttributes);
|
|
913
|
-
paragraphFragment.import(paragraphPropertiesFragment);
|
|
914
|
-
if (isVNode(vNode) && vNodeHasChildren(vNode)) {
|
|
915
|
-
if (
|
|
916
|
-
[
|
|
917
|
-
'span',
|
|
918
|
-
'strong',
|
|
919
|
-
'b',
|
|
920
|
-
'em',
|
|
921
|
-
'i',
|
|
922
|
-
'u',
|
|
923
|
-
'ins',
|
|
924
|
-
'strike',
|
|
925
|
-
'del',
|
|
926
|
-
's',
|
|
927
|
-
'sub',
|
|
928
|
-
'sup',
|
|
929
|
-
'mark',
|
|
930
|
-
'a',
|
|
931
|
-
'code',
|
|
932
|
-
'pre',
|
|
933
|
-
].includes(vNode.tagName)
|
|
934
|
-
) {
|
|
935
|
-
const runOrHyperlinkFragments = await buildRunOrHyperLink(
|
|
936
|
-
vNode,
|
|
937
|
-
modifiedAttributes,
|
|
938
|
-
docxDocumentInstance
|
|
939
|
-
);
|
|
940
|
-
if (Array.isArray(runOrHyperlinkFragments)) {
|
|
941
|
-
for (
|
|
942
|
-
let iteratorIndex = 0;
|
|
943
|
-
iteratorIndex < runOrHyperlinkFragments.length;
|
|
944
|
-
iteratorIndex++
|
|
945
|
-
) {
|
|
946
|
-
const runOrHyperlinkFragment = runOrHyperlinkFragments[iteratorIndex];
|
|
947
|
-
|
|
948
|
-
paragraphFragment.import(runOrHyperlinkFragment);
|
|
949
|
-
}
|
|
950
|
-
} else {
|
|
951
|
-
paragraphFragment.import(runOrHyperlinkFragments);
|
|
952
|
-
}
|
|
953
|
-
} else if (vNode.tagName === 'blockquote') {
|
|
954
|
-
const runFragmentOrFragments = await buildRun(vNode, attributes);
|
|
955
|
-
if (Array.isArray(runFragmentOrFragments)) {
|
|
956
|
-
for (let index = 0; index < runFragmentOrFragments.length; index++) {
|
|
957
|
-
paragraphFragment.import(runFragmentOrFragments[index]);
|
|
958
|
-
}
|
|
959
|
-
} else {
|
|
960
|
-
paragraphFragment.import(runFragmentOrFragments);
|
|
961
|
-
}
|
|
962
|
-
} else {
|
|
963
|
-
for (let index = 0; index < vNode.children.length; index++) {
|
|
964
|
-
const childVNode = vNode.children[index];
|
|
965
|
-
if (childVNode.tagName === 'img') {
|
|
966
|
-
let base64String;
|
|
967
|
-
const imageSource = childVNode.properties.src;
|
|
968
|
-
if (isValidUrl(imageSource)) {
|
|
969
|
-
base64String = await imageToBase64(imageSource).catch((error) => {
|
|
970
|
-
// eslint-disable-next-line no-console
|
|
971
|
-
console.warning(`skipping image download and conversion due to ${error}`);
|
|
972
|
-
});
|
|
973
|
-
|
|
974
|
-
if (base64String && mimeTypes.lookup(imageSource)) {
|
|
975
|
-
childVNode.properties.src = `data:${mimeTypes.lookup(
|
|
976
|
-
imageSource
|
|
977
|
-
)};base64, ${base64String}`;
|
|
978
|
-
} else {
|
|
979
|
-
break;
|
|
980
|
-
}
|
|
981
|
-
} else {
|
|
982
|
-
// eslint-disable-next-line no-useless-escape, prefer-destructuring
|
|
983
|
-
base64String = imageSource.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/)[2];
|
|
984
|
-
}
|
|
985
|
-
const imageBuffer = Buffer.from(decodeURIComponent(base64String), 'base64');
|
|
986
|
-
const imageProperties = sizeOf(imageBuffer);
|
|
987
|
-
|
|
988
|
-
modifiedAttributes.maximumWidth =
|
|
989
|
-
modifiedAttributes.maximumWidth || docxDocumentInstance.availableDocumentSpace;
|
|
990
|
-
modifiedAttributes.originalWidth = imageProperties.width;
|
|
991
|
-
modifiedAttributes.originalHeight = imageProperties.height;
|
|
992
|
-
|
|
993
|
-
computeImageDimensions(childVNode, modifiedAttributes);
|
|
994
|
-
}
|
|
995
|
-
const runOrHyperlinkFragments = await buildRunOrHyperLink(
|
|
996
|
-
childVNode,
|
|
997
|
-
isVNode(childVNode) && childVNode.tagName === 'img'
|
|
998
|
-
? { ...modifiedAttributes, type: 'picture' }
|
|
999
|
-
: modifiedAttributes,
|
|
1000
|
-
docxDocumentInstance
|
|
1001
|
-
);
|
|
1002
|
-
if (Array.isArray(runOrHyperlinkFragments)) {
|
|
1003
|
-
for (
|
|
1004
|
-
let iteratorIndex = 0;
|
|
1005
|
-
iteratorIndex < runOrHyperlinkFragments.length;
|
|
1006
|
-
iteratorIndex++
|
|
1007
|
-
) {
|
|
1008
|
-
const runOrHyperlinkFragment = runOrHyperlinkFragments[iteratorIndex];
|
|
1009
|
-
|
|
1010
|
-
paragraphFragment.import(runOrHyperlinkFragment);
|
|
1011
|
-
}
|
|
1012
|
-
} else {
|
|
1013
|
-
paragraphFragment.import(runOrHyperlinkFragments);
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
} else {
|
|
1018
|
-
// In case paragraphs has to be rendered where vText is present. Eg. table-cell
|
|
1019
|
-
// Or in case the vNode is something like img
|
|
1020
|
-
if (isVNode(vNode) && vNode.tagName === 'img') {
|
|
1021
|
-
const imageSource = vNode.properties.src;
|
|
1022
|
-
let base64String = imageSource;
|
|
1023
|
-
if (isValidUrl(imageSource)) {
|
|
1024
|
-
base64String = await imageToBase64(imageSource).catch((error) => {
|
|
1025
|
-
// eslint-disable-next-line no-console
|
|
1026
|
-
console.warning(`skipping image download and conversion due to ${error}`);
|
|
1027
|
-
});
|
|
1028
|
-
|
|
1029
|
-
if (base64String && mimeTypes.lookup(imageSource)) {
|
|
1030
|
-
vNode.properties.src = `data:${mimeTypes.lookup(imageSource)};base64, ${base64String}`;
|
|
1031
|
-
} else {
|
|
1032
|
-
paragraphFragment.up();
|
|
1033
|
-
|
|
1034
|
-
return paragraphFragment;
|
|
1035
|
-
}
|
|
1036
|
-
} else {
|
|
1037
|
-
// eslint-disable-next-line no-useless-escape, prefer-destructuring
|
|
1038
|
-
base64String = base64String.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/)[2];
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
const imageBuffer = Buffer.from(decodeURIComponent(base64String), 'base64');
|
|
1042
|
-
const imageProperties = sizeOf(imageBuffer);
|
|
1043
|
-
|
|
1044
|
-
modifiedAttributes.maximumWidth =
|
|
1045
|
-
modifiedAttributes.maximumWidth || docxDocumentInstance.availableDocumentSpace;
|
|
1046
|
-
modifiedAttributes.originalWidth = imageProperties.width;
|
|
1047
|
-
modifiedAttributes.originalHeight = imageProperties.height;
|
|
1048
|
-
|
|
1049
|
-
computeImageDimensions(vNode, modifiedAttributes);
|
|
1050
|
-
}
|
|
1051
|
-
const runFragments = await buildRunOrRuns(vNode, modifiedAttributes, docxDocumentInstance);
|
|
1052
|
-
if (Array.isArray(runFragments)) {
|
|
1053
|
-
for (let index = 0; index < runFragments.length; index++) {
|
|
1054
|
-
const runFragment = runFragments[index];
|
|
1055
|
-
|
|
1056
|
-
paragraphFragment.import(runFragment);
|
|
1057
|
-
}
|
|
1058
|
-
} else {
|
|
1059
|
-
paragraphFragment.import(runFragments);
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
paragraphFragment.up();
|
|
1063
|
-
|
|
1064
|
-
return paragraphFragment;
|
|
1065
|
-
};
|
|
1066
|
-
|
|
1067
|
-
const buildGridSpanFragment = (spanValue) =>
|
|
1068
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
1069
|
-
.ele('@w', 'gridSpan')
|
|
1070
|
-
.att('@w', 'val', spanValue)
|
|
1071
|
-
.up();
|
|
1072
|
-
|
|
1073
|
-
const buildTableCellSpacing = (cellSpacing = 0) =>
|
|
1074
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
1075
|
-
.ele('@w', 'tblCellSpacing')
|
|
1076
|
-
.att('@w', 'w', cellSpacing)
|
|
1077
|
-
.att('@w', 'type', 'dxa')
|
|
1078
|
-
.up();
|
|
1079
|
-
|
|
1080
|
-
const buildTableCellBorders = (tableCellBorder) => {
|
|
1081
|
-
const tableCellBordersFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele(
|
|
1082
|
-
'@w',
|
|
1083
|
-
'tcBorders'
|
|
1084
|
-
);
|
|
1085
|
-
|
|
1086
|
-
const { color, stroke, ...borders } = tableCellBorder;
|
|
1087
|
-
Object.keys(borders).forEach((border) => {
|
|
1088
|
-
if (tableCellBorder[border]) {
|
|
1089
|
-
const borderFragment = buildBorder(border, tableCellBorder[border], 0, color, stroke);
|
|
1090
|
-
tableCellBordersFragment.import(borderFragment);
|
|
1091
|
-
}
|
|
1092
|
-
});
|
|
1093
|
-
|
|
1094
|
-
tableCellBordersFragment.up();
|
|
1095
|
-
|
|
1096
|
-
return tableCellBordersFragment;
|
|
1097
|
-
};
|
|
1098
|
-
|
|
1099
|
-
const buildTableCellWidth = (tableCellWidth) =>
|
|
1100
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
1101
|
-
.ele('@w', 'tcW')
|
|
1102
|
-
.att('@w', 'w', fixupColumnWidth(tableCellWidth))
|
|
1103
|
-
.att('@w', 'type', 'dxa')
|
|
1104
|
-
.up();
|
|
1105
|
-
|
|
1106
|
-
const buildTableCellProperties = (attributes) => {
|
|
1107
|
-
const tableCellPropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele(
|
|
1108
|
-
'@w',
|
|
1109
|
-
'tcPr'
|
|
1110
|
-
);
|
|
1111
|
-
if (attributes && attributes.constructor === Object) {
|
|
1112
|
-
Object.keys(attributes).forEach((key) => {
|
|
1113
|
-
switch (key) {
|
|
1114
|
-
case 'backgroundColor':
|
|
1115
|
-
const shadingFragment = buildShading(attributes[key]);
|
|
1116
|
-
tableCellPropertiesFragment.import(shadingFragment);
|
|
1117
|
-
// eslint-disable-next-line no-param-reassign
|
|
1118
|
-
delete attributes.backgroundColor;
|
|
1119
|
-
break;
|
|
1120
|
-
case 'verticalAlign':
|
|
1121
|
-
const verticalAlignmentFragment = buildVerticalAlignment(attributes[key]);
|
|
1122
|
-
tableCellPropertiesFragment.import(verticalAlignmentFragment);
|
|
1123
|
-
// eslint-disable-next-line no-param-reassign
|
|
1124
|
-
delete attributes.verticalAlign;
|
|
1125
|
-
break;
|
|
1126
|
-
case 'colSpan':
|
|
1127
|
-
const gridSpanFragment = buildGridSpanFragment(attributes[key]);
|
|
1128
|
-
tableCellPropertiesFragment.import(gridSpanFragment);
|
|
1129
|
-
// eslint-disable-next-line no-param-reassign
|
|
1130
|
-
delete attributes.colSpan;
|
|
1131
|
-
break;
|
|
1132
|
-
case 'tableCellBorder':
|
|
1133
|
-
const tableCellBorderFragment = buildTableCellBorders(attributes[key]);
|
|
1134
|
-
tableCellPropertiesFragment.import(tableCellBorderFragment);
|
|
1135
|
-
// eslint-disable-next-line no-param-reassign
|
|
1136
|
-
delete attributes.tableCellBorder;
|
|
1137
|
-
break;
|
|
1138
|
-
case 'rowSpan':
|
|
1139
|
-
const verticalMergeFragment = buildVerticalMerge(attributes[key]);
|
|
1140
|
-
tableCellPropertiesFragment.import(verticalMergeFragment);
|
|
1141
|
-
|
|
1142
|
-
delete attributes.rowSpan;
|
|
1143
|
-
break;
|
|
1144
|
-
case 'width':
|
|
1145
|
-
const widthFragment = buildTableCellWidth(attributes[key]);
|
|
1146
|
-
tableCellPropertiesFragment.import(widthFragment);
|
|
1147
|
-
delete attributes.width;
|
|
1148
|
-
break;
|
|
1149
|
-
}
|
|
1150
|
-
});
|
|
1151
|
-
}
|
|
1152
|
-
tableCellPropertiesFragment.up();
|
|
1153
|
-
|
|
1154
|
-
return tableCellPropertiesFragment;
|
|
1155
|
-
};
|
|
1156
|
-
|
|
1157
|
-
const fixupTableCellBorder = (vNode, attributes) => {
|
|
1158
|
-
if (Object.prototype.hasOwnProperty.call(vNode.properties.style, 'border')) {
|
|
1159
|
-
if (vNode.properties.style.border === 'none' || vNode.properties.style.border === 0) {
|
|
1160
|
-
attributes.tableCellBorder = {};
|
|
1161
|
-
} else {
|
|
1162
|
-
// eslint-disable-next-line no-use-before-define
|
|
1163
|
-
const [borderSize, borderStroke, borderColor] = cssBorderParser(
|
|
1164
|
-
vNode.properties.style.border
|
|
1165
|
-
);
|
|
1166
|
-
|
|
1167
|
-
attributes.tableCellBorder = {
|
|
1168
|
-
top: borderSize,
|
|
1169
|
-
left: borderSize,
|
|
1170
|
-
bottom: borderSize,
|
|
1171
|
-
right: borderSize,
|
|
1172
|
-
color: borderColor,
|
|
1173
|
-
stroke: borderStroke,
|
|
1174
|
-
};
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
if (vNode.properties.style['border-top'] && vNode.properties.style['border-top'] === '0') {
|
|
1178
|
-
attributes.tableCellBorder = {
|
|
1179
|
-
...attributes.tableCellBorder,
|
|
1180
|
-
top: 0,
|
|
1181
|
-
};
|
|
1182
|
-
} else if (vNode.properties.style['border-top'] && vNode.properties.style['border-top'] !== '0') {
|
|
1183
|
-
// eslint-disable-next-line no-use-before-define
|
|
1184
|
-
const [borderSize, borderStroke, borderColor] = cssBorderParser(
|
|
1185
|
-
vNode.properties.style['border-top']
|
|
1186
|
-
);
|
|
1187
|
-
attributes.tableCellBorder = {
|
|
1188
|
-
...attributes.tableCellBorder,
|
|
1189
|
-
top: borderSize,
|
|
1190
|
-
color: borderColor,
|
|
1191
|
-
stroke: borderStroke,
|
|
1192
|
-
};
|
|
1193
|
-
}
|
|
1194
|
-
if (vNode.properties.style['border-left'] && vNode.properties.style['border-left'] === '0') {
|
|
1195
|
-
attributes.tableCellBorder = {
|
|
1196
|
-
...attributes.tableCellBorder,
|
|
1197
|
-
left: 0,
|
|
1198
|
-
};
|
|
1199
|
-
} else if (
|
|
1200
|
-
vNode.properties.style['border-left'] &&
|
|
1201
|
-
vNode.properties.style['border-left'] !== '0'
|
|
1202
|
-
) {
|
|
1203
|
-
// eslint-disable-next-line no-use-before-define
|
|
1204
|
-
const [borderSize, borderStroke, borderColor] = cssBorderParser(
|
|
1205
|
-
vNode.properties.style['border-left']
|
|
1206
|
-
);
|
|
1207
|
-
attributes.tableCellBorder = {
|
|
1208
|
-
...attributes.tableCellBorder,
|
|
1209
|
-
left: borderSize,
|
|
1210
|
-
color: borderColor,
|
|
1211
|
-
stroke: borderStroke,
|
|
1212
|
-
};
|
|
1213
|
-
}
|
|
1214
|
-
if (vNode.properties.style['border-bottom'] && vNode.properties.style['border-bottom'] === '0') {
|
|
1215
|
-
attributes.tableCellBorder = {
|
|
1216
|
-
...attributes.tableCellBorder,
|
|
1217
|
-
bottom: 0,
|
|
1218
|
-
};
|
|
1219
|
-
} else if (
|
|
1220
|
-
vNode.properties.style['border-bottom'] &&
|
|
1221
|
-
vNode.properties.style['border-bottom'] !== '0'
|
|
1222
|
-
) {
|
|
1223
|
-
// eslint-disable-next-line no-use-before-define
|
|
1224
|
-
const [borderSize, borderStroke, borderColor] = cssBorderParser(
|
|
1225
|
-
vNode.properties.style['border-bottom']
|
|
1226
|
-
);
|
|
1227
|
-
attributes.tableCellBorder = {
|
|
1228
|
-
...attributes.tableCellBorder,
|
|
1229
|
-
bottom: borderSize,
|
|
1230
|
-
color: borderColor,
|
|
1231
|
-
stroke: borderStroke,
|
|
1232
|
-
};
|
|
1233
|
-
}
|
|
1234
|
-
if (vNode.properties.style['border-right'] && vNode.properties.style['border-right'] === '0') {
|
|
1235
|
-
attributes.tableCellBorder = {
|
|
1236
|
-
...attributes.tableCellBorder,
|
|
1237
|
-
right: 0,
|
|
1238
|
-
};
|
|
1239
|
-
} else if (
|
|
1240
|
-
vNode.properties.style['border-right'] &&
|
|
1241
|
-
vNode.properties.style['border-right'] !== '0'
|
|
1242
|
-
) {
|
|
1243
|
-
// eslint-disable-next-line no-use-before-define
|
|
1244
|
-
const [borderSize, borderStroke, borderColor] = cssBorderParser(
|
|
1245
|
-
vNode.properties.style['border-right']
|
|
1246
|
-
);
|
|
1247
|
-
attributes.tableCellBorder = {
|
|
1248
|
-
...attributes.tableCellBorder,
|
|
1249
|
-
right: borderSize,
|
|
1250
|
-
color: borderColor,
|
|
1251
|
-
stroke: borderStroke,
|
|
1252
|
-
};
|
|
1253
|
-
}
|
|
1254
|
-
};
|
|
1255
|
-
|
|
1256
|
-
const buildTableCell = async (vNode, attributes, rowSpanMap, columnIndex, docxDocumentInstance) => {
|
|
1257
|
-
const tableCellFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tc');
|
|
1258
|
-
|
|
1259
|
-
let modifiedAttributes = { ...attributes };
|
|
1260
|
-
if (isVNode(vNode) && vNode.properties) {
|
|
1261
|
-
if (vNode.properties.rowSpan) {
|
|
1262
|
-
rowSpanMap.set(columnIndex.index, { rowSpan: vNode.properties.rowSpan - 1, colSpan: 0 });
|
|
1263
|
-
modifiedAttributes.rowSpan = 'restart';
|
|
1264
|
-
} else {
|
|
1265
|
-
const previousSpanObject = rowSpanMap.get(columnIndex.index);
|
|
1266
|
-
rowSpanMap.set(
|
|
1267
|
-
columnIndex.index,
|
|
1268
|
-
// eslint-disable-next-line prefer-object-spread
|
|
1269
|
-
Object.assign({}, previousSpanObject, {
|
|
1270
|
-
rowSpan: 0,
|
|
1271
|
-
colSpan: (previousSpanObject && previousSpanObject.colSpan) || 0,
|
|
1272
|
-
})
|
|
1273
|
-
);
|
|
1274
|
-
}
|
|
1275
|
-
if (
|
|
1276
|
-
vNode.properties.colSpan ||
|
|
1277
|
-
(vNode.properties.style && vNode.properties.style['column-span'])
|
|
1278
|
-
) {
|
|
1279
|
-
modifiedAttributes.colSpan =
|
|
1280
|
-
vNode.properties.colSpan ||
|
|
1281
|
-
(vNode.properties.style && vNode.properties.style['column-span']);
|
|
1282
|
-
const previousSpanObject = rowSpanMap.get(columnIndex.index);
|
|
1283
|
-
rowSpanMap.set(
|
|
1284
|
-
columnIndex.index,
|
|
1285
|
-
// eslint-disable-next-line prefer-object-spread
|
|
1286
|
-
Object.assign({}, previousSpanObject, {
|
|
1287
|
-
colSpan: parseInt(modifiedAttributes.colSpan) || 0,
|
|
1288
|
-
})
|
|
1289
|
-
);
|
|
1290
|
-
columnIndex.index += parseInt(modifiedAttributes.colSpan) - 1;
|
|
1291
|
-
}
|
|
1292
|
-
if (vNode.properties.style) {
|
|
1293
|
-
modifiedAttributes = {
|
|
1294
|
-
...modifiedAttributes,
|
|
1295
|
-
...modifiedStyleAttributesBuilder(vNode, attributes),
|
|
1296
|
-
};
|
|
1297
|
-
|
|
1298
|
-
fixupTableCellBorder(vNode, modifiedAttributes);
|
|
1299
|
-
}
|
|
1300
|
-
}
|
|
1301
|
-
const tableCellPropertiesFragment = buildTableCellProperties(modifiedAttributes);
|
|
1302
|
-
tableCellFragment.import(tableCellPropertiesFragment);
|
|
1303
|
-
if (vNodeHasChildren(vNode)) {
|
|
1304
|
-
for (let index = 0; index < vNode.children.length; index++) {
|
|
1305
|
-
const childVNode = vNode.children[index];
|
|
1306
|
-
if (isVNode(childVNode) && childVNode.tagName === 'img') {
|
|
1307
|
-
const imageFragment = await buildImage(
|
|
1308
|
-
docxDocumentInstance,
|
|
1309
|
-
childVNode,
|
|
1310
|
-
modifiedAttributes.maximumWidth
|
|
1311
|
-
);
|
|
1312
|
-
if (imageFragment) {
|
|
1313
|
-
tableCellFragment.import(imageFragment);
|
|
1314
|
-
}
|
|
1315
|
-
} else if (isVNode(childVNode) && childVNode.tagName === 'figure') {
|
|
1316
|
-
if (vNodeHasChildren(childVNode)) {
|
|
1317
|
-
// eslint-disable-next-line no-plusplus
|
|
1318
|
-
for (let iteratorIndex = 0; iteratorIndex < childVNode.children.length; iteratorIndex++) {
|
|
1319
|
-
const grandChildVNode = childVNode.children[iteratorIndex];
|
|
1320
|
-
if (grandChildVNode.tagName === 'img') {
|
|
1321
|
-
const imageFragment = await buildImage(
|
|
1322
|
-
docxDocumentInstance,
|
|
1323
|
-
grandChildVNode,
|
|
1324
|
-
modifiedAttributes.maximumWidth
|
|
1325
|
-
);
|
|
1326
|
-
if (imageFragment) {
|
|
1327
|
-
tableCellFragment.import(imageFragment);
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
} else if (isVNode(childVNode) && ['ul', 'ol'].includes(childVNode.tagName)) {
|
|
1333
|
-
// render list in table
|
|
1334
|
-
if (vNodeHasChildren(childVNode)) {
|
|
1335
|
-
await buildList(childVNode, docxDocumentInstance, tableCellFragment);
|
|
1336
|
-
}
|
|
1337
|
-
} else {
|
|
1338
|
-
const paragraphFragment = await buildParagraph(
|
|
1339
|
-
childVNode,
|
|
1340
|
-
modifiedAttributes,
|
|
1341
|
-
docxDocumentInstance
|
|
1342
|
-
);
|
|
1343
|
-
|
|
1344
|
-
tableCellFragment.import(paragraphFragment);
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1347
|
-
} else {
|
|
1348
|
-
// TODO: Figure out why building with buildParagraph() isn't working
|
|
1349
|
-
const paragraphFragment = fragment({ namespaceAlias: { w: namespaces.w } })
|
|
1350
|
-
.ele('@w', 'p')
|
|
1351
|
-
.up();
|
|
1352
|
-
tableCellFragment.import(paragraphFragment);
|
|
1353
|
-
}
|
|
1354
|
-
tableCellFragment.up();
|
|
1355
|
-
|
|
1356
|
-
return tableCellFragment;
|
|
1357
|
-
};
|
|
1358
|
-
|
|
1359
|
-
const buildRowSpanCell = (rowSpanMap, columnIndex, attributes) => {
|
|
1360
|
-
const rowSpanCellFragments = [];
|
|
1361
|
-
let spanObject = rowSpanMap.get(columnIndex.index);
|
|
1362
|
-
while (spanObject && spanObject.rowSpan) {
|
|
1363
|
-
const rowSpanCellFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tc');
|
|
1364
|
-
|
|
1365
|
-
const tableCellPropertiesFragment = buildTableCellProperties({
|
|
1366
|
-
...attributes,
|
|
1367
|
-
rowSpan: 'continue',
|
|
1368
|
-
colSpan: spanObject.colSpan ? spanObject.colSpan : 0,
|
|
1369
|
-
});
|
|
1370
|
-
rowSpanCellFragment.import(tableCellPropertiesFragment);
|
|
1371
|
-
|
|
1372
|
-
const paragraphFragment = fragment({ namespaceAlias: { w: namespaces.w } })
|
|
1373
|
-
.ele('@w', 'p')
|
|
1374
|
-
.up();
|
|
1375
|
-
rowSpanCellFragment.import(paragraphFragment);
|
|
1376
|
-
rowSpanCellFragment.up();
|
|
1377
|
-
|
|
1378
|
-
rowSpanCellFragments.push(rowSpanCellFragment);
|
|
1379
|
-
|
|
1380
|
-
if (spanObject.rowSpan - 1 === 0) {
|
|
1381
|
-
rowSpanMap.delete(columnIndex.index);
|
|
1382
|
-
} else {
|
|
1383
|
-
rowSpanMap.set(columnIndex.index, {
|
|
1384
|
-
rowSpan: spanObject.rowSpan - 1,
|
|
1385
|
-
colSpan: spanObject.colSpan || 0,
|
|
1386
|
-
});
|
|
1387
|
-
}
|
|
1388
|
-
columnIndex.index += spanObject.colSpan || 1;
|
|
1389
|
-
spanObject = rowSpanMap.get(columnIndex.index);
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
|
-
return rowSpanCellFragments;
|
|
1393
|
-
};
|
|
1394
|
-
|
|
1395
|
-
const buildTableRowProperties = (attributes) => {
|
|
1396
|
-
const tableRowPropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele(
|
|
1397
|
-
'@w',
|
|
1398
|
-
'trPr'
|
|
1399
|
-
);
|
|
1400
|
-
if (attributes && attributes.constructor === Object) {
|
|
1401
|
-
Object.keys(attributes).forEach((key) => {
|
|
1402
|
-
switch (key) {
|
|
1403
|
-
case 'tableRowHeight':
|
|
1404
|
-
const tableRowHeightFragment = buildTableRowHeight(attributes[key]);
|
|
1405
|
-
tableRowPropertiesFragment.import(tableRowHeightFragment);
|
|
1406
|
-
// eslint-disable-next-line no-param-reassign
|
|
1407
|
-
delete attributes.tableRowHeight;
|
|
1408
|
-
break;
|
|
1409
|
-
case 'rowCantSplit':
|
|
1410
|
-
if (attributes.rowCantSplit) {
|
|
1411
|
-
const cantSplitFragment = fragment({ namespaceAlias: { w: namespaces.w } })
|
|
1412
|
-
.ele('@w', 'cantSplit')
|
|
1413
|
-
.up();
|
|
1414
|
-
tableRowPropertiesFragment.import(cantSplitFragment);
|
|
1415
|
-
// eslint-disable-next-line no-param-reassign
|
|
1416
|
-
delete attributes.rowCantSplit;
|
|
1417
|
-
}
|
|
1418
|
-
break;
|
|
1419
|
-
}
|
|
1420
|
-
});
|
|
1421
|
-
}
|
|
1422
|
-
tableRowPropertiesFragment.up();
|
|
1423
|
-
return tableRowPropertiesFragment;
|
|
1424
|
-
};
|
|
1425
|
-
|
|
1426
|
-
const buildTableRow = async (vNode, attributes, rowSpanMap, docxDocumentInstance) => {
|
|
1427
|
-
const tableRowFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tr');
|
|
1428
|
-
const modifiedAttributes = { ...attributes };
|
|
1429
|
-
if (isVNode(vNode) && vNode.properties) {
|
|
1430
|
-
// FIXME: find a better way to get row height from cell style
|
|
1431
|
-
if (
|
|
1432
|
-
(vNode.properties.style && vNode.properties.style.height) ||
|
|
1433
|
-
(vNode.children[0] &&
|
|
1434
|
-
isVNode(vNode.children[0]) &&
|
|
1435
|
-
vNode.children[0].properties.style &&
|
|
1436
|
-
vNode.children[0].properties.style.height)
|
|
1437
|
-
) {
|
|
1438
|
-
modifiedAttributes.tableRowHeight = fixupRowHeight(
|
|
1439
|
-
(vNode.properties.style && vNode.properties.style.height) ||
|
|
1440
|
-
(vNode.children[0] &&
|
|
1441
|
-
isVNode(vNode.children[0]) &&
|
|
1442
|
-
vNode.children[0].properties.style &&
|
|
1443
|
-
vNode.children[0].properties.style.height
|
|
1444
|
-
? vNode.children[0].properties.style.height
|
|
1445
|
-
: undefined)
|
|
1446
|
-
);
|
|
1447
|
-
}
|
|
1448
|
-
if (vNode.properties.style) {
|
|
1449
|
-
fixupTableCellBorder(vNode, modifiedAttributes);
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
|
-
const tableRowPropertiesFragment = buildTableRowProperties(modifiedAttributes);
|
|
1454
|
-
tableRowFragment.import(tableRowPropertiesFragment);
|
|
1455
|
-
|
|
1456
|
-
const columnIndex = { index: 0 };
|
|
1457
|
-
|
|
1458
|
-
if (vNodeHasChildren(vNode)) {
|
|
1459
|
-
const tableColumns = vNode.children.filter((childVNode) =>
|
|
1460
|
-
['td', 'th'].includes(childVNode.tagName)
|
|
1461
|
-
);
|
|
1462
|
-
const maximumColumnWidth = docxDocumentInstance.availableDocumentSpace / tableColumns.length;
|
|
1463
|
-
|
|
1464
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
1465
|
-
for (const column of tableColumns) {
|
|
1466
|
-
const rowSpanCellFragments = buildRowSpanCell(rowSpanMap, columnIndex, modifiedAttributes);
|
|
1467
|
-
if (Array.isArray(rowSpanCellFragments)) {
|
|
1468
|
-
for (let iteratorIndex = 0; iteratorIndex < rowSpanCellFragments.length; iteratorIndex++) {
|
|
1469
|
-
const rowSpanCellFragment = rowSpanCellFragments[iteratorIndex];
|
|
1470
|
-
|
|
1471
|
-
tableRowFragment.import(rowSpanCellFragment);
|
|
1472
|
-
}
|
|
1473
|
-
}
|
|
1474
|
-
const tableCellFragment = await buildTableCell(
|
|
1475
|
-
column,
|
|
1476
|
-
{ ...modifiedAttributes, maximumWidth: maximumColumnWidth },
|
|
1477
|
-
rowSpanMap,
|
|
1478
|
-
columnIndex,
|
|
1479
|
-
docxDocumentInstance
|
|
1480
|
-
);
|
|
1481
|
-
columnIndex.index++;
|
|
1482
|
-
|
|
1483
|
-
tableRowFragment.import(tableCellFragment);
|
|
1484
|
-
}
|
|
1485
|
-
}
|
|
1486
|
-
|
|
1487
|
-
if (columnIndex.index < rowSpanMap.size) {
|
|
1488
|
-
const rowSpanCellFragments = buildRowSpanCell(rowSpanMap, columnIndex, modifiedAttributes);
|
|
1489
|
-
if (Array.isArray(rowSpanCellFragments)) {
|
|
1490
|
-
for (let iteratorIndex = 0; iteratorIndex < rowSpanCellFragments.length; iteratorIndex++) {
|
|
1491
|
-
const rowSpanCellFragment = rowSpanCellFragments[iteratorIndex];
|
|
1492
|
-
|
|
1493
|
-
tableRowFragment.import(rowSpanCellFragment);
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
}
|
|
1497
|
-
|
|
1498
|
-
tableRowFragment.up();
|
|
1499
|
-
|
|
1500
|
-
return tableRowFragment;
|
|
1501
|
-
};
|
|
1502
|
-
|
|
1503
|
-
const buildTableGridCol = (gridWidth) =>
|
|
1504
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
1505
|
-
.ele('@w', 'gridCol')
|
|
1506
|
-
.att('@w', 'w', String(gridWidth));
|
|
1507
|
-
|
|
1508
|
-
const buildTableGrid = (vNode, attributes) => {
|
|
1509
|
-
const tableGridFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tblGrid');
|
|
1510
|
-
if (vNodeHasChildren(vNode)) {
|
|
1511
|
-
const gridColumns = vNode.children.filter((childVNode) => childVNode.tagName === 'col');
|
|
1512
|
-
const gridWidth = attributes.maximumWidth / gridColumns.length;
|
|
1513
|
-
|
|
1514
|
-
for (let index = 0; index < gridColumns.length; index++) {
|
|
1515
|
-
const tableGridColFragment = buildTableGridCol(gridWidth);
|
|
1516
|
-
tableGridFragment.import(tableGridColFragment);
|
|
1517
|
-
}
|
|
1518
|
-
}
|
|
1519
|
-
tableGridFragment.up();
|
|
1520
|
-
|
|
1521
|
-
return tableGridFragment;
|
|
1522
|
-
};
|
|
1523
|
-
|
|
1524
|
-
const buildTableGridFromTableRow = (vNode, attributes) => {
|
|
1525
|
-
const tableGridFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tblGrid');
|
|
1526
|
-
if (vNodeHasChildren(vNode)) {
|
|
1527
|
-
const numberOfGridColumns = vNode.children.reduce((accumulator, childVNode) => {
|
|
1528
|
-
const colSpan =
|
|
1529
|
-
childVNode.properties.colSpan ||
|
|
1530
|
-
(childVNode.properties.style && childVNode.properties.style['column-span']);
|
|
1531
|
-
|
|
1532
|
-
return accumulator + (colSpan ? parseInt(colSpan) : 1);
|
|
1533
|
-
}, 0);
|
|
1534
|
-
const gridWidth = attributes.maximumWidth / numberOfGridColumns;
|
|
1535
|
-
|
|
1536
|
-
for (let index = 0; index < numberOfGridColumns; index++) {
|
|
1537
|
-
const tableGridColFragment = buildTableGridCol(gridWidth);
|
|
1538
|
-
tableGridFragment.import(tableGridColFragment);
|
|
1539
|
-
}
|
|
1540
|
-
}
|
|
1541
|
-
tableGridFragment.up();
|
|
1542
|
-
|
|
1543
|
-
return tableGridFragment;
|
|
1544
|
-
};
|
|
1545
|
-
|
|
1546
|
-
const buildTableBorders = (tableBorder) => {
|
|
1547
|
-
const tableBordersFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele(
|
|
1548
|
-
'@w',
|
|
1549
|
-
'tblBorders'
|
|
1550
|
-
);
|
|
1551
|
-
|
|
1552
|
-
const { color, stroke, ...borders } = tableBorder;
|
|
1553
|
-
|
|
1554
|
-
Object.keys(borders).forEach((border) => {
|
|
1555
|
-
if (borders[border]) {
|
|
1556
|
-
const borderFragment = buildBorder(border, borders[border], 0, color, stroke);
|
|
1557
|
-
tableBordersFragment.import(borderFragment);
|
|
1558
|
-
}
|
|
1559
|
-
});
|
|
1560
|
-
|
|
1561
|
-
tableBordersFragment.up();
|
|
1562
|
-
|
|
1563
|
-
return tableBordersFragment;
|
|
1564
|
-
};
|
|
1565
|
-
|
|
1566
|
-
const buildTableWidth = (tableWidth) =>
|
|
1567
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
1568
|
-
.ele('@w', 'tblW')
|
|
1569
|
-
.att('@w', 'type', 'dxa')
|
|
1570
|
-
.att('@w', 'w', String(tableWidth))
|
|
1571
|
-
.up();
|
|
1572
|
-
|
|
1573
|
-
const buildCellMargin = (side, margin) =>
|
|
1574
|
-
fragment({ namespaceAlias: { w: namespaces.w } })
|
|
1575
|
-
.ele('@w', side)
|
|
1576
|
-
.att('@w', 'type', 'dxa')
|
|
1577
|
-
.att('@w', 'w', String(margin))
|
|
1578
|
-
.up();
|
|
1579
|
-
|
|
1580
|
-
const buildTableCellMargins = (margin) => {
|
|
1581
|
-
const tableCellMarFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele(
|
|
1582
|
-
'@w',
|
|
1583
|
-
'tblCellMar'
|
|
1584
|
-
);
|
|
1585
|
-
|
|
1586
|
-
['top', 'bottom'].forEach((side) => {
|
|
1587
|
-
const marginFragment = buildCellMargin(side, margin / 2);
|
|
1588
|
-
tableCellMarFragment.import(marginFragment);
|
|
1589
|
-
});
|
|
1590
|
-
['left', 'right'].forEach((side) => {
|
|
1591
|
-
const marginFragment = buildCellMargin(side, margin);
|
|
1592
|
-
tableCellMarFragment.import(marginFragment);
|
|
1593
|
-
});
|
|
1594
|
-
|
|
1595
|
-
return tableCellMarFragment;
|
|
1596
|
-
};
|
|
1597
|
-
|
|
1598
|
-
const buildTableProperties = (attributes) => {
|
|
1599
|
-
const tablePropertiesFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele(
|
|
1600
|
-
'@w',
|
|
1601
|
-
'tblPr'
|
|
1602
|
-
);
|
|
1603
|
-
|
|
1604
|
-
if (attributes && attributes.constructor === Object) {
|
|
1605
|
-
Object.keys(attributes).forEach((key) => {
|
|
1606
|
-
switch (key) {
|
|
1607
|
-
case 'tableBorder':
|
|
1608
|
-
const tableBordersFragment = buildTableBorders(attributes[key]);
|
|
1609
|
-
tablePropertiesFragment.import(tableBordersFragment);
|
|
1610
|
-
// eslint-disable-next-line no-param-reassign
|
|
1611
|
-
delete attributes.tableBorder;
|
|
1612
|
-
break;
|
|
1613
|
-
case 'tableCellSpacing':
|
|
1614
|
-
const tableCellSpacingFragment = buildTableCellSpacing(attributes[key]);
|
|
1615
|
-
tablePropertiesFragment.import(tableCellSpacingFragment);
|
|
1616
|
-
// eslint-disable-next-line no-param-reassign
|
|
1617
|
-
delete attributes.tableCellSpacing;
|
|
1618
|
-
break;
|
|
1619
|
-
case 'width':
|
|
1620
|
-
if (attributes[key]) {
|
|
1621
|
-
const tableWidthFragment = buildTableWidth(attributes[key]);
|
|
1622
|
-
tablePropertiesFragment.import(tableWidthFragment);
|
|
1623
|
-
}
|
|
1624
|
-
// eslint-disable-next-line no-param-reassign
|
|
1625
|
-
delete attributes.width;
|
|
1626
|
-
break;
|
|
1627
|
-
}
|
|
1628
|
-
});
|
|
1629
|
-
}
|
|
1630
|
-
const tableCellMarginFragment = buildTableCellMargins(160);
|
|
1631
|
-
tablePropertiesFragment.import(tableCellMarginFragment);
|
|
1632
|
-
|
|
1633
|
-
// by default, all tables are center aligned.
|
|
1634
|
-
const alignmentFragment = buildHorizontalAlignment('center');
|
|
1635
|
-
tablePropertiesFragment.import(alignmentFragment);
|
|
1636
|
-
|
|
1637
|
-
tablePropertiesFragment.up();
|
|
1638
|
-
|
|
1639
|
-
return tablePropertiesFragment;
|
|
1640
|
-
};
|
|
1641
|
-
|
|
1642
|
-
const cssBorderParser = (borderString) => {
|
|
1643
|
-
let [size, stroke, color] = borderString.split(' ');
|
|
1644
|
-
|
|
1645
|
-
if (pointRegex.test(size)) {
|
|
1646
|
-
const matchedParts = size.match(pointRegex);
|
|
1647
|
-
// convert point to eighth of a point
|
|
1648
|
-
size = pointToEIP(matchedParts[1]);
|
|
1649
|
-
} else if (pixelRegex.test(size)) {
|
|
1650
|
-
const matchedParts = size.match(pixelRegex);
|
|
1651
|
-
// convert pixels to eighth of a point
|
|
1652
|
-
size = pixelToEIP(matchedParts[1]);
|
|
1653
|
-
}
|
|
1654
|
-
stroke = stroke && ['dashed', 'dotted', 'double'].includes(stroke) ? stroke : 'single';
|
|
1655
|
-
|
|
1656
|
-
color = color && fixupColorCode(color).toUpperCase();
|
|
1657
|
-
|
|
1658
|
-
return [size, stroke, color];
|
|
1659
|
-
};
|
|
1660
|
-
|
|
1661
|
-
const buildTable = async (vNode, attributes, docxDocumentInstance) => {
|
|
1662
|
-
const tableFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'tbl');
|
|
1663
|
-
const modifiedAttributes = { ...attributes };
|
|
1664
|
-
if (isVNode(vNode) && vNode.properties) {
|
|
1665
|
-
const tableAttributes = vNode.properties.attributes || {};
|
|
1666
|
-
const tableStyles = vNode.properties.style || {};
|
|
1667
|
-
const tableBorders = {};
|
|
1668
|
-
const tableCellBorders = {};
|
|
1669
|
-
let [borderSize, borderStrike, borderColor] = [2, 'single', '000000'];
|
|
1670
|
-
|
|
1671
|
-
// eslint-disable-next-line no-restricted-globals
|
|
1672
|
-
if (!isNaN(tableAttributes.border)) {
|
|
1673
|
-
borderSize = parseInt(tableAttributes.border, 10);
|
|
1674
|
-
}
|
|
1675
|
-
|
|
1676
|
-
// css style overrides table border properties
|
|
1677
|
-
if (tableStyles.border) {
|
|
1678
|
-
const [cssSize, cssStroke, cssColor] = cssBorderParser(tableStyles.border);
|
|
1679
|
-
borderSize = cssSize || borderSize;
|
|
1680
|
-
borderColor = cssColor || borderColor;
|
|
1681
|
-
borderStrike = cssStroke || borderStrike;
|
|
1682
|
-
}
|
|
1683
|
-
|
|
1684
|
-
tableBorders.top = borderSize;
|
|
1685
|
-
tableBorders.bottom = borderSize;
|
|
1686
|
-
tableBorders.left = borderSize;
|
|
1687
|
-
tableBorders.right = borderSize;
|
|
1688
|
-
tableBorders.stroke = borderStrike;
|
|
1689
|
-
tableBorders.color = borderColor;
|
|
1690
|
-
|
|
1691
|
-
if (tableStyles['border-collapse'] === 'collapse') {
|
|
1692
|
-
tableBorders.insideV = borderSize;
|
|
1693
|
-
tableBorders.insideH = borderSize;
|
|
1694
|
-
} else {
|
|
1695
|
-
tableBorders.insideV = 0;
|
|
1696
|
-
tableBorders.insideH = 0;
|
|
1697
|
-
tableCellBorders.top = 1;
|
|
1698
|
-
tableCellBorders.bottom = 1;
|
|
1699
|
-
tableCellBorders.left = 1;
|
|
1700
|
-
tableCellBorders.right = 1;
|
|
1701
|
-
}
|
|
1702
|
-
|
|
1703
|
-
modifiedAttributes.tableBorder = tableBorders;
|
|
1704
|
-
modifiedAttributes.tableCellSpacing = 0;
|
|
1705
|
-
|
|
1706
|
-
if (Object.keys(tableCellBorders).length) {
|
|
1707
|
-
modifiedAttributes.tableCellBorder = tableCellBorders;
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
|
-
let minimumWidth;
|
|
1711
|
-
let maximumWidth;
|
|
1712
|
-
let width;
|
|
1713
|
-
// Calculate minimum width of table
|
|
1714
|
-
if (pixelRegex.test(tableStyles['min-width'])) {
|
|
1715
|
-
minimumWidth = pixelToTWIP(tableStyles['min-width'].match(pixelRegex)[1]);
|
|
1716
|
-
} else if (percentageRegex.test(tableStyles['min-width'])) {
|
|
1717
|
-
const percentageValue = tableStyles['min-width'].match(percentageRegex)[1];
|
|
1718
|
-
minimumWidth = Math.round((percentageValue / 100) * attributes.maximumWidth);
|
|
1719
|
-
}
|
|
1720
|
-
|
|
1721
|
-
// Calculate maximum width of table
|
|
1722
|
-
if (pixelRegex.test(tableStyles['max-width'])) {
|
|
1723
|
-
pixelRegex.lastIndex = 0;
|
|
1724
|
-
maximumWidth = pixelToTWIP(tableStyles['max-width'].match(pixelRegex)[1]);
|
|
1725
|
-
} else if (percentageRegex.test(tableStyles['max-width'])) {
|
|
1726
|
-
percentageRegex.lastIndex = 0;
|
|
1727
|
-
const percentageValue = tableStyles['max-width'].match(percentageRegex)[1];
|
|
1728
|
-
maximumWidth = Math.round((percentageValue / 100) * attributes.maximumWidth);
|
|
1729
|
-
}
|
|
1730
|
-
|
|
1731
|
-
// Calculate specified width of table
|
|
1732
|
-
if (pixelRegex.test(tableStyles.width)) {
|
|
1733
|
-
pixelRegex.lastIndex = 0;
|
|
1734
|
-
width = pixelToTWIP(tableStyles.width.match(pixelRegex)[1]);
|
|
1735
|
-
} else if (percentageRegex.test(tableStyles.width)) {
|
|
1736
|
-
percentageRegex.lastIndex = 0;
|
|
1737
|
-
const percentageValue = tableStyles.width.match(percentageRegex)[1];
|
|
1738
|
-
width = Math.round((percentageValue / 100) * attributes.maximumWidth);
|
|
1739
|
-
}
|
|
1740
|
-
|
|
1741
|
-
// If width isn't supplied, we should have min-width as the width.
|
|
1742
|
-
if (width) {
|
|
1743
|
-
modifiedAttributes.width = width;
|
|
1744
|
-
if (maximumWidth) {
|
|
1745
|
-
modifiedAttributes.width = Math.min(modifiedAttributes.width, maximumWidth);
|
|
1746
|
-
}
|
|
1747
|
-
if (minimumWidth) {
|
|
1748
|
-
modifiedAttributes.width = Math.max(modifiedAttributes.width, minimumWidth);
|
|
1749
|
-
}
|
|
1750
|
-
} else if (minimumWidth) {
|
|
1751
|
-
modifiedAttributes.width = minimumWidth;
|
|
1752
|
-
}
|
|
1753
|
-
if (modifiedAttributes.width) {
|
|
1754
|
-
modifiedAttributes.width = Math.min(modifiedAttributes.width, attributes.maximumWidth);
|
|
1755
|
-
}
|
|
1756
|
-
}
|
|
1757
|
-
const tablePropertiesFragment = buildTableProperties(modifiedAttributes);
|
|
1758
|
-
tableFragment.import(tablePropertiesFragment);
|
|
1759
|
-
|
|
1760
|
-
const rowSpanMap = new Map();
|
|
1761
|
-
|
|
1762
|
-
if (vNodeHasChildren(vNode)) {
|
|
1763
|
-
for (let index = 0; index < vNode.children.length; index++) {
|
|
1764
|
-
const childVNode = vNode.children[index];
|
|
1765
|
-
if (childVNode.tagName === 'colgroup') {
|
|
1766
|
-
const tableGridFragment = buildTableGrid(childVNode, modifiedAttributes);
|
|
1767
|
-
tableFragment.import(tableGridFragment);
|
|
1768
|
-
} else if (childVNode.tagName === 'thead') {
|
|
1769
|
-
for (let iteratorIndex = 0; iteratorIndex < childVNode.children.length; iteratorIndex++) {
|
|
1770
|
-
const grandChildVNode = childVNode.children[iteratorIndex];
|
|
1771
|
-
if (grandChildVNode.tagName === 'tr') {
|
|
1772
|
-
if (iteratorIndex === 0) {
|
|
1773
|
-
const tableGridFragment = buildTableGridFromTableRow(
|
|
1774
|
-
grandChildVNode,
|
|
1775
|
-
modifiedAttributes
|
|
1776
|
-
);
|
|
1777
|
-
tableFragment.import(tableGridFragment);
|
|
1778
|
-
}
|
|
1779
|
-
const tableRowFragment = await buildTableRow(
|
|
1780
|
-
grandChildVNode,
|
|
1781
|
-
modifiedAttributes,
|
|
1782
|
-
rowSpanMap,
|
|
1783
|
-
docxDocumentInstance
|
|
1784
|
-
);
|
|
1785
|
-
tableFragment.import(tableRowFragment);
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
} else if (childVNode.tagName === 'tbody') {
|
|
1789
|
-
for (let iteratorIndex = 0; iteratorIndex < childVNode.children.length; iteratorIndex++) {
|
|
1790
|
-
const grandChildVNode = childVNode.children[iteratorIndex];
|
|
1791
|
-
if (grandChildVNode.tagName === 'tr') {
|
|
1792
|
-
if (iteratorIndex === 0) {
|
|
1793
|
-
const tableGridFragment = buildTableGridFromTableRow(
|
|
1794
|
-
grandChildVNode,
|
|
1795
|
-
modifiedAttributes
|
|
1796
|
-
);
|
|
1797
|
-
tableFragment.import(tableGridFragment);
|
|
1798
|
-
}
|
|
1799
|
-
const tableRowFragment = await buildTableRow(
|
|
1800
|
-
grandChildVNode,
|
|
1801
|
-
modifiedAttributes,
|
|
1802
|
-
rowSpanMap,
|
|
1803
|
-
docxDocumentInstance
|
|
1804
|
-
);
|
|
1805
|
-
tableFragment.import(tableRowFragment);
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
} else if (childVNode.tagName === 'tr') {
|
|
1809
|
-
if (index === 0) {
|
|
1810
|
-
const tableGridFragment = buildTableGridFromTableRow(childVNode, modifiedAttributes);
|
|
1811
|
-
tableFragment.import(tableGridFragment);
|
|
1812
|
-
}
|
|
1813
|
-
const tableRowFragment = await buildTableRow(
|
|
1814
|
-
childVNode,
|
|
1815
|
-
modifiedAttributes,
|
|
1816
|
-
rowSpanMap,
|
|
1817
|
-
docxDocumentInstance
|
|
1818
|
-
);
|
|
1819
|
-
tableFragment.import(tableRowFragment);
|
|
1820
|
-
}
|
|
1821
|
-
}
|
|
1822
|
-
}
|
|
1823
|
-
tableFragment.up();
|
|
1824
|
-
|
|
1825
|
-
return tableFragment;
|
|
1826
|
-
};
|
|
1827
|
-
|
|
1828
|
-
const buildPresetGeometry = () =>
|
|
1829
|
-
fragment({ namespaceAlias: { a: namespaces.a } })
|
|
1830
|
-
.ele('@a', 'prstGeom')
|
|
1831
|
-
.att('prst', 'rect')
|
|
1832
|
-
.up();
|
|
1833
|
-
|
|
1834
|
-
const buildExtents = ({ width, height }) =>
|
|
1835
|
-
fragment({ namespaceAlias: { a: namespaces.a } })
|
|
1836
|
-
.ele('@a', 'ext')
|
|
1837
|
-
.att('cx', width)
|
|
1838
|
-
.att('cy', height)
|
|
1839
|
-
.up();
|
|
1840
|
-
|
|
1841
|
-
const buildOffset = () =>
|
|
1842
|
-
fragment({ namespaceAlias: { a: namespaces.a } })
|
|
1843
|
-
.ele('@a', 'off')
|
|
1844
|
-
.att('x', '0')
|
|
1845
|
-
.att('y', '0')
|
|
1846
|
-
.up();
|
|
1847
|
-
|
|
1848
|
-
const buildGraphicFrameTransform = (attributes) => {
|
|
1849
|
-
const graphicFrameTransformFragment = fragment({ namespaceAlias: { a: namespaces.a } }).ele(
|
|
1850
|
-
'@a',
|
|
1851
|
-
'xfrm'
|
|
1852
|
-
);
|
|
1853
|
-
|
|
1854
|
-
const offsetFragment = buildOffset();
|
|
1855
|
-
graphicFrameTransformFragment.import(offsetFragment);
|
|
1856
|
-
const extentsFragment = buildExtents(attributes);
|
|
1857
|
-
graphicFrameTransformFragment.import(extentsFragment);
|
|
1858
|
-
|
|
1859
|
-
graphicFrameTransformFragment.up();
|
|
1860
|
-
|
|
1861
|
-
return graphicFrameTransformFragment;
|
|
1862
|
-
};
|
|
1863
|
-
|
|
1864
|
-
const buildShapeProperties = (attributes) => {
|
|
1865
|
-
const shapeProperties = fragment({ namespaceAlias: { pic: namespaces.pic } }).ele('@pic', 'spPr');
|
|
1866
|
-
|
|
1867
|
-
const graphicFrameTransformFragment = buildGraphicFrameTransform(attributes);
|
|
1868
|
-
shapeProperties.import(graphicFrameTransformFragment);
|
|
1869
|
-
const presetGeometryFragment = buildPresetGeometry();
|
|
1870
|
-
shapeProperties.import(presetGeometryFragment);
|
|
1871
|
-
|
|
1872
|
-
shapeProperties.up();
|
|
1873
|
-
|
|
1874
|
-
return shapeProperties;
|
|
1875
|
-
};
|
|
1876
|
-
|
|
1877
|
-
const buildFillRect = () =>
|
|
1878
|
-
fragment({ namespaceAlias: { a: namespaces.a } })
|
|
1879
|
-
.ele('@a', 'fillRect')
|
|
1880
|
-
.up();
|
|
1881
|
-
|
|
1882
|
-
const buildStretch = () => {
|
|
1883
|
-
const stretchFragment = fragment({ namespaceAlias: { a: namespaces.a } }).ele('@a', 'stretch');
|
|
1884
|
-
|
|
1885
|
-
const fillRectFragment = buildFillRect();
|
|
1886
|
-
stretchFragment.import(fillRectFragment);
|
|
1887
|
-
|
|
1888
|
-
stretchFragment.up();
|
|
1889
|
-
|
|
1890
|
-
return stretchFragment;
|
|
1891
|
-
};
|
|
1892
|
-
|
|
1893
|
-
const buildSrcRectFragment = () =>
|
|
1894
|
-
fragment({ namespaceAlias: { a: namespaces.a } })
|
|
1895
|
-
.ele('@a', 'srcRect')
|
|
1896
|
-
.att('b', '0')
|
|
1897
|
-
.att('l', '0')
|
|
1898
|
-
.att('r', '0')
|
|
1899
|
-
.att('t', '0')
|
|
1900
|
-
.up();
|
|
1901
|
-
|
|
1902
|
-
const buildBinaryLargeImageOrPicture = (relationshipId) =>
|
|
1903
|
-
fragment({
|
|
1904
|
-
namespaceAlias: { a: namespaces.a, r: namespaces.r },
|
|
1905
|
-
})
|
|
1906
|
-
.ele('@a', 'blip')
|
|
1907
|
-
.att('@r', 'embed', `rId${relationshipId}`)
|
|
1908
|
-
// FIXME: possible values 'email', 'none', 'print', 'hqprint', 'screen'
|
|
1909
|
-
.att('cstate', 'print')
|
|
1910
|
-
.up();
|
|
1911
|
-
|
|
1912
|
-
const buildBinaryLargeImageOrPictureFill = (relationshipId) => {
|
|
1913
|
-
const binaryLargeImageOrPictureFillFragment = fragment({
|
|
1914
|
-
namespaceAlias: { pic: namespaces.pic },
|
|
1915
|
-
}).ele('@pic', 'blipFill');
|
|
1916
|
-
const binaryLargeImageOrPictureFragment = buildBinaryLargeImageOrPicture(relationshipId);
|
|
1917
|
-
binaryLargeImageOrPictureFillFragment.import(binaryLargeImageOrPictureFragment);
|
|
1918
|
-
const srcRectFragment = buildSrcRectFragment();
|
|
1919
|
-
binaryLargeImageOrPictureFillFragment.import(srcRectFragment);
|
|
1920
|
-
const stretchFragment = buildStretch();
|
|
1921
|
-
binaryLargeImageOrPictureFillFragment.import(stretchFragment);
|
|
1922
|
-
|
|
1923
|
-
binaryLargeImageOrPictureFillFragment.up();
|
|
1924
|
-
|
|
1925
|
-
return binaryLargeImageOrPictureFillFragment;
|
|
1926
|
-
};
|
|
1927
|
-
|
|
1928
|
-
const buildNonVisualPictureDrawingProperties = () =>
|
|
1929
|
-
fragment({ namespaceAlias: { pic: namespaces.pic } })
|
|
1930
|
-
.ele('@pic', 'cNvPicPr')
|
|
1931
|
-
.up();
|
|
1932
|
-
|
|
1933
|
-
const buildNonVisualDrawingProperties = (
|
|
1934
|
-
pictureId,
|
|
1935
|
-
pictureNameWithExtension,
|
|
1936
|
-
pictureDescription = ''
|
|
1937
|
-
) =>
|
|
1938
|
-
fragment({ namespaceAlias: { pic: namespaces.pic } })
|
|
1939
|
-
.ele('@pic', 'cNvPr')
|
|
1940
|
-
.att('id', pictureId)
|
|
1941
|
-
.att('name', pictureNameWithExtension)
|
|
1942
|
-
.att('descr', pictureDescription)
|
|
1943
|
-
.up();
|
|
1944
|
-
|
|
1945
|
-
const buildNonVisualPictureProperties = (
|
|
1946
|
-
pictureId,
|
|
1947
|
-
pictureNameWithExtension,
|
|
1948
|
-
pictureDescription
|
|
1949
|
-
) => {
|
|
1950
|
-
const nonVisualPicturePropertiesFragment = fragment({
|
|
1951
|
-
namespaceAlias: { pic: namespaces.pic },
|
|
1952
|
-
}).ele('@pic', 'nvPicPr');
|
|
1953
|
-
// TODO: Handle picture attributes
|
|
1954
|
-
const nonVisualDrawingPropertiesFragment = buildNonVisualDrawingProperties(
|
|
1955
|
-
pictureId,
|
|
1956
|
-
pictureNameWithExtension,
|
|
1957
|
-
pictureDescription
|
|
1958
|
-
);
|
|
1959
|
-
nonVisualPicturePropertiesFragment.import(nonVisualDrawingPropertiesFragment);
|
|
1960
|
-
const nonVisualPictureDrawingPropertiesFragment = buildNonVisualPictureDrawingProperties();
|
|
1961
|
-
nonVisualPicturePropertiesFragment.import(nonVisualPictureDrawingPropertiesFragment);
|
|
1962
|
-
nonVisualPicturePropertiesFragment.up();
|
|
1963
|
-
|
|
1964
|
-
return nonVisualPicturePropertiesFragment;
|
|
1965
|
-
};
|
|
1966
|
-
|
|
1967
|
-
const buildPicture = ({
|
|
1968
|
-
id,
|
|
1969
|
-
fileNameWithExtension,
|
|
1970
|
-
description,
|
|
1971
|
-
relationshipId,
|
|
1972
|
-
width,
|
|
1973
|
-
height,
|
|
1974
|
-
}) => {
|
|
1975
|
-
const pictureFragment = fragment({ namespaceAlias: { pic: namespaces.pic } }).ele('@pic', 'pic');
|
|
1976
|
-
const nonVisualPicturePropertiesFragment = buildNonVisualPictureProperties(
|
|
1977
|
-
id,
|
|
1978
|
-
fileNameWithExtension,
|
|
1979
|
-
description
|
|
1980
|
-
);
|
|
1981
|
-
pictureFragment.import(nonVisualPicturePropertiesFragment);
|
|
1982
|
-
const binaryLargeImageOrPictureFill = buildBinaryLargeImageOrPictureFill(relationshipId);
|
|
1983
|
-
pictureFragment.import(binaryLargeImageOrPictureFill);
|
|
1984
|
-
const shapeProperties = buildShapeProperties({ width, height });
|
|
1985
|
-
pictureFragment.import(shapeProperties);
|
|
1986
|
-
pictureFragment.up();
|
|
1987
|
-
|
|
1988
|
-
return pictureFragment;
|
|
1989
|
-
};
|
|
1990
|
-
|
|
1991
|
-
const buildGraphicData = (graphicType, attributes) => {
|
|
1992
|
-
const graphicDataFragment = fragment({ namespaceAlias: { a: namespaces.a } })
|
|
1993
|
-
.ele('@a', 'graphicData')
|
|
1994
|
-
.att('uri', 'http://schemas.openxmlformats.org/drawingml/2006/picture');
|
|
1995
|
-
if (graphicType === 'picture') {
|
|
1996
|
-
const pictureFragment = buildPicture(attributes);
|
|
1997
|
-
graphicDataFragment.import(pictureFragment);
|
|
1998
|
-
}
|
|
1999
|
-
graphicDataFragment.up();
|
|
2000
|
-
|
|
2001
|
-
return graphicDataFragment;
|
|
2002
|
-
};
|
|
2003
|
-
|
|
2004
|
-
const buildGraphic = (graphicType, attributes) => {
|
|
2005
|
-
const graphicFragment = fragment({ namespaceAlias: { a: namespaces.a } }).ele('@a', 'graphic');
|
|
2006
|
-
// TODO: Handle drawing type
|
|
2007
|
-
const graphicDataFragment = buildGraphicData(graphicType, attributes);
|
|
2008
|
-
graphicFragment.import(graphicDataFragment);
|
|
2009
|
-
graphicFragment.up();
|
|
2010
|
-
|
|
2011
|
-
return graphicFragment;
|
|
2012
|
-
};
|
|
2013
|
-
|
|
2014
|
-
const buildDrawingObjectNonVisualProperties = (pictureId, pictureName) =>
|
|
2015
|
-
fragment({ namespaceAlias: { wp: namespaces.wp } })
|
|
2016
|
-
.ele('@wp', 'docPr')
|
|
2017
|
-
.att('id', pictureId)
|
|
2018
|
-
.att('name', pictureName)
|
|
2019
|
-
.up();
|
|
2020
|
-
|
|
2021
|
-
const buildWrapSquare = () =>
|
|
2022
|
-
fragment({ namespaceAlias: { wp: namespaces.wp } })
|
|
2023
|
-
.ele('@wp', 'wrapSquare')
|
|
2024
|
-
.att('wrapText', 'bothSides')
|
|
2025
|
-
.att('distB', '228600')
|
|
2026
|
-
.att('distT', '228600')
|
|
2027
|
-
.att('distL', '228600')
|
|
2028
|
-
.att('distR', '228600')
|
|
2029
|
-
.up();
|
|
2030
|
-
|
|
2031
|
-
// eslint-disable-next-line no-unused-vars
|
|
2032
|
-
const buildWrapNone = () =>
|
|
2033
|
-
fragment({ namespaceAlias: { wp: namespaces.wp } })
|
|
2034
|
-
.ele('@wp', 'wrapNone')
|
|
2035
|
-
.up();
|
|
2036
|
-
|
|
2037
|
-
const buildEffectExtentFragment = () =>
|
|
2038
|
-
fragment({ namespaceAlias: { wp: namespaces.wp } })
|
|
2039
|
-
.ele('@wp', 'effectExtent')
|
|
2040
|
-
.att('b', '0')
|
|
2041
|
-
.att('l', '0')
|
|
2042
|
-
.att('r', '0')
|
|
2043
|
-
.att('t', '0')
|
|
2044
|
-
.up();
|
|
2045
|
-
|
|
2046
|
-
const buildExtent = ({ width, height }) =>
|
|
2047
|
-
fragment({ namespaceAlias: { wp: namespaces.wp } })
|
|
2048
|
-
.ele('@wp', 'extent')
|
|
2049
|
-
.att('cx', width)
|
|
2050
|
-
.att('cy', height)
|
|
2051
|
-
.up();
|
|
2052
|
-
|
|
2053
|
-
const buildPositionV = () =>
|
|
2054
|
-
fragment({ namespaceAlias: { wp: namespaces.wp } })
|
|
2055
|
-
.ele('@wp', 'positionV')
|
|
2056
|
-
.att('relativeFrom', 'paragraph')
|
|
2057
|
-
.ele('@wp', 'posOffset')
|
|
2058
|
-
.txt('19050')
|
|
2059
|
-
.up()
|
|
2060
|
-
.up();
|
|
2061
|
-
|
|
2062
|
-
const buildPositionH = () =>
|
|
2063
|
-
fragment({ namespaceAlias: { wp: namespaces.wp } })
|
|
2064
|
-
.ele('@wp', 'positionH')
|
|
2065
|
-
.att('relativeFrom', 'column')
|
|
2066
|
-
.ele('@wp', 'posOffset')
|
|
2067
|
-
.txt('19050')
|
|
2068
|
-
.up()
|
|
2069
|
-
.up();
|
|
2070
|
-
|
|
2071
|
-
const buildSimplePos = () =>
|
|
2072
|
-
fragment({ namespaceAlias: { wp: namespaces.wp } })
|
|
2073
|
-
.ele('@wp', 'simplePos')
|
|
2074
|
-
.att('x', '0')
|
|
2075
|
-
.att('y', '0')
|
|
2076
|
-
.up();
|
|
2077
|
-
|
|
2078
|
-
const buildAnchoredDrawing = (graphicType, attributes) => {
|
|
2079
|
-
const anchoredDrawingFragment = fragment({ namespaceAlias: { wp: namespaces.wp } })
|
|
2080
|
-
.ele('@wp', 'anchor')
|
|
2081
|
-
.att('distB', '0')
|
|
2082
|
-
.att('distL', '0')
|
|
2083
|
-
.att('distR', '0')
|
|
2084
|
-
.att('distT', '0')
|
|
2085
|
-
.att('relativeHeight', '0')
|
|
2086
|
-
.att('behindDoc', 'false')
|
|
2087
|
-
.att('locked', 'true')
|
|
2088
|
-
.att('layoutInCell', 'true')
|
|
2089
|
-
.att('allowOverlap', 'false')
|
|
2090
|
-
.att('simplePos', 'false');
|
|
2091
|
-
// Even though simplePos isnt supported by Word 2007 simplePos is required.
|
|
2092
|
-
const simplePosFragment = buildSimplePos();
|
|
2093
|
-
anchoredDrawingFragment.import(simplePosFragment);
|
|
2094
|
-
const positionHFragment = buildPositionH();
|
|
2095
|
-
anchoredDrawingFragment.import(positionHFragment);
|
|
2096
|
-
const positionVFragment = buildPositionV();
|
|
2097
|
-
anchoredDrawingFragment.import(positionVFragment);
|
|
2098
|
-
const extentFragment = buildExtent({ width: attributes.width, height: attributes.height });
|
|
2099
|
-
anchoredDrawingFragment.import(extentFragment);
|
|
2100
|
-
const effectExtentFragment = buildEffectExtentFragment();
|
|
2101
|
-
anchoredDrawingFragment.import(effectExtentFragment);
|
|
2102
|
-
const wrapSquareFragment = buildWrapSquare();
|
|
2103
|
-
anchoredDrawingFragment.import(wrapSquareFragment);
|
|
2104
|
-
const drawingObjectNonVisualPropertiesFragment = buildDrawingObjectNonVisualProperties(
|
|
2105
|
-
attributes.id,
|
|
2106
|
-
attributes.fileNameWithExtension
|
|
2107
|
-
);
|
|
2108
|
-
anchoredDrawingFragment.import(drawingObjectNonVisualPropertiesFragment);
|
|
2109
|
-
const graphicFragment = buildGraphic(graphicType, attributes);
|
|
2110
|
-
anchoredDrawingFragment.import(graphicFragment);
|
|
2111
|
-
|
|
2112
|
-
anchoredDrawingFragment.up();
|
|
2113
|
-
|
|
2114
|
-
return anchoredDrawingFragment;
|
|
2115
|
-
};
|
|
2116
|
-
|
|
2117
|
-
const buildInlineDrawing = (graphicType, attributes) => {
|
|
2118
|
-
const inlineDrawingFragment = fragment({ namespaceAlias: { wp: namespaces.wp } })
|
|
2119
|
-
.ele('@wp', 'inline')
|
|
2120
|
-
.att('distB', '0')
|
|
2121
|
-
.att('distL', '0')
|
|
2122
|
-
.att('distR', '0')
|
|
2123
|
-
.att('distT', '0');
|
|
2124
|
-
|
|
2125
|
-
const extentFragment = buildExtent({ width: attributes.width, height: attributes.height });
|
|
2126
|
-
inlineDrawingFragment.import(extentFragment);
|
|
2127
|
-
const effectExtentFragment = buildEffectExtentFragment();
|
|
2128
|
-
inlineDrawingFragment.import(effectExtentFragment);
|
|
2129
|
-
const drawingObjectNonVisualPropertiesFragment = buildDrawingObjectNonVisualProperties(
|
|
2130
|
-
attributes.id,
|
|
2131
|
-
attributes.fileNameWithExtension
|
|
2132
|
-
);
|
|
2133
|
-
inlineDrawingFragment.import(drawingObjectNonVisualPropertiesFragment);
|
|
2134
|
-
const graphicFragment = buildGraphic(graphicType, attributes);
|
|
2135
|
-
inlineDrawingFragment.import(graphicFragment);
|
|
2136
|
-
|
|
2137
|
-
inlineDrawingFragment.up();
|
|
2138
|
-
|
|
2139
|
-
return inlineDrawingFragment;
|
|
2140
|
-
};
|
|
2141
|
-
|
|
2142
|
-
const buildDrawing = (inlineOrAnchored = false, graphicType, attributes) => {
|
|
2143
|
-
const drawingFragment = fragment({ namespaceAlias: { w: namespaces.w } }).ele('@w', 'drawing');
|
|
2144
|
-
const inlineOrAnchoredDrawingFragment = inlineOrAnchored
|
|
2145
|
-
? buildInlineDrawing(graphicType, attributes)
|
|
2146
|
-
: buildAnchoredDrawing(graphicType, attributes);
|
|
2147
|
-
drawingFragment.import(inlineOrAnchoredDrawingFragment);
|
|
2148
|
-
drawingFragment.up();
|
|
2149
|
-
|
|
2150
|
-
return drawingFragment;
|
|
2151
|
-
};
|
|
2152
|
-
|
|
2153
|
-
export {
|
|
2154
|
-
buildParagraph,
|
|
2155
|
-
buildTable,
|
|
2156
|
-
buildNumberingInstances,
|
|
2157
|
-
buildLineBreak,
|
|
2158
|
-
buildIndentation,
|
|
2159
|
-
buildTextElement,
|
|
2160
|
-
buildBold,
|
|
2161
|
-
buildItalics,
|
|
2162
|
-
buildUnderline,
|
|
2163
|
-
buildDrawing,
|
|
2164
|
-
fixupLineHeight,
|
|
2165
|
-
};
|