Trying to make a minimal version #152
Answered
by
brianjenkins94
brianjenkins94
asked this question in
Q&A
Replies: 1 comment
-
// TODO: Rewrite this using the regex sticky flag
function parse(template) {
template = template
.replace(/(?<!:)\/\/.*?$/gmu, "") // comments
.replace(/\\/gu, "\\\\") // backslashes
.replace(/"/gu, "\\\"") // double quotes
.replace(/`/gu, "\\`") // backticks
.replace(/\$\{/gu, "\\${"); // substitutions
const buffer = [];
const openTagRegex = /(.*?)<%\s*(=|-)?\s*/gsu;
const closeTagRegex = /'|"|`|\/\*|(\s*%>)/gu;
let index = 0;
let match;
while (match = openTagRegex.exec(template)) {
index = match[0].length + match.index;
const prefix = match[2] ?? "";
buffer.push(match[1]);
closeTagRegex.lastIndex = index;
let closeTag;
while (closeTag = closeTagRegex.exec(template)) {
if (closeTag[1] !== undefined) {
const value = template.substring(index, closeTag.index);
index = closeTagRegex.lastIndex;
openTagRegex.lastIndex = index;
buffer.push({
"type": {
"": "execute",
"-": "raw",
"=": "interpolate"
}[prefix],
"value": value
});
break;
}
}
}
if (index < template.length) {
buffer.push(template.substring(index));
}
return buffer;
}
function compile(nodes) {
const buffer = ["const buffer = [];"];
for (const node of nodes) {
if (typeof node === "string") {
buffer.push("buffer.push(`" + node + "`);");
} else {
let { type, value } = node;
switch (type) {
case "interpolate":
if (/[&<>"']/gu.test(value)) {
value = value.replace(/[&<>"']/gu, function(character) {
return {
"&": "&",
"<": "<",
">": ">",
"\"": """,
"'": "'"
}[character];
});
}
case "raw":
buffer.push("buffer.push(`" + value + "`);");
break;
case "execute":
buffer.push(value);
break;
default:
}
}
}
buffer.push("return buffer.join(\"\\n\");");
return buffer.join("\n");
}
function render(template, data = {}) {
// eslint-disable-next-line no-new-func, @typescript-eslint/no-implied-eval
return new Function(...Object.keys(data), compile(parse(template)))(...Object.values(data));
}
console.log(render("<%= foo %>\n<%= bar %>\n<%= baz %>\n<%= 2 + 2 %>\n<%- \"<br />\" %>", {
"foo": "bar",
"bar": "baz",
"baz": "foo"
})); |
Beta Was this translation helpful? Give feedback.
0 replies
Answer selected by
brianjenkins94
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
But I can't make sense of this:
https://github.com/eta-dev/eta/blob/master/src/compile-string.ts#L25-L41
Beta Was this translation helpful? Give feedback.
All reactions