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('../../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) if (frontMatter.attributes.draft) { callback(null, null) return } 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, link: '/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 if (result == null) { callback() } else { 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