124 lines
2.9 KiB
JavaScript
124 lines
2.9 KiB
JavaScript
const wrapper = require("../module-wrapper");
|
|
const { getScopeCompilationError } = require("../errors");
|
|
const { utf8ToWord, hasCorruptCharacters } = require("../doc-utils");
|
|
const { getCorruptCharactersException } = require("../errors");
|
|
|
|
const ftprefix = {
|
|
docx: "w",
|
|
pptx: "a",
|
|
};
|
|
|
|
class Render {
|
|
constructor() {
|
|
this.name = "Render";
|
|
this.recordRun = false;
|
|
this.recordedRun = [];
|
|
}
|
|
set(obj) {
|
|
if (obj.compiled) {
|
|
this.compiled = obj.compiled;
|
|
}
|
|
if (obj.data != null) {
|
|
this.data = obj.data;
|
|
}
|
|
}
|
|
getRenderedMap(mapper) {
|
|
return Object.keys(this.compiled).reduce((mapper, from) => {
|
|
mapper[from] = { from, data: this.data };
|
|
return mapper;
|
|
}, mapper);
|
|
}
|
|
optionsTransformer(options, docxtemplater) {
|
|
this.parser = docxtemplater.parser;
|
|
this.fileType = docxtemplater.fileType;
|
|
return options;
|
|
}
|
|
postparse(postparsed, options) {
|
|
const errors = [];
|
|
postparsed.forEach((p) => {
|
|
if (p.type === "placeholder") {
|
|
const tag = p.value;
|
|
try {
|
|
options.cachedParsers[p.lIndex] = this.parser(tag, { tag: p });
|
|
} catch (rootError) {
|
|
errors.push(
|
|
getScopeCompilationError({ tag, rootError, offset: p.offset })
|
|
);
|
|
}
|
|
}
|
|
});
|
|
return { postparsed, errors };
|
|
}
|
|
recordRuns(part) {
|
|
if (part.tag === `${ftprefix[this.fileType]}:r`) {
|
|
this.recordRun = false;
|
|
this.recordedRun = [];
|
|
} else if (part.tag === `${ftprefix[this.fileType]}:rPr`) {
|
|
if (part.position === "start") {
|
|
this.recordRun = true;
|
|
this.recordedRun = [part.value];
|
|
}
|
|
if (part.position === "end") {
|
|
this.recordedRun.push(part.value);
|
|
this.recordRun = false;
|
|
}
|
|
} else if (this.recordRun) {
|
|
this.recordedRun.push(part.value);
|
|
}
|
|
}
|
|
render(part, { scopeManager, linebreaks, nullGetter }) {
|
|
if (linebreaks) {
|
|
this.recordRuns(part);
|
|
}
|
|
if (part.type !== "placeholder" || part.module) {
|
|
return;
|
|
}
|
|
let value;
|
|
try {
|
|
value = scopeManager.getValue(part.value, { part });
|
|
} catch (e) {
|
|
return { errors: [e] };
|
|
}
|
|
if (value == null) {
|
|
value = nullGetter(part);
|
|
}
|
|
if (hasCorruptCharacters(value)) {
|
|
return {
|
|
errors: [
|
|
getCorruptCharactersException({
|
|
tag: part.value,
|
|
value,
|
|
offset: part.offset,
|
|
}),
|
|
],
|
|
};
|
|
}
|
|
if (typeof value !== "string") {
|
|
value = value.toString();
|
|
}
|
|
if (linebreaks) {
|
|
return this.renderLineBreaks(value);
|
|
}
|
|
return { value: utf8ToWord(value) };
|
|
}
|
|
renderLineBreaks(value) {
|
|
const p = ftprefix[this.fileType];
|
|
const br = this.fileType === "docx" ? "<w:r><w:br/></w:r>" : "<a:br/>";
|
|
const lines = value.split("\n");
|
|
const runprops = this.recordedRun.join("");
|
|
return {
|
|
value: lines
|
|
.map(function (line) {
|
|
return utf8ToWord(line);
|
|
})
|
|
.join(
|
|
`</${p}:t></${p}:r>${br}<${p}:r>${runprops}<${p}:t${
|
|
this.fileType === "docx" ? ' xml:space="preserve"' : ""
|
|
}>`
|
|
),
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = () => wrapper(new Render());
|