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