docxtemplater
Version:
docx and pptx generator working with templates and data (like Mustache, for Word and Powerpoint documents)
1,646 lines (1,374 loc) • 144 kB
JavaScript
/******/ (function() { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 760:
/***/ (function(module) {
module.exports = {
XMLSerializer: window.XMLSerializer,
DOMParser: window.DOMParser,
XMLDocument: window.XMLDocument
};
/***/ }),
/***/ 712:
/***/ (function(module) {
var ctXML = "[Content_Types].xml";
function collectContentTypes(overrides, defaults, zip) {
var partNames = {};
for (var i = 0, len = overrides.length; i < len; i++) {
var override = overrides[i];
var contentType = override.getAttribute("ContentType");
var partName = override.getAttribute("PartName").substr(1);
partNames[partName] = contentType;
}
var _loop = function _loop(_i, _len) {
var def = defaults[_i];
var contentType = def.getAttribute("ContentType");
var extension = def.getAttribute("Extension"); // eslint-disable-next-line no-loop-func
zip.file(/./).map(function (_ref) {
var name = _ref.name;
if (name.slice(name.length - extension.length - 1) === ".xml" && !partNames[name] && name !== ctXML) {
partNames[name] = contentType;
}
});
};
for (var _i = 0, _len = defaults.length; _i < _len; _i++) {
_loop(_i, _len);
}
return partNames;
}
module.exports = collectContentTypes;
/***/ }),
/***/ 557:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
var _require = __webpack_require__(760),
DOMParser = _require.DOMParser,
XMLSerializer = _require.XMLSerializer;
var _require2 = __webpack_require__(257),
throwXmlTagNotFound = _require2.throwXmlTagNotFound;
var _require3 = __webpack_require__(287),
last = _require3.last,
first = _require3.first;
function parser(tag) {
return {
get: function get(scope) {
if (tag === ".") {
return scope;
}
return scope[tag];
}
};
}
function setSingleAttribute(partValue, attr, attrValue) {
var regex = new RegExp("(<.* ".concat(attr, "=\")([^\"]+)(\".*)$"));
if (regex.test(partValue)) {
return partValue.replace(regex, "$1".concat(attrValue, "$3"));
}
var end = partValue.lastIndexOf("/>");
if (end === -1) {
end = partValue.lastIndexOf(">");
}
return partValue.substr(0, end) + " ".concat(attr, "=\"").concat(attrValue, "\"") + partValue.substr(end);
}
function getSingleAttribute(value, attributeName) {
var index = value.indexOf("".concat(attributeName, "=\""));
if (index === -1) {
return null;
}
var startIndex = value.substr(index).search(/["']/) + index;
var endIndex = value.substr(startIndex + 1).search(/["']/) + startIndex;
return value.substr(startIndex + 1, endIndex - startIndex);
}
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
function startsWith(str, prefix) {
return str.substring(0, prefix.length) === prefix;
}
function uniq(arr) {
var hash = {},
result = [];
for (var i = 0, l = arr.length; i < l; ++i) {
if (!hash[arr[i]]) {
hash[arr[i]] = true;
result.push(arr[i]);
}
}
return result;
}
function chunkBy(parsed, f) {
return parsed.reduce(function (chunks, p) {
var currentChunk = last(chunks);
var res = f(p);
if (res === "start") {
chunks.push([p]);
} else if (res === "end") {
currentChunk.push(p);
chunks.push([]);
} else {
currentChunk.push(p);
}
return chunks;
}, [[]]).filter(function (p) {
return p.length > 0;
});
}
var defaults = {
errorLogging: true,
paragraphLoop: false,
nullGetter: function nullGetter(part) {
return part.module ? "" : "undefined";
},
xmlFileNames: [],
parser: parser,
linebreaks: false,
fileTypeConfig: null,
delimiters: {
start: "{",
end: "}"
}
};
function mergeObjects() {
var resObj = {};
var obj, keys;
for (var i = 0; i < arguments.length; i += 1) {
obj = arguments[i];
keys = Object.keys(obj);
for (var j = 0; j < keys.length; j += 1) {
resObj[keys[j]] = obj[keys[j]];
}
}
return resObj;
}
function xml2str(xmlNode) {
var a = new XMLSerializer();
return a.serializeToString(xmlNode).replace(/xmlns(:[a-z0-9]+)?="" ?/g, "");
}
function str2xml(str) {
if (str.charCodeAt(0) === 65279) {
// BOM sequence
str = str.substr(1);
}
var parser = new DOMParser();
return parser.parseFromString(str, "text/xml");
}
var charMap = [["&", "&"], ["<", "<"], [">", ">"], ['"', """], ["'", "'"]];
function escapeRegExp(str) {
// to be able to use a string as a regex
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
var charMapRegexes = charMap.map(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
endChar = _ref2[0],
startChar = _ref2[1];
return {
rstart: new RegExp(escapeRegExp(startChar), "g"),
rend: new RegExp(escapeRegExp(endChar), "g"),
start: startChar,
end: endChar
};
});
function wordToUtf8(string) {
var r;
for (var i = charMapRegexes.length - 1; i >= 0; i--) {
r = charMapRegexes[i];
string = string.replace(r.rstart, r.end);
}
return string;
}
function utf8ToWord(string) {
if (typeof string !== "string") {
string = string.toString();
}
var r;
for (var i = 0, l = charMapRegexes.length; i < l; i++) {
r = charMapRegexes[i];
string = string.replace(r.rend, r.start);
}
return string;
} // This function is written with for loops for performance
function concatArrays(arrays) {
var result = [];
for (var i = 0; i < arrays.length; i++) {
var array = arrays[i];
for (var j = 0, len = array.length; j < len; j++) {
result.push(array[j]);
}
}
return result;
}
var spaceRegexp = new RegExp(String.fromCharCode(160), "g");
function convertSpaces(s) {
return s.replace(spaceRegexp, " ");
}
function pregMatchAll(regex, content) {
/* regex is a string, content is the content. It returns an array of all matches with their offset, for example:
regex=la
content=lolalolilala
returns: [{array: {0: 'la'},offset: 2},{array: {0: 'la'},offset: 8},{array: {0: 'la'} ,offset: 10}]
*/
var matchArray = [];
var match;
while ((match = regex.exec(content)) != null) {
matchArray.push({
array: match,
offset: match.index
});
}
return matchArray;
}
function isEnding(value, element) {
return value === "</" + element + ">";
}
function isStarting(value, element) {
return value.indexOf("<" + element) === 0 && [">", " "].indexOf(value[element.length + 1]) !== -1;
}
function getRight(parsed, element, index) {
var val = getRightOrNull(parsed, element, index);
if (val !== null) {
return val;
}
throwXmlTagNotFound({
position: "right",
element: element,
parsed: parsed,
index: index
});
}
function getRightOrNull(parsed, elements, index) {
if (typeof elements === "string") {
elements = [elements];
}
var level = 1;
for (var i = index, l = parsed.length; i < l; i++) {
var part = parsed[i];
for (var j = 0, len = elements.length; j < len; j++) {
var element = elements[j];
if (isEnding(part.value, element)) {
level--;
}
if (isStarting(part.value, element)) {
level++;
}
if (level === 0) {
return i;
}
}
}
return null;
}
function getLeft(parsed, element, index) {
var val = getLeftOrNull(parsed, element, index);
if (val !== null) {
return val;
}
throwXmlTagNotFound({
position: "left",
element: element,
parsed: parsed,
index: index
});
}
function getLeftOrNull(parsed, elements, index) {
if (typeof elements === "string") {
elements = [elements];
}
var level = 1;
for (var i = index; i >= 0; i--) {
var part = parsed[i];
for (var j = 0, len = elements.length; j < len; j++) {
var element = elements[j];
if (isStarting(part.value, element)) {
level--;
}
if (isEnding(part.value, element)) {
level++;
}
if (level === 0) {
return i;
}
}
}
return null;
}
function isTagStart(tagType, _ref3) {
var type = _ref3.type,
tag = _ref3.tag,
position = _ref3.position;
return type === "tag" && tag === tagType && position === "start";
}
function isTagEnd(tagType, _ref4) {
var type = _ref4.type,
tag = _ref4.tag,
position = _ref4.position;
return type === "tag" && tag === tagType && position === "end";
}
function isParagraphStart(part) {
return isTagStart("w:p", part) || isTagStart("a:p", part);
}
function isParagraphEnd(part) {
return isTagEnd("w:p", part) || isTagEnd("a:p", part);
}
function isTextStart(part) {
return part.type === "tag" && part.position === "start" && part.text;
}
function isTextEnd(part) {
return part.type === "tag" && part.position === "end" && part.text;
}
function isContent(p) {
return p.type === "placeholder" || p.type === "content" && p.position === "insidetag";
}
var corruptCharacters = /[\x00-\x08\x0B\x0C\x0E-\x1F]/; // 00 NUL '\0' (null character)
// 01 SOH (start of heading)
// 02 STX (start of text)
// 03 ETX (end of text)
// 04 EOT (end of transmission)
// 05 ENQ (enquiry)
// 06 ACK (acknowledge)
// 07 BEL '\a' (bell)
// 08 BS '\b' (backspace)
// 0B VT '\v' (vertical tab)
// 0C FF '\f' (form feed)
// 0E SO (shift out)
// 0F SI (shift in)
// 10 DLE (data link escape)
// 11 DC1 (device control 1)
// 12 DC2 (device control 2)
// 13 DC3 (device control 3)
// 14 DC4 (device control 4)
// 15 NAK (negative ack.)
// 16 SYN (synchronous idle)
// 17 ETB (end of trans. blk)
// 18 CAN (cancel)
// 19 EM (end of medium)
// 1A SUB (substitute)
// 1B ESC (escape)
// 1C FS (file separator)
// 1D GS (group separator)
// 1E RS (record separator)
// 1F US (unit separator)
function hasCorruptCharacters(string) {
return corruptCharacters.test(string);
}
function invertMap(map) {
return Object.keys(map).reduce(function (invertedMap, key) {
var value = map[key];
invertedMap[value] = invertedMap[value] || [];
invertedMap[value].push(key);
return invertedMap;
}, {});
}
module.exports = {
endsWith: endsWith,
startsWith: startsWith,
isContent: isContent,
isParagraphStart: isParagraphStart,
isParagraphEnd: isParagraphEnd,
isTagStart: isTagStart,
isTagEnd: isTagEnd,
isTextStart: isTextStart,
isTextEnd: isTextEnd,
uniq: uniq,
chunkBy: chunkBy,
last: last,
first: first,
mergeObjects: mergeObjects,
xml2str: xml2str,
str2xml: str2xml,
getRightOrNull: getRightOrNull,
getRight: getRight,
getLeftOrNull: getLeftOrNull,
getLeft: getLeft,
pregMatchAll: pregMatchAll,
convertSpaces: convertSpaces,
escapeRegExp: escapeRegExp,
charMapRegexes: charMapRegexes,
hasCorruptCharacters: hasCorruptCharacters,
defaults: defaults,
wordToUtf8: wordToUtf8,
utf8ToWord: utf8ToWord,
concatArrays: concatArrays,
invertMap: invertMap,
charMap: charMap,
getSingleAttribute: getSingleAttribute,
setSingleAttribute: setSingleAttribute
};
/***/ }),
/***/ 380:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
var _excluded = ["modules"];
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var DocUtils = __webpack_require__(557);
DocUtils.traits = __webpack_require__(505);
DocUtils.moduleWrapper = __webpack_require__(223);
var createScope = __webpack_require__(919);
var _require = __webpack_require__(257),
throwMultiError = _require.throwMultiError,
throwResolveBeforeCompile = _require.throwResolveBeforeCompile,
throwRenderInvalidTemplate = _require.throwRenderInvalidTemplate;
var logErrors = __webpack_require__(567);
var collectContentTypes = __webpack_require__(712);
var ctXML = "[Content_Types].xml";
var commonModule = __webpack_require__(107);
var Lexer = __webpack_require__(303);
var defaults = DocUtils.defaults,
str2xml = DocUtils.str2xml,
xml2str = DocUtils.xml2str,
moduleWrapper = DocUtils.moduleWrapper,
concatArrays = DocUtils.concatArrays,
uniq = DocUtils.uniq;
var _require2 = __webpack_require__(257),
XTInternalError = _require2.XTInternalError,
throwFileTypeNotIdentified = _require2.throwFileTypeNotIdentified,
throwFileTypeNotHandled = _require2.throwFileTypeNotHandled,
throwApiVersionError = _require2.throwApiVersionError;
var currentModuleApiVersion = [3, 27, 0];
var Docxtemplater = /*#__PURE__*/function () {
function Docxtemplater(zip) {
var _this = this;
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$modules = _ref.modules,
modules = _ref$modules === void 0 ? [] : _ref$modules,
options = _objectWithoutProperties(_ref, _excluded);
_classCallCheck(this, Docxtemplater);
if (!Array.isArray(modules)) {
throw new Error("The modules argument of docxtemplater's constructor must be an array");
}
this.scopeManagers = {};
this.compiled = {};
this.modules = [commonModule()];
this.setOptions(options);
modules.forEach(function (module) {
_this.attachModule(module);
});
if (arguments.length > 0) {
if (!zip || !zip.files || typeof zip.file !== "function") {
throw new Error("The first argument of docxtemplater's constructor must be a valid zip file (jszip v2 or pizzip v3)");
}
this.loadZip(zip); // remove the unsupported modules
this.modules = this.modules.filter(function (module) {
if (module.supportedFileTypes) {
if (!Array.isArray(module.supportedFileTypes)) {
throw new Error("The supportedFileTypes field of the module must be an array");
}
var isSupportedModule = module.supportedFileTypes.indexOf(_this.fileType) !== -1;
if (!isSupportedModule) {
module.on("detached");
}
return isSupportedModule;
}
return true;
});
this.compile();
this.v4Constructor = true;
}
}
_createClass(Docxtemplater, [{
key: "verifyApiVersion",
value: function verifyApiVersion(neededVersion) {
neededVersion = neededVersion.split(".").map(function (i) {
return parseInt(i, 10);
});
if (neededVersion.length !== 3) {
throwApiVersionError("neededVersion is not a valid version", {
neededVersion: neededVersion,
explanation: "the neededVersion must be an array of length 3"
});
}
if (neededVersion[0] !== currentModuleApiVersion[0]) {
throwApiVersionError("The major api version do not match, you probably have to update docxtemplater with npm install --save docxtemplater", {
neededVersion: neededVersion,
currentModuleApiVersion: currentModuleApiVersion,
explanation: "moduleAPIVersionMismatch : needed=".concat(neededVersion.join("."), ", current=").concat(currentModuleApiVersion.join("."))
});
}
if (neededVersion[1] > currentModuleApiVersion[1]) {
throwApiVersionError("The minor api version is not uptodate, you probably have to update docxtemplater with npm install --save docxtemplater", {
neededVersion: neededVersion,
currentModuleApiVersion: currentModuleApiVersion,
explanation: "moduleAPIVersionMismatch : needed=".concat(neededVersion.join("."), ", current=").concat(currentModuleApiVersion.join("."))
});
}
if (neededVersion[1] === currentModuleApiVersion[1] && neededVersion[2] > currentModuleApiVersion[2]) {
throwApiVersionError("The patch api version is not uptodate, you probably have to update docxtemplater with npm install --save docxtemplater", {
neededVersion: neededVersion,
currentModuleApiVersion: currentModuleApiVersion,
explanation: "moduleAPIVersionMismatch : needed=".concat(neededVersion.join("."), ", current=").concat(currentModuleApiVersion.join("."))
});
}
return true;
}
}, {
key: "setModules",
value: function setModules(obj) {
this.modules.forEach(function (module) {
module.set(obj);
});
}
}, {
key: "sendEvent",
value: function sendEvent(eventName) {
this.modules.forEach(function (module) {
module.on(eventName);
});
}
}, {
key: "attachModule",
value: function attachModule(module) {
if (this.v4Constructor) {
throw new Error("attachModule() should not be called manually when using the v4 constructor");
}
if (module.requiredAPIVersion) {
this.verifyApiVersion(module.requiredAPIVersion);
}
if (module.attached === true) {
throw new Error("Cannot attach a module that was already attached : \"".concat(module.name, "\". Maybe you are instantiating the module at the root level, and using it for multiple instances of Docxtemplater"));
}
module.attached = true;
if (typeof module === "function") {
throw new Error("Cannot attach a class/function as a module. Most probably you forgot to instantiate the module by using `new` on the module.");
}
var wrappedModule = moduleWrapper(module);
this.modules.push(wrappedModule);
wrappedModule.on("attached");
return this;
}
}, {
key: "setOptions",
value: function setOptions(options) {
var _this2 = this;
if (this.v4Constructor) {
throw new Error("setOptions() should not be called manually when using the v4 constructor");
}
if (!options) {
throw new Error("setOptions should be called with an object as first parameter");
}
this.options = {};
Object.keys(defaults).forEach(function (key) {
var defaultValue = defaults[key];
_this2.options[key] = options[key] != null ? options[key] : defaultValue;
_this2[key] = _this2.options[key];
});
if (this.zip) {
this.updateFileTypeConfig();
}
return this;
}
}, {
key: "loadZip",
value: function loadZip(zip) {
if (this.v4Constructor) {
throw new Error("loadZip() should not be called manually when using the v4 constructor");
}
if (zip.loadAsync) {
throw new XTInternalError("Docxtemplater doesn't handle JSZip version >=3, please use pizzip");
}
this.zip = zip;
this.updateFileTypeConfig();
this.modules = concatArrays([this.fileTypeConfig.baseModules.map(function (moduleFunction) {
return moduleFunction();
}), this.modules]);
return this;
}
}, {
key: "precompileFile",
value: function precompileFile(fileName) {
var currentFile = this.createTemplateClass(fileName);
currentFile.preparse();
this.compiled[fileName] = currentFile;
}
}, {
key: "compileFile",
value: function compileFile(fileName) {
this.compiled[fileName].parse();
}
}, {
key: "getScopeManager",
value: function getScopeManager(to, currentFile, tags) {
if (!this.scopeManagers[to]) {
this.scopeManagers[to] = createScope({
tags: tags || {},
parser: this.parser,
cachedParsers: currentFile.cachedParsers
});
}
return this.scopeManagers[to];
}
}, {
key: "resolveData",
value: function resolveData(data) {
var _this3 = this;
var errors = [];
if (!Object.keys(this.compiled).length) {
throwResolveBeforeCompile();
}
return Promise.resolve(data).then(function (data) {
_this3.setData(data);
_this3.setModules({
data: _this3.data,
Lexer: Lexer
});
_this3.mapper = _this3.modules.reduce(function (value, module) {
return module.getRenderedMap(value);
}, {});
return Promise.all(Object.keys(_this3.mapper).map(function (to) {
var _this3$mapper$to = _this3.mapper[to],
from = _this3$mapper$to.from,
data = _this3$mapper$to.data;
return Promise.resolve(data).then(function (data) {
var currentFile = _this3.compiled[from];
currentFile.filePath = to;
currentFile.scopeManager = _this3.getScopeManager(to, currentFile, data);
return currentFile.resolveTags(data).then(function (result) {
currentFile.scopeManager.finishedResolving = true;
return result;
}, function (errs) {
errors = errors.concat(errs);
});
});
})).then(function (resolved) {
if (errors.length !== 0) {
if (_this3.options.errorLogging) {
logErrors(errors);
}
throwMultiError(errors);
}
return concatArrays(resolved);
});
});
}
}, {
key: "compile",
value: function compile() {
var _this4 = this;
if (Object.keys(this.compiled).length) {
return this;
}
this.options = this.modules.reduce(function (options, module) {
return module.optionsTransformer(options, _this4);
}, this.options);
this.options.xmlFileNames = uniq(this.options.xmlFileNames);
this.xmlDocuments = this.options.xmlFileNames.reduce(function (xmlDocuments, fileName) {
var content = _this4.zip.files[fileName].asText();
xmlDocuments[fileName] = str2xml(content);
return xmlDocuments;
}, {});
this.setModules({
zip: this.zip,
xmlDocuments: this.xmlDocuments
});
this.getTemplatedFiles(); // Loop inside all templatedFiles (ie xml files with content).
// Sometimes they don't exist (footer.xml for example)
this.templatedFiles.forEach(function (fileName) {
if (_this4.zip.files[fileName] != null) {
_this4.precompileFile(fileName);
}
});
this.templatedFiles.forEach(function (fileName) {
if (_this4.zip.files[fileName] != null) {
_this4.compileFile(fileName);
}
});
this.setModules({
compiled: this.compiled
});
verifyErrors(this);
return this;
}
}, {
key: "updateFileTypeConfig",
value: function updateFileTypeConfig() {
var _this5 = this;
var fileType;
if (this.zip.files.mimetype) {
fileType = "odt";
}
var contentTypes = this.zip.files[ctXML];
this.targets = [];
var contentTypeXml = contentTypes ? str2xml(contentTypes.asText()) : null;
var overrides = contentTypeXml ? contentTypeXml.getElementsByTagName("Override") : null;
var defaults = contentTypeXml ? contentTypeXml.getElementsByTagName("Default") : null;
if (contentTypeXml) {
this.filesContentTypes = collectContentTypes(overrides, defaults, this.zip);
this.invertedContentTypes = DocUtils.invertMap(this.filesContentTypes);
this.setModules({
contentTypes: this.contentTypes,
invertedContentTypes: this.invertedContentTypes
});
}
this.modules.forEach(function (module) {
fileType = module.getFileType({
zip: _this5.zip,
contentTypes: contentTypes,
contentTypeXml: contentTypeXml,
overrides: overrides,
defaults: defaults,
doc: _this5
}) || fileType;
});
if (fileType === "odt") {
throwFileTypeNotHandled(fileType);
}
if (!fileType) {
throwFileTypeNotIdentified();
}
this.fileType = fileType;
this.fileTypeConfig = this.options.fileTypeConfig || this.fileTypeConfig || Docxtemplater.FileTypeConfig[this.fileType]();
return this;
}
}, {
key: "renderAsync",
value: function renderAsync(data) {
var _this6 = this;
return this.resolveData(data).then(function () {
return _this6.render();
});
}
}, {
key: "render",
value: function render(data) {
var _this7 = this;
this.compile();
if (this.errors.length > 0) {
throwRenderInvalidTemplate();
}
if (data) {
this.setData(data);
}
this.setModules({
data: this.data,
Lexer: Lexer
});
this.mapper = this.mapper || this.modules.reduce(function (value, module) {
return module.getRenderedMap(value);
}, {});
Object.keys(this.mapper).forEach(function (to) {
var _this7$mapper$to = _this7.mapper[to],
from = _this7$mapper$to.from,
data = _this7$mapper$to.data;
var currentFile = _this7.compiled[from];
currentFile.scopeManager = _this7.getScopeManager(to, currentFile, data);
currentFile.render(to);
_this7.zip.file(to, currentFile.content, {
createFolders: true
});
});
verifyErrors(this);
this.sendEvent("syncing-zip");
this.syncZip();
return this;
}
}, {
key: "syncZip",
value: function syncZip() {
var _this8 = this;
Object.keys(this.xmlDocuments).forEach(function (fileName) {
_this8.zip.remove(fileName);
var content = xml2str(_this8.xmlDocuments[fileName]);
return _this8.zip.file(fileName, content, {
createFolders: true
});
});
}
}, {
key: "setData",
value: function setData(data) {
this.data = data;
return this;
}
}, {
key: "getZip",
value: function getZip() {
return this.zip;
}
}, {
key: "createTemplateClass",
value: function createTemplateClass(path) {
var content = this.zip.files[path].asText();
return this.createTemplateClassFromContent(content, path);
}
}, {
key: "createTemplateClassFromContent",
value: function createTemplateClassFromContent(content, filePath) {
var _this9 = this;
var xmltOptions = {
filePath: filePath,
contentType: this.filesContentTypes[filePath]
};
Object.keys(defaults).concat(["filesContentTypes", "fileTypeConfig", "modules"]).forEach(function (key) {
xmltOptions[key] = _this9[key];
});
return new Docxtemplater.XmlTemplater(content, xmltOptions);
}
}, {
key: "getFullText",
value: function getFullText(path) {
return this.createTemplateClass(path || this.fileTypeConfig.textPath(this)).getFullText();
}
}, {
key: "getTemplatedFiles",
value: function getTemplatedFiles() {
var _this10 = this;
this.templatedFiles = this.fileTypeConfig.getTemplatedFiles(this.zip);
this.targets.forEach(function (target) {
_this10.templatedFiles.push(target);
});
return this.templatedFiles;
}
}]);
return Docxtemplater;
}();
function verifyErrors(doc) {
var compiled = doc.compiled;
var allErrors = [];
Object.keys(compiled).forEach(function (name) {
var templatePart = compiled[name];
allErrors = concatArrays([allErrors, templatePart.allErrors]);
});
doc.errors = allErrors;
if (allErrors.length !== 0) {
if (doc.options.errorLogging) {
logErrors(allErrors);
}
throwMultiError(allErrors);
}
}
Docxtemplater.DocUtils = DocUtils;
Docxtemplater.Errors = __webpack_require__(257);
Docxtemplater.XmlTemplater = __webpack_require__(827);
Docxtemplater.FileTypeConfig = __webpack_require__(952);
Docxtemplater.XmlMatcher = __webpack_require__(465);
module.exports = Docxtemplater;
/***/ }),
/***/ 567:
/***/ (function(module) {
// The error thrown here contains additional information when logged with JSON.stringify (it contains a properties object containing all suberrors).
function replaceErrors(key, value) {
if (value instanceof Error) {
return Object.getOwnPropertyNames(value).concat("stack").reduce(function (error, key) {
error[key] = value[key];
if (key === "stack") {
// This is used because in Firefox, stack is not an own property
error[key] = value[key].toString();
}
return error;
}, {});
}
return value;
}
function logger(error) {
// eslint-disable-next-line no-console
console.log(JSON.stringify({
error: error
}, replaceErrors));
if (error.properties && error.properties.errors instanceof Array) {
var errorMessages = error.properties.errors.map(function (error) {
return error.properties.explanation;
}).join("\n"); // eslint-disable-next-line no-console
console.log("errorMessages", errorMessages); // errorMessages is a humanly readable message looking like this :
// 'The tag beginning with "foobar" is unopened'
}
}
module.exports = logger;
/***/ }),
/***/ 257:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var _require = __webpack_require__(287),
last = _require.last,
first = _require.first;
function XTError(message) {
this.name = "GenericError";
this.message = message;
this.stack = new Error(message).stack;
}
XTError.prototype = Error.prototype;
function XTTemplateError(message) {
this.name = "TemplateError";
this.message = message;
this.stack = new Error(message).stack;
}
XTTemplateError.prototype = new XTError();
function XTRenderingError(message) {
this.name = "RenderingError";
this.message = message;
this.stack = new Error(message).stack;
}
XTRenderingError.prototype = new XTError();
function XTScopeParserError(message) {
this.name = "ScopeParserError";
this.message = message;
this.stack = new Error(message).stack;
}
XTScopeParserError.prototype = new XTError();
function XTInternalError(message) {
this.name = "InternalError";
this.properties = {
explanation: "InternalError"
};
this.message = message;
this.stack = new Error(message).stack;
}
XTInternalError.prototype = new XTError();
function XTAPIVersionError(message) {
this.name = "APIVersionError";
this.properties = {
explanation: "APIVersionError"
};
this.message = message;
this.stack = new Error(message).stack;
}
XTAPIVersionError.prototype = new XTError();
function throwApiVersionError(msg, properties) {
var err = new XTAPIVersionError(msg);
err.properties = _objectSpread({
id: "api_version_error"
}, properties);
throw err;
}
function throwMultiError(errors) {
var err = new XTTemplateError("Multi error");
err.properties = {
errors: errors,
id: "multi_error",
explanation: "The template has multiple errors"
};
throw err;
}
function getUnopenedTagException(options) {
var err = new XTTemplateError("Unopened tag");
err.properties = {
xtag: last(options.xtag.split(" ")),
id: "unopened_tag",
context: options.xtag,
offset: options.offset,
lIndex: options.lIndex,
explanation: "The tag beginning with \"".concat(options.xtag.substr(0, 10), "\" is unopened")
};
return err;
}
function getDuplicateOpenTagException(options) {
var err = new XTTemplateError("Duplicate open tag, expected one open tag");
err.properties = {
xtag: first(options.xtag.split(" ")),
id: "duplicate_open_tag",
context: options.xtag,
offset: options.offset,
lIndex: options.lIndex,
explanation: "The tag beginning with \"".concat(options.xtag.substr(0, 10), "\" has duplicate open tags")
};
return err;
}
function getDuplicateCloseTagException(options) {
var err = new XTTemplateError("Duplicate close tag, expected one close tag");
err.properties = {
xtag: first(options.xtag.split(" ")),
id: "duplicate_close_tag",
context: options.xtag,
offset: options.offset,
lIndex: options.lIndex,
explanation: "The tag ending with \"".concat(options.xtag.substr(0, 10), "\" has duplicate close tags")
};
return err;
}
function getUnclosedTagException(options) {
var err = new XTTemplateError("Unclosed tag");
err.properties = {
xtag: first(options.xtag.split(" ")).substr(1),
id: "unclosed_tag",
context: options.xtag,
offset: options.offset,
lIndex: options.lIndex,
explanation: "The tag beginning with \"".concat(options.xtag.substr(0, 10), "\" is unclosed")
};
return err;
}
function throwXmlTagNotFound(options) {
var err = new XTTemplateError("No tag \"".concat(options.element, "\" was found at the ").concat(options.position));
var part = options.parsed[options.index];
err.properties = {
id: "no_xml_tag_found_at_".concat(options.position),
explanation: "No tag \"".concat(options.element, "\" was found at the ").concat(options.position),
offset: part.offset,
part: part,
parsed: options.parsed,
index: options.index,
element: options.element
};
throw err;
}
function getCorruptCharactersException(_ref) {
var tag = _ref.tag,
value = _ref.value,
offset = _ref.offset;
var err = new XTRenderingError("There are some XML corrupt characters");
err.properties = {
id: "invalid_xml_characters",
xtag: tag,
value: value,
offset: offset,
explanation: "There are some corrupt characters for the field ${tag}"
};
return err;
}
function throwExpandNotFound(options) {
var _options$part = options.part,
value = _options$part.value,
offset = _options$part.offset,
_options$id = options.id,
id = _options$id === void 0 ? "raw_tag_outerxml_invalid" : _options$id,
_options$message = options.message,
message = _options$message === void 0 ? "Raw tag not in paragraph" : _options$message;
var part = options.part;
var _options$explanation = options.explanation,
explanation = _options$explanation === void 0 ? "The tag \"".concat(value, "\" is not inside a paragraph") : _options$explanation;
if (typeof explanation === "function") {
explanation = explanation(part);
}
var err = new XTTemplateError(message);
err.properties = {
id: id,
explanation: explanation,
rootError: options.rootError,
xtag: value,
offset: offset,
postparsed: options.postparsed,
expandTo: options.expandTo,
index: options.index
};
throw err;
}
function throwRawTagShouldBeOnlyTextInParagraph(options) {
var err = new XTTemplateError("Raw tag should be the only text in paragraph");
var tag = options.part.value;
err.properties = {
id: "raw_xml_tag_should_be_only_text_in_paragraph",
explanation: "The raw tag \"".concat(tag, "\" should be the only text in this paragraph. This means that this tag should not be surrounded by any text or spaces."),
xtag: tag,
offset: options.part.offset,
paragraphParts: options.paragraphParts
};
throw err;
}
function getUnmatchedLoopException(part) {
var location = part.location,
offset = part.offset;
var t = location === "start" ? "unclosed" : "unopened";
var T = location === "start" ? "Unclosed" : "Unopened";
var err = new XTTemplateError("".concat(T, " loop"));
var tag = part.value;
err.properties = {
id: "".concat(t, "_loop"),
explanation: "The loop with tag \"".concat(tag, "\" is ").concat(t),
xtag: tag,
offset: offset
};
return err;
}
function getUnbalancedLoopException(pair, lastPair) {
var err = new XTTemplateError("Unbalanced loop tag");
var lastL = lastPair[0].part.value;
var lastR = lastPair[1].part.value;
var l = pair[0].part.value;
var r = pair[1].part.value;
err.properties = {
id: "unbalanced_loop_tags",
explanation: "Unbalanced loop tags {#".concat(lastL, "}{/").concat(lastR, "}{#").concat(l, "}{/").concat(r, "}"),
offset: [lastPair[0].part.offset, pair[1].part.offset],
lastPair: {
left: lastPair[0].part.value,
right: lastPair[1].part.value
},
pair: {
left: pair[0].part.value,
right: pair[1].part.value
}
};
return err;
}
function getClosingTagNotMatchOpeningTag(_ref2) {
var tags = _ref2.tags;
var err = new XTTemplateError("Closing tag does not match opening tag");
err.properties = {
id: "closing_tag_does_not_match_opening_tag",
explanation: "The tag \"".concat(tags[0].value, "\" is closed by the tag \"").concat(tags[1].value, "\""),
openingtag: first(tags).value,
offset: [first(tags).offset, last(tags).offset],
closingtag: last(tags).value
};
return err;
}
function getScopeCompilationError(_ref3) {
var tag = _ref3.tag,
rootError = _ref3.rootError,
offset = _ref3.offset;
var err = new XTScopeParserError("Scope parser compilation failed");
err.properties = {
id: "scopeparser_compilation_failed",
offset: offset,
tag: tag,
explanation: "The scope parser for the tag \"".concat(tag, "\" failed to compile"),
rootError: rootError
};
return err;
}
function getScopeParserExecutionError(_ref4) {
var tag = _ref4.tag,
scope = _ref4.scope,
error = _ref4.error,
offset = _ref4.offset;
var err = new XTScopeParserError("Scope parser execution failed");
err.properties = {
id: "scopeparser_execution_failed",
explanation: "The scope parser for the tag ".concat(tag, " failed to execute"),
scope: scope,
offset: offset,
tag: tag,
rootError: error
};
return err;
}
function getLoopPositionProducesInvalidXMLError(_ref5) {
var tag = _ref5.tag,
offset = _ref5.offset;
var err = new XTTemplateError("The position of the loop tags \"".concat(tag, "\" would produce invalid XML"));
err.properties = {
tag: tag,
id: "loop_position_invalid",
explanation: "The tags \"".concat(tag, "\" are misplaced in the document, for example one of them is in a table and the other one outside the table"),
offset: offset
};
return err;
}
function throwUnimplementedTagType(part, index) {
var errorMsg = "Unimplemented tag type \"".concat(part.type, "\"");
if (part.module) {
errorMsg += " \"".concat(part.module, "\"");
}
var err = new XTTemplateError(errorMsg);
err.properties = {
part: part,
index: index,
id: "unimplemented_tag_type"
};
throw err;
}
function throwMalformedXml(part) {
var err = new XTInternalError("Malformed xml");
err.properties = {
part: part,
id: "malformed_xml"
};
throw err;
}
function throwResolveBeforeCompile() {
var err = new XTInternalError("You must run `.compile()` before running `.resolveData()`");
err.properties = {
id: "resolve_before_compile",
explanation: "You must run `.compile()` before running `.resolveData()`"
};
throw err;
}
function throwRenderInvalidTemplate() {
var err = new XTInternalError("You should not call .render on a document that had compilation errors");
err.properties = {
id: "render_on_invalid_template",
explanation: "You should not call .render on a document that had compilation errors"
};
throw err;
}
function throwFileTypeNotIdentified() {
var err = new XTInternalError("The filetype for this file could not be identified, is this file corrupted ?");
err.properties = {
id: "filetype_not_identified",
explanation: "The filetype for this file could not be identified, is this file corrupted ?"
};
throw err;
}
function throwXmlInvalid(content, offset) {
var err = new XTTemplateError("An XML file has invalid xml");
err.properties = {
id: "file_has_invalid_xml",
content: content,
offset: offset,
explanation: "The docx contains invalid XML, it is most likely corrupt"
};
throw err;
}
function throwFileTypeNotHandled(fileType) {
var err = new XTInternalError("The filetype \"".concat(fileType, "\" is not handled by docxtemplater"));
err.properties = {
id: "filetype_not_handled",
explanation: "The file you are trying to generate is of type \"".concat(fileType, "\", but only docx and pptx formats are handled"),
fileType: fileType
};
throw err;
}
module.exports = {
XTError: XTError,
XTTemplateError: XTTemplateError,
XTInternalError: XTInternalError,
XTScopeParserError: XTScopeParserError,
XTAPIVersionError: XTAPIVersionError,
// Remove this alias in v4
RenderingError: XTRenderingError,
XTRenderingError: XTRenderingError,
getClosingTagNotMatchOpeningTag: getClosingTagNotMatchOpeningTag,
getLoopPositionProducesInvalidXMLError: getLoopPositionProducesInvalidXMLError,
getScopeCompilationError: getScopeCompilationError,
getScopeParserExecutionError: getScopeParserExecutionError,
getUnclosedTagException: getUnclosedTagException,
getUnopenedTagException: getUnopenedTagException,
getUnmatchedLoopException: getUnmatchedLoopException,
getDuplicateCloseTagException: getDuplicateCloseTagException,
getDuplicateOpenTagException: getDuplicateOpenTagException,
getCorruptCharactersException: getCorruptCharactersException,
getUnbalancedLoopException: getUnbalancedLoopException,
throwApiVersionError: throwApiVersionError,
throwFileTypeNotHandled: throwFileTypeNotHandled,
throwFileTypeNotIdentified: throwFileTypeNotIdentified,
throwMalformedXml: throwMalformedXml,
throwMultiError: throwMultiError,
throwExpandNotFound: throwExpandNotFound,
throwRawTagShouldBeOnlyTextInParagraph: throwRawTagShouldBeOnlyTextInParagraph,
throwUnimplementedTagType: throwUnimplementedTagType,
throwXmlTagNotFound: throwXmlTagNotFound,
throwXmlInvalid: throwXmlInvalid,
throwResolveBeforeCompile: throwResolveBeforeCompile,
throwRenderInvalidTemplate: throwRenderInvalidTemplate
};
/***/ }),
/***/ 952:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
var loopModule = __webpack_require__(19);
var spacePreserveModule = __webpack_require__(95);
var rawXmlModule = __webpack_require__(182);
var expandPairTrait = __webpack_require__(999);
var render = __webpack_require__(163);
function PptXFileTypeConfig() {
return {
getTemplatedFiles: function getTemplatedFiles(zip) {
var slideTemplates = zip.file(/ppt\/(slideMasters)\/(slideMaster)\d+\.xml/).map(function (file) {
return file.name;
});
return slideTemplates.concat(["ppt/presentation.xml", "docProps/app.xml", "docProps/core.xml"]);
},
textPath: function textPath() {
return "ppt/slides/slide1.xml";
},
tagsXmlTextArray: ["Company", "HyperlinkBase", "Manager", "cp:category", "cp:keywords", "dc:creator", "dc:description", "dc:subject", "dc:title", "a:t", "m:t", "vt:lpstr"],
tagsXmlLexedArray: ["p:sp", "a:tc", "a:tr", "a:table", "a:p", "a:r", "a:rPr", "p:txBody", "a:txBody", "a:off", "a:ext", "p:graphicFrame", "p:xfrm", "a16:rowId"],
expandTags: [{
contains: "a:tc",
expand: "a:tr"
}],
onParagraphLoop: [{
contains: "a:p",
expand: "a:p",
onlyTextInTag: true
}],
tagRawXml: "p:sp",
baseModules: [loopModule, expandPairTrait, rawXmlModule, render],
tagShouldContain: [{
tag: "p:txBody",
shouldContain: ["a:p"],
value: "<a:p></a:p>"
}, {
tag: "a:txBody",
shouldContain: ["a:p"],
value: "<a:p></a:p>"
}]
};
}
function DocXFileTypeConfig() {
return {
getTemplatedFiles: function getTemplatedFiles(zip) {
var baseTags = ["docProps/core.xml", "docProps/app.xml", "word/settings.xml"];
var headerFooters = zip.file(/word\/(header|footer)\d+\.xml/).map(function (file) {
return file.name;
});
return headerFooters.concat(baseTags);
},
textPath: function textPath(doc) {
return doc.targets[0];
},
tagsXmlTextArray: ["Company", "HyperlinkBase", "Manager", "cp:category", "cp:keywords", "dc:creator", "dc:description", "dc:subject", "dc:title", "w:t", "m:t", "vt:lpstr"],
tagsXmlLexedArray: ["w:proofState", "w:tc", "w:tr", "w:table", "w:p", "w:r", "w:br", "w:rPr", "w:pPr", "w:spacing", "w:sdtContent", "w:drawing", "w:sectPr", "w:type", "w:headerReference", "w:footerReference"],
expandTags: [{
contains: "w:tc",
expand: "w:tr"
}],
onParagraphLoop: [{
contains: "w:p",
expand: "w:p",
onlyTextInTag: true
}],
tagRawXml: "w:p",
baseModules: [loopModule, spacePreserveModule, expandPairTrait, rawXmlModule, render],
tagShouldContain: [{
tag: "w:tc",
shouldContain: ["w:p"],
value: "<w:p></w:p>"
}, {
tag: "w:sdtContent",
shouldContain: ["w:p", "w:r"],
value: "<w:p></w:p>"
}]
};
}
module.exports = {
docx: DocXFileTypeConfig,
pptx: PptXFileTypeConfig
};
/***/ }),
/***/ 330:
/***/ (function(module) {
var docxContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml";
var docxmContentType = "application/vnd.ms-word.document.macroEnabled.main+xml";
var pptxContentType = "application/vnd.openxmlformats-officedocument.presentationml.slide+xml";
var dotxContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml";
var dotmContentType = "application/vnd.ms-word.template.macroEnabledTemplate.main+xml";
var filetypes = {
docx: [docxContentType, docxmContentType, dotxContentType, dotmContentType],
pptx: [pptxContentType]
};
module.exports = filetypes;
/***/ }),
/***/ 127:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
var _require = __webpack_require__(557),
endsWith = _require.endsWith,
startsWith = _require.startsWith;
var filetypes = __webpack_require__(330);
function addEmptyParagraphAfterTable(parts) {
var beforeSectPr = false;
for (var i = parts.length - 1; i >= 0; i--) {
var part = parts[i];
if (startsWith(part, "<w:sectPr")) {
beforeSectPr = true;
}
if (beforeSectPr) {
var trimmed = part.trim();
if (endsWith(trimmed, "</w:tbl>")) {
parts.splice(i + 1, 0, "<w:p><w:r><w:t></w:t></w:r></w:p>");
return parts;
}
if (endsWith(trimmed, "</w:p>")) {
return parts;
}
}
}
return parts;
}
function joinUncorrupt(parts, options) {
var contains = options.fileTypeConfig.tagShouldContain || []; // Before doing this "uncorruption" method here, th