2020-04-26 22:05:19 +00:00
|
|
|
import fs, {promises as fsp} from 'fs';
|
2020-03-20 18:08:29 +00:00
|
|
|
import {join} from 'path';
|
2020-04-26 22:05:19 +00:00
|
|
|
import cpy from 'cpy';
|
2020-08-06 12:47:06 +00:00
|
|
|
// @ts-expect-error
|
2020-03-20 18:08:29 +00:00
|
|
|
import htmlclean from 'htmlclean';
|
2020-04-26 22:05:19 +00:00
|
|
|
import marked from 'marked';
|
2020-03-20 18:08:29 +00:00
|
|
|
import nunjucks from 'nunjucks';
|
2020-04-26 22:05:19 +00:00
|
|
|
import refractor from 'refractor';
|
|
|
|
import rehype from 'rehype';
|
2020-03-20 18:08:29 +00:00
|
|
|
import sass from 'sass';
|
|
|
|
import {generateLove, LoveVariant} from './love';
|
2020-04-26 22:05:19 +00:00
|
|
|
import {getVersions, Versions} from './version';
|
2020-03-20 18:08:29 +00:00
|
|
|
|
2020-08-06 12:47:06 +00:00
|
|
|
export async function main(): Promise<void> {
|
2020-03-20 18:08:29 +00:00
|
|
|
// Create all required directories for the website.
|
|
|
|
await fsp.mkdir(join(__dirname, '../../public/css/'), {recursive: true});
|
2020-08-06 12:47:06 +00:00
|
|
|
await fsp.copyFile(
|
|
|
|
join(__dirname, '../../node_modules/modern-normalize/modern-normalize.css'),
|
|
|
|
join(__dirname, '../../public/css/modern-normalize.css')
|
|
|
|
);
|
|
|
|
|
2020-03-20 18:08:29 +00:00
|
|
|
await fsp.mkdir(join(__dirname, '../../public/images/'), {recursive: true});
|
|
|
|
|
|
|
|
// Configure Nunjucks to use the templates for `source/pages/`.
|
|
|
|
nunjucks.configure(join(__dirname, '../pages/'), {
|
|
|
|
lstripBlocks: true,
|
|
|
|
trimBlocks: true,
|
|
|
|
throwOnUndefined: true
|
|
|
|
});
|
|
|
|
|
|
|
|
const love: LoveVariant[] = generateLove();
|
|
|
|
|
2020-04-26 22:05:19 +00:00
|
|
|
const versions: Versions = await getVersions();
|
|
|
|
|
2020-03-20 18:08:29 +00:00
|
|
|
// Write the colors to file.
|
|
|
|
await writeJSON(join(__dirname, '../../public/love.json'), love);
|
|
|
|
|
|
|
|
// Render the Sass to CSS.
|
|
|
|
let css: string = sass
|
|
|
|
.renderSync({
|
|
|
|
file: join(__dirname, '../pages/scss/style.scss'),
|
|
|
|
sourceMap: false
|
|
|
|
})
|
|
|
|
.css.toString();
|
|
|
|
|
|
|
|
// Generate the CSS custom properties.
|
|
|
|
const cssProperties = `:root {
|
|
|
|
--foreground-1: ${love[0].colors.foreground1};
|
|
|
|
--foreground-2: ${love[0].colors.foreground2};
|
|
|
|
--background-1: ${love[0].colors.background1};
|
|
|
|
--background-2: ${love[0].colors.background2};
|
|
|
|
${love[0].colors.accents
|
|
|
|
.map((value, index) => ` --dark-accent-${index + 1}: ${value};`)
|
|
|
|
.join('\n')}
|
|
|
|
${love[0].colors.grays
|
|
|
|
.map((value, index) => ` --dark-gray-${index + 1}: ${value};`)
|
|
|
|
.join('\n')}
|
|
|
|
${love[1].colors.accents
|
|
|
|
.map((value, index) => ` --light-accent-${index + 1}: ${value};`)
|
|
|
|
.join('\n')}
|
|
|
|
${love[1].colors.grays
|
|
|
|
.map((value, index) => ` --light-gray-${index + 1}: ${value};`)
|
|
|
|
.join('\n')}
|
|
|
|
}\n`;
|
|
|
|
|
|
|
|
// Replace the predefined `:root` location with our properties.
|
|
|
|
css = css.replace(/\/\* :root-insert \*\//, cssProperties);
|
|
|
|
|
|
|
|
// Write the CSS to file.
|
|
|
|
await fsp.writeFile(join(__dirname, '../../public/css/style.css'), css);
|
|
|
|
|
|
|
|
// Render and write the `index.html` file.
|
|
|
|
await fsp.writeFile(
|
|
|
|
join(__dirname, '../../public/index.html'),
|
|
|
|
htmlclean(nunjucks.render('index.html', {love}))
|
|
|
|
);
|
|
|
|
|
2020-04-26 22:05:19 +00:00
|
|
|
const renderer: marked.Renderer = new marked.Renderer();
|
|
|
|
|
|
|
|
renderer.code = (code: string, language: string | undefined): string => {
|
|
|
|
if (language === undefined) {
|
|
|
|
throw new Error('Markdown code block with no language detected');
|
|
|
|
}
|
|
|
|
|
|
|
|
const codeHTML: string = rehype()
|
|
|
|
.stringify({type: 'root', children: refractor.highlight(code, language)})
|
|
|
|
.toString();
|
|
|
|
return `<pre><code class="language-${language}">${codeHTML}</code></pre>`;
|
|
|
|
};
|
|
|
|
|
|
|
|
await fsp.mkdir(join(__dirname, '../../public/get/'), {recursive: true});
|
|
|
|
const pagesToCreate: string[] = (
|
|
|
|
await fsp.readdir(join(__dirname, '../'))
|
2020-08-06 12:47:06 +00:00
|
|
|
).filter((value) => !['pages', 'scripts'].includes(value));
|
2020-04-26 22:05:19 +00:00
|
|
|
for (const page of pagesToCreate) {
|
|
|
|
const markdown: string = marked(
|
|
|
|
nunjucks.renderString(
|
|
|
|
await fsp.readFile(
|
2020-08-06 12:47:06 +00:00
|
|
|
join(__dirname, `../${page}/SITE README.md`),
|
2020-04-26 22:05:19 +00:00
|
|
|
'utf8'
|
|
|
|
),
|
|
|
|
{versions}
|
|
|
|
),
|
|
|
|
{renderer}
|
|
|
|
);
|
|
|
|
await fsp.mkdir(join(__dirname, `../../public/images/${page}/`), {
|
|
|
|
recursive: true
|
|
|
|
});
|
|
|
|
if (fs.existsSync(join(__dirname, `../${page}/images/`))) {
|
|
|
|
await cpy(
|
|
|
|
join(__dirname, `../${page}/images/*`),
|
|
|
|
join(__dirname, `../../public/images/${page}/`)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
let title = `Love for ${page
|
|
|
|
.replace(/-/g, ' ')
|
|
|
|
.split(' ')
|
2020-08-06 12:47:06 +00:00
|
|
|
.map((value) => capitalize(value))
|
2020-04-26 22:05:19 +00:00
|
|
|
.join(' ')}`;
|
|
|
|
|
|
|
|
switch (page) {
|
|
|
|
case 'vscode':
|
|
|
|
title = 'Love for VS Code';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-08-06 12:47:06 +00:00
|
|
|
const directory = join(__dirname, `../../public/get/${page}/`);
|
|
|
|
await fsp.mkdir(directory, {recursive: true});
|
2020-04-26 22:05:19 +00:00
|
|
|
await fsp.writeFile(
|
2020-08-06 12:47:06 +00:00
|
|
|
join(directory, 'index.html'),
|
2020-04-26 22:05:19 +00:00
|
|
|
htmlclean(nunjucks.render('get.html', {love, markdown, title}))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function capitalize(word: string): string {
|
|
|
|
return `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`;
|
2020-03-20 18:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Utility helper function to write some data to file as JSON.
|
|
|
|
export async function writeJSON(path: string, data: unknown): Promise<void> {
|
|
|
|
await fsp.writeFile(path, JSON.stringify(data, null, 2));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (require.main === module) {
|
2020-08-06 12:47:06 +00:00
|
|
|
void main();
|
2020-03-20 18:08:29 +00:00
|
|
|
}
|