on 99bdb21 help sign in
urbit.org/lib/buildPageTree.js
110 lines 3.2 kB history raw
1const fs = require("fs");
2const path = require("path");
3const matter = require("gray-matter");
4const toml = require("@iarna/toml");
6// node ./buildPageTree.js [directory] [sort]
7// eg. node ./buildPageTree docs weight
8// will produce docs.json in the cache folder.
10const options = {
11 engines: {
12 toml: toml.parse.bind(toml),
13 },
14 language: "toml",
15 delimiters: "+++",
16};
18/**
19 * buildPageTree is written to provide a recursive index of posts
20 * for nested directories for creating sidebars
21 * @param {string} path Absolute path to the subdirectory.
22 * @returns {Object.<string,string|Object<string,string[]|number>>} Title of the directory, child pages, and child directories (recursive structure).
23 *
24 */
26// type PageTree =
27// { title: string,
28// pages: [{
29// title: string,
30// base: string,
31// slug: string,
32// weight: number,
33// }],
34// children: { [string]: PageTree },
35// }
37function buildPageTree(dirPath, ordering = "", content = false) {
38 const metadata = matter(
39 fs.readFileSync(path.join(dirPath, "_index.md")),
40 options
41 );
42 // get a list of contents at the dirPath, with file types so that the item at the dirPath can be identified as file or folder
43 const children = fs.readdirSync(dirPath, { withFileTypes: true });
44 // get a list of files
45 const pages = children.filter((f) => f.isFile() && f.name !== "_index.md");
46 // get a list of folders
47 const subdirs = children.filter((f) => f.isDirectory());
48 // return a pagetree datastructure
49 return {
50 title: metadata.data.title,
51 pages: pages
52 .map((page) => {
53 // retrieve topmatter as JSON
54 const { content, data } = matter(
55 fs.readFileSync(path.join(dirPath, page.name)),
56 options
57 );
59 return {
60 title: data.title,
61 base: page.name,
62 slug: page.name.replace(/.md$/, ""),
63 ...(ordering === "weight" && { weight: data?.weight ?? 0 }),
64 ...(ordering === "date" && {
65 date: data?.date ?? "2000-01-01T00:00:00.000Z",
66 }),
67 };
68 })
69 .sort((a, b) => a.weight - b.weight),
70 children: Object.fromEntries(
71 subdirs
72 .sort((a, b) => {
73 const aMetadata = matter(
74 fs.readFileSync(path.join(dirPath, a.name, "_index.md")),
75 options
76 );
77 const bMetadata = matter(
78 fs.readFileSync(path.join(dirPath, b.name, "_index.md")),
79 options
80 );
81 return aMetadata?.data?.weight - bMetadata?.data?.weight || 0;
82 })
83 .map((subdir) => [
84 subdir.name,
85 buildPageTree(path.join(dirPath, subdir.name), ordering, content),
86 ])
87 ),
88 };
91const process = require("process");
93const arg = process.argv?.[2];
94const sort = process?.argv?.[3] || "weight";
96const dir = buildPageTree(path.join(process.cwd(), `content/${arg}`), sort);
97const fileContents = `${JSON.stringify(dir)}`;
99try {
100 fs.readdirSync("cache");
101} catch (err) {
102 fs.mkdirSync("cache");
105fs.writeFile(`cache/${arg}.json`, fileContents, function (err) {
106 if (err) return console.error(err);
107 console.log(`${arg} directory structure created.`);
108});
110module.exports = { buildPageTree };