easy-template-x 3.2.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -1
- package/dist/cjs/easy-template-x.js +150 -95
- package/dist/es/easy-template-x.js +144 -86
- package/dist/types/compilation/delimiterMark.d.ts +6 -6
- package/dist/types/compilation/delimiterSearcher.d.ts +16 -16
- package/dist/types/compilation/index.d.ts +7 -7
- package/dist/types/compilation/scopeData.d.ts +21 -21
- package/dist/types/compilation/tag.d.ts +14 -12
- package/dist/types/compilation/tagParser.d.ts +13 -13
- package/dist/types/compilation/templateCompiler.d.ts +25 -25
- package/dist/types/compilation/templateContext.d.ts +5 -5
- package/dist/types/delimiters.d.ts +10 -8
- package/dist/types/errors/index.d.ts +11 -10
- package/dist/types/errors/malformedFileError.d.ts +4 -4
- package/dist/types/errors/maxXmlDepthError.d.ts +4 -4
- package/dist/types/errors/missingArgumentError.d.ts +4 -4
- package/dist/types/errors/missingCloseDelimiterError.d.ts +4 -4
- package/dist/types/errors/missingStartDelimiterError.d.ts +4 -4
- package/dist/types/errors/tagOptionsParseError.d.ts +5 -0
- package/dist/types/errors/unclosedTagError.d.ts +4 -4
- package/dist/types/errors/unidentifiedFileTypeError.d.ts +3 -3
- package/dist/types/errors/unknownContentTypeError.d.ts +6 -6
- package/dist/types/errors/unopenedTagError.d.ts +4 -4
- package/dist/types/errors/unsupportedFileTypeError.d.ts +4 -4
- package/dist/types/extensions/extensionOptions.d.ts +5 -5
- package/dist/types/extensions/index.d.ts +2 -2
- package/dist/types/extensions/templateExtension.d.ts +14 -14
- package/dist/types/index.d.ts +13 -13
- package/dist/types/mimeType.d.ts +11 -11
- package/dist/types/office/contentPartType.d.ts +9 -9
- package/dist/types/office/contentTypesFile.d.ts +16 -16
- package/dist/types/office/docx.d.ts +28 -28
- package/dist/types/office/docxParser.d.ts +35 -35
- package/dist/types/office/index.d.ts +4 -4
- package/dist/types/office/mediaFiles.d.ts +14 -14
- package/dist/types/office/relationship.d.ts +11 -11
- package/dist/types/office/rels.d.ts +20 -20
- package/dist/types/office/xmlPart.d.ts +14 -14
- package/dist/types/plugins/defaultPlugins.d.ts +2 -2
- package/dist/types/plugins/image/imageContent.d.ts +12 -12
- package/dist/types/plugins/image/imagePlugin.d.ts +10 -10
- package/dist/types/plugins/image/index.d.ts +2 -2
- package/dist/types/plugins/index.d.ts +8 -8
- package/dist/types/plugins/link/index.d.ts +2 -2
- package/dist/types/plugins/link/linkContent.d.ts +7 -7
- package/dist/types/plugins/link/linkPlugin.d.ts +9 -9
- package/dist/types/plugins/loop/index.d.ts +1 -1
- package/dist/types/plugins/loop/loopPlugin.d.ts +13 -13
- package/dist/types/plugins/loop/loopTagOptions.d.ts +7 -0
- package/dist/types/plugins/loop/strategy/iLoopStrategy.d.ts +14 -14
- package/dist/types/plugins/loop/strategy/index.d.ts +4 -4
- package/dist/types/plugins/loop/strategy/loopListStrategy.d.ts +11 -11
- package/dist/types/plugins/loop/strategy/loopParagraphStrategy.d.ts +11 -11
- package/dist/types/plugins/loop/strategy/loopTableStrategy.d.ts +11 -11
- package/dist/types/plugins/pluginContent.d.ts +6 -6
- package/dist/types/plugins/rawXml/index.d.ts +2 -2
- package/dist/types/plugins/rawXml/rawXmlContent.d.ts +6 -6
- package/dist/types/plugins/rawXml/rawXmlPlugin.d.ts +6 -6
- package/dist/types/plugins/templatePlugin.d.ts +15 -15
- package/dist/types/plugins/text/index.d.ts +1 -1
- package/dist/types/plugins/text/textPlugin.d.ts +11 -11
- package/dist/types/templateData.d.ts +6 -6
- package/dist/types/templateHandler.d.ts +20 -20
- package/dist/types/templateHandlerOptions.d.ts +15 -15
- package/dist/types/types.d.ts +4 -6
- package/dist/types/utils/array.d.ts +6 -6
- package/dist/types/utils/base64.d.ts +3 -3
- package/dist/types/utils/binary.d.ts +11 -12
- package/dist/types/utils/index.d.ts +9 -9
- package/dist/types/utils/number.d.ts +1 -1
- package/dist/types/utils/path.d.ts +5 -5
- package/dist/types/utils/regex.d.ts +3 -3
- package/dist/types/utils/sha1.d.ts +1 -1
- package/dist/types/utils/txt.d.ts +2 -1
- package/dist/types/utils/types.d.ts +3 -3
- package/dist/types/xml/index.d.ts +3 -3
- package/dist/types/xml/xmlDepthTracker.d.ts +7 -7
- package/dist/types/xml/xmlNode.d.ts +58 -58
- package/dist/types/xml/xmlParser.d.ts +8 -8
- package/dist/types/zip/index.d.ts +2 -2
- package/dist/types/zip/jsZipHelper.d.ts +7 -7
- package/dist/types/zip/zip.d.ts +13 -13
- package/dist/types/zip/zipObject.d.ts +13 -13
- package/package.json +24 -19
- package/src/compilation/tag.ts +4 -2
- package/src/compilation/tagParser.ts +32 -13
- package/src/delimiters.ts +3 -1
- package/src/errors/index.ts +1 -0
- package/src/errors/malformedFileError.ts +1 -4
- package/src/errors/maxXmlDepthError.ts +1 -4
- package/src/errors/missingArgumentError.ts +1 -4
- package/src/errors/missingCloseDelimiterError.ts +1 -4
- package/src/errors/missingStartDelimiterError.ts +1 -4
- package/src/errors/tagOptionsParseError.ts +12 -0
- package/src/errors/unclosedTagError.ts +1 -4
- package/src/errors/unidentifiedFileTypeError.ts +1 -4
- package/src/errors/unknownContentTypeError.ts +1 -4
- package/src/errors/unopenedTagError.ts +1 -4
- package/src/errors/unsupportedFileTypeError.ts +1 -4
- package/src/plugins/loop/loopPlugin.ts +1 -1
- package/src/plugins/loop/loopTagOptions.ts +14 -0
- package/src/plugins/loop/strategy/loopTableStrategy.ts +22 -3
- package/src/plugins/templatePlugin.ts +0 -2
- package/src/types.ts +1 -3
- package/src/utils/txt.ts +29 -1
- package/src/xml/xmlNode.ts +8 -4
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ Generate docx documents from templates, in Node or in the browser.
|
|
|
14
14
|
- [Loop plugin](#loop-plugin)
|
|
15
15
|
- [Conditions](#conditions)
|
|
16
16
|
- [Nested Conditions](#nested-conditions)
|
|
17
|
+
- [Controlling loop behavior](#controlling-loop-behavior)
|
|
17
18
|
- [Image plugin](#image-plugin)
|
|
18
19
|
- [Link plugin](#link-plugin)
|
|
19
20
|
- [Raw xml plugin](#raw-xml-plugin)
|
|
@@ -253,6 +254,39 @@ Output document:
|
|
|
253
254
|
|
|
254
255
|
_If you are looking for a yet more powerful conditional syntax see the [alternative syntax](#advanced-syntax-and-custom-resolvers) section._
|
|
255
256
|
|
|
257
|
+
#### Controlling loop behavior
|
|
258
|
+
|
|
259
|
+
To control the loop (or condition) behavior you can use the `loopOver` option.
|
|
260
|
+
|
|
261
|
+
Given this data:
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
{
|
|
265
|
+
students: [
|
|
266
|
+
{ name: "Alice" },
|
|
267
|
+
{ name: "Bob" }
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
You can use either this template:
|
|
273
|
+
|
|
274
|
+

|
|
275
|
+
|
|
276
|
+
Or this one:
|
|
277
|
+
|
|
278
|
+

|
|
279
|
+
|
|
280
|
+
The first will produce this document:
|
|
281
|
+
|
|
282
|
+

|
|
283
|
+
|
|
284
|
+
And the second will produce this one:
|
|
285
|
+
|
|
286
|
+

|
|
287
|
+
|
|
288
|
+
By default `easy-template-x` will loop over "content" if the opening and closing loop tags are in the same table cell and "row" otherwise.
|
|
289
|
+
|
|
256
290
|
### Image plugin
|
|
257
291
|
|
|
258
292
|
Embed images into the document.
|
|
@@ -480,7 +514,9 @@ const handler = new TemplateHandler({
|
|
|
480
514
|
tagStart: "{",
|
|
481
515
|
tagEnd: "}",
|
|
482
516
|
containerTagOpen: "#",
|
|
483
|
-
containerTagClose: "/"
|
|
517
|
+
containerTagClose: "/",
|
|
518
|
+
tagOptionsStart: "[",
|
|
519
|
+
tagOptionsEnd: "]"
|
|
484
520
|
},
|
|
485
521
|
|
|
486
522
|
maxXmlDepth: 20,
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var xmldom = require('@xmldom/xmldom');
|
|
6
4
|
var getProp = require('lodash.get');
|
|
5
|
+
var JSON5 = require('json5');
|
|
7
6
|
var JSZip = require('jszip');
|
|
8
7
|
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
function _interopNamespace(e) {
|
|
12
|
-
if (e && e.__esModule) return e;
|
|
8
|
+
function _interopNamespaceDefault(e) {
|
|
13
9
|
var n = Object.create(null);
|
|
14
10
|
if (e) {
|
|
15
11
|
Object.keys(e).forEach(function (k) {
|
|
@@ -22,40 +18,34 @@ function _interopNamespace(e) {
|
|
|
22
18
|
}
|
|
23
19
|
});
|
|
24
20
|
}
|
|
25
|
-
n
|
|
21
|
+
n.default = e;
|
|
26
22
|
return Object.freeze(n);
|
|
27
23
|
}
|
|
28
24
|
|
|
29
|
-
var
|
|
30
|
-
var JSZip__namespace = /*#__PURE__*/
|
|
25
|
+
var JSON5__namespace = /*#__PURE__*/_interopNamespaceDefault(JSON5);
|
|
26
|
+
var JSZip__namespace = /*#__PURE__*/_interopNamespaceDefault(JSZip);
|
|
31
27
|
|
|
32
|
-
function _defineProperty(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
writable: true
|
|
40
|
-
});
|
|
41
|
-
} else {
|
|
42
|
-
obj[key] = value;
|
|
43
|
-
}
|
|
44
|
-
return obj;
|
|
28
|
+
function _defineProperty(e, r, t) {
|
|
29
|
+
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
30
|
+
value: t,
|
|
31
|
+
enumerable: !0,
|
|
32
|
+
configurable: !0,
|
|
33
|
+
writable: !0
|
|
34
|
+
}) : e[r] = t, e;
|
|
45
35
|
}
|
|
46
|
-
function _toPrimitive(
|
|
47
|
-
if (
|
|
48
|
-
var
|
|
49
|
-
if (
|
|
50
|
-
var
|
|
51
|
-
if (
|
|
36
|
+
function _toPrimitive(t, r) {
|
|
37
|
+
if ("object" != typeof t || !t) return t;
|
|
38
|
+
var e = t[Symbol.toPrimitive];
|
|
39
|
+
if (void 0 !== e) {
|
|
40
|
+
var i = e.call(t, r || "default");
|
|
41
|
+
if ("object" != typeof i) return i;
|
|
52
42
|
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
53
43
|
}
|
|
54
|
-
return (
|
|
44
|
+
return ("string" === r ? String : Number)(t);
|
|
55
45
|
}
|
|
56
|
-
function _toPropertyKey(
|
|
57
|
-
var
|
|
58
|
-
return
|
|
46
|
+
function _toPropertyKey(t) {
|
|
47
|
+
var i = _toPrimitive(t, "string");
|
|
48
|
+
return "symbol" == typeof i ? i : i + "";
|
|
59
49
|
}
|
|
60
50
|
|
|
61
51
|
class MalformedFileError extends Error {
|
|
@@ -63,9 +53,6 @@ class MalformedFileError extends Error {
|
|
|
63
53
|
super(`Malformed file detected. Make sure the file is a valid ${expectedFileType} file.`);
|
|
64
54
|
_defineProperty(this, "expectedFileType", void 0);
|
|
65
55
|
this.expectedFileType = expectedFileType;
|
|
66
|
-
|
|
67
|
-
// typescript hack: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
68
|
-
Object.setPrototypeOf(this, MalformedFileError.prototype);
|
|
69
56
|
}
|
|
70
57
|
}
|
|
71
58
|
|
|
@@ -74,9 +61,6 @@ class MaxXmlDepthError extends Error {
|
|
|
74
61
|
super(`XML maximum depth reached (max depth: ${maxDepth}).`);
|
|
75
62
|
_defineProperty(this, "maxDepth", void 0);
|
|
76
63
|
this.maxDepth = maxDepth;
|
|
77
|
-
|
|
78
|
-
// typescript hack: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
79
|
-
Object.setPrototypeOf(this, MaxXmlDepthError.prototype);
|
|
80
64
|
}
|
|
81
65
|
}
|
|
82
66
|
|
|
@@ -85,9 +69,6 @@ class MissingArgumentError extends Error {
|
|
|
85
69
|
super(`Argument '${argName}' is missing.`);
|
|
86
70
|
_defineProperty(this, "argName", void 0);
|
|
87
71
|
this.argName = argName;
|
|
88
|
-
|
|
89
|
-
// typescript hack: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
90
|
-
Object.setPrototypeOf(this, MissingArgumentError.prototype);
|
|
91
72
|
}
|
|
92
73
|
}
|
|
93
74
|
|
|
@@ -96,9 +77,6 @@ class MissingCloseDelimiterError extends Error {
|
|
|
96
77
|
super(`Close delimiter is missing from '${openDelimiterText}'.`);
|
|
97
78
|
_defineProperty(this, "openDelimiterText", void 0);
|
|
98
79
|
this.openDelimiterText = openDelimiterText;
|
|
99
|
-
|
|
100
|
-
// typescript hack: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
101
|
-
Object.setPrototypeOf(this, MissingCloseDelimiterError.prototype);
|
|
102
80
|
}
|
|
103
81
|
}
|
|
104
82
|
|
|
@@ -107,9 +85,16 @@ class MissingStartDelimiterError extends Error {
|
|
|
107
85
|
super(`Open delimiter is missing from '${closeDelimiterText}'.`);
|
|
108
86
|
_defineProperty(this, "closeDelimiterText", void 0);
|
|
109
87
|
this.closeDelimiterText = closeDelimiterText;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
110
90
|
|
|
111
|
-
|
|
112
|
-
|
|
91
|
+
class TagOptionsParseError extends Error {
|
|
92
|
+
constructor(tagRawText, parseError) {
|
|
93
|
+
super(`Failed to parse tag options of '${tagRawText}': ${parseError.message}.`);
|
|
94
|
+
_defineProperty(this, "tagRawText", void 0);
|
|
95
|
+
_defineProperty(this, "parseError", void 0);
|
|
96
|
+
this.tagRawText = tagRawText;
|
|
97
|
+
this.parseError = parseError;
|
|
113
98
|
}
|
|
114
99
|
}
|
|
115
100
|
|
|
@@ -118,18 +103,12 @@ class UnclosedTagError extends Error {
|
|
|
118
103
|
super(`Tag '${tagName}' is never closed.`);
|
|
119
104
|
_defineProperty(this, "tagName", void 0);
|
|
120
105
|
this.tagName = tagName;
|
|
121
|
-
|
|
122
|
-
// typescript hack: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
123
|
-
Object.setPrototypeOf(this, UnclosedTagError.prototype);
|
|
124
106
|
}
|
|
125
107
|
}
|
|
126
108
|
|
|
127
109
|
class UnidentifiedFileTypeError extends Error {
|
|
128
110
|
constructor() {
|
|
129
111
|
super(`The filetype for this file could not be identified, is this file corrupted?`);
|
|
130
|
-
|
|
131
|
-
// typescript hack: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
132
|
-
Object.setPrototypeOf(this, UnidentifiedFileTypeError.prototype);
|
|
133
112
|
}
|
|
134
113
|
}
|
|
135
114
|
|
|
@@ -142,9 +121,6 @@ class UnknownContentTypeError extends Error {
|
|
|
142
121
|
this.contentType = contentType;
|
|
143
122
|
this.tagRawText = tagRawText;
|
|
144
123
|
this.path = path;
|
|
145
|
-
|
|
146
|
-
// typescript hack: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
147
|
-
Object.setPrototypeOf(this, UnknownContentTypeError.prototype);
|
|
148
124
|
}
|
|
149
125
|
}
|
|
150
126
|
|
|
@@ -153,9 +129,6 @@ class UnopenedTagError extends Error {
|
|
|
153
129
|
super(`Tag '${tagName}' is closed but was never opened.`);
|
|
154
130
|
_defineProperty(this, "tagName", void 0);
|
|
155
131
|
this.tagName = tagName;
|
|
156
|
-
|
|
157
|
-
// typescript hack: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
158
|
-
Object.setPrototypeOf(this, UnopenedTagError.prototype);
|
|
159
132
|
}
|
|
160
133
|
}
|
|
161
134
|
|
|
@@ -164,9 +137,6 @@ class UnsupportedFileTypeError extends Error {
|
|
|
164
137
|
super(`Filetype "${fileType}" is not supported.`);
|
|
165
138
|
_defineProperty(this, "fileType", void 0);
|
|
166
139
|
this.fileType = fileType;
|
|
167
|
-
|
|
168
|
-
// typescript hack: https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
|
|
169
|
-
Object.setPrototypeOf(this, UnsupportedFileTypeError.prototype);
|
|
170
140
|
}
|
|
171
141
|
}
|
|
172
142
|
|
|
@@ -416,12 +386,48 @@ function utf8Encode(str) {
|
|
|
416
386
|
return utfStr;
|
|
417
387
|
}
|
|
418
388
|
|
|
389
|
+
// Copied from: https://gist.github.com/thanpolas/244d9a13151caf5a12e42208b6111aa6
|
|
390
|
+
// And see: https://unicode-table.com/en/sets/quotation-marks/
|
|
391
|
+
const nonStandardDoubleQuotes = ['“',
|
|
392
|
+
// U+201c
|
|
393
|
+
'”',
|
|
394
|
+
// U+201d
|
|
395
|
+
'«',
|
|
396
|
+
// U+00AB
|
|
397
|
+
'»',
|
|
398
|
+
// U+00BB
|
|
399
|
+
'„',
|
|
400
|
+
// U+201E
|
|
401
|
+
'“',
|
|
402
|
+
// U+201C
|
|
403
|
+
'‟',
|
|
404
|
+
// U+201F
|
|
405
|
+
'”',
|
|
406
|
+
// U+201D
|
|
407
|
+
'❝',
|
|
408
|
+
// U+275D
|
|
409
|
+
'❞',
|
|
410
|
+
// U+275E
|
|
411
|
+
'〝',
|
|
412
|
+
// U+301D
|
|
413
|
+
'〞',
|
|
414
|
+
// U+301E
|
|
415
|
+
'〟',
|
|
416
|
+
// U+301F
|
|
417
|
+
'"' // U+FF02
|
|
418
|
+
];
|
|
419
|
+
const standardDoubleQuotes = '"'; // U+0022
|
|
420
|
+
|
|
421
|
+
const nonStandardDoubleQuotesRegex = new RegExp(nonStandardDoubleQuotes.join('|'), 'g');
|
|
419
422
|
function stringValue(val) {
|
|
420
423
|
if (val === null || val === undefined) {
|
|
421
424
|
return '';
|
|
422
425
|
}
|
|
423
426
|
return val.toString();
|
|
424
427
|
}
|
|
428
|
+
function normalizeDoubleQuotes(text) {
|
|
429
|
+
return text.replace(nonStandardDoubleQuotesRegex, standardDoubleQuotes);
|
|
430
|
+
}
|
|
425
431
|
|
|
426
432
|
class XmlDepthTracker {
|
|
427
433
|
constructor(maxDepth) {
|
|
@@ -536,31 +542,39 @@ const XmlNode = {
|
|
|
536
542
|
* The conversion is always deep.
|
|
537
543
|
*/
|
|
538
544
|
fromDomNode(domNode) {
|
|
539
|
-
var _domNode$textContent;
|
|
540
545
|
let xmlNode;
|
|
541
546
|
|
|
542
547
|
// basic properties
|
|
543
548
|
switch (domNode.nodeType) {
|
|
544
549
|
case domNode.TEXT_NODE:
|
|
545
|
-
|
|
546
|
-
|
|
550
|
+
{
|
|
551
|
+
xmlNode = this.createTextNode(domNode.textContent);
|
|
552
|
+
break;
|
|
553
|
+
}
|
|
547
554
|
case domNode.COMMENT_NODE:
|
|
548
|
-
|
|
549
|
-
|
|
555
|
+
{
|
|
556
|
+
var _domNode$textContent;
|
|
557
|
+
xmlNode = this.createCommentNode((_domNode$textContent = domNode.textContent) === null || _domNode$textContent === void 0 ? void 0 : _domNode$textContent.trim());
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
550
560
|
case domNode.ELEMENT_NODE:
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
561
|
+
{
|
|
562
|
+
const generalNode = xmlNode = this.createGeneralNode(domNode.nodeName);
|
|
563
|
+
const attributes = domNode.attributes;
|
|
564
|
+
if (attributes) {
|
|
565
|
+
generalNode.attributes = {};
|
|
566
|
+
for (let i = 0; i < attributes.length; i++) {
|
|
567
|
+
const curAttribute = attributes.item(i);
|
|
568
|
+
generalNode.attributes[curAttribute.name] = curAttribute.value;
|
|
569
|
+
}
|
|
558
570
|
}
|
|
571
|
+
break;
|
|
559
572
|
}
|
|
560
|
-
break;
|
|
561
573
|
default:
|
|
562
|
-
|
|
563
|
-
|
|
574
|
+
{
|
|
575
|
+
xmlNode = this.createGeneralNode(domNode.nodeName);
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
564
578
|
}
|
|
565
579
|
|
|
566
580
|
// children
|
|
@@ -836,9 +850,11 @@ const XmlNode = {
|
|
|
836
850
|
*
|
|
837
851
|
* * **Note:** Prefer calling with explicit index.
|
|
838
852
|
*/
|
|
853
|
+
|
|
839
854
|
/**
|
|
840
855
|
* Remove a child node from it's parent. Returns the removed child.
|
|
841
856
|
*/
|
|
857
|
+
|
|
842
858
|
function removeChild(parent, childOrIndex) {
|
|
843
859
|
if (!parent) throw new MissingArgumentError("parent");
|
|
844
860
|
if (childOrIndex === null || childOrIndex === undefined) throw new MissingArgumentError("childOrIndex");
|
|
@@ -1115,7 +1131,7 @@ class ScopeData {
|
|
|
1115
1131
|
const curPath = args.strPath.slice();
|
|
1116
1132
|
while (result === undefined && curPath.length) {
|
|
1117
1133
|
curPath.pop();
|
|
1118
|
-
result =
|
|
1134
|
+
result = getProp(args.data, curPath.concat(lastKey));
|
|
1119
1135
|
}
|
|
1120
1136
|
return result;
|
|
1121
1137
|
}
|
|
@@ -1165,7 +1181,8 @@ class TagParser {
|
|
|
1165
1181
|
_defineProperty(this, "tagRegex", void 0);
|
|
1166
1182
|
if (!docParser) throw new MissingArgumentError("docParser");
|
|
1167
1183
|
if (!delimiters) throw new MissingArgumentError("delimiters");
|
|
1168
|
-
|
|
1184
|
+
const tagOptionsRegex = `${Regex.escape(delimiters.tagOptionsStart)}(?<tagOptions>.*?)${Regex.escape(delimiters.tagOptionsEnd)}`;
|
|
1185
|
+
this.tagRegex = new RegExp(`^${Regex.escape(delimiters.tagStart)}(?<tagName>.*?)(${tagOptionsRegex})?${Regex.escape(delimiters.tagEnd)}`, 'm');
|
|
1169
1186
|
}
|
|
1170
1187
|
parse(delimiters) {
|
|
1171
1188
|
const tags = [];
|
|
@@ -1264,23 +1281,44 @@ class TagParser {
|
|
|
1264
1281
|
closeDelimiter.xmlTextNode = endTextNode;
|
|
1265
1282
|
}
|
|
1266
1283
|
processTag(tag) {
|
|
1284
|
+
var _tagParts$groups, _tagParts$groups2;
|
|
1267
1285
|
tag.rawText = tag.xmlTextNode.textContent;
|
|
1268
1286
|
const tagParts = this.tagRegex.exec(tag.rawText);
|
|
1269
|
-
const
|
|
1270
|
-
|
|
1287
|
+
const tagName = (((_tagParts$groups = tagParts.groups) === null || _tagParts$groups === void 0 ? void 0 : _tagParts$groups["tagName"]) || '').trim();
|
|
1288
|
+
|
|
1289
|
+
// Ignoring empty tags.
|
|
1290
|
+
if (!(tagName !== null && tagName !== void 0 && tagName.length)) {
|
|
1271
1291
|
tag.disposition = TagDisposition.SelfClosed;
|
|
1272
1292
|
return;
|
|
1273
1293
|
}
|
|
1274
|
-
|
|
1294
|
+
|
|
1295
|
+
// Tag options.
|
|
1296
|
+
const tagOptionsText = (((_tagParts$groups2 = tagParts.groups) === null || _tagParts$groups2 === void 0 ? void 0 : _tagParts$groups2["tagOptions"]) || '').trim();
|
|
1297
|
+
if (tagOptionsText) {
|
|
1298
|
+
try {
|
|
1299
|
+
tag.options = JSON5__namespace.parse("{" + normalizeDoubleQuotes(tagOptionsText) + "}");
|
|
1300
|
+
} catch (e) {
|
|
1301
|
+
throw new TagOptionsParseError(tag.rawText, e);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
// Container open tag.
|
|
1306
|
+
if (tagName.startsWith(this.delimiters.containerTagOpen)) {
|
|
1275
1307
|
tag.disposition = TagDisposition.Open;
|
|
1276
|
-
tag.name =
|
|
1277
|
-
|
|
1308
|
+
tag.name = tagName.slice(this.delimiters.containerTagOpen.length).trim();
|
|
1309
|
+
return;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
// Container close tag.
|
|
1313
|
+
if (tagName.startsWith(this.delimiters.containerTagClose)) {
|
|
1278
1314
|
tag.disposition = TagDisposition.Close;
|
|
1279
|
-
tag.name =
|
|
1280
|
-
|
|
1281
|
-
tag.disposition = TagDisposition.SelfClosed;
|
|
1282
|
-
tag.name = tagContent;
|
|
1315
|
+
tag.name = tagName.slice(this.delimiters.containerTagClose.length).trim();
|
|
1316
|
+
return;
|
|
1283
1317
|
}
|
|
1318
|
+
|
|
1319
|
+
// Self-closed tag.
|
|
1320
|
+
tag.disposition = TagDisposition.SelfClosed;
|
|
1321
|
+
tag.name = tagName;
|
|
1284
1322
|
}
|
|
1285
1323
|
}
|
|
1286
1324
|
|
|
@@ -1323,8 +1361,6 @@ class MimeTypeHelper {
|
|
|
1323
1361
|
}
|
|
1324
1362
|
}
|
|
1325
1363
|
|
|
1326
|
-
/* eslint-disable @typescript-eslint/member-ordering */
|
|
1327
|
-
|
|
1328
1364
|
class TemplatePlugin {
|
|
1329
1365
|
constructor() {
|
|
1330
1366
|
/**
|
|
@@ -1877,6 +1913,7 @@ class Docx {
|
|
|
1877
1913
|
//
|
|
1878
1914
|
// static methods
|
|
1879
1915
|
//
|
|
1916
|
+
|
|
1880
1917
|
static async open(zip, xmlParser) {
|
|
1881
1918
|
const mainDocumentPath = await Docx.getMainDocumentPath(zip, xmlParser);
|
|
1882
1919
|
if (!mainDocumentPath) throw new MalformedFileError('docx');
|
|
@@ -2023,6 +2060,7 @@ class DocxParser {
|
|
|
2023
2060
|
//
|
|
2024
2061
|
// constructor
|
|
2025
2062
|
//
|
|
2063
|
+
|
|
2026
2064
|
constructor(xmlParser) {
|
|
2027
2065
|
this.xmlParser = xmlParser;
|
|
2028
2066
|
}
|
|
@@ -2547,6 +2585,12 @@ class LoopParagraphStrategy {
|
|
|
2547
2585
|
}
|
|
2548
2586
|
}
|
|
2549
2587
|
|
|
2588
|
+
let LoopOver = /*#__PURE__*/function (LoopOver) {
|
|
2589
|
+
LoopOver["Row"] = "row";
|
|
2590
|
+
LoopOver["Content"] = "content";
|
|
2591
|
+
return LoopOver;
|
|
2592
|
+
}({});
|
|
2593
|
+
|
|
2550
2594
|
class LoopTableStrategy {
|
|
2551
2595
|
constructor() {
|
|
2552
2596
|
_defineProperty(this, "utilities", void 0);
|
|
@@ -2555,9 +2599,18 @@ class LoopTableStrategy {
|
|
|
2555
2599
|
this.utilities = utilities;
|
|
2556
2600
|
}
|
|
2557
2601
|
isApplicable(openTag, closeTag) {
|
|
2558
|
-
const
|
|
2559
|
-
if (!
|
|
2560
|
-
|
|
2602
|
+
const openParagraph = this.utilities.docxParser.containingParagraphNode(openTag.xmlTextNode);
|
|
2603
|
+
if (!openParagraph.parentNode) return false;
|
|
2604
|
+
if (!this.utilities.docxParser.isTableCellNode(openParagraph.parentNode)) return false;
|
|
2605
|
+
const closeParagraph = this.utilities.docxParser.containingParagraphNode(closeTag.xmlTextNode);
|
|
2606
|
+
if (!closeParagraph.parentNode) return false;
|
|
2607
|
+
if (!this.utilities.docxParser.isTableCellNode(closeParagraph.parentNode)) return false;
|
|
2608
|
+
const options = openTag.options;
|
|
2609
|
+
const forceRowLoop = (options === null || options === void 0 ? void 0 : options.loopOver) === LoopOver.Row;
|
|
2610
|
+
|
|
2611
|
+
// If both tags are in the same cell, assume it's a paragraph loop (iterate content, not rows).
|
|
2612
|
+
if (!forceRowLoop && openParagraph.parentNode === closeParagraph.parentNode) return false;
|
|
2613
|
+
return true;
|
|
2561
2614
|
}
|
|
2562
2615
|
splitBefore(openTag, closeTag) {
|
|
2563
2616
|
const firstRow = this.utilities.docxParser.containingTableRowNode(openTag.xmlTextNode);
|
|
@@ -2596,7 +2649,6 @@ class LoopPlugin extends TemplatePlugin {
|
|
|
2596
2649
|
_defineProperty(this, "loopStrategies", [new LoopTableStrategy(), new LoopListStrategy(), new LoopParagraphStrategy() // the default strategy
|
|
2597
2650
|
]);
|
|
2598
2651
|
}
|
|
2599
|
-
|
|
2600
2652
|
setUtilities(utilities) {
|
|
2601
2653
|
this.utilities = utilities;
|
|
2602
2654
|
this.loopStrategies.forEach(strategy => strategy.setUtilities(utilities));
|
|
@@ -2607,7 +2659,7 @@ class LoopPlugin extends TemplatePlugin {
|
|
|
2607
2659
|
// Non array value - treat as a boolean condition.
|
|
2608
2660
|
const isCondition = !Array.isArray(value);
|
|
2609
2661
|
if (isCondition) {
|
|
2610
|
-
if (
|
|
2662
|
+
if (value) {
|
|
2611
2663
|
value = [{}];
|
|
2612
2664
|
} else {
|
|
2613
2665
|
value = [];
|
|
@@ -2978,7 +3030,6 @@ class Zip {
|
|
|
2978
3030
|
level: 6 // between 1 (best speed) and 9 (best compression)
|
|
2979
3031
|
}
|
|
2980
3032
|
});
|
|
2981
|
-
|
|
2982
3033
|
return output;
|
|
2983
3034
|
}
|
|
2984
3035
|
}
|
|
@@ -2989,6 +3040,8 @@ class Delimiters {
|
|
|
2989
3040
|
_defineProperty(this, "tagEnd", "}");
|
|
2990
3041
|
_defineProperty(this, "containerTagOpen", "#");
|
|
2991
3042
|
_defineProperty(this, "containerTagClose", "/");
|
|
3043
|
+
_defineProperty(this, "tagOptionsStart", "[");
|
|
3044
|
+
_defineProperty(this, "tagOptionsEnd", "]");
|
|
2992
3045
|
Object.assign(this, initial);
|
|
2993
3046
|
this.encodeAndValidate();
|
|
2994
3047
|
if (this.containerTagOpen === this.containerTagClose) throw new Error(`${"containerTagOpen"} can not be equal to ${"containerTagClose"}`);
|
|
@@ -3211,6 +3264,7 @@ exports.ScopeData = ScopeData;
|
|
|
3211
3264
|
exports.TEXT_CONTENT_TYPE = TEXT_CONTENT_TYPE;
|
|
3212
3265
|
exports.TEXT_NODE_NAME = TEXT_NODE_NAME;
|
|
3213
3266
|
exports.TagDisposition = TagDisposition;
|
|
3267
|
+
exports.TagOptionsParseError = TagOptionsParseError;
|
|
3214
3268
|
exports.TagParser = TagParser;
|
|
3215
3269
|
exports.TemplateCompiler = TemplateCompiler;
|
|
3216
3270
|
exports.TemplateExtension = TemplateExtension;
|
|
@@ -3236,6 +3290,7 @@ exports.inheritsFrom = inheritsFrom;
|
|
|
3236
3290
|
exports.isNumber = isNumber;
|
|
3237
3291
|
exports.isPromiseLike = isPromiseLike;
|
|
3238
3292
|
exports.last = last;
|
|
3293
|
+
exports.normalizeDoubleQuotes = normalizeDoubleQuotes;
|
|
3239
3294
|
exports.pushMany = pushMany;
|
|
3240
3295
|
exports.sha1 = sha1;
|
|
3241
3296
|
exports.stringValue = stringValue;
|