-
Notifications
You must be signed in to change notification settings - Fork 340
/
notable-html-generator.js
178 lines (156 loc) · 4.89 KB
/
notable-html-generator.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
/* libraries */
const fs = require('fs');
const _ = require('underscore');
const jsonic = require('jsonic');
/* Files */
const hallOfFameURLFile = '_data/notable-entries.json';
const hallOfFameCardsFile = '_includes/notableCards.html';
/* constant */
const TYPE_ESSAY = 'essay';
const TYPE_PROJECT = 'project';
const TYPE_PROFILE = 'site';
/* Util method for simulating printf("%s", arg1) function */
function formatString(string, ...args) {
let formatted = string;
for (let i = 0; i < arguments.length; i += 1) {
formatted = formatted.replace(/{{.*}}/, args[i]);
}
return formatted;
}
/* Util method for making an iterator for array */
function makeIterator(array) {
let nextIndex = 0;
return {
next() {
if (nextIndex < array.length) {
return {
value() {
const element = array[nextIndex];
nextIndex += 1;
return element;
},
};
}
return {
value() {
return null;
},
};
},
};
}
/* Util method to get the next piece of work in the order of site, project, essay */
function createWorkRotationalIterator(sites, projects, essays) {
const sitesIterator = makeIterator(sites);
const projectsIterator = makeIterator(projects);
const essaysIterator = makeIterator(essays);
const iterators = [sitesIterator, projectsIterator, essaysIterator];
const totalCount = sites.length + projects.length + essays.length;
let nextIteratorIndex = 0;
let currentIndex = 0;
return {
hasNext() {
return currentIndex < totalCount;
},
next() {
return {
value() {
const work = iterators[nextIteratorIndex].next().value();
if (work != null) {
currentIndex += 1;
}
nextIteratorIndex = (nextIteratorIndex + 1) % 3;
return work;
},
};
},
};
}
/* Attach extra fields to the work by looping through profileData to find the author's name and avatar url */
function attachIdentificationFields(work, profileData) {
const matchingProfile = _.find(profileData, function (profile) {
return profile.username && work.github && profile.username.toLowerCase() === work.github.toLowerCase();
});
if (matchingProfile != null) {
const identifiedWork = work;
identifiedWork.author = matchingProfile.name;
identifiedWork.imgURL = matchingProfile.picture;
return identifiedWork;
}
console.log(`Cannot find the owner for ${work.url}`);
return null;
}
/* Get the card's HTML */
function getCardHtml(data) {
const template =
`
<div class="ui centered fluid card">
<div class="content">
<img class="right floated tiny ui image" src="{{ img_url }}}">
<div class="header">{{ title }}}</div>
<div class="meta">{{ author }}</div>
<div class="description">{{{ reason }}}</div>
</div>
<a class="ui bottom attached button" href="{{ url }}" target="_blank">
<p> <i class="external icon"></i> View Work </p>
</a>
</div>
`;
const entry = formatString(template, data.imgURL, data.title, data.author, data.reason, data.url);
return entry;
}
/* Generate a row of exceptional work */
function getRowHtml(site, project, essay) {
let html = '<div class="three column stretched row">';
const works = [site, project, essay];
for (let i = 0; i < works.length; i += 1) {
html += '<div class="column">';
if (works[i] != null) {
html += getCardHtml(works[i]);
}
html += '</div>';
}
html += '</div>';
return html;
}
/* Generate template codes for hall of fame files */
function generateHallOfFameTemplate(profileData) {
const hallOfFameContents = fs.readFileSync(hallOfFameURLFile, 'utf8');
const works = jsonic(hallOfFameContents);
if (works.length > 0) {
const essays = [];
const projects = [];
const profiles = [];
for (let i = 0; i < works.length; i += 1) {
const work = attachIdentificationFields(works[i], profileData);
if (work != null) {
if (work.type === TYPE_ESSAY) {
essays.push(work);
} else if (work.type === TYPE_PROJECT) {
projects.push(work);
} else if (work.type === TYPE_PROFILE) {
profiles.push(work);
}
} else {
console.log(`Cannot find the author in data.json for ${works[i].title} using the given github username`);
}
}
const workRotationalIterator = createWorkRotationalIterator(profiles, projects, essays);
let html = '';
while (workRotationalIterator.hasNext()) {
html += getRowHtml(workRotationalIterator.next().value(),
workRotationalIterator.next().value(),
workRotationalIterator.next().value());
}
fs.writeFile(hallOfFameCardsFile, html, function (IOerr) {
console.log(`Writing to ${hallOfFameCardsFile}`);
if (IOerr) {
return console.log(IOerr);
}
return null;
});
}
}
module.exports = {
generateHallOfFameTemplate,
};