-
Notifications
You must be signed in to change notification settings - Fork 2
/
build-helpers.js
113 lines (104 loc) · 3.39 KB
/
build-helpers.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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
const { cfs, dir } = require('./fs-helpers');
const frontMatter = require('front-matter');
async function getFormattedDoc({ allDocs, getPath, filePathsDontExist = [] }) {
return async function getDoc(key) {
if (allDocs.hasOwnProperty(key)) return allDocs[key];
let contents;
try {
contents = await cfs.read(getPath(key));
} catch (e) {
console.error(`Doc not found: ${key}`);
return;
}
const { attributes, body } = frontMatter(contents);
const normalizedAttributes = normalizeFrontmatter(attributes);
const href = key.replace(/(^|\/)index$/, '');
const doc = {
key,
frontMatter: normalizedAttributes,
body,
href,
tree: formatTree({
tree: normalizedAttributes.tree || '',
key,
getPath,
filePathsDontExist,
}),
};
allDocs[key] = doc;
doc.index = await getIndex({ doc, getPath, getDoc });
// if current doc's index doesn't have tree, we set it to '{root directory}/index'
if (allDocs[doc.index].tree.length === 0) {
await getDoc('/index');
doc.index = '/index';
}
return doc;
};
}
function formatTree({ tree, key, getPath, filePathsDontExist }) {
return tree
.split('\n')
.filter((_) => _)
.map((line) => {
// 'folder-name | title' format is split here
const split = line.split('|');
const level = split[0].match(/^\s+/)?.[0].length / 2 || 0;
const title = split.length > 1 && split.slice(1).join('|').trim();
// 'folder-name' from the above split is stored in navKey
// which will be used as a link to the page while generating navigation
const navKey = split[0].trim();
/** We are checking if paths given in the tree file exists or not
* we are pushing all the file paths that don't exist in an array
* and the build would fail at the end listing all these file paths
*/
if (navKey && navKey !== 'index') {
const filePath = key.replace(/(^|\/)index$/, '') + '/' + navKey;
const content = cfs.readSync(getPath(filePath));
if (
!content &&
!filePathsDontExist.find((obj) => obj.filePath === filePath)
) {
filePathsDontExist.push({
filePath,
treeFilePath: key,
});
}
}
return {
/*
as the mapped (in allDocs) key is used as a link to the page, which don't starts with '/'
we need to remove '/' from the beginning of the key
hence only adding '/' if dir(key) is not empty
*/
key: navKey && dir(key) + (dir(key) && '/') + navKey,
title,
level,
};
});
}
async function getIndex({ doc, getPath, getDoc }) {
if (doc.frontMatter.tree) {
return doc.key;
}
const split = doc.key.split('/');
for (let i = split.length - 1; i >= 0; i--) {
const maybeKey = split.slice(0, i).concat('index').join('/');
if (maybeKey === doc.key) continue;
const file = await cfs.read(getPath(maybeKey));
if (file) {
const maybeDoc = await getDoc(maybeKey);
if (maybeDoc.tree.find((t) => t.key === doc.key || t.key === doc.href)) {
return maybeKey;
}
} else {
continue;
}
}
return doc.key;
}
function normalizeFrontmatter(frontMatter = {}) {
return { ...frontMatter, heading: frontMatter.heading || frontMatter.title };
}
module.exports = {
getFormattedDoc,
};