fs = require("co-fs-extra"), is = require("is"), matter = require("gray-matter"), Mode = require("stat-mode"), path = require("path"), readdir = require("recursive-readdir"), rm = require("rimraf"), thunkify = require("thunkify"), unyield = require("unyield"), utf8 = require("is-utf8"), Ware = require("ware"); function Metalsmith(t) { if (!(this instanceof Metalsmith)) return new Metalsmith(t); assert(t, "You must pass a working directory path."), this.plugins = [], this.ignores = [], this.directory(t), this.metadata({}), this.source("src"), this.destination("build"), this.concurrency(1 / 0), this.clean(!0), this.frontmatter(!0); } readdir = thunkify(readdir), rm = thunkify(rm), module.exports = Metalsmith, Metalsmith.prototype.use = function(t) { return this.plugins.push(t), this; }, Metalsmith.prototype.directory = function(t) { return arguments.length ? (assert(is.string(t), "You must pass a directory path string."), this._directory = t, this) : path.resolve(this._directory); }, Metalsmith.prototype.metadata = function(t) { return arguments.length ? (assert(is.object(t), "You must pass a metadata object."), this._metadata = clone(t), this) : this._metadata; }, Metalsmith.prototype.source = function(t) { return arguments.length ? (assert(is.string(t), "You must pass a source path string."), this._source = t, this) : this.path(this._source); }, Metalsmith.prototype.destination = function(t) { return arguments.length ? (assert(is.string(t), "You must pass a destination path string."), this._destination = t, this) : this.path(this._destination); }, Metalsmith.prototype.concurrency = function(t) { return arguments.length ? (assert(is.number(t), "You must pass a number for concurrency."), this._concurrency = t, this) : this._concurrency; }, Metalsmith.prototype.clean = function(t) { return arguments.length ? (assert(is.boolean(t), "You must pass a boolean."), this._clean = t, this) : this._clean; }, Metalsmith.prototype.frontmatter = function(t) { return arguments.length ? (assert(is.boolean(t), "You must pass a boolean."), this._frontmatter = t, this) : this._frontmatter; }, Metalsmith.prototype.ignore = function(t) { return arguments.length ? (this.ignores = this.ignores.concat(t), this) : this.ignores.slice(); }, Metalsmith.prototype.path = function() { var t = [].slice.call(arguments); return t.unshift(this.directory()), path.resolve.apply(path, t); }, Metalsmith.prototype.build = unyield(function*() { var t = this.clean(), e = this.destination(); t && (yield rm(path.join(e, "*"))); var i = yield this.process(); return yield this.write(i), i; }), Metalsmith.prototype.process = unyield(function*() { var t = yield this.read(); return t = yield this.run(t); }), Metalsmith.prototype.run = unyield(function*(t, e) { var i = new Ware(e || this.plugins); return (yield thunkify(i.run.bind(i))(t, this))[0]; }), Metalsmith.prototype.read = unyield(function*(t) { t = t || this.source(); for (var e, i = this.readFile.bind(this), r = this.concurrency(), s = this.ignores || null, n = yield readdir(t, s), a = [], o = 0; o < n.length; ) e = yield (e = n.slice(o, o + r)).map(i), a = a.concat(e), o += r; return n.reduce(function(e, i, r) { return i = path.relative(t, i), e[i] = a[r], e; }, {}); }), Metalsmith.prototype.readFile = unyield(function*(t) { var e = this.source(), i = {}; absolute(t) || (t = path.resolve(e, t)); try { var r, s = this.frontmatter(), n = yield fs.stat(t), a = yield fs.readFile(t); if (s && utf8(a)) { try { r = matter(a.toString()); } catch (e) { var o = new Error("Invalid frontmatter in the file at: " + t); throw o.code = "invalid_frontmatter", o; } (i = r.data).contents = new Buffer(r.content); } else i.contents = a; i.mode = Mode(n).toOctal(), i.stats = n; } catch (e) { if ("invalid_frontmatter" == e.code) throw e; throw e.message = "Failed to read the file at: " + t + "\n\n" + e.message, e.code = "failed_read", e; } return i; }), Metalsmith.prototype.write = unyield(function*(t, e) { e = e || this.destination(); for (var i = this.writeFile.bind(this), r = this.concurrency(), s = Object.keys(t), n = 0; n < s.length; ) yield s.slice(n, n + r).map(a), n += r; function a(r) { var s = path.resolve(e, r); return i(s, t[r]); } }), Metalsmith.prototype.writeFile = unyield(function*(t, e) { var i = this.destination(); absolute(t) || (t = path.resolve(i, t)); try { yield fs.outputFile(t, e.contents), e.mode && (yield fs.chmod(t, e.mode)); } catch (e) { throw e.message = "Failed to write the file at: " + t + "\n\n" + e.message, e; } }); Metalsmith actually fits on one slide File size does not matter on server side applications… but simplicity does