53 lines
1.6 KiB
JavaScript
53 lines
1.6 KiB
JavaScript
|
const fs = require('fs');
|
||
|
const path = require('path');
|
||
|
const showdown = require('showdown');
|
||
|
const frontmatter = require('front-matter');
|
||
|
const converter = new showdown.Converter();
|
||
|
|
||
|
// Pages to process
|
||
|
const dir = 'src/pages';
|
||
|
// Where to put them
|
||
|
const distDir = 'dist'
|
||
|
// Required meta
|
||
|
const requiredMeta = ['title']
|
||
|
|
||
|
// Actual processing
|
||
|
function run() {
|
||
|
if (!fs.existsSync(distDir)) fs.mkdirSync(distDir);
|
||
|
fs.readdirSync(dir).forEach((file) => {
|
||
|
const filePath = path.join(dir, file)
|
||
|
const contents = fs.readFileSync(filePath);
|
||
|
const meta = frontmatter(contents.toString())
|
||
|
const errs = validateMeta(meta);
|
||
|
if (errs.length) throw `Errors in ${file}:\n${errs.join('\n')}`;
|
||
|
const dirPath = path.join(distDir, 'path' in meta.attributes ? meta.attributes.path : path.basename(file, '.md'));
|
||
|
if (!fs.existsSync(dirPath)) fs.mkdirSync(dirPath);
|
||
|
const body = converter.makeHtml(meta.body);
|
||
|
fs.writeFileSync(path.join(dirPath, 'index.html'), buildTemplate(meta.attributes.title, body))
|
||
|
});
|
||
|
}
|
||
|
|
||
|
|
||
|
// Generic template
|
||
|
const template = fs.readFileSync(path.join('src', 'pages.html')).toString();
|
||
|
|
||
|
// Inject the title and body
|
||
|
function buildTemplate(title, body) {
|
||
|
return template
|
||
|
.replace('{{title}}', title)
|
||
|
.replace('{{body}}', body)
|
||
|
}
|
||
|
|
||
|
// Validate a page's metadata
|
||
|
function validateMeta(meta) {
|
||
|
const attr = meta.attributes;
|
||
|
let errs = [];
|
||
|
requiredMeta.forEach((required) => {
|
||
|
if (!(required in attr)) errs.push(`missing ${required}`);
|
||
|
});
|
||
|
return errs
|
||
|
}
|
||
|
|
||
|
// Run the h*ckin' thing
|
||
|
run();
|