easy-template-x 4.1.1 → 4.1.3
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/dist/cjs/easy-template-x.cjs +155 -253
- package/dist/es/easy-template-x.mjs +155 -234
- package/package.json +12 -10
- package/src/compilation/delimiterSearcher.ts +35 -18
- package/src/compilation/tagParser.ts +1 -1
|
@@ -5,48 +5,6 @@ var getProp = require('lodash.get');
|
|
|
5
5
|
var JSON5 = require('json5');
|
|
6
6
|
var JSZip = require('jszip');
|
|
7
7
|
|
|
8
|
-
function _interopNamespaceDefault(e) {
|
|
9
|
-
var n = Object.create(null);
|
|
10
|
-
if (e) {
|
|
11
|
-
Object.keys(e).forEach(function (k) {
|
|
12
|
-
if (k !== 'default') {
|
|
13
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
-
enumerable: true,
|
|
16
|
-
get: function () { return e[k]; }
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
n.default = e;
|
|
22
|
-
return Object.freeze(n);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
var JSON5__namespace = /*#__PURE__*/_interopNamespaceDefault(JSON5);
|
|
26
|
-
|
|
27
|
-
function _defineProperty(e, r, t) {
|
|
28
|
-
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
29
|
-
value: t,
|
|
30
|
-
enumerable: !0,
|
|
31
|
-
configurable: !0,
|
|
32
|
-
writable: !0
|
|
33
|
-
}) : e[r] = t, e;
|
|
34
|
-
}
|
|
35
|
-
function _toPrimitive(t, r) {
|
|
36
|
-
if ("object" != typeof t || !t) return t;
|
|
37
|
-
var e = t[Symbol.toPrimitive];
|
|
38
|
-
if (void 0 !== e) {
|
|
39
|
-
var i = e.call(t, r || "default");
|
|
40
|
-
if ("object" != typeof i) return i;
|
|
41
|
-
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
42
|
-
}
|
|
43
|
-
return ("string" === r ? String : Number)(t);
|
|
44
|
-
}
|
|
45
|
-
function _toPropertyKey(t) {
|
|
46
|
-
var i = _toPrimitive(t, "string");
|
|
47
|
-
return "symbol" == typeof i ? i : i + "";
|
|
48
|
-
}
|
|
49
|
-
|
|
50
8
|
class ArgumentError extends Error {
|
|
51
9
|
constructor(message) {
|
|
52
10
|
super(message);
|
|
@@ -56,7 +14,6 @@ class ArgumentError extends Error {
|
|
|
56
14
|
class MalformedFileError extends Error {
|
|
57
15
|
constructor(expectedFileType) {
|
|
58
16
|
super(`Malformed file detected. Make sure the file is a valid ${expectedFileType} file.`);
|
|
59
|
-
_defineProperty(this, "expectedFileType", void 0);
|
|
60
17
|
this.expectedFileType = expectedFileType;
|
|
61
18
|
}
|
|
62
19
|
}
|
|
@@ -64,7 +21,6 @@ class MalformedFileError extends Error {
|
|
|
64
21
|
class MaxXmlDepthError extends Error {
|
|
65
22
|
constructor(maxDepth) {
|
|
66
23
|
super(`XML maximum depth reached (max depth: ${maxDepth}).`);
|
|
67
|
-
_defineProperty(this, "maxDepth", void 0);
|
|
68
24
|
this.maxDepth = maxDepth;
|
|
69
25
|
}
|
|
70
26
|
}
|
|
@@ -72,7 +28,6 @@ class MaxXmlDepthError extends Error {
|
|
|
72
28
|
class MissingArgumentError extends ArgumentError {
|
|
73
29
|
constructor(argName) {
|
|
74
30
|
super(`Argument '${argName}' is missing.`);
|
|
75
|
-
_defineProperty(this, "argName", void 0);
|
|
76
31
|
this.argName = argName;
|
|
77
32
|
}
|
|
78
33
|
}
|
|
@@ -80,7 +35,6 @@ class MissingArgumentError extends ArgumentError {
|
|
|
80
35
|
class MissingCloseDelimiterError extends Error {
|
|
81
36
|
constructor(openDelimiterText) {
|
|
82
37
|
super(`Close delimiter is missing from '${openDelimiterText}'.`);
|
|
83
|
-
_defineProperty(this, "openDelimiterText", void 0);
|
|
84
38
|
this.openDelimiterText = openDelimiterText;
|
|
85
39
|
}
|
|
86
40
|
}
|
|
@@ -88,7 +42,6 @@ class MissingCloseDelimiterError extends Error {
|
|
|
88
42
|
class MissingStartDelimiterError extends Error {
|
|
89
43
|
constructor(closeDelimiterText) {
|
|
90
44
|
super(`Open delimiter is missing from '${closeDelimiterText}'.`);
|
|
91
|
-
_defineProperty(this, "closeDelimiterText", void 0);
|
|
92
45
|
this.closeDelimiterText = closeDelimiterText;
|
|
93
46
|
}
|
|
94
47
|
}
|
|
@@ -96,8 +49,6 @@ class MissingStartDelimiterError extends Error {
|
|
|
96
49
|
class TagOptionsParseError extends Error {
|
|
97
50
|
constructor(tagRawText, parseError) {
|
|
98
51
|
super(`Failed to parse tag options of '${tagRawText}': ${parseError.message}.`);
|
|
99
|
-
_defineProperty(this, "tagRawText", void 0);
|
|
100
|
-
_defineProperty(this, "parseError", void 0);
|
|
101
52
|
this.tagRawText = tagRawText;
|
|
102
53
|
this.parseError = parseError;
|
|
103
54
|
}
|
|
@@ -106,7 +57,6 @@ class TagOptionsParseError extends Error {
|
|
|
106
57
|
class UnclosedTagError extends Error {
|
|
107
58
|
constructor(tagName) {
|
|
108
59
|
super(`Tag '${tagName}' is never closed.`);
|
|
109
|
-
_defineProperty(this, "tagName", void 0);
|
|
110
60
|
this.tagName = tagName;
|
|
111
61
|
}
|
|
112
62
|
}
|
|
@@ -120,9 +70,6 @@ class UnidentifiedFileTypeError extends Error {
|
|
|
120
70
|
class UnknownContentTypeError extends Error {
|
|
121
71
|
constructor(contentType, tagRawText, path) {
|
|
122
72
|
super(`Content type '${contentType}' does not have a registered plugin to handle it.`);
|
|
123
|
-
_defineProperty(this, "tagRawText", void 0);
|
|
124
|
-
_defineProperty(this, "contentType", void 0);
|
|
125
|
-
_defineProperty(this, "path", void 0);
|
|
126
73
|
this.contentType = contentType;
|
|
127
74
|
this.tagRawText = tagRawText;
|
|
128
75
|
this.path = path;
|
|
@@ -132,7 +79,6 @@ class UnknownContentTypeError extends Error {
|
|
|
132
79
|
class UnopenedTagError extends Error {
|
|
133
80
|
constructor(tagName) {
|
|
134
81
|
super(`Tag '${tagName}' is closed but was never opened.`);
|
|
135
|
-
_defineProperty(this, "tagName", void 0);
|
|
136
82
|
this.tagName = tagName;
|
|
137
83
|
}
|
|
138
84
|
}
|
|
@@ -140,7 +86,6 @@ class UnopenedTagError extends Error {
|
|
|
140
86
|
class UnsupportedFileTypeError extends Error {
|
|
141
87
|
constructor(fileType) {
|
|
142
88
|
super(`Filetype "${fileType}" is not supported.`);
|
|
143
|
-
_defineProperty(this, "fileType", void 0);
|
|
144
89
|
this.fileType = fileType;
|
|
145
90
|
}
|
|
146
91
|
}
|
|
@@ -252,7 +197,7 @@ class Path {
|
|
|
252
197
|
return path.substring(0, lastSlashIndex);
|
|
253
198
|
}
|
|
254
199
|
static combine(...parts) {
|
|
255
|
-
return parts.filter(part => part
|
|
200
|
+
return parts.filter(part => part?.trim()).join('/');
|
|
256
201
|
}
|
|
257
202
|
}
|
|
258
203
|
|
|
@@ -435,9 +380,9 @@ function normalizeDoubleQuotes(text) {
|
|
|
435
380
|
}
|
|
436
381
|
|
|
437
382
|
class XmlDepthTracker {
|
|
383
|
+
depth = 0;
|
|
438
384
|
constructor(maxDepth) {
|
|
439
385
|
this.maxDepth = maxDepth;
|
|
440
|
-
_defineProperty(this, "depth", 0);
|
|
441
386
|
}
|
|
442
387
|
increment() {
|
|
443
388
|
this.depth++;
|
|
@@ -558,8 +503,7 @@ const XmlNode = {
|
|
|
558
503
|
}
|
|
559
504
|
case domNode.COMMENT_NODE:
|
|
560
505
|
{
|
|
561
|
-
|
|
562
|
-
xmlNode = this.createCommentNode((_domNode$textContent = domNode.textContent) === null || _domNode$textContent === void 0 ? void 0 : _domNode$textContent.trim());
|
|
506
|
+
xmlNode = this.createCommentNode(domNode.textContent?.trim());
|
|
563
507
|
break;
|
|
564
508
|
}
|
|
565
509
|
case domNode.ELEMENT_NODE:
|
|
@@ -945,6 +889,13 @@ function recursiveRemoveEmptyTextNodes(node) {
|
|
|
945
889
|
}
|
|
946
890
|
|
|
947
891
|
class XmlParser {
|
|
892
|
+
static xmlHeader = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
|
|
893
|
+
/**
|
|
894
|
+
* We always use the DOMParser from 'xmldom', even in the browser since it
|
|
895
|
+
* handles xml namespaces more forgivingly (required mainly by the
|
|
896
|
+
* RawXmlPlugin).
|
|
897
|
+
*/
|
|
898
|
+
static parser = new xmldom.DOMParser();
|
|
948
899
|
parse(str) {
|
|
949
900
|
const doc = this.domParse(str);
|
|
950
901
|
return XmlNode.fromDomNode(doc.documentElement);
|
|
@@ -957,20 +908,28 @@ class XmlParser {
|
|
|
957
908
|
return XmlParser.xmlHeader + XmlNode.serialize(xmlNode);
|
|
958
909
|
}
|
|
959
910
|
}
|
|
960
|
-
_defineProperty(XmlParser, "xmlHeader", '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>');
|
|
961
|
-
/**
|
|
962
|
-
* We always use the DOMParser from 'xmldom', even in the browser since it
|
|
963
|
-
* handles xml namespaces more forgivingly (required mainly by the
|
|
964
|
-
* RawXmlPlugin).
|
|
965
|
-
*/
|
|
966
|
-
_defineProperty(XmlParser, "parser", new xmldom.DOMParser());
|
|
967
911
|
|
|
968
912
|
class MatchState {
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
913
|
+
/**
|
|
914
|
+
* The index of the current delimiter character being matched.
|
|
915
|
+
*
|
|
916
|
+
* Example: If the delimiter is `{!` and delimiterIndex is 0, it means we
|
|
917
|
+
* are now looking for the character `{`. If it is 1, then we are looking
|
|
918
|
+
* for `!`.
|
|
919
|
+
*/
|
|
920
|
+
delimiterIndex = 0;
|
|
921
|
+
/**
|
|
922
|
+
* The list of text nodes containing the delimiter characters.
|
|
923
|
+
*/
|
|
924
|
+
openNodes = [];
|
|
925
|
+
/**
|
|
926
|
+
* The index of the first character of the delimiter, in the text node it
|
|
927
|
+
* was found at.
|
|
928
|
+
*
|
|
929
|
+
* Example: If the delimiter is `{!`, and the text node content is `abc{!xyz`,
|
|
930
|
+
* then the firstMatchIndex is 3.
|
|
931
|
+
*/
|
|
932
|
+
firstMatchIndex = -1;
|
|
974
933
|
reset() {
|
|
975
934
|
this.delimiterIndex = 0;
|
|
976
935
|
this.openNodes = [];
|
|
@@ -978,11 +937,11 @@ class MatchState {
|
|
|
978
937
|
}
|
|
979
938
|
}
|
|
980
939
|
class DelimiterSearcher {
|
|
940
|
+
maxXmlDepth = 20;
|
|
941
|
+
startDelimiter = "{";
|
|
942
|
+
endDelimiter = "}";
|
|
981
943
|
constructor(docxParser) {
|
|
982
944
|
this.docxParser = docxParser;
|
|
983
|
-
_defineProperty(this, "maxXmlDepth", 20);
|
|
984
|
-
_defineProperty(this, "startDelimiter", "{");
|
|
985
|
-
_defineProperty(this, "endDelimiter", "}");
|
|
986
945
|
if (!docxParser) throw new MissingArgumentError("docxParser");
|
|
987
946
|
}
|
|
988
947
|
findDelimiters(node) {
|
|
@@ -992,8 +951,8 @@ class DelimiterSearcher {
|
|
|
992
951
|
// The search efficiency is o(m*n) where n is the text size and m is the
|
|
993
952
|
// delimiter length. We could use a variation of the KMP algorithm here
|
|
994
953
|
// to reduce it to o(m+n) but since our m is expected to be small
|
|
995
|
-
// (delimiters defaults to
|
|
996
|
-
// not expected to be much longer) it does not worth the extra
|
|
954
|
+
// (delimiters defaults to a single characters and even on custom inputs
|
|
955
|
+
// are not expected to be much longer) it does not worth the extra
|
|
997
956
|
// complexity and effort.
|
|
998
957
|
//
|
|
999
958
|
|
|
@@ -1002,44 +961,44 @@ class DelimiterSearcher {
|
|
|
1002
961
|
const depth = new XmlDepthTracker(this.maxXmlDepth);
|
|
1003
962
|
let lookForOpenDelimiter = true;
|
|
1004
963
|
while (node) {
|
|
1005
|
-
//
|
|
964
|
+
// Reset state on paragraph transition
|
|
1006
965
|
if (this.docxParser.isParagraphNode(node)) {
|
|
1007
966
|
match.reset();
|
|
1008
967
|
}
|
|
1009
968
|
|
|
1010
|
-
//
|
|
969
|
+
// Skip irrelevant nodes
|
|
1011
970
|
if (!this.shouldSearchNode(node)) {
|
|
1012
971
|
node = this.findNextNode(node, depth);
|
|
1013
972
|
continue;
|
|
1014
973
|
}
|
|
1015
974
|
|
|
1016
|
-
//
|
|
975
|
+
// Search delimiters in text nodes
|
|
1017
976
|
match.openNodes.push(node);
|
|
1018
977
|
let textIndex = 0;
|
|
1019
978
|
while (textIndex < node.textContent.length) {
|
|
1020
979
|
const delimiterPattern = lookForOpenDelimiter ? this.startDelimiter : this.endDelimiter;
|
|
1021
980
|
const char = node.textContent[textIndex];
|
|
1022
981
|
|
|
1023
|
-
//
|
|
982
|
+
// No match
|
|
1024
983
|
if (char !== delimiterPattern[match.delimiterIndex]) {
|
|
1025
984
|
[node, textIndex] = this.noMatch(node, textIndex, match);
|
|
1026
985
|
textIndex++;
|
|
1027
986
|
continue;
|
|
1028
987
|
}
|
|
1029
988
|
|
|
1030
|
-
//
|
|
989
|
+
// First match
|
|
1031
990
|
if (match.firstMatchIndex === -1) {
|
|
1032
991
|
match.firstMatchIndex = textIndex;
|
|
1033
992
|
}
|
|
1034
993
|
|
|
1035
|
-
//
|
|
994
|
+
// Partial match
|
|
1036
995
|
if (match.delimiterIndex !== delimiterPattern.length - 1) {
|
|
1037
996
|
match.delimiterIndex++;
|
|
1038
997
|
textIndex++;
|
|
1039
998
|
continue;
|
|
1040
999
|
}
|
|
1041
1000
|
|
|
1042
|
-
//
|
|
1001
|
+
// Full delimiter match
|
|
1043
1002
|
[node, textIndex, lookForOpenDelimiter] = this.fullMatch(node, textIndex, lookForOpenDelimiter, match, delimiters);
|
|
1044
1003
|
textIndex++;
|
|
1045
1004
|
}
|
|
@@ -1049,7 +1008,7 @@ class DelimiterSearcher {
|
|
|
1049
1008
|
}
|
|
1050
1009
|
noMatch(node, textIndex, match) {
|
|
1051
1010
|
//
|
|
1052
|
-
//
|
|
1011
|
+
// Go back to first open node
|
|
1053
1012
|
//
|
|
1054
1013
|
// Required for cases where the text has repeating
|
|
1055
1014
|
// characters that are the same as a delimiter prefix.
|
|
@@ -1061,7 +1020,7 @@ class DelimiterSearcher {
|
|
|
1061
1020
|
textIndex = match.firstMatchIndex;
|
|
1062
1021
|
}
|
|
1063
1022
|
|
|
1064
|
-
//
|
|
1023
|
+
// Update state
|
|
1065
1024
|
match.reset();
|
|
1066
1025
|
if (textIndex < node.textContent.length - 1) {
|
|
1067
1026
|
match.openNodes.push(node);
|
|
@@ -1069,7 +1028,7 @@ class DelimiterSearcher {
|
|
|
1069
1028
|
return [node, textIndex];
|
|
1070
1029
|
}
|
|
1071
1030
|
fullMatch(node, textIndex, lookForOpenDelimiter, match, delimiters) {
|
|
1072
|
-
//
|
|
1031
|
+
// Move all delimiters characters to the same text node
|
|
1073
1032
|
if (match.openNodes.length > 1) {
|
|
1074
1033
|
const firstNode = first(match.openNodes);
|
|
1075
1034
|
const lastNode = last(match.openNodes);
|
|
@@ -1078,11 +1037,11 @@ class DelimiterSearcher {
|
|
|
1078
1037
|
node = firstNode;
|
|
1079
1038
|
}
|
|
1080
1039
|
|
|
1081
|
-
//
|
|
1040
|
+
// Store delimiter
|
|
1082
1041
|
const delimiterMark = this.createDelimiterMark(match, lookForOpenDelimiter);
|
|
1083
1042
|
delimiters.push(delimiterMark);
|
|
1084
1043
|
|
|
1085
|
-
//
|
|
1044
|
+
// Update state
|
|
1086
1045
|
lookForOpenDelimiter = !lookForOpenDelimiter;
|
|
1087
1046
|
match.reset();
|
|
1088
1047
|
if (textIndex < node.textContent.length - 1) {
|
|
@@ -1098,23 +1057,23 @@ class DelimiterSearcher {
|
|
|
1098
1057
|
return true;
|
|
1099
1058
|
}
|
|
1100
1059
|
findNextNode(node, depth) {
|
|
1101
|
-
//
|
|
1060
|
+
// Children
|
|
1102
1061
|
if (node.childNodes && node.childNodes.length) {
|
|
1103
1062
|
depth.increment();
|
|
1104
1063
|
return node.childNodes[0];
|
|
1105
1064
|
}
|
|
1106
1065
|
|
|
1107
|
-
//
|
|
1066
|
+
// Siblings
|
|
1108
1067
|
if (node.nextSibling) return node.nextSibling;
|
|
1109
1068
|
|
|
1110
|
-
//
|
|
1069
|
+
// Parent sibling
|
|
1111
1070
|
while (node.parentNode) {
|
|
1112
1071
|
if (node.parentNode.nextSibling) {
|
|
1113
1072
|
depth.decrement();
|
|
1114
1073
|
return node.parentNode.nextSibling;
|
|
1115
1074
|
}
|
|
1116
1075
|
|
|
1117
|
-
//
|
|
1076
|
+
// Go up
|
|
1118
1077
|
depth.decrement();
|
|
1119
1078
|
node = node.parentNode;
|
|
1120
1079
|
}
|
|
@@ -1140,11 +1099,9 @@ class ScopeData {
|
|
|
1140
1099
|
}
|
|
1141
1100
|
return result;
|
|
1142
1101
|
}
|
|
1102
|
+
path = [];
|
|
1103
|
+
strPath = [];
|
|
1143
1104
|
constructor(data) {
|
|
1144
|
-
_defineProperty(this, "scopeDataResolver", void 0);
|
|
1145
|
-
_defineProperty(this, "allData", void 0);
|
|
1146
|
-
_defineProperty(this, "path", []);
|
|
1147
|
-
_defineProperty(this, "strPath", []);
|
|
1148
1105
|
this.allData = data;
|
|
1149
1106
|
}
|
|
1150
1107
|
pathPush(pathPart) {
|
|
@@ -1183,7 +1140,6 @@ class TagParser {
|
|
|
1183
1140
|
constructor(docParser, delimiters) {
|
|
1184
1141
|
this.docParser = docParser;
|
|
1185
1142
|
this.delimiters = delimiters;
|
|
1186
|
-
_defineProperty(this, "tagRegex", void 0);
|
|
1187
1143
|
if (!docParser) throw new MissingArgumentError("docParser");
|
|
1188
1144
|
if (!delimiters) throw new MissingArgumentError("delimiters");
|
|
1189
1145
|
const tagOptionsRegex = `${Regex.escape(delimiters.tagOptionsStart)}(?<tagOptions>.*?)${Regex.escape(delimiters.tagOptionsEnd)}`;
|
|
@@ -1286,22 +1242,21 @@ class TagParser {
|
|
|
1286
1242
|
closeDelimiter.xmlTextNode = endTextNode;
|
|
1287
1243
|
}
|
|
1288
1244
|
processTag(tag) {
|
|
1289
|
-
var _tagParts$groups, _tagParts$groups2;
|
|
1290
1245
|
tag.rawText = tag.xmlTextNode.textContent;
|
|
1291
1246
|
const tagParts = this.tagRegex.exec(tag.rawText);
|
|
1292
|
-
const tagName = (
|
|
1247
|
+
const tagName = (tagParts.groups?.["tagName"] || '').trim();
|
|
1293
1248
|
|
|
1294
1249
|
// Ignoring empty tags.
|
|
1295
|
-
if (!
|
|
1250
|
+
if (!tagName?.length) {
|
|
1296
1251
|
tag.disposition = TagDisposition.SelfClosed;
|
|
1297
1252
|
return;
|
|
1298
1253
|
}
|
|
1299
1254
|
|
|
1300
1255
|
// Tag options.
|
|
1301
|
-
const tagOptionsText = (
|
|
1256
|
+
const tagOptionsText = (tagParts.groups?.["tagOptions"] || '').trim();
|
|
1302
1257
|
if (tagOptionsText) {
|
|
1303
1258
|
try {
|
|
1304
|
-
tag.options =
|
|
1259
|
+
tag.options = JSON5.parse("{" + normalizeDoubleQuotes(tagOptionsText) + "}");
|
|
1305
1260
|
} catch (e) {
|
|
1306
1261
|
throw new TagOptionsParseError(tag.rawText, e);
|
|
1307
1262
|
}
|
|
@@ -1367,13 +1322,10 @@ class MimeTypeHelper {
|
|
|
1367
1322
|
}
|
|
1368
1323
|
|
|
1369
1324
|
class TemplatePlugin {
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
_defineProperty(this, "contentType", void 0);
|
|
1375
|
-
_defineProperty(this, "utilities", void 0);
|
|
1376
|
-
}
|
|
1325
|
+
/**
|
|
1326
|
+
* The content type this plugin handles.
|
|
1327
|
+
*/
|
|
1328
|
+
|
|
1377
1329
|
/**
|
|
1378
1330
|
* Called by the TemplateHandler at runtime.
|
|
1379
1331
|
*/
|
|
@@ -1414,10 +1366,7 @@ class TemplatePlugin {
|
|
|
1414
1366
|
*/
|
|
1415
1367
|
let nextImageId = 1;
|
|
1416
1368
|
class ImagePlugin extends TemplatePlugin {
|
|
1417
|
-
|
|
1418
|
-
super(...args);
|
|
1419
|
-
_defineProperty(this, "contentType", 'image');
|
|
1420
|
-
}
|
|
1369
|
+
contentType = 'image';
|
|
1421
1370
|
async simpleTagReplacements(tag, data, context) {
|
|
1422
1371
|
const wordTextNode = this.utilities.docxParser.containingTextNode(tag.xmlTextNode);
|
|
1423
1372
|
const content = data.getScopeData();
|
|
@@ -1569,12 +1518,11 @@ let ContentPartType = /*#__PURE__*/function (ContentPartType) {
|
|
|
1569
1518
|
* http://officeopenxml.com/anatomyofOOXML.php
|
|
1570
1519
|
*/
|
|
1571
1520
|
class ContentTypesFile {
|
|
1521
|
+
static contentTypesFilePath = '[Content_Types].xml';
|
|
1522
|
+
addedNew = false;
|
|
1572
1523
|
constructor(zip, xmlParser) {
|
|
1573
1524
|
this.zip = zip;
|
|
1574
1525
|
this.xmlParser = xmlParser;
|
|
1575
|
-
_defineProperty(this, "addedNew", false);
|
|
1576
|
-
_defineProperty(this, "root", void 0);
|
|
1577
|
-
_defineProperty(this, "contentTypes", void 0);
|
|
1578
1526
|
}
|
|
1579
1527
|
async ensureContentType(mime) {
|
|
1580
1528
|
// parse the content types file
|
|
@@ -1629,17 +1577,16 @@ class ContentTypesFile {
|
|
|
1629
1577
|
}
|
|
1630
1578
|
}
|
|
1631
1579
|
}
|
|
1632
|
-
_defineProperty(ContentTypesFile, "contentTypesFilePath", '[Content_Types].xml');
|
|
1633
1580
|
|
|
1634
1581
|
/**
|
|
1635
1582
|
* Handles media files of the main document.
|
|
1636
1583
|
*/
|
|
1637
1584
|
class MediaFiles {
|
|
1585
|
+
static mediaDir = 'word/media';
|
|
1586
|
+
files = new Map();
|
|
1587
|
+
nextFileId = 0;
|
|
1638
1588
|
constructor(zip) {
|
|
1639
1589
|
this.zip = zip;
|
|
1640
|
-
_defineProperty(this, "hashes", void 0);
|
|
1641
|
-
_defineProperty(this, "files", new Map());
|
|
1642
|
-
_defineProperty(this, "nextFileId", 0);
|
|
1643
1590
|
}
|
|
1644
1591
|
|
|
1645
1592
|
/**
|
|
@@ -1698,23 +1645,17 @@ class MediaFiles {
|
|
|
1698
1645
|
}
|
|
1699
1646
|
}
|
|
1700
1647
|
}
|
|
1701
|
-
_defineProperty(MediaFiles, "mediaDir", 'word/media');
|
|
1702
1648
|
|
|
1703
1649
|
class Relationship {
|
|
1704
1650
|
static fromXml(xml) {
|
|
1705
|
-
var _xml$attributes, _xml$attributes2, _xml$attributes3, _xml$attributes4;
|
|
1706
1651
|
return new Relationship({
|
|
1707
|
-
id:
|
|
1708
|
-
type:
|
|
1709
|
-
target:
|
|
1710
|
-
targetMode:
|
|
1652
|
+
id: xml.attributes?.['Id'],
|
|
1653
|
+
type: xml.attributes?.['Type'],
|
|
1654
|
+
target: xml.attributes?.['Target'],
|
|
1655
|
+
targetMode: xml.attributes?.['TargetMode']
|
|
1711
1656
|
});
|
|
1712
1657
|
}
|
|
1713
1658
|
constructor(initial) {
|
|
1714
|
-
_defineProperty(this, "id", void 0);
|
|
1715
|
-
_defineProperty(this, "type", void 0);
|
|
1716
|
-
_defineProperty(this, "target", void 0);
|
|
1717
|
-
_defineProperty(this, "targetMode", void 0);
|
|
1718
1659
|
Object.assign(this, initial);
|
|
1719
1660
|
}
|
|
1720
1661
|
toXml() {
|
|
@@ -1738,17 +1679,13 @@ class Relationship {
|
|
|
1738
1679
|
* http://officeopenxml.com/anatomyofOOXML.php
|
|
1739
1680
|
*/
|
|
1740
1681
|
class Rels {
|
|
1682
|
+
nextRelId = 0;
|
|
1741
1683
|
constructor(partPath, zip, xmlParser) {
|
|
1742
1684
|
this.zip = zip;
|
|
1743
1685
|
this.xmlParser = xmlParser;
|
|
1744
|
-
_defineProperty(this, "rels", void 0);
|
|
1745
|
-
_defineProperty(this, "relTargets", void 0);
|
|
1746
|
-
_defineProperty(this, "nextRelId", 0);
|
|
1747
|
-
_defineProperty(this, "partDir", void 0);
|
|
1748
|
-
_defineProperty(this, "relsFilePath", void 0);
|
|
1749
1686
|
this.partDir = partPath && Path.getDirectory(partPath);
|
|
1750
1687
|
const partFilename = partPath && Path.getFilename(partPath);
|
|
1751
|
-
this.relsFilePath = Path.combine(this.partDir, '_rels', `${partFilename
|
|
1688
|
+
this.relsFilePath = Path.combine(this.partDir, '_rels', `${partFilename ?? ''}.rels`);
|
|
1752
1689
|
}
|
|
1753
1690
|
|
|
1754
1691
|
/**
|
|
@@ -1877,8 +1814,6 @@ class XmlPart {
|
|
|
1877
1814
|
this.path = path;
|
|
1878
1815
|
this.zip = zip;
|
|
1879
1816
|
this.xmlParser = xmlParser;
|
|
1880
|
-
_defineProperty(this, "rels", void 0);
|
|
1881
|
-
_defineProperty(this, "root", void 0);
|
|
1882
1817
|
this.rels = new Rels(this.path, zip, xmlParser);
|
|
1883
1818
|
}
|
|
1884
1819
|
|
|
@@ -1926,6 +1861,8 @@ class XmlPart {
|
|
|
1926
1861
|
* Represents a single docx file.
|
|
1927
1862
|
*/
|
|
1928
1863
|
class Docx {
|
|
1864
|
+
static mainDocumentRelType = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument';
|
|
1865
|
+
|
|
1929
1866
|
//
|
|
1930
1867
|
// static methods
|
|
1931
1868
|
//
|
|
@@ -1936,17 +1873,18 @@ class Docx {
|
|
|
1936
1873
|
return new Docx(mainDocumentPath, zip, xmlParser);
|
|
1937
1874
|
}
|
|
1938
1875
|
static async getMainDocumentPath(zip, xmlParser) {
|
|
1939
|
-
var _relations$find;
|
|
1940
1876
|
const rootPart = '';
|
|
1941
1877
|
const rootRels = new Rels(rootPart, zip, xmlParser);
|
|
1942
1878
|
const relations = await rootRels.list();
|
|
1943
|
-
return
|
|
1879
|
+
return relations.find(rel => rel.type == Docx.mainDocumentRelType)?.target;
|
|
1944
1880
|
}
|
|
1945
1881
|
|
|
1946
1882
|
//
|
|
1947
1883
|
// fields
|
|
1948
1884
|
//
|
|
1949
1885
|
|
|
1886
|
+
_parts = {};
|
|
1887
|
+
|
|
1950
1888
|
/**
|
|
1951
1889
|
* **Notice:** You should only use this property if there is no other way to
|
|
1952
1890
|
* do what you need. Use with caution.
|
|
@@ -1962,10 +1900,6 @@ class Docx {
|
|
|
1962
1900
|
constructor(mainDocumentPath, zip, xmlParser) {
|
|
1963
1901
|
this.zip = zip;
|
|
1964
1902
|
this.xmlParser = xmlParser;
|
|
1965
|
-
_defineProperty(this, "mainDocument", void 0);
|
|
1966
|
-
_defineProperty(this, "mediaFiles", void 0);
|
|
1967
|
-
_defineProperty(this, "contentTypes", void 0);
|
|
1968
|
-
_defineProperty(this, "_parts", {});
|
|
1969
1903
|
this.mainDocument = new XmlPart(mainDocumentPath, zip, xmlParser);
|
|
1970
1904
|
this.mediaFiles = new MediaFiles(zip);
|
|
1971
1905
|
this.contentTypes = new ContentTypesFile(zip, xmlParser);
|
|
@@ -2002,7 +1936,6 @@ class Docx {
|
|
|
2002
1936
|
//
|
|
2003
1937
|
|
|
2004
1938
|
async getHeaderOrFooter(type) {
|
|
2005
|
-
var _sectionProps$childNo, _attributes;
|
|
2006
1939
|
const nodeName = this.headerFooterNodeName(type);
|
|
2007
1940
|
const nodeTypeAttribute = this.headerFooterType(type);
|
|
2008
1941
|
|
|
@@ -2015,11 +1948,10 @@ class Docx {
|
|
|
2015
1948
|
if (sectionProps.nodeName != 'w:sectPr') return null;
|
|
2016
1949
|
|
|
2017
1950
|
// find the header or footer reference
|
|
2018
|
-
const reference =
|
|
2019
|
-
|
|
2020
|
-
return node.nodeType === XmlNodeType.General && node.nodeName === nodeName && ((_node$attributes = node.attributes) === null || _node$attributes === void 0 ? void 0 : _node$attributes['w:type']) === nodeTypeAttribute;
|
|
1951
|
+
const reference = sectionProps.childNodes?.find(node => {
|
|
1952
|
+
return node.nodeType === XmlNodeType.General && node.nodeName === nodeName && node.attributes?.['w:type'] === nodeTypeAttribute;
|
|
2021
1953
|
});
|
|
2022
|
-
const relId = reference
|
|
1954
|
+
const relId = reference?.attributes?.['r:id'];
|
|
2023
1955
|
if (!relId) return null;
|
|
2024
1956
|
|
|
2025
1957
|
// return the XmlPart
|
|
@@ -2070,9 +2002,38 @@ class Docx {
|
|
|
2070
2002
|
await this.contentTypes.save();
|
|
2071
2003
|
}
|
|
2072
2004
|
}
|
|
2073
|
-
_defineProperty(Docx, "mainDocumentRelType", 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument');
|
|
2074
2005
|
|
|
2075
2006
|
class DocxParser {
|
|
2007
|
+
/*
|
|
2008
|
+
* Word markup intro:
|
|
2009
|
+
*
|
|
2010
|
+
* In Word text nodes are contained in "run" nodes (which specifies text
|
|
2011
|
+
* properties such as font and color). The "run" nodes in turn are
|
|
2012
|
+
* contained in paragraph nodes which is the core unit of content.
|
|
2013
|
+
*
|
|
2014
|
+
* Example:
|
|
2015
|
+
*
|
|
2016
|
+
* <w:p> <-- paragraph
|
|
2017
|
+
* <w:r> <-- run
|
|
2018
|
+
* <w:rPr> <-- run properties
|
|
2019
|
+
* <w:b/> <-- bold
|
|
2020
|
+
* </w:rPr>
|
|
2021
|
+
* <w:t>This is text.</w:t> <-- actual text
|
|
2022
|
+
* </w:r>
|
|
2023
|
+
* </w:p>
|
|
2024
|
+
*
|
|
2025
|
+
* see: http://officeopenxml.com/WPcontentOverview.php
|
|
2026
|
+
*/
|
|
2027
|
+
|
|
2028
|
+
static PARAGRAPH_NODE = 'w:p';
|
|
2029
|
+
static PARAGRAPH_PROPERTIES_NODE = 'w:pPr';
|
|
2030
|
+
static RUN_NODE = 'w:r';
|
|
2031
|
+
static RUN_PROPERTIES_NODE = 'w:rPr';
|
|
2032
|
+
static TEXT_NODE = 'w:t';
|
|
2033
|
+
static TABLE_ROW_NODE = 'w:tr';
|
|
2034
|
+
static TABLE_CELL_NODE = 'w:tc';
|
|
2035
|
+
static NUMBER_PROPERTIES_NODE = 'w:numPr';
|
|
2036
|
+
|
|
2076
2037
|
//
|
|
2077
2038
|
// constructor
|
|
2078
2039
|
//
|
|
@@ -2371,9 +2332,8 @@ class DocxParser {
|
|
|
2371
2332
|
//
|
|
2372
2333
|
|
|
2373
2334
|
isEmptyTextNode(node) {
|
|
2374
|
-
var _node$childNodes;
|
|
2375
2335
|
if (!this.isTextNode(node)) throw new Error(`Text node expected but '${node.nodeName}' received.`);
|
|
2376
|
-
if (!
|
|
2336
|
+
if (!node.childNodes?.length) return true;
|
|
2377
2337
|
const xmlTextNode = node.childNodes[0];
|
|
2378
2338
|
if (!XmlNode.isTextNode(xmlTextNode)) throw new Error("Invalid XML structure. 'w:t' node should contain a single text node only.");
|
|
2379
2339
|
if (!xmlTextNode.textContent) return true;
|
|
@@ -2381,8 +2341,7 @@ class DocxParser {
|
|
|
2381
2341
|
}
|
|
2382
2342
|
isEmptyRun(node) {
|
|
2383
2343
|
if (!this.isRunNode(node)) throw new Error(`Run node expected but '${node.nodeName}' received.`);
|
|
2384
|
-
for (const child of
|
|
2385
|
-
var _node$childNodes2;
|
|
2344
|
+
for (const child of node.childNodes ?? []) {
|
|
2386
2345
|
if (this.isRunPropertiesNode(child)) continue;
|
|
2387
2346
|
if (this.isTextNode(child) && this.isEmptyTextNode(child)) continue;
|
|
2388
2347
|
return false;
|
|
@@ -2390,40 +2349,10 @@ class DocxParser {
|
|
|
2390
2349
|
return true;
|
|
2391
2350
|
}
|
|
2392
2351
|
}
|
|
2393
|
-
/*
|
|
2394
|
-
* Word markup intro:
|
|
2395
|
-
*
|
|
2396
|
-
* In Word text nodes are contained in "run" nodes (which specifies text
|
|
2397
|
-
* properties such as font and color). The "run" nodes in turn are
|
|
2398
|
-
* contained in paragraph nodes which is the core unit of content.
|
|
2399
|
-
*
|
|
2400
|
-
* Example:
|
|
2401
|
-
*
|
|
2402
|
-
* <w:p> <-- paragraph
|
|
2403
|
-
* <w:r> <-- run
|
|
2404
|
-
* <w:rPr> <-- run properties
|
|
2405
|
-
* <w:b/> <-- bold
|
|
2406
|
-
* </w:rPr>
|
|
2407
|
-
* <w:t>This is text.</w:t> <-- actual text
|
|
2408
|
-
* </w:r>
|
|
2409
|
-
* </w:p>
|
|
2410
|
-
*
|
|
2411
|
-
* see: http://officeopenxml.com/WPcontentOverview.php
|
|
2412
|
-
*/
|
|
2413
|
-
_defineProperty(DocxParser, "PARAGRAPH_NODE", 'w:p');
|
|
2414
|
-
_defineProperty(DocxParser, "PARAGRAPH_PROPERTIES_NODE", 'w:pPr');
|
|
2415
|
-
_defineProperty(DocxParser, "RUN_NODE", 'w:r');
|
|
2416
|
-
_defineProperty(DocxParser, "RUN_PROPERTIES_NODE", 'w:rPr');
|
|
2417
|
-
_defineProperty(DocxParser, "TEXT_NODE", 'w:t');
|
|
2418
|
-
_defineProperty(DocxParser, "TABLE_ROW_NODE", 'w:tr');
|
|
2419
|
-
_defineProperty(DocxParser, "TABLE_CELL_NODE", 'w:tc');
|
|
2420
|
-
_defineProperty(DocxParser, "NUMBER_PROPERTIES_NODE", 'w:numPr');
|
|
2421
2352
|
|
|
2422
2353
|
class LinkPlugin extends TemplatePlugin {
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
_defineProperty(this, "contentType", 'link');
|
|
2426
|
-
}
|
|
2354
|
+
static linkRelType = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink';
|
|
2355
|
+
contentType = 'link';
|
|
2427
2356
|
async simpleTagReplacements(tag, data, context) {
|
|
2428
2357
|
const wordTextNode = this.utilities.docxParser.containingTextNode(tag.xmlTextNode);
|
|
2429
2358
|
const content = data.getScopeData();
|
|
@@ -2492,12 +2421,8 @@ class LinkPlugin extends TemplatePlugin {
|
|
|
2492
2421
|
}
|
|
2493
2422
|
}
|
|
2494
2423
|
}
|
|
2495
|
-
_defineProperty(LinkPlugin, "linkRelType", 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink');
|
|
2496
2424
|
|
|
2497
2425
|
class LoopListStrategy {
|
|
2498
|
-
constructor() {
|
|
2499
|
-
_defineProperty(this, "utilities", void 0);
|
|
2500
|
-
}
|
|
2501
2426
|
setUtilities(utilities) {
|
|
2502
2427
|
this.utilities = utilities;
|
|
2503
2428
|
}
|
|
@@ -2535,9 +2460,6 @@ class LoopListStrategy {
|
|
|
2535
2460
|
}
|
|
2536
2461
|
|
|
2537
2462
|
class LoopParagraphStrategy {
|
|
2538
|
-
constructor() {
|
|
2539
|
-
_defineProperty(this, "utilities", void 0);
|
|
2540
|
-
}
|
|
2541
2463
|
setUtilities(utilities) {
|
|
2542
2464
|
this.utilities = utilities;
|
|
2543
2465
|
}
|
|
@@ -2608,9 +2530,6 @@ let LoopOver = /*#__PURE__*/function (LoopOver) {
|
|
|
2608
2530
|
}({});
|
|
2609
2531
|
|
|
2610
2532
|
class LoopTableStrategy {
|
|
2611
|
-
constructor() {
|
|
2612
|
-
_defineProperty(this, "utilities", void 0);
|
|
2613
|
-
}
|
|
2614
2533
|
setUtilities(utilities) {
|
|
2615
2534
|
this.utilities = utilities;
|
|
2616
2535
|
}
|
|
@@ -2622,7 +2541,7 @@ class LoopTableStrategy {
|
|
|
2622
2541
|
if (!closeParagraph.parentNode) return false;
|
|
2623
2542
|
if (!this.utilities.docxParser.isTableCellNode(closeParagraph.parentNode)) return false;
|
|
2624
2543
|
const options = openTag.options;
|
|
2625
|
-
const forceRowLoop =
|
|
2544
|
+
const forceRowLoop = options?.loopOver === LoopOver.Row;
|
|
2626
2545
|
|
|
2627
2546
|
// If both tags are in the same cell, assume it's a paragraph loop (iterate content, not rows).
|
|
2628
2547
|
if (!forceRowLoop && openParagraph.parentNode === closeParagraph.parentNode) return false;
|
|
@@ -2659,12 +2578,9 @@ class LoopTableStrategy {
|
|
|
2659
2578
|
|
|
2660
2579
|
const LOOP_CONTENT_TYPE = 'loop';
|
|
2661
2580
|
class LoopPlugin extends TemplatePlugin {
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
_defineProperty(this, "loopStrategies", [new LoopTableStrategy(), new LoopListStrategy(), new LoopParagraphStrategy() // the default strategy
|
|
2666
|
-
]);
|
|
2667
|
-
}
|
|
2581
|
+
contentType = LOOP_CONTENT_TYPE;
|
|
2582
|
+
loopStrategies = [new LoopTableStrategy(), new LoopListStrategy(), new LoopParagraphStrategy() // the default strategy
|
|
2583
|
+
];
|
|
2668
2584
|
setUtilities(utilities) {
|
|
2669
2585
|
this.utilities = utilities;
|
|
2670
2586
|
this.loopStrategies.forEach(strategy => strategy.setUtilities(utilities));
|
|
@@ -2769,14 +2685,11 @@ class LoopPlugin extends TemplatePlugin {
|
|
|
2769
2685
|
}
|
|
2770
2686
|
|
|
2771
2687
|
class RawXmlPlugin extends TemplatePlugin {
|
|
2772
|
-
|
|
2773
|
-
super(...args);
|
|
2774
|
-
_defineProperty(this, "contentType", 'rawXml');
|
|
2775
|
-
}
|
|
2688
|
+
contentType = 'rawXml';
|
|
2776
2689
|
simpleTagReplacements(tag, data) {
|
|
2777
2690
|
const value = data.getScopeData();
|
|
2778
|
-
const replaceNode = value
|
|
2779
|
-
if (typeof
|
|
2691
|
+
const replaceNode = value?.replaceParagraph ? this.utilities.docxParser.containingParagraphNode(tag.xmlTextNode) : this.utilities.docxParser.containingTextNode(tag.xmlTextNode);
|
|
2692
|
+
if (typeof value?.xml === 'string') {
|
|
2780
2693
|
const newNode = this.utilities.xmlParser.parse(value.xml);
|
|
2781
2694
|
XmlNode.insertBefore(newNode, replaceNode);
|
|
2782
2695
|
}
|
|
@@ -2786,10 +2699,8 @@ class RawXmlPlugin extends TemplatePlugin {
|
|
|
2786
2699
|
|
|
2787
2700
|
const TEXT_CONTENT_TYPE = 'text';
|
|
2788
2701
|
class TextPlugin extends TemplatePlugin {
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
_defineProperty(this, "contentType", TEXT_CONTENT_TYPE);
|
|
2792
|
-
}
|
|
2702
|
+
contentType = TEXT_CONTENT_TYPE;
|
|
2703
|
+
|
|
2793
2704
|
/**
|
|
2794
2705
|
* Replace the node text content with the specified value.
|
|
2795
2706
|
*/
|
|
@@ -2864,7 +2775,6 @@ class TemplateCompiler {
|
|
|
2864
2775
|
this.delimiterSearcher = delimiterSearcher;
|
|
2865
2776
|
this.tagParser = tagParser;
|
|
2866
2777
|
this.options = options;
|
|
2867
|
-
_defineProperty(this, "pluginsLookup", void 0);
|
|
2868
2778
|
this.pluginsLookup = toDictionary(plugins, p => p.contentType);
|
|
2869
2779
|
}
|
|
2870
2780
|
|
|
@@ -2963,9 +2873,6 @@ class TemplateCompiler {
|
|
|
2963
2873
|
}
|
|
2964
2874
|
|
|
2965
2875
|
class TemplateExtension {
|
|
2966
|
-
constructor() {
|
|
2967
|
-
_defineProperty(this, "utilities", void 0);
|
|
2968
|
-
}
|
|
2969
2876
|
/**
|
|
2970
2877
|
* Called by the TemplateHandler at runtime.
|
|
2971
2878
|
*/
|
|
@@ -3051,13 +2958,13 @@ class Zip {
|
|
|
3051
2958
|
}
|
|
3052
2959
|
|
|
3053
2960
|
class Delimiters {
|
|
2961
|
+
tagStart = "{";
|
|
2962
|
+
tagEnd = "}";
|
|
2963
|
+
containerTagOpen = "#";
|
|
2964
|
+
containerTagClose = "/";
|
|
2965
|
+
tagOptionsStart = "[";
|
|
2966
|
+
tagOptionsEnd = "]";
|
|
3054
2967
|
constructor(initial) {
|
|
3055
|
-
_defineProperty(this, "tagStart", "{");
|
|
3056
|
-
_defineProperty(this, "tagEnd", "}");
|
|
3057
|
-
_defineProperty(this, "containerTagOpen", "#");
|
|
3058
|
-
_defineProperty(this, "containerTagClose", "/");
|
|
3059
|
-
_defineProperty(this, "tagOptionsStart", "[");
|
|
3060
|
-
_defineProperty(this, "tagOptionsEnd", "]");
|
|
3061
2968
|
Object.assign(this, initial);
|
|
3062
2969
|
this.encodeAndValidate();
|
|
3063
2970
|
if (this.containerTagOpen === this.containerTagClose) throw new Error(`${"containerTagOpen"} can not be equal to ${"containerTagClose"}`);
|
|
@@ -3073,22 +2980,22 @@ class Delimiters {
|
|
|
3073
2980
|
}
|
|
3074
2981
|
|
|
3075
2982
|
class TemplateHandlerOptions {
|
|
2983
|
+
plugins = createDefaultPlugins();
|
|
2984
|
+
|
|
2985
|
+
/**
|
|
2986
|
+
* Determines the behavior in case of an empty input data. If set to true
|
|
2987
|
+
* the tag will be left untouched, if set to false the tag will be replaced
|
|
2988
|
+
* by an empty string.
|
|
2989
|
+
*
|
|
2990
|
+
* Default: false
|
|
2991
|
+
*/
|
|
2992
|
+
skipEmptyTags = false;
|
|
2993
|
+
defaultContentType = TEXT_CONTENT_TYPE;
|
|
2994
|
+
containerContentType = LOOP_CONTENT_TYPE;
|
|
2995
|
+
delimiters = new Delimiters();
|
|
2996
|
+
maxXmlDepth = 20;
|
|
2997
|
+
extensions = {};
|
|
3076
2998
|
constructor(initial) {
|
|
3077
|
-
_defineProperty(this, "plugins", createDefaultPlugins());
|
|
3078
|
-
/**
|
|
3079
|
-
* Determines the behavior in case of an empty input data. If set to true
|
|
3080
|
-
* the tag will be left untouched, if set to false the tag will be replaced
|
|
3081
|
-
* by an empty string.
|
|
3082
|
-
*
|
|
3083
|
-
* Default: false
|
|
3084
|
-
*/
|
|
3085
|
-
_defineProperty(this, "skipEmptyTags", false);
|
|
3086
|
-
_defineProperty(this, "defaultContentType", TEXT_CONTENT_TYPE);
|
|
3087
|
-
_defineProperty(this, "containerContentType", LOOP_CONTENT_TYPE);
|
|
3088
|
-
_defineProperty(this, "delimiters", new Delimiters());
|
|
3089
|
-
_defineProperty(this, "maxXmlDepth", 20);
|
|
3090
|
-
_defineProperty(this, "extensions", {});
|
|
3091
|
-
_defineProperty(this, "scopeDataResolver", void 0);
|
|
3092
2999
|
Object.assign(this, initial);
|
|
3093
3000
|
if (initial) {
|
|
3094
3001
|
this.delimiters = new Delimiters(initial.delimiters);
|
|
@@ -3100,16 +3007,12 @@ class TemplateHandlerOptions {
|
|
|
3100
3007
|
}
|
|
3101
3008
|
|
|
3102
3009
|
class TemplateHandler {
|
|
3010
|
+
/**
|
|
3011
|
+
* Version number of the `easy-template-x` library.
|
|
3012
|
+
*/
|
|
3013
|
+
version = "4.1.3" ;
|
|
3014
|
+
xmlParser = new XmlParser();
|
|
3103
3015
|
constructor(options) {
|
|
3104
|
-
var _this$options$extensi, _this$options$extensi2, _this$options$extensi3, _this$options$extensi4;
|
|
3105
|
-
/**
|
|
3106
|
-
* Version number of the `easy-template-x` library.
|
|
3107
|
-
*/
|
|
3108
|
-
_defineProperty(this, "version", "4.1.0" );
|
|
3109
|
-
_defineProperty(this, "xmlParser", new XmlParser());
|
|
3110
|
-
_defineProperty(this, "docxParser", void 0);
|
|
3111
|
-
_defineProperty(this, "compiler", void 0);
|
|
3112
|
-
_defineProperty(this, "options", void 0);
|
|
3113
3016
|
this.options = new TemplateHandlerOptions(options);
|
|
3114
3017
|
|
|
3115
3018
|
//
|
|
@@ -3140,10 +3043,10 @@ class TemplateHandler {
|
|
|
3140
3043
|
tagParser,
|
|
3141
3044
|
compiler: this.compiler
|
|
3142
3045
|
};
|
|
3143
|
-
|
|
3046
|
+
this.options.extensions?.beforeCompilation?.forEach(extension => {
|
|
3144
3047
|
extension.setUtilities(extensionUtilities);
|
|
3145
3048
|
});
|
|
3146
|
-
|
|
3049
|
+
this.options.extensions?.afterCompilation?.forEach(extension => {
|
|
3147
3050
|
extension.setUtilities(extensionUtilities);
|
|
3148
3051
|
});
|
|
3149
3052
|
}
|
|
@@ -3165,18 +3068,17 @@ class TemplateHandler {
|
|
|
3165
3068
|
};
|
|
3166
3069
|
const contentParts = await docx.getContentParts();
|
|
3167
3070
|
for (const part of contentParts) {
|
|
3168
|
-
var _this$options$extensi5, _this$options$extensi6;
|
|
3169
3071
|
context.currentPart = part;
|
|
3170
3072
|
|
|
3171
3073
|
// extensions - before compilation
|
|
3172
|
-
await this.callExtensions(
|
|
3074
|
+
await this.callExtensions(this.options.extensions?.beforeCompilation, scopeData, context);
|
|
3173
3075
|
|
|
3174
3076
|
// compilation (do replacements)
|
|
3175
3077
|
const xmlRoot = await part.xmlRoot();
|
|
3176
3078
|
await this.compiler.compile(xmlRoot, scopeData, context);
|
|
3177
3079
|
|
|
3178
3080
|
// extensions - after compilation
|
|
3179
|
-
await this.callExtensions(
|
|
3081
|
+
await this.callExtensions(this.options.extensions?.afterCompilation, scopeData, context);
|
|
3180
3082
|
}
|
|
3181
3083
|
|
|
3182
3084
|
// export the result
|
|
@@ -3243,7 +3145,7 @@ class TemplateHandler {
|
|
|
3243
3145
|
let zip;
|
|
3244
3146
|
try {
|
|
3245
3147
|
zip = await Zip.load(file);
|
|
3246
|
-
} catch
|
|
3148
|
+
} catch {
|
|
3247
3149
|
throw new MalformedFileError('docx');
|
|
3248
3150
|
}
|
|
3249
3151
|
|