@@ -1,9 +1,9 @@
1−import remark from 'remark'
1+import remark from "remark";
2−import html from 'remark-html'
2+import html from "remark-html";
3−import fs from 'fs'
3+import fs from "fs";
4−import { join } from 'path'
4+import { join, parse } from "path";
5−import matter from 'gray-matter'
5+import matter from "gray-matter";
6−import toml from '@iarna/toml'
6+import toml from "@iarna/toml";
8// export async function markdownToHtml(markdown) {
8// export async function markdownToHtml(markdown) {
9// const result = await remark().use(html).process(markdown)
9// const result = await remark().use(html).process(markdown)
@@ -11,13 +11,13 @@ import toml from '@iarna/toml'
13const directories = {
13const directories = {
14− blog: join(process.cwd(), 'content/blog'),
14+ blog: join(process.cwd(), "content/blog"),
15− events: join(process.cwd(), 'content/events'),
15+ events: join(process.cwd(), "content/events"),
16− docs: join(process.cwd(), 'content/docs'),
16+ docs: join(process.cwd(), "content/docs"),
19export function getPostSlugs(key) {
19export function getPostSlugs(key) {
20− return fs.readdirSync(directories[key])
20+ return fs.readdirSync(directories[key]);
23// NB Gavin: This could be much simpler if we converted everything to a more common standard, like YAML
23// NB Gavin: This could be much simpler if we converted everything to a more common standard, like YAML
@@ -25,79 +25,87 @@ const options = {
25 engines: {
25 engines: {
26 toml: toml.parse.bind(toml),
26 toml: toml.parse.bind(toml),
28− language: 'toml',
28+ language: "toml",
29− delimiters: '+++'
29+ delimiters: "+++",
32export function getPostBySlug(slug, fields = [], key) {
32export function getPostBySlug(slug, fields = [], key) {
33− const realSlug = slug.replace(/\.md$/, '')
33+ const realSlug = slug.replace(/\.md$/, "");
34− const fullPath = join(directories[key], `${realSlug}.md`)
34+ const fullPath = join(directories[key], `${realSlug}.md`);
35− const fileContents = fs.readFileSync(fullPath, 'utf8')
35+ const fileContents = fs.readFileSync(fullPath, "utf8");
36− const { data, content } = matter(fileContents, options)
36+ const { data, content } = matter(fileContents, options);
37− const items = {}
37+ const items = {};
39 // Ensure only the minimal needed data is exposed
39 // Ensure only the minimal needed data is exposed
40 fields.forEach((field) => {
40 fields.forEach((field) => {
42− if (field === 'slug') {
41+ if (field === "slug") {
43− items[field] = realSlug
42+ items[field] = realSlug;
46− if (field === 'content') {
45+ if (field === "content") {
47− items[field] = content
46+ items[field] = content;
50− if (data[field]) {
49+ if (data[field]) {
51− items[field] = data[field]
50+ items[field] = data[field];
56 // NB Gavin: This could be removed if the TOML engine returned a JSON date (string) instead of a JS Date object. The YAML engine did this parsing by default.
54 // NB Gavin: This could be removed if the TOML engine returned a JSON date (string) instead of a JS Date object. The YAML engine did this parsing by default.
57− items.date = JSON.stringify(items.date).replace(/\"/g, '');
55+ items.date = JSON.stringify(items.date).replace(/\"/g, "");
60− return items
57+ return items;
63export function getAllPosts(fields = [], key) {
60export function getAllPosts(fields = [], key) {
64− const slugs = getPostSlugs(key)
61+ const slugs = getPostSlugs(key);
65 const posts = slugs
62 const posts = slugs
66− .map((slug) => getPostBySlug(slug, fields, key))
63+ .map((slug) => getPostBySlug(slug, fields, key))
67− // sort posts by date in descending order
64+ // sort posts by date in descending order
68− .sort((post1, post2) => (post1.date > post2.date ? -1 : 1))
65+ .sort((post1, post2) => (post1.date > post2.date ? -1 : 1));
70− return posts
67+ return posts;
73export function getNextPost(slug, fields = [], key) {
70export function getNextPost(slug, fields = [], key) {
74− let resultPost = null
71+ let resultPost = null;
76− getAllPosts(fields, key)
77− .forEach((post, index, array) => {
73+ getAllPosts(fields, key).forEach((post, index, array) => {
78− if (post.slug === slug) {
74+ if (post.slug === slug) {
79− resultPost = array[index - 1]
75+ resultPost = array[index - 1];
82− return resultPost
78+ return resultPost;
85export function getPreviousPost(slug, fields = [], key) {
81export function getPreviousPost(slug, fields = [], key) {
86− let resultPost = null
82+ let resultPost = null;
88− getAllPosts(fields, key)
89− .forEach((post, index, array) => {
84+ getAllPosts(fields, key).forEach((post, index, array) => {
90− if (post.slug === slug) {
85+ if (post.slug === slug) {
91− resultPost = array[index + 1]
86+ resultPost = array[index + 1];
94− return resultPost
89+ return resultPost;
97export function formatDate(d) {
92export function formatDate(d) {
98 // const wk = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
93 // const wk = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
99− const mn =["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
94+ const mn = [
100− return mn[d.getMonth()] + " " + d.getDate() + ", " + d.getFullYear()
108+ return mn[d.getMonth()] + " " + d.getDate() + ", " + d.getFullYear();
103// export function capitalize(str) {
111// export function capitalize(str) {
@@ -113,4 +121,49 @@ export function formatDate(d) {
113// key: crumb,
121// key: crumb,
114// path: crumbs.slice(0, index+2).join('/'),
122// path: crumbs.slice(0, index+2).join('/'),
126+export const getAllFiles = function (dirPath, arrayOfFiles) {
127+ let files = fs.readdirSync(dirPath);
129+ arrayOfFiles = arrayOfFiles || [];
131+ files.forEach(function (file) {
132+ if (fs.statSync(dirPath + "/" + file).isDirectory()) {
133+ arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles);
135+ arrayOfFiles.push(join(__dirname, dirPath, "/", file));
139+ return arrayOfFiles;
142+export function getLinksinSubdirs(path) {
143+ const allFiles = getAllFiles(path);
144+ const fileTree = {};
145+ allFiles.forEach((e) => {
146+ const parsed = parse(e.substr(e.indexOf("content/") + 7));
148+ if (!(parsed.dir in fileTree)) {
149+ const fullPathofDir = join(
155+ const dirContents = fs.readFileSync(fullPathofDir, "utf8");
156+ const { data: dirData } = matter(dirContents, options);
157+ fileTree[parsed.dir] = { name: dirData.title, pages: [] };
160+ const fileContents = fs.readFileSync(e, "utf8");
161+ const { data } = matter(fileContents, options);
162+ fileTree[parsed.dir].pages.push({