UNPKG

hikaru-coffee

Version:

A static site generator that generates routes based on directories naturally.

317 lines (287 loc) 9.96 kB
// Generated by CoffeeScript 2.3.1 (function() { var Router, dateStrCompare, fm, fse, getAbsPathFn, getURLFn, glob, isCurrentPathFn, moment, path, yaml; path = require("path"); fm = require("front-matter"); fse = require("fs-extra"); yaml = require("js-yaml"); glob = require("glob"); moment = require("moment"); ({dateStrCompare, getAbsPathFn, getURLFn, isCurrentPathFn} = require("./utils")); module.exports = Router = class Router { constructor(logger, renderer, generator, translator, site) { // fn: param site, change site. this.register = this.register.bind(this); this.readData = this.readData.bind(this); this.writeData = this.writeData.bind(this); this.loadThemeAssets = this.loadThemeAssets.bind(this); this.loadTemplates = this.loadTemplates.bind(this); this.loadSrcs = this.loadSrcs.bind(this); this.renderAssets = this.renderAssets.bind(this); this.renderTemplates = this.renderTemplates.bind(this); this.renderPosts = this.renderPosts.bind(this); this.renderPages = this.renderPages.bind(this); this.generateData = this.generateData.bind(this); this.generatePosts = this.generatePosts.bind(this); this.generatePages = this.generatePages.bind(this); this.saveAssets = this.saveAssets.bind(this); this.savePosts = this.savePosts.bind(this); this.savePages = this.savePages.bind(this); this.saveData = this.saveData.bind(this); this.route = this.route.bind(this); this.logger = logger; this.renderer = renderer; this.generator = generator; this.translator = translator; this.site = site; this.store = { "beforeGenerating": [], "afterGenerating": [] }; this.getURL = getURLFn(this.site["siteConfig"]["baseURL"], this.site["siteConfig"]["rootDir"]); this.getAbsPath = getAbsPathFn(this.site["siteConfig"]["rootDir"]); } register(type, fn) { if (!(type in this.store)) { return; } if (fn instanceof Function) { return this.store[type].push(fn); } } matchFiles(pattern, options) { return new Promise(function(resolve, reject) { return glob(pattern, options, function(err, res) { if (err) { return reject(err); } return resolve(res); }); }); } readData(srcDir, srcPath) { this.logger.debug(`Hikaru is reading \`${path.join(srcDir, srcPath)}\`...`); return fse.readFile(path.join(srcDir, srcPath), "utf8").then(function(raw) { return { "srcPath": srcPath, "srcDir": srcDir, "text": raw, "raw": raw }; }); } writeData(srcDir, data) { this.logger.debug(`Hikaru is writing \`${path.join(this.site["docDir"], data["docPath"])}\`...`); if (data["content"] != null) { return fse.outputFile(path.join(this.site["docDir"], data["docPath"]), data["content"]); } return fse.copy(path.join(srcDir, data["srcPath"]), path.join(this.site["docDir"], data["docPath"])); } loadThemeAssets() { return this.matchFiles(path.join("**", "*"), { "nodir": true, "dot": true, "cwd": this.site["themeSrcDir"] }).then((themeSrcs) => { return Promise.all(themeSrcs.filter(function(srcPath) { // Asset is in sub dir. return path.dirname(srcPath) !== "."; }).map((srcPath) => { return this.readData(this.site["themeSrcDir"], srcPath).then((data) => { return this.site["assets"].push(data); }); })); }); } loadTemplates() { return this.matchFiles("*", { "nodir": true, "dot": true, "cwd": this.site["themeSrcDir"] }).then((templates) => { return Promise.all(templates.map((srcPath) => { return this.readData(this.site["themeSrcDir"], srcPath).then((data) => { data["key"] = path.basename(srcPath, path.extname(srcPath)); return this.site["templates"][data["key"]] = data; }); })); }); } loadSrcs() { return this.matchFiles(path.join("**", "*"), { "nodir": true, "dot": true, "cwd": this.site["srcDir"] }).then((srcs) => { return Promise.all(srcs.map((srcPath) => { return this.readData(this.site["srcDir"], srcPath).then((data) => { var parsed; if (typeof data["raw"] === "string") { parsed = fm(data["raw"]); data["text"] = parsed["body"]; data = Object.assign(data, parsed["attributes"]); if (data["text"] !== data["raw"]) { if (data["title"] != null) { data["title"] = data["title"].toString(); } if (data["layout"] === "post") { return this.site["posts"].push(data); } else { // Need load templates first. if (!(data["layout"] in this.site["templates"])) { data["layout"] = "page"; } return this.site["pages"].push(data); } } else { return this.site["assets"].push(data); } } }); })); }); } renderAssets() { return Promise.all(this.site["assets"].map((asset) => { return this.renderer.render(asset); })); } renderTemplates() { return Promise.all(Object.values(this.site["templates"]).map((template) => { return this.renderer.render(template); })); } renderPosts() { return Promise.all(this.site["posts"].map((post) => { return this.renderer.render(post); })); } renderPages() { return Promise.all(this.site["pages"].map((page) => { return this.renderer.render(page); })); } generateData(p) { var err, lang, language; lang = p["language"] || this.site["siteConfig"]["language"]; if (!(lang in this.translator.list())) { try { language = yaml.safeLoad(fse.readFileSync(path.join(this.site["themeDir"], "languages", `${lang}.yml`))); this.translator.register(lang, language); } catch (error) { err = error; null; } } p = this.generator.generate(p, this.site["posts"], { "site": this.site, "siteConfig": this.site["siteConfig"], "themeConfig": this.site["themeConfig"], "moment": moment, "getURL": this.getURL, "getAbsPath": this.getAbsPath, "isCurrentPath": isCurrentPathFn(this.site["siteConfig"]["rootDir"], p["docPath"]), "__": this.translator.getTranslateFn(lang) }); if (!(p instanceof Array)) { return [p]; } return p; } generatePosts() { var generated, i, j, k, len, p, ref, ref1, results; this.site["posts"].sort(dateStrCompare); generated = []; ref = this.site["posts"]; for (j = 0, len = ref.length; j < len; j++) { p = ref[j]; p = this.generateData(p); generated = generated.concat(p); } this.site["posts"] = generated; results = []; for (i = k = 0, ref1 = this.site["posts"].length; (0 <= ref1 ? k < ref1 : k > ref1); i = 0 <= ref1 ? ++k : --k) { if (i > 0) { this.site["posts"][i]["next"] = this.site["posts"][i - 1]; } if (i < this.site["posts"].length - 1) { results.push(this.site["posts"][i]["prev"] = this.site["posts"][i + 1]); } else { results.push(void 0); } } return results; } generatePages() { var generated, j, len, p, ref; generated = []; ref = this.site["pages"]; for (j = 0, len = ref.length; j < len; j++) { p = ref[j]; p = this.generateData(p); generated = generated.concat(p); } return this.site["pages"] = generated; } saveAssets() { return this.site["assets"].map((asset) => { this.writeData(asset["srcDir"], asset); return asset; }); } savePosts() { return this.site["posts"].map((post) => { this.site["templates"][post["layout"]]["content"](post).then((content) => { post["content"] = content; return this.writeData(this.site["srcDir"], post); }); return post; }); } savePages() { return this.site["pages"].map((page) => { this.site["templates"][page["layout"]]["content"](page).then((content) => { page["content"] = content; return this.writeData(this.site["srcDir"], page); }); return page; }); } saveData() { return this.site["data"].map((data) => { this.writeData(null, data); return data; }); } route() { return Promise.all([ this.loadThemeAssets(), this.loadTemplates().then(() => { return this.loadSrcs(); }) ]).then(() => { this.renderAssets().then(() => { return this.saveAssets(); }); return Promise.all([this.renderTemplates(), this.renderPages(), this.renderPosts()]); }).then(() => { var fn, j, k, len, len1, ref, ref1; ref = this.store["beforeGenerating"]; for (j = 0, len = ref.length; j < len; j++) { fn = ref[j]; this.site = fn(this.site); } this.generatePosts(); this.generatePages(); ref1 = this.store["afterGenerating"]; for (k = 0, len1 = ref1.length; k < len1; k++) { fn = ref1[k]; this.site = fn(this.site); } this.savePosts(); this.savePages(); return this.saveData(); }); } }; }).call(this);