This repository has been archived by the owner on Dec 4, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 130
/
Copy pathmetalsmith-hierarchy.js
70 lines (57 loc) · 2.07 KB
/
metalsmith-hierarchy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
const { sortPages } = require("../core/utils");
const withMenus = [];
const paths = {};
const stripLast = (file) => file.replace(/\/[^/]+\/?$/, "");
const findLongestExisting = (path, fallback) => {
if (fallback && path.length < fallback.length) return fallback;
return paths[path] ? path : findLongestExisting(stripLast(path));
};
const firstParagraph = (file) => {
const contents = file.contents
.toString("utf-8")
.split(/\r?\n/g)
.filter((n) => n);
return contents[0] || "";
};
/**
* This plugin puts all files into a tree structure and adds some other variables:
* * children
* * id - used for sorting
* * shortDesc - if no excerpt is set in the frontmatter, we'll add the first paragraph
* * subtree - this propagates variables down to all ancestors
* * parent
*/
module.exports = (files, metalsmith, done) => {
setImmediate(done);
Object.entries(files).forEach(([filePath, file]) => {
if (!filePath.endsWith(".md")) return;
Object.assign(file, {
children: [],
id: filePath.split("/").slice(-2)[0],
path: "/" + filePath.replace(/index.md$/, "").replace(/\/$/, ""),
shortDesc: file.excerpt || firstParagraph(file),
});
file.parent = files[filePath.replace(/[^/]+\/index.md$/, "index.md")];
if (!file.parent) return;
// subtree-prop inheritance
file.subtree = Object.assign({}, file.parent.subtree, file.subtree);
Object.assign(file, file.subtree);
if (file.draft && process.env.NODE_ENV == "production") return;
paths[file.path] = file;
if (file.menus) withMenus.push(file);
file.parent.children.push(file);
file.parent.children.sort(sortPages);
});
Object.entries(files).forEach(([filePath, file]) => {
if (file.draft && process.env.NODE_ENV == "production")
delete files[filePath];
});
metalsmith.metadata().hierarchy = {
findByPath(pathToFind) {
if (!paths[pathToFind]) throw new Error(`Missing file: ${pathToFind}`);
return paths[pathToFind];
},
findLongestExisting,
findMenus: (v) => withMenus.filter((c) => v(c.menus)).sort(sortPages),
};
};