-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
executable file
·186 lines (155 loc) · 5.55 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
'use strict';
const fs = require('fs');
const path = require('path');
const promisedHandlebars = require('promised-handlebars');
const HandlebarsAsync = promisedHandlebars(require('handlebars'));
const Handlebars = require('handlebars');
const handlebarsWax = require('handlebars-wax');
const addressFormat = require('address-format');
const imageToBase64 = require('image-to-base64');
const marked = require('marked');
const settings = require('./settings');
const BACKGROUND_COLOR = '#222831';
const ACCENT_COLOR = '#393e46';
const COLLORED_ACCENT_COLOR = '#FF5701';
const TEXT_COLOR = '#FFFFFF';
// global flags
let RENDER_ASCYNC = false;
let RENDER_MARKDOWN = process.env.RENDER_MARKDOWN || false;
let PROCESS_IMAGE = process.env.PROCESS_IMAGE || false;
const customHelpers = {
/**
* DO NOT USE ARROW FUNCTIONS! https://blog.pixelkritzel.de/posts/handlebars-dont-use-es6-arrow-functions-to-define-helpers/
*/
is: function(val1, val2, options) {
if(val1 && val1 === val2) {
return options.fn(this);
}
return options.inverse(this);
},
lowercase: function(str) {
return str.toLowerCase();
},
and: function(testA, testB, options) {
if (testA && testB) {
return options.fn(this);
} else {
return options.inverse(this);
}
},
imgPathToBase64: async function(imgPath) {
try {
// The image processing is disabled by default
if (!PROCESS_IMAGE) return imgPath;
// If no path provided throw an error
if (!imgPath) { throw new Error('No valid path for the profile-picture image!'); }
return RENDER_ASCYNC ? `data:image/jpg;base64,${await imageToBase64(imgPath)}` : imgPath;
} catch (e) {
throw new Error(`There was an error when trying to convert the image ${imgPath}: ${e}`)
}
},
removeProtocol: function(url) {
return url.replace(/.*?:\/\//g, '')
},
mdToHtml: function(string) {
// The rendering of Markdown markup is disabled by default
return RENDER_MARKDOWN ? marked(string) : string;
},
concat: function() {
let res = '';
for(let arg in arguments){
if (typeof arguments[arg] !== 'object' && typeof arguments[arg] !== 'function') {
res += arguments[arg];
}
}
return res;
},
formatAddress: function(address, city, region, postalCode, countryCode) {
let addressList = addressFormat({
address: address,
city: city,
subdivision: region,
postalCode: postalCode,
countryCode: countryCode
});
return addressList.join('<br/>');
},
formatDate: function(dateString) {
const parsedDate = new Date(dateString);
// standalone year
if (/^([1-2][0-9]{3})$/.test(dateString)) {
return (parsedDate.getFullYear()).toString();
// year month YYYY-MM format
} else if (/^([1-2][0-9]{3}-[0-1]?[0-9])$/.test(dateString)) {
return `${String(parsedDate.getMonth() + 1).padStart(2, '0')}/${parsedDate.getFullYear()}`;
} else {
// return the date in DD/MM/YYYY format
return parsedDate.toLocaleDateString('en-GB', {year: 'numeric', month: '2-digit', day: '2-digit'});
}
},
};
// Register custom handlebars helpers
HandlebarsAsync.registerHelper(customHelpers);
Handlebars.registerHelper(customHelpers);
/**
* Setter for the RENDER_MARKDOWN flag
*/
const enableMarkdownSupport = () => RENDER_MARKDOWN = true;
/**
* Setter for the PROCESS_IMAGE flag
*/
const enableImageProcessing = () => PROCESS_IMAGE = true;
/**
* Function rendering the resume with 2promised-handlebars" allowing usage of async helpers
* @param {Object} resumeJson The source resume object
* @returns {Promise<String>} Promise resolving to the HTML markup
*/
const renderAsync = async (resumeJson) => {
// change the global flag
RENDER_ASCYNC = true;
return await render(resumeJson);
};
/**
* Renders resume from a resume object and returns HTML Markup
* @param {Object] resumeJson The source resume object
* @returns {string|Promise<String>} The rednered HMTML Markupt or a Promise resolving to it
*/
const render = (resumeJson) => {
let css, fa, faV4Shim, resumeTemplate;
try {
css = fs.readFileSync(path.resolve(__dirname, 'styles/main.css'), 'utf-8');
// Replace the default colors if defined in settings
// Replace background #222831
if (settings.colors.background) { css = css.replace(new RegExp(BACKGROUND_COLOR, 'g'), settings.colors.background); }
// Replace accent #393e46
if (settings.colors.accent) { css = css.replace(new RegExp(ACCENT_COLOR, 'g'), settings.colors.accent); }
// Replace colored accent
if (settings.colors.coloredAccent) { css = css.replace(new RegExp(COLLORED_ACCENT_COLOR, 'g'), settings.colors.coloredAccent); }
// Replace text color
if (settings.colors.text) { css = css.replace(new RegExp(TEXT_COLOR, 'g'), settings.colors.text); }
resumeTemplate = fs.readFileSync(path.resolve(__dirname, 'resume.hbs'), 'utf-8');
fa = fs.readFileSync(path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/css/all.min.css"), 'utf-8');
} catch (err) {
throw new Error('The source handlebar template file or the stylesheet could not be read.');
}
const handlebars = RENDER_ASCYNC ? handlebarsWax(HandlebarsAsync) : handlebarsWax(Handlebars);
handlebars.partials(path.resolve(__dirname, 'views/partials/**/*.{hbs,js}'));
handlebars.partials(path.resolve(__dirname, 'views/components/**/*.{hbs,js}'));
try {
// as long as we use promised-handlebars handlebars.compile returns a Promise!
return handlebars.compile(resumeTemplate)({
css: css,
fa: fa,
faV4Shim: faV4Shim,
resume: resumeJson
});
} catch (err) {
throw new Error(`Error when rendering the template: ${err}!`);
}
};
module.exports = {
render,
renderAsync,
enableMarkdownSupport,
enableImageProcessing,
};