-
Notifications
You must be signed in to change notification settings - Fork 0
/
templater.js
68 lines (61 loc) · 1.55 KB
/
templater.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// by ZestyLemonade
const fs = require("fs");
const path = require("path");
function compile(template) {
const parts = [];
const reg = /{{.+?}}/g;
let index = 0;
while ((match = reg.exec(template)) !== null) {
const slice = match[0].slice(2, -2)
parts.push(["data", template.slice(index, match.index)]);
if(slice[0] === "#") {
parts.push(["func", slice.slice(1).split(" ")]);
} else {
parts.push(["fmt", slice]);
}
index = reg.lastIndex;
}
parts.push(["data", template.slice(index)]);
return parts.filter((i) => i);
}
function write(res, data) {
if(typeof data === "function") return data(res, false);
if(!data) return;
return res.write(data.toString());
}
function render(template, data, res) {
let shouldWrite = [true];
for (let part of template) {
if(part[0] === "func") {
switch(part[1][0]) {
case "if": shouldWrite.unshift(data[part[1][1]]); break;
case "unless": shouldWrite.unshift(!data[part[1][1]]); break;
case "end": shouldWrite.shift(); break;
}
continue;
}
if(!shouldWrite[0]) continue;
if(part[0] === "fmt") {
write(res, data[part[1]]);
} else {
res.write(part[1]);
}
}
}
class Templater {
constructor() {
this.templates = new Map();
}
add(file, name) {
if(!name) name = path.parse(file).name;
this.templates.set(name, compile(fs.readFileSync(file, "utf8")));
}
render(name, data) {
return (res, main = true) => {
if(main) res.writeHead(200, { "Content-Type": "text/html" });
render(this.templates.get(name), data, res);
if(main) res.end();
}
}
}
module.exports = Templater;