"use strict"; const h = require("highland"); const fs = require("fs"); const path = require("path"); const { promisify } = require("util"); const matter = require("gray-matter"); const markdown = require("../modules/markdown.js"); const predentation = require("predentation"); const { indentForTemplate, postIndentLevel } = require("../responders.js"); const grayMatterOptions = { lang: "toml", delims: "+++" }; function* lowercaseKeys(iterator) { for (let [k, v] of iterator) { yield [String(k).toLowerCase(), v]; } } function canonicaliseMetadata(meta) { if (meta.data) { meta.data = new Map(lowercaseKeys(Object.entries(meta.data))); } else { meta.data = new Map(); } return meta; } function getTitle(file) { return path.basename(file.path, path.extname(file.path)); } async function indentBody(content) { return await h( h .of(content) .map(markdown) .map(html => indentForTemplate(html, postIndentLevel)) .pipe(predentation()) ) .invoke("toString", ["utf-8"]) .toPromise(Promise); } async function get(getURL, filename) { const fileMatter = matter.read(filename, grayMatterOptions); fileMatter.basename = getTitle(fileMatter); delete fileMatter.orig; fileMatter.body = await indentBody(fileMatter.content); fileMatter.url = getURL(fileMatter.basename); return Promise.resolve(canonicaliseMetadata(fileMatter)); } async function getFolder(folder, getURL) { const files = (await promisify(fs.readdir)(folder)).map(f => path.resolve(folder, f) ); const posts = await Promise.all(files.map(get.bind(this, getURL))); return new Map(posts.map(f => [getTitle(f), f])); } function taxonomise(taxonomies, posts) { const taxons = new Map(Object.keys(taxonomies).map(t => [t, new Map()])); for (let [, post] of posts) { for (let [singularName, pluralName] of Object.entries(taxonomies)) { if (post.data.has(pluralName)) { for (let term of post.data.get(pluralName)) { const current = taxons.get(singularName).get(term); taxons .get(singularName) .set(term, current ? current.concat(post) : [post]); } } } } return taxons; } module.exports = async function(config, getURL) { const posts = await getFolder(config.folder, getURL); const taxonomies = taxonomise(config.taxonomies, posts); return { posts, taxonomies, get }; };