const MarkdownIt = require('markdown-it'); const fs = require('fs'); const path = require('path'); const moment = require('moment'); const jsonfile = require('jsonfile'); const async = require('async'); const fm = require('front-matter'); const config = require('../utils/config.json'); /** * Renders file using MarkdownIt */ function render(file) { const md = new MarkdownIt({html: true}); return md.render(file); } /** * Extracts file metadata such as parent directory */ function fileMetadata(filepath) { const paths = filepath.split('/'); const basename = path.basename(filepath); const metadata = { basename, filename: basename.substr(0, basename.lastIndexOf('.')), parrent: paths[paths.length - 2], dirname: path.dirname(filepath), }; return metadata; } /** * Compiles file that is a blog post */ function compilePost(filepath, data, fileData, callback) { const frontMatter = fm(fileData); const rendered = render(frontMatter.body); const metadata = fileMetadata(filepath); let published; if (frontMatter.attributes.date) { published = moment(frontMatter.attributes.date); } else { published = moment(); } const post = { published: published.format('MMMM DD, YYYY'), filename: metadata.filename, title: frontMatter.attributes.title, summary: frontMatter.attributes.summary, link: config.baseURL + '/post/' + metadata.filename }; const renderedpath = path.join(process.cwd(), config.renderPath, `${metadata.filename}.html`); fs.writeFile(renderedpath, rendered, (err) => { if (err) callback(err); else callback(null, post); }); } /** * Compiles other types of files such as resumes, about me and so on. */ function compileOther(filepath, data, fileData, callback) { const frontMatter = fm(fileData); const rendered = render(frontMatter.body); const metadata = fileMetadata(filepath); const post = { filename: metadata.filename } const renderedpath = path.join(process.cwd(), config.renderPath, `${metadata.filename}.html`); fs.writeFile(renderedpath, rendered, (err) => { if (err) callback(err); else callback(null, post); }); } function Compiler(data) { this.data = data; } /** * */ Compiler.prototype.addFile = function(filepath, isPost, callback) { if (isPost) { async.waterfall([ fs.readFile.bind(fs, filepath, 'utf8'), compilePost.bind(compilePost, filepath, this.data), ], (err, result) => { if (err) throw err; this.data.posts.push(result); console.log("[Compiler] File %s compiled", filepath); callback(); }); } else { async.waterfall([ fs.readFile.bind(fs, filepath, 'utf8'), compileOther.bind(compileOther, filepath, this.data), ], (err, result) => { if (err) throw err; this.data.other.push(result); console.log("[Compiler] File %s compiled", filepath); callback(); }); } }; /** * Writes updated data to the data file */ Compiler.prototype.writeData = function(callback) { const dataPath = path.join(process.cwd(), 'src/utils/data.json'); jsonfile.writeFile(dataPath, this.data, callback); }; module.exports = Compiler;