-
Notifications
You must be signed in to change notification settings - Fork 8
/
index.js
124 lines (105 loc) · 2.53 KB
/
index.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const fs = require("fs");
const Handlebars = require("handlebars");
const { marked } = require("marked");
const { minify } = require('html-minifier');
/**
* Custom renderer for marked, namely to disable unwanted features.
* We only want to allow basic inline elements, like links, bold, or inline-code.
*
* @type {object}
*/
const renderer = {
heading(text) {
return text;
},
html(html) {
return html;
},
hr() {
return '';
},
list(body) {
return body;
},
listitem(text) {
return text;
},
br() {
return '';
},
paragraph(text) {
return text;
}
}
marked.use({ renderer });
/**
* Plugins to enable to minify HTML after generating from the template.
*/
const minifyOptions = {
collapseBooleanAttributes: true,
collapseWhitespace: true,
decodeEntities: true,
minifyCSS: true,
removeComments: true,
removeRedundantAttributes: true,
sortAttributes: true,
sortClassName: true,
};
Handlebars.registerHelper("date", (body) => {
if (!body) {
return "Present"
}
const date = new Date(body);
const datetime = date.toISOString();
const localeString = date.toLocaleDateString('en-US', {
month: "short",
year: "numeric"
});
return `<time datetime="${datetime}">${localeString}</time>`;
});
Handlebars.registerHelper("markdown", (body) => {
return marked.parse(body);
});
Handlebars.registerHelper("link", (body) => {
const parsed = new URL(body);
const host = (parsed.host.startsWith('www.')) ? parsed.host.substring(4) : parsed.host;
return `<a href="${body}">${host}</a>`;
});
/**
* @param {Object} resume
* @returns {string}
*/
function render(resume) {
const css = fs.readFileSync(__dirname + "/style.css", "utf-8");
const template = fs.readFileSync(__dirname + "/resume.handlebars", "utf-8");
const { profiles } = resume.basics;
if (Array.isArray(profiles)) {
const xTwitter = profiles.find((profile) => {
const name = profile.network.toLowerCase();
return name === 'x' || name === 'twitter';
});
if (xTwitter) {
let { username, url } = xTwitter;
if (!username && url) {
const match = url.match(/https?:\/\/.+?\/(\w{1,15})/);
if (match.length == 2) {
username = match[1];
}
}
if (username && !username.startsWith('@')) {
username = `@${username}`;
}
resume.custom = {
xTwitterHandle: username
}
}
}
const html = Handlebars.compile(template)({
css,
resume
});
return minify(html, minifyOptions);
}
module.exports = {
render
};