/
chapters.js
156 lines (139 loc) · 3.98 KB
/
chapters.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
'use strict';
const fs = require('fs-extra');
const path = require('path');
const yaml = require('js-yaml');
const debug = require('debug')('[' + __filename + ']');
const log = require('./utils').log;
const walkSync = require('walk-sync');
const CHAPTERS_FILE = 'chapters.yml';
function mkFileHandler(prefix) {
return function (file) {
// handle directory name
if (file[file.length - 1] === path.sep) {
const obj = {};
const key = file;
const value = path.basename(file);
obj[key] = value;
return obj;
}
// handle markdown file
const filePath = path.join(path.resolve(process.cwd(), prefix), file);
const fileContent = fs.readFileSync(filePath, 'utf8');
const h1Regex = /^\s*#\s*([^#].*?)\s*$/m;
const result = h1Regex.exec(fileContent);
const obj = {};
if (result && result[1]) {
const key = file;
const value = result[1];
obj[key] = value;
} else {
const key = file;
const value = path.basename(file);
obj[key] = value;
}
return obj;
};
}
function excludeEmptyDirectory(dirArr) {
let hasEmptyDirectory = false;
dirArr = dirArr.filter(function (d, i, arr) {
if (i === (arr.length - 1)) {
if (d.substr(-1) === path.sep) {
hasEmptyDirectory = true;
return false;
}
return true;
}
if (d.substr(-3).toLowerCase() === '.md') {
return true;
}
if (arr[i + 1].indexOf(d) !== 0) {
hasEmptyDirectory = true;
return false;
}
return true;
});
if (hasEmptyDirectory) {
dirArr = excludeEmptyDirectory(dirArr);
}
return dirArr;
}
function chapters(option) {
log.success('[BEGIN] handle chapters file');
// find whether user's chapters file exists
let isChaptersExists;
try {
fs.accessSync(path.resolve(process.cwd(), CHAPTERS_FILE));
isChaptersExists = true;
} catch (e) {
isChaptersExists = false;
}
debug('does chapters file exists? ' + isChaptersExists);
// if exists, read it, then return
let chapters_content;
let chapters_array;
if (isChaptersExists) {
try {
chapters_content = fs.readFileSync(path.resolve(process.cwd(), CHAPTERS_FILE), 'utf8');
chapters_array = yaml.safeLoad(chapters_content);
} catch (e) {
log.error(e);
throw e;
}
/*
if (!chapters_array || chapters_array.length === 0) {
log.error('The chapters file is invalid');
throw new Error('The chapters file is invalid');
}
*/
debug('chapter file %o', chapters_array);
option.chapters = chapters_array;
log.success('[END] handle chapters file');
return option;
}
// check if the doc dir exists
try {
fs.accessSync(path.resolve(process.cwd(), option.dir));
} catch (e) {
log.error(e);
throw e;
}
// read the files and directories under the doc dir into an array
let doc_items = walkSync(path.resolve(process.cwd(), option.dir), { ignore: ['node_modules'] });
doc_items = doc_items.filter(function (i) {
if (i[0] === '.' || i[0] === '_') {
return false;
}
return true;
}).filter(function (i) {
if (i.substr(-9).toLowerCase() === 'readme.md') return false;
if (i.substr(-3) === '.md') return true;
if (i[i.length - 1] === path.sep) return true;
return false;
});
/* exclude empty directories from doc_items */
doc_items = excludeEmptyDirectory(doc_items);
/*
if (doc_items.length === 0) {
log.error('There is NO valid markdown files in the doc directory');
throw new Error('There is NO valid markdown files in the doc directory');
}
*/
// read markdown file's title
const doc_array = doc_items.map(mkFileHandler(option.dir));
try {
fs.writeFileSync(
path.resolve(process.cwd(), CHAPTERS_FILE),
yaml.safeDump(doc_array),
'utf8'
);
log.info('[INFO] create the chapters file');
} catch (e) {
log.error(e);
throw e;
}
option.chapters = doc_array;
log.success('[END] handle chapters file');
return option;
}
module.exports = chapters;