-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.js
197 lines (188 loc) · 8.04 KB
/
build.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
187
188
189
190
191
192
193
194
195
196
197
const fs = require('fs');
const rss = require('./functions/rss');
const domino = require( 'domino' );
const utils = require( './utils' );
const getmeta = (html) => {
let image;
const doc = domino.createWindow().document;
const node = doc.createElement('div');
node.innerHTML = html;
const img = node.querySelector('img');
const description = node.querySelector('p').textContent;
const src = img ? img.getAttribute('src') : 'https://jdlrobson.com/gifme-200.gif';
if(src.indexOf('https://') === -1) {
image = `https://jdlrobson.com/${src}`;
} else {
image = src;
}
return {
description,
image
};
};
const slideshow = (items, className, includeImage) => {
return `<div class="slideshow ${className}">
<button class="slideshow__button" aria-hidden="true">left</button>
<ul class="slideshow__items">${items.map((item, i)=>`<li
class="slideshow__item ${i === 0 ? 'slideshow__item--active':''}">
${includeImage ? `<img src="/images/${utils.getImageSrcFromUri(item.url)}.png" alt="screenshot of ${item.url}"/>`: ''}
<a href="${item.url}">${item.title}</a>
<span>${item.description}</span>
</li>`).join('')}</ul>
<button class="slideshow__button slideshow__button--right" aria-hidden="true">right</button>
</div>`;
};
const buildpage = (path, title, html, stylesheetpath = '/index.css', meta) => {
if (!meta) {
meta = getmeta(html);
}
fs.writeFileSync(`${__dirname}/public/${path}`, `<!DOCTYPE HTML>
<html lang="en-gb" class="theme-light">
<head>
<meta property="og:type" content="profile"/>
<meta property="og:site_name" content="Jon Robson"/>
<meta property="og:image" content="${meta.image}"/>
<meta property="og:title" content="${title}"/>
<meta property="og:description" content="${meta.description}"/>
<meta property="og:url" content="https://jdlrobson.com/${path}"/>
<link rel="apple-touch-icon" sizes="180x180" href="/img-home/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/img-home/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/img-home/favicon-16x16.png">
<link rel="alternate" type="application/rss+xml" title="Journal RSS" href="/rss.xml" />
<link rel="manifest" href="/site.webmanifest">
<meta name="google-site-verification" content="mzjjfIIUZtRWhQwfd49STTtZLoyK0WiGkmMQG83ektw">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="stylesheet" href="/common.css" />
<link rel="stylesheet" href="${stylesheetpath}" />
<link rel="stylesheet" href="/icons.css" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>${title} - By Jon Robson</title>
<meta name="keywords" content="short stories, writing, web development, javascript" />
<meta name="Author" content="Jon Robson" />
<meta name="viewport" content="width=device-width,minimum-scale=0.5,initial-scale=1.0"/>
<meta name="google-site-verification" content="mzjjfIIUZtRWhQwfd49STTtZLoyK0WiGkmMQG83ektw" />
<!-- Cloudflare Web Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "e5a98d82be534f9e82e9d492f3632e56"}'></script><!-- End Cloudflare Web Analytics -->
<script>
(function () {
const mode = localStorage.getItem('darkmode');
const classList = document.documentElement.classList;
if ( mode ) {
classList.remove( 'theme-light' );
classList.add( 'theme-dark' );
}
}());
</script>
<body>
<script>
if ( document.querySelectorAll && Array.from !== undefined ) {
document.documentElement.className += ' client-js';
}
// ie 8 support
document.createElement('article');
document.createElement('section');
document.createElement('nav');
document.createElement('header');
</script>
${html}
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-75478054-1');
</script>
<script src="/index.js"></script>
<button class="darkModeToggle" id="enable-light-mode">☀️</button>
<button class="darkModeToggle" id="enable-dark-mode">🌙</button>
</body>
</html>`);
console.log(`Built page ${path}`)
};
const ABOUTME = `<header id="me">
<a href="/"><img src="/img-home/jdlr.jpg" title="Jon Robson"></a>
<p>I'm Jon Robson, a Welsh/English/European/adopted-Singaporean <a href="https://github.com/jdlrobson">open source web developer</a> and <a href="https://littledailydose.com/">published writer</a> living in San Francisco.</p>
<ul class="icons">
<li><a class="icon--tweet" href="https://twitter.com/jdlrobson">Twitter</a></li>
<li><a href="/rss.xml"><img src="/images/rss.png" alt="rss link"></a></li>
</ul>
</header>`;
function makePosts() {
const postsfolder = `${__dirname}/content/posts/`;
const posts = fs.readdirSync(postsfolder);
const namedPosts = [];
// All blog posts must look like <body>....</body>
for (var i=0; i<posts.length; i++) {
const filename = posts[i];
const blog = fs.readFileSync(`${postsfolder}/${filename}`).toString();
const startIndex = blog.indexOf('<body>') + '<body>'.length;
const endIndex = blog.indexOf('</body>');
const parts = filename.split('_');
let name = parts[1];
let index = undefined;
if ( name.match(/-[0-9a-f]+\.html/ ) ) {
index = -1;
} else {
name = name.replace( '.html', '' );
}
const title = name.split('-').slice(0, index).join(' ');
const html = `<nav><a href="/">Jon Robson</a> > <a href="/posts/">Blog posts</a> > <span>${title}</span></nav>`
+ blog.substr(startIndex, endIndex - startIndex) + ABOUTME;
// important to rename ' to - to match medium uris
const savefilename = filename.replace(/'/g, '-')
const path = `posts/${savefilename}`;
const published = new Date(parts[0]);
buildpage(path, title, html, '/posts.css');
namedPosts.push( { title, path, published } );
}
const postindexhtml = `
<nav><a href="/">Jon Robson</a></nav>
<article>
<section>
<h3>Blog posts</h3>
<ul>
${namedPosts.sort((p, p2)=>p.published < p2.published ? 1 : -1)
.map((post) => `<li><a href="/${post.path}">${post.title}</a> <div>${post.published.toDateString()}</div></li>`).join('')}
</ul>
</section>
</article>
${ ABOUTME }`;
buildpage(`posts/index.html`, `Jon Robson's blog posts`, postindexhtml, '/posts.css');
}
function makeHome() {
const homeheader = fs.readFileSync(`${__dirname}/content/index__header.html`);
const projects = JSON.parse(fs.readFileSync(`${__dirname}/content/projects.json`));
const homefooter = fs.readFileSync(`${__dirname}/content/index__footer.html`);
const technical = JSON.parse(fs.readFileSync(`${__dirname}/content/technical.json`));
const fiction = JSON.parse(fs.readFileSync(`${__dirname}/content/fiction.json`));
const html = `
<article>
${homeheader}
<section id="writes">
<h2>Technical writing</h2>
${slideshow(technical.filter((a) => !a.hidden))}
</section>
<section id="writes-fiction">
<h2>fiction / non-fiction</h2>
${slideshow(fiction)}
</section>
<section id="websites">
<h2>projects</h2>
${slideshow(projects, 'slideshow--projects', true)}
<p>Other clients include <a href="//ilga.org">ilga.org</a>, <a href=""http://tunbridgewellswintershelter.co.uk">tunbridge wells winter shelter</a>, <a href="https://bt.com">BT Group (internal)</a>, <a href="https://notesmusiccoffee.com">notesmusiccoffee</a>.</p>
</section>
${homefooter}</article>
`;
buildpage(`index.html`, `Jon Robson's personal site`, html, '/index.css');
}
function makerss() {
console.log('making RSS');
rss.makerss(true).then((html) => {
fs.writeFileSync(`${__dirname}/public/rss.xml`, html);
}, () => {
console.warn( 'Error generating RSS');
});
}
makeHome();
makePosts();
makerss();