-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex_generator.js
130 lines (113 loc) · 3.49 KB
/
index_generator.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* A script to obtain all topics' intro file and take the list of topics listed under
* the "### All pages" heading. All the result will be combined to generate an index.md file.
*
* This script depends on the topic list on each intro file, so make sure they are right!
* Always put topic list after the heading and never put anything below it.
*/
const fs = require("fs");
const path = require("path");
const matter = require("gray-matter");
function extractTopicList(filePath) {
const fileContents = fs.readFileSync(filePath, "utf-8");
const { data, content } = matter(fileContents);
const { slug, title } = data;
if (slug && title) {
const extractContentAfter = content.indexOf("### All pages");
if (extractContentAfter !== -1) {
const topicsContent = content
.substring(extractContentAfter + "### All pages".length)
.trim();
const topicsCount = topicsContent
.split("\n")
// A specific topic should be linked to a note, implies that it has "[name](/link-to-name)" for the link.
.filter((line) => line.trim().length > 0 && line.includes("[")).length;
return {
slug,
title,
topicsContent,
topicsCount,
};
}
}
return null;
}
function getAllIntroFiles(directoryPath) {
const files = fs.readdirSync(directoryPath);
const introTopics = [];
for (const file of files) {
const filePath = path.join(directoryPath, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
const results = getAllIntroFiles(filePath);
introTopics.push(...results);
} else if (
file.toLowerCase().includes("intro.md") &&
file.toLowerCase() !== "intro.md"
) {
const result = extractTopicList(filePath);
if (result) {
introTopics.push(result);
}
}
}
return introTopics;
}
// Topics order
const order = [
"Computer & Programming Fundamentals",
"Digital Signal Processing",
"Digital Media Processing",
"Computer Networking",
"Data Structures & Algorithms",
"Computer Organization & Architecture",
"Operating System",
"Theory of Computation & Automata",
"Compilers & Programming Languages",
"Database System",
"Computer Graphics",
"Internet & Web",
"Backend System",
"Computer Security",
"Machine Learning",
"Deep Learning",
"Software Engineering",
"Cloud Computing & Distributed Systems",
"Android OS",
"Android Development",
];
const introTopicsData = getAllIntroFiles("docs");
let num = 0;
let totalTopicsCount = 0;
const markdownContent = introTopicsData
.sort((a, b) => {
const indexA = order.indexOf(a.title);
const indexB = order.indexOf(b.title);
return indexA - indexB;
})
.map(({ slug, title, topicsContent, topicsCount }) => {
const indentedTopicsContent = topicsContent
.split("\n")
.filter((line) => line.trim().length > 0)
.map((line) => ` ${line}`)
.join("\n");
num += 1;
totalTopicsCount += topicsCount;
return `${num}. [${title}](${slug}) (**${topicsCount}** subtopics)\n${indentedTopicsContent}`;
})
.join("\n");
const indexPath = path.join(__dirname, "docs/0index", "index.md");
fs.writeFileSync(
indexPath,
`---
slug: /index
id: index
title: Index
description: Index
---
This page contains all the notes on this site. The structure is similar to the sidebar on the left.
A total of **${introTopicsData.length}** topics, and a total of **${totalTopicsCount}** notes.
${markdownContent}
`
);
console.log("index.md generated successfully.");