forked from jaywcjlove/linux-command
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompile.js
381 lines (324 loc) · 11.8 KB
/
compile.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
var exec = require('child_process').exec;
var fs = require('fs');
var ejs = require('ejs');
var path = require('path');
var marked = require('marked');
var watch = require('watch');
var stylus = require('stylus')
var highlight = require('highlight.js')
var UglifyJS = require("uglify-js");
var renderer = new marked.Renderer();
var color = require('colors-cli/safe');
var error = color.red.bold;
var warn = color.yellow;
var notice = color.blue;
var success = color.green;
// console.log("该行代码所在的目录::",__dirname);
// console.log("当前运行的的根目录::",path.dirname(__dirname));
// console.log("当前目录名字::",path.basename(process.cwd()));
// console.log("当前目录::",process.cwd());
renderer.heading = function (text, level) {
if(/[\u4E00-\u9FA5]/i.test(text)){
return '<h' + level + ' id="'+text.toLowerCase()+'">'+text+'</h' + level + '>';
}else{
var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');
return '<h' + level + ' id="'+escapedText+'">'+text+'</h' + level + '>';
}
}
marked.setOptions({
renderer: renderer,
gfm: true,
tables: true,
breaks: false,
pedantic: false,
sanitize: false,
smartLists: true,
smartypants: false,
highlight: function (code, lang, callback) {
lang = lang?lang:"bash";
return callback('',highlight.highlight(lang,code).value);
}
// highlight: function (code, lang, callback) {
// if(lang){
// return highlight.highlight(lang,code).value;
// // return callback('',highlight.highlight(lang,code).value);
// }else{
// return highlight.highlightAuto(code).value;
// // return callback('',highlight.highlightAuto(code).value);
// }
// }
});
// 根目录
// var path_root = path.dirname(__dirname);
var path_root = process.cwd();
// 删除文件夹
exec('rm -rf .deploy');
// .deploy
// 当前项目根目录
// 生成 项目所需的文件
CreateDatajs('./.deploy/js/dt.js',function(dt_path,arr){
// 拷贝 favicon.ico 文件 start
var filetopath = path.join(process.cwd(),'/template/img/favicon.ico');
var topath = '.deploy/img/favicon.ico'
mkdirsSync(path.join(process.cwd(),'.deploy/img/'));
// 创建读取流
readable = fs.createReadStream( filetopath );
// 创建写入流
writable = fs.createWriteStream(topath);
// 通过管道来传输流
readable.pipe( writable);
console.log(success(" → ")+topath + '');
// 拷贝 favicon.ico 文件 end
CreateJS('/template/js/index.js','/.deploy/js/index.js')
CreateStyl('/template/styl/index.styl','/.deploy/css/index.css')
// 首页生成
ReadTmpToHTML('/template/index.ejs','/.deploy/index.html',null,{
'p':'/index.html',
'n':'Linux命令搜索',
'd':'最专业的Linux命令大全,内容包含Linux命令手册、详解、学习,值得收藏的Linux命令速查手册。',
'command_length':arr.length
});
ReadTmpToHTML('/template/list.ejs','/.deploy/list.html',null,{
p:'/list.html',
n:'搜索',
d:'最专业的Linux命令大全,内容包含Linux命令手册、详解、学习,值得收藏的Linux命令速查手册。'
});
// 文章批量生成
arr.forEach(function(itm,idx){
var ejstpm = path.join('/template/',itm.p);
var md_path = path.join('/command',itm.p);
var dep = path.join('/.deploy/c',itm.p);
ReadTmpToHTML('/template/details.ejs', dep+'.html' ,md_path+'.md', itm)
});
console.log(success(" → "),arr.length)
})
function copy(src, dst) {
fs.createReadStream(src).pipe(fs.createWriteStream(dst));
}
// // 监听实时编译
// watch.watchTree(path.join(path.dirname(__dirname),'/'), function (f, curr, prev) {
// if (typeof f == "object" && prev === null && curr === null) {
// console.log(success(" → :watching ") + '/template/');
// // Finished walking the tree
// } else if (prev === null) {
// // f is a new file
// } else if (curr.nlink === 0) {
// // f was removed
// } else {
// if(/\.styl$/.test(f)){
// CreateStyl('/template/styl/index.styl','/.deploy/css/index.css')
// }else if(/\.js$/.test(f)){
// CreateJS('/template/js/index.js','/.deploy/js/index.js')
// }else if(/\.ejs$/.test(f)){
// // 首页生成
// ReadTmpToHTML('/template/index.ejs','/.deploy/index.html');
// ReadTmpToHTML('/template/list.ejs','/.deploy/list.html');
// }else if(/\.md$/.test(f)){
// var mdp = f.replace(path_root,'');
// var dep = path.join('/.deploy/',mdp);
// ReadTmpToHTML('/template/details.ejs',dep.replace('.md','.html'),mdp);
// }
// }
// })
function CreateJS(from_path,to_path){
// 生成到指定目录
var new_to_path = path.join(path.dirname(__dirname),to_path);
// 循环创建目录
mkdirsSync(path.dirname(new_to_path));
var js_code = UglifyJS.minify(path.join(path_root,from_path), { mangle: { toplevel: true } });
fs.writeFileSync(new_to_path, js_code.code);
console.log(success(" → ")+to_path + '');
}
/**
* [ReadTmpToHTML ejs 模板转换成HTML]
* @param {[type]} from_path [模版来源地址]
* @param {[type]} to_path [生成到指定的位置]
* @param {[type]} md_path [Markdown的路径] // 给md地址就生产详情页面
* @param {[type]} des_json [页面信息 json 格式]
*/
function ReadTmpToHTML(from_path,to_path,md_path,des_json){
var tmp_path = path.join(path.dirname(__dirname),from_path);
if(!exists(tmp_path)) return console.log("\n → error: 模板文件 "+tmp_path+" 不存在")
var tmp_str = fs.readFileSync(tmp_path);
tmp_str = tmp_str.toString();
var relative_path = '';
var current_path = to_path.replace(/^\/\.deploy/,'');
if(md_path){
//CSS/JS 引用相对地址
relative_path = path.relative(md_path.toString(),'/');
relative_path = relative_path.replace(/\.\.$/,'');
}
// 生成 HTML
var html = ejs.render(tmp_str,{
filename: tmp_path,
relative_path:relative_path, // 当前文件相对于根目录的相对路径
md_path:md_path?md_path:'', // markdown 路径
current_path:current_path, // 当前 html 路径
describe:des_json?des_json:{}, // 当前 md 的描述
});
// 生成到指定目录
var new_to_path = path.join(path.dirname(__dirname),to_path);
// 循环创建目录
!exists(path.dirname(new_to_path)) && mkdirsSync(path.dirname(new_to_path));
if(md_path){
var new_md_path = path.join(path.dirname(__dirname),md_path);
var README_str = fs.readFileSync(new_md_path);
marked(README_str.toString(),function(err,md_html){
if (err) return console.log(error(' → '+md_path+" 转换成HTML失败!"));
html = html.replace('{{content}}',md_html);
fs.writeFileSync(new_to_path,html);
console.log(success(" → ")+to_path + '');
})
}else{
html = html.toString();
fs.writeFileSync(new_to_path, html.replace(/\n/g,''));
console.log(success(" → ")+to_path + '');
}
}
/**
* [CreateStyl 生成CSS]
* @param {[type]} styl_path [description]
* @param {[type]} css_path [description]
*/
function CreateStyl(styl_path,css_path){
var new_css_path = path.join(path.dirname(__dirname),css_path);
styl_path = path.dirname(__dirname) + styl_path;
// var paths = [
// path.dirname(__dirname) , path.dirname(__dirname) + '/'
// ];
var styl_str = fs.readFileSync(styl_path, 'utf8');
stylus(styl_str.toString())
.set('filename', styl_path )
.set('compress', true)
.render(function(err, css){
if (err) throw err;
// 循环创建目录
mkdirsSync(path.dirname(new_css_path));
fs.writeFileSync(new_css_path, css);
// console.log(err,css);
console.log(success(" → ")+styl_path + '');
});
}
// 生成数据索引JS
function CreateDatajs(dt_path,callback){
// 获取 markdown文件所在的目录
var path_md = path.join(path.dirname(__dirname),'command');
var path_dist = path.join(path.dirname(__dirname),'dist');
if(!exists(path_md)) return console.log("\n → error: 文件夹 "+path_md+" 不存在 \n ")
// 获取 markdown 目录的集合
var path_arr = readMDSync(path_md);
path_arr = sortLength(path_arr);
var indexes = [];
var command_data={}
path_arr.forEach(function(md_path,i){
var json = {}
var con = fs.readFileSync(md_path);
var str = con.toString();
var title = str.match(/[^===]+(?=[===])/g);
title = title[0]?title[0].replace(/\n/g,''):title[0];
// 命令名称
json["n"] = title;
// 命令路径
json["p"] = md_path.replace(/\.md$/,'').replace(path_md,'');
// 命令描述
var des = str.match(/\n==={1,}([\s\S]*?)##/i);
des = des[1]?des[1].replace(/\n/g,''):des[1];
des = des.replace(/\r/g,'')
json["d"] = des;
indexes.push(json)
command_data[title] = json;
})
mkdirsSync(path.dirname(dt_path));
console.log("path.dirname(__dirname)",path.dirname(__dirname))
//生成数据文件
fs.writeFile(dt_path, 'var linux_commands='+JSON.stringify(indexes) , 'utf8',function(err){
console.log(success("\n → ")+"生成数据成功!"+dt_path+" \n ");
path_dist = path.join(path_dist,'data.json')
fs.writeFile(path_dist, JSON.stringify(command_data) , 'utf8',function(err){
console.log(success("\n → ")+"生成数据成功!"+path_dist+" \n ");
callback&&callback(dt_path,indexes);
});
});
}
// 按长度排序
function sortLength(arr){
var compare = function (x, y) {//比较函数
x = path.basename(x,'.md');
y = path.basename(y,'.md');
if (x.length < y.length) {
return -1;
} else if (x.length > y.length) {
return 1;
} else {
return 0;
}
}
return arr.sort(compare)
}
// 同步循环创建所有目录 resolvePath
function mkdirsSync(dirpath, mode, callback) {
if(fs.existsSync(dirpath)){
callback&&callback(dirpath);
return true;
}else{
if(mkdirsSync(path.dirname(dirpath), mode)){
fs.mkdirSync(dirpath, mode, callback);
callback&&callback(dirpath);
return true;
}else{
callback&&callback(dirpath);
}
}
};
var fixture = path.join.bind(path, __dirname, 'template');
function cp(src, dest, cb) {
// yield support
if ('function' != typeof cb) return thunk;
var complete = false;
var read = fs.createReadStream(src);
var write = fs.createWriteStream(dest);
write.on('error', done);
write.on('close', done);
read.on('error', done);
read.pipe(write);
// done callback
function done(err) {
if (!complete) {
complete = true;
read.destroy();
write.destroy();
cb(err);
}
}
// thunk-ified
function thunk(done) {
cp(src, dest, done);
}
}
//返回 MD 所有路径的 Array
function readMDSync(filepath){
if(!exists(filepath)) return [];
var str = '',files = fs.readdirSync(filepath);
for (var i = 0; i < files.length; i++) {
var path_c = path.join(filepath,files[i]);
if( isDir(path_c) ) {
str += readMDSync(path_c) + ',';
}
else if(/\.(md)$/.test(files[i])) str += path_c + ',';
};
str = str.replace(/^\*|\,*$/g,'');
return str.split(',');
}
//写文件
function writeSync(filepath, content, callback) {
mkdirsSync(path.dirname(filepath));
return fs.writeFileSync(filepath, content, callback);
};
//写文件
function write(filepath, content) {
return fs.writeFile(filepath, content);
};
//判断是不是目录
function isDir(_path){return exists(_path) && fs.statSync(_path).isDirectory();}
//检查指定路径的文件或者目录,是否存在
function exists(_path){return fs.existsSync(_path);}