-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
/
Copy pathconcatenate-docs.js
78 lines (61 loc) · 2.9 KB
/
concatenate-docs.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
// start message
console.info("\x1b[0m\x1b[36mConcatenating help files of each directory to create chapter-wide help files to be used for printing help ...\x1b[0m");
// ------ various includes ------
const fs = require("fs");
const path = require("path");
const os = require("os");
const front = require("front-matter");
// root path
const rootPath = path.join("src", "content");
/* getDirectoryRecursive() recursively walks through
all sub directories of the provided root path,
concatenates the MarkDown files' content in
each directory, sorted by their FrontMatter sort
attribute, and creates a compound MarkDown file
named by using the directory name, prefixed by an
underscore and suffixed by "_all.md" from the
concatenated content in the corresponding directory.
*/
(function getDirectoryRecursive(basePath)
{
// log current working directory
console.log("\x1b[0m\x1b[32m " + basePath + "\x1b[0m");
// create destination file name of compound file
const targetFilePath = path.join(basePath, `${basePath.substr(rootPath.length).replace(/[/\\]/, "_")}_all.md`);
if (fs.existsSync(targetFilePath)) fs.unlinkSync(targetFilePath); // delete target file if it already exists
fs.readdir(basePath, function (err, fileNames) // list current working directory
{
if (err) throw err;
let fileContents = [];
for (let file of fileNames) // for each directory entry ...
{
const fullPath = path.join(basePath, file);
if (fs.statSync(fullPath).isDirectory()) getDirectoryRecursive(fullPath); // if the directory entry is a directory, recurse into that directory
else if (fullPath.endsWith(".md")) // if the directory entry is a MarkDown file, add it to the list of files to be processed
{
let fc = fileContents[fileContents.length] = front(fs.readFileSync(fullPath).toString());
if (!fc.attributes.sort) --fileContents.length; // only include files providing a FrontMatter "sort" attribute
}
}
// sort MarkDown files by FrontMatter "sort" attribute (QuickSort)
for (let i = 0;i < fileContents.length - 1;++i)
for (let j = i + 1;j < fileContents.length;++j)
{
const left = fileContents[i].attributes, right = fileContents[j].attributes;
if (left.sort > right.sort
|| left.sort == right.sort && left.title > right.title)
[fileContents[i], fileContents[j]] = [fileContents[j], fileContents[i]];
}
// write compound target file
const targetFile = fs.createWriteStream(targetFilePath);
targetFile.on("error", (error) => { throw error; });
for (let file of fileContents)
{
targetFile.write(os.EOL + os.EOL + "# " + file.attributes.title + os.EOL); // use FrontMatter "title" attribute as main heading of target file
targetFile.write(file.body);
}
targetFile.end();
});
})(rootPath);
// end message
process.on("exit", () => { console.info("\x1b[0m\x1b[36mSuccessfully created \"_all.md\" help files in each directory within \"" + rootPath + "\".\x1b[0m"); });