'use strict';
const util = require('util');
const gulp = require('gulp');
const concat = require('gulp-concat');
const terser = require('gulp-terser');
const clean = require('gulp-clean-css');
const settings = require('./settings.js');
const minify = require('html-minifier').minify;
const fs = require('fs');
const markdown = require('markdown-it');
const prism = require('markdown-it-prism');
const nunjucks = require('nunjucks');
const yaml = require('yaml');
const slugify = require('slugify');
const dayjs = require('dayjs');
const md = new markdown({
html: true,
linkify: false,
typographer: true,
breaks: true,
})
.use(prism)
.use(require('markdown-it-table').markdownItTable)
.use(require('markdown-it-deflist'))
.use(require('markdown-it-footnote'))
.use(require('markdown-it-anchor'))
.use(require('markdown-it-checkbox'))
nunjucks.configure('source/layouts', {
autoescape: false,
noCache: true,
});
gulp.task('js', () => gulp.src(settings.assets.javascript)
.pipe(concat('bundle.js'))
.pipe(terser())
.pipe(gulp.dest('tmp'))
);
gulp.task('css', () => gulp.src(settings.assets.css)
.pipe(concat('bundle.css'))
.pipe(clean({}))
.pipe(gulp.dest('tmp'))
);
gulp.task('generate-static', function (done) {
fs.readdir('content', function (err, items) {
let posts = [];
items.forEach(item => {
if (item.endsWith('.md')) {
processMarkdown(`content/${item}`);
let contents = fs.readFileSync(`content/${item}`, 'utf8');
let raw = contents.split('---');
let meta = null;
try {
meta = yaml.parse(raw[1])
} catch (error) { }
if (meta.layout == 'post') {
meta.dateFormatted = dayjs(meta.date).format('MMMM D, YYYY');
meta.dateOriginal = meta.date;
meta.date = new Date(meta.date);
posts.push(meta)
}
}
});
const css = fs.readFileSync('tmp/bundle.css', 'utf8');
const javascript = fs.readFileSync('tmp/bundle.js', 'utf8');
let page = nunjucks.render(`index.njk`, {
css: ``,
javascript: ``,
currentYear: new Date().getFullYear(),
timestamp: Math.floor(Date.now() / 1000),
vars: settings.vars,
posts: posts.reverse(),
});
util.log(`Processing: Index`);
fs.writeFileSync(`public/index.html`, minify(page, {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true,
removeTagWhitespace: true,
}));
});
done();
});
const processMarkdown = (file) => {
const contents = fs.readFileSync(file, 'utf8');
let raw = contents.split('---');
let meta = null;
try {
meta = yaml.parse(raw[1])
} catch (error) { }
//const slug = slugify(meta.title, { lower: true });
const slug = meta.slug;
const css = fs.readFileSync('tmp/bundle.css', 'utf8');
const javascript = fs.readFileSync('tmp/bundle.js', 'utf8');
raw.shift();
raw.shift();
let post = nunjucks.render(`${meta.layout}.njk`, {
content: md.render(raw.join('')),
title: meta.title.substring(0, 65),
description: meta.description,
css: ``,
javascript: ``,
slug: slug,
currentYear: new Date().getFullYear(),
timestamp: Math.floor(Date.now() / 1000),
vars: settings.vars,
writtenDate: {
formatted: dayjs(meta.date).format('MMMM D, YYYY'),
original: meta.date,
},
});
util.log(`Processing: ${meta.title}`);
fs.writeFileSync(`public/${slug}.html`, minify(post, {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true,
removeTagWhitespace: true,
}));
};
const watchers = (done) => {
gulp.watch('source/assets/*.css', {
awaitWriteFinish: true,
}).on('change', gulp.series('css'));
gulp.watch('source/assets/*.js', {
awaitWriteFinish: true,
}).on('change', gulp.series('js'));
gulp.watch('content/*.md', {
awaitWriteFinish: true,
}).on('change', processMarkdown);
done();
}
gulp.task('dev', gulp.parallel(watchers));
gulp.task('build', gulp.series('css', 'js', 'generate-static'));