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;