116 lines
3.0 KiB
JavaScript
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;
|