docxtemplater/es6/xml-templater.js
2021-09-04 10:15:02 +05:00

175 lines
5.1 KiB
JavaScript

const { wordToUtf8, convertSpaces, defaults } = require("./doc-utils");
const createScope = require("./scope-manager");
const xmlMatcher = require("./xml-matcher");
const { throwContentMustBeString } = require("./errors");
const Lexer = require("./lexer");
const Parser = require("./parser.js");
const render = require("./render.js");
const postrender = require("./postrender.js");
const resolve = require("./resolve.js");
const joinUncorrupt = require("./join-uncorrupt");
function getFullText(content, tagsXmlArray) {
const matcher = xmlMatcher(content, tagsXmlArray);
const result = matcher.matches.map(function (match) {
return match.array[2];
});
return wordToUtf8(convertSpaces(result.join("")));
}
module.exports = class XmlTemplater {
constructor(content, options) {
this.filePath = options.filePath;
this.cachedParsers = {};
this.modules = options.modules;
this.fileTypeConfig = options.fileTypeConfig;
this.contentType = options.contentType;
Object.keys(defaults).map(function (key) {
this[key] = options[key] != null ? options[key] : defaults[key];
}, this);
this.setModules({ inspect: { filePath: this.filePath } });
this.load(content);
}
load(content) {
if (typeof content !== "string") {
throwContentMustBeString(typeof content);
}
this.content = content;
}
setTags(tags) {
this.tags = tags != null ? tags : {};
this.scopeManager = createScope({
tags: this.tags,
parser: this.parser,
cachedParsers: this.cachedParsers,
});
return this;
}
resolveTags(tags) {
this.tags = tags != null ? tags : {};
this.scopeManager = createScope({
tags: this.tags,
parser: this.parser,
cachedParsers: this.cachedParsers,
});
const options = this.getOptions();
options.scopeManager = createScope(options);
options.resolve = resolve;
return resolve(options).then(({ resolved, errors }) => {
errors.forEach((error) => {
// error properties might not be defined if some foreign
// (unhandled error not throw by docxtemplater willingly) is
// thrown.
error.properties = error.properties || {};
error.properties.file = this.filePath;
});
if (errors.length !== 0) {
throw errors;
}
return Promise.all(resolved).then((resolved) => {
this.setModules({ inspect: { resolved } });
return (this.resolved = resolved);
});
});
}
getFullText() {
return getFullText(this.content, this.fileTypeConfig.tagsXmlTextArray);
}
setModules(obj) {
this.modules.forEach((module) => {
module.set(obj);
});
}
preparse() {
this.allErrors = [];
this.xmllexed = Lexer.xmlparse(this.content, {
text: this.fileTypeConfig.tagsXmlTextArray,
other: this.fileTypeConfig.tagsXmlLexedArray,
});
this.setModules({ inspect: { xmllexed: this.xmllexed } });
const { lexed, errors: lexerErrors } = Lexer.parse(
this.xmllexed,
this.delimiters
);
this.allErrors = this.allErrors.concat(lexerErrors);
this.lexed = lexed;
this.setModules({ inspect: { lexed: this.lexed } });
const options = this.getOptions();
Parser.preparse(this.lexed, this.modules, options);
}
parse() {
this.setModules({ inspect: { filePath: this.filePath } });
const options = this.getOptions();
this.parsed = Parser.parse(this.lexed, this.modules, options);
this.setModules({ inspect: { parsed: this.parsed } });
const { postparsed, errors: postparsedErrors } = Parser.postparse(
this.parsed,
this.modules,
options
);
this.postparsed = postparsed;
this.setModules({ inspect: { postparsed: this.postparsed } });
this.allErrors = this.allErrors.concat(postparsedErrors);
this.errorChecker(this.allErrors);
return this;
}
errorChecker(errors) {
if (errors.length) {
errors.forEach((error) => {
// error properties might not be defined if some foreign
// (unhandled error not thrown by docxtemplater willingly) is
// thrown.
error.properties = error.properties || {};
error.properties.file = this.filePath;
});
this.modules.forEach(function (module) {
errors = module.errorsTransformer(errors);
});
}
}
baseNullGetter(part, sm) {
const value = this.modules.reduce((value, module) => {
if (value != null) {
return value;
}
return module.nullGetter(part, sm, this);
}, null);
if (value != null) {
return value;
}
return this.nullGetter(part, sm);
}
getOptions() {
return {
compiled: this.postparsed,
cachedParsers: this.cachedParsers,
tags: this.tags,
modules: this.modules,
parser: this.parser,
contentType: this.contentType,
baseNullGetter: this.baseNullGetter.bind(this),
filePath: this.filePath,
fileTypeConfig: this.fileTypeConfig,
linebreaks: this.linebreaks,
};
}
render(to) {
this.filePath = to;
const options = this.getOptions();
options.resolved = this.resolved;
options.scopeManager = createScope(options);
options.render = render;
options.joinUncorrupt = joinUncorrupt;
const { errors, parts } = render(options);
this.allErrors = errors;
this.errorChecker(errors);
if (errors.length > 0) {
return this;
}
this.content = postrender(parts, options);
this.setModules({ inspect: { content: this.content } });
return this;
}
};