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

116 lines
3.0 KiB
JavaScript

const { wordToUtf8, concatArrays } = require("./doc-utils");
const { match, getValue, getValues } = require("./prefix-matcher");
function moduleParse(placeHolderContent, options) {
const modules = options.modules;
const startOffset = options.startOffset;
const endLindex = options.lIndex;
let moduleParsed;
options.offset = startOffset;
options.lIndex = endLindex;
options.match = match;
options.getValue = getValue;
options.getValues = getValues;
for (let i = 0, l = modules.length; i < l; i++) {
const module = modules[i];
moduleParsed = module.parse(placeHolderContent, options);
if (moduleParsed) {
moduleParsed.offset = startOffset;
moduleParsed.endLindex = endLindex;
moduleParsed.lIndex = endLindex;
moduleParsed.raw = placeHolderContent;
return moduleParsed;
}
}
return {
type: "placeholder",
value: placeHolderContent,
offset: startOffset,
endLindex,
lIndex: endLindex,
};
}
const parser = {
preparse(parsed, modules, options) {
function preparse(parsed, options) {
return modules.forEach(function (module) {
module.preparse(parsed, options);
});
}
return { preparsed: preparse(parsed, options) };
},
postparse(postparsed, modules, options) {
function getTraits(traitName, postparsed) {
return modules.map(function (module) {
return module.getTraits(traitName, postparsed);
});
}
let errors = [];
function postparse(postparsed, options) {
return modules.reduce(function (postparsed, module) {
const r = module.postparse(postparsed, {
...options,
postparse: (parsed, opts) => {
return postparse(parsed, { ...options, ...opts });
},
getTraits,
});
if (r == null) {
return postparsed;
}
if (r.errors) {
errors = concatArrays([errors, r.errors]);
return r.postparsed;
}
return r;
}, postparsed);
}
return { postparsed: postparse(postparsed, options), errors };
},
parse(lexed, modules, options) {
let inPlaceHolder = false;
let placeHolderContent = "";
let startOffset;
let tailParts = [];
return lexed.reduce(function lexedToParsed(parsed, token) {
if (token.type === "delimiter") {
inPlaceHolder = token.position === "start";
if (token.position === "end") {
placeHolderContent = wordToUtf8(placeHolderContent);
options.parse = (placeHolderContent) =>
moduleParse(placeHolderContent, {
...options,
...token,
startOffset,
modules,
});
parsed.push(options.parse(placeHolderContent));
Array.prototype.push.apply(parsed, tailParts);
tailParts = [];
}
if (token.position === "start") {
tailParts = [];
startOffset = token.offset;
}
placeHolderContent = "";
return parsed;
}
if (!inPlaceHolder) {
parsed.push(token);
return parsed;
}
if (token.type !== "content" || token.position !== "insidetag") {
tailParts.push(token);
return parsed;
}
placeHolderContent += token.value;
return parsed;
}, []);
},
};
module.exports = parser;