apollo-nico
Version:
对 nico 及 apollo-theme 的封装,方便跨平台使用
351 lines (307 loc) • 8.89 kB
JavaScript
var path = require('path');
var util = require('util');
var nico = require('nico');
var fs = require('fs');
var file = nico.sdk.file;
var BaseWriter = nico.BaseWriter;
var cheerio = require('cheerio');
var filters = require('./filters');
exports.name = 'apollo';
exports.version = '1.0';
exports.lang = 'zh';
function ResultFormatWriter() {}
util.inherits(ResultFormatWriter, BaseWriter);
//处理已经编译好的html
ResultFormatWriter.prototype.run = function () {
var option = nico.sdk.option;
//将markdown高亮代码插入包裹层中
var dest = path.join(option.get('outputdir'), 'index.html');
var base = option.get('baseURL');
//回写到option中
//option.set('dependence', deps);
// console.log(option)
fs.readFile(dest, 'utf-8', function (err, data) {
//利用各种过滤器过滤生成的html文件
for (var key in filters) {
data = filters[key](data);
}
//console.log(data)
if (err)
throw err;
//查找依赖
var deps = getDeps(data);
var $ = cheerio.load(data);
//人工添加依赖
var dependString = '';
for (var i = 0, l = deps.length; i < l; i++) {
if (deps[i].indexOf('css' !== -1)) {
dependString = dependString + '<link type="text/css" rel="stylesheet" href = "' +path.join(base,deps[i])+ '"/>'
} else if (deps[i].indexOf('js' !== -1)) {
}//js部分依赖,todo
}
$('head').append(dependString);
fs.writeFile(dest, $.html(), function (err) {
if (err)
throw err;
});
});
};
exports.ResultFormatWriter = ResultFormatWriter;
//读markdown文件并处理
exports.reader = function (post) {
var filename = post.meta.filepath.toLowerCase();
if (filename === 'history.md') {
post.template = post.meta.template = 'history';
} else {
post.template = post.meta.template = 'post';
}
if (filename === 'readme.md') {
post.filename = post.meta.filename = 'index';
post.meta.category = 'docs';
}
if (!post.meta.category) {
post.meta.category = post.meta.directory;
}
return post;
}
var pkg = require(path.join(process.cwd(), 'package.json'))
function getDevPath() {
var family = pkg.family;
var name = pkg.name;
var path = '../';
if (family && name) {
switch (family) {
case 'arale':
path = 'js/6v/lib/arale/' + name + '/_dev/';
break;
case 'icbu':
path = 'js/6v/lib/icbu/' + name + '/_dev/';
break;
case 'gallery':
path = 'js/6v/lib/gallery/' + name + '/_dev/';
break;
case 'biz-common':
path = 'js/6v/biz/common/' + name + '/_dev/';
break;
}
}
return path;
}
var devPath = getDevPath();
//处理模板文件,模板引擎用的helper
exports.filters = {
debug : function (args) {
return args.indexOf('debug') != -1;
},
debug_file : function (val) {
if (/\-debug\.(js|css)$/.test(val)) {
return val;
}
return val.replace(/\.(js|css)$/, '-debug.$1');
},
find : function (pages, cat) {
var ret = findCategory(pages, cat);
if (ret.length)
return ret[0];
return null;
},
find_category : findCategory,
replace_css : function (content) {
// css 路径加时间戳
var regexCss = new RegExp(
'(\-(?:sc|ws)\.css)"', 'g');
return content.replace(regexCss, '$1?t=0_0"');
},
replace_code : function (content) {
var _regex = new RegExp(
'<span class="string">(\'|\")((?:js/6v|biz\.common)/[a-z0-9-/]+(?:\.js)*)(\'|\")</span>', 'g');
var _regex2 = new RegExp(
'<span class="value">"((?:js/6v|biz\.common)/[a-z0-9-/]+(?:\.js)*)"</span>', 'g');
content = content.replace(_regex, '<span class="string">$1#stamp("$2")$3</span>')
.replace(_regex2, '<span class="value">"#stamp("$1")"</span>');
// 上面是老代码
//插入查看代码、复制代码
// content = content.replace(/<div class\="apollo-demo .*?">/,'<div class="apollo-demo demo-button"><a href="javascript:;" class="demo-show-code">查看代码</a><a href="javascript:;" class="demo-copy-code">复制代码</a>');
var keys = [];
for (var key in gAlias) {
keys.push(key.replace('-', '\\-'));
}
// 将 alias -> #stamp('')
var regex = new RegExp(
'<span class="string">(?:\'|\")(' + keys.join('|') + ')(?:\'|\")</span>', 'g');
/*var regex2 = new RegExp(
'<span class="value">"((?:js/6v|biz\.common)/[a-z0-9-/]+(?:\.js)*)"</span>', 'g'
);*/
return content.replace(regex, function (m, $1) {
return '<span class="string">\'#stamp("' + gAlias[$1] + '")\'</span>';
});
//.replace(regex2, '<span class="value">"#stamp("$1")"</span>');
},
history_tags_beautyfy : function (content) {
return content.replace(/(<code>tag:(.+?)<\/code>)/ig, function ($, $0, $1) {
return '<span class="history-tag history-tag-' + $1 + '">' + $1 + '</span>';
});
},
clean_alias : function (alias) {
Object.keys(alias).forEach(function (key) {
if (key === alias[key]) {
delete alias[key];
}
});
return alias;
},
render_src : function (writer) {
var base = path.relative(path.dirname(writer.filepath), '');
var ret = findSrc(base);
return JSON.stringify(ret);
}
}
var srcFiles = function () {
var srcdir = path.join(process.cwd(), 'src');
var ret = {
js : [],
css : [],
alias : {}
};
if (!file.exists(srcdir)) {
return ret;
}
file.recurse(srcdir, function (fpath) {
var fname = path.relative(srcdir, fpath).replace(/\\/g, '/');
var key;
if (/\.js$/.test(fname)) {
ret.js.push(fname);
key = fname.replace(/\.js$/, '');
ret.alias[key] = fname;
} else if (/\.css$/.test(fname)) {
ret.css.push(fname);
key = fname.replace(/\.css$/, '');
ret.alias[key] = fname;
}
});
return ret;
};
var getAlias = function () {
var srcs = srcFiles();
var srcAlias = srcs.alias;
var alias = {};
for (var key in srcAlias) {
if (srcAlias.hasOwnProperty(key)) {
var value = srcAlias[key];
// 不要css
if (value.indexOf('.css') === -1) {
alias[key] = (devPath + 'src/' + value).replace('_dev/src/', '');
}
}
}
return alias;
}
var gAlias = getAlias();
exports.functions = {
dist_files : function () {
var distdir = path.join(process.cwd(), 'dist');
var ret = {
js : [],
css : []
};
if (!file.exists(distdir)) {
return ret;
}
file.recurse(distdir, function (fpath) {
var fname = path.relative(distdir, fpath).replace(/\\/g, '/');
if (fname.indexOf('-debug') !== -1)
return;
if (/\.js$/.test(fname)) {
ret.js.push(fname);
} else if (/\.css$/.test(fname)) {
ret.css.push(fname);
}
});
return ret;
},
src_files : srcFiles,
alias_rets : function () {
return gAlias;
},
spec_files : function () {
var specdir = path.join(process.cwd(), 'tests');
var ret = [];
if (!file.exists(specdir)) {
return ret;
}
file.recurse(specdir, function (fpath) {
var fname = path.relative(specdir, fpath).replace(/\\/g, '/');
if (fname.indexOf('-spec') !== -1) {
ret.push(fname);
}
});
return ret;
},
engines : function () {
var ret = [];
if (pkg.spm && pkg.spm.engines) {
var engines = pkg.spm.engines;
Object.keys(engines).forEach(function (key) {
var js = engines[key];
if (/\.js$/.test(js)) {
ret.push(js);
} else {
ret.push(js + '.js');
}
});
}
return ret;
}
}
exports.hasHistory = file.exists(path.join(process.cwd(), 'HISTORY.md'));
//exports.hasTest = file.exists(path.join(process.cwd(), 'tests'));
//根据文件中的require依赖回写依赖给config,从而渲染layout.html
function getDeps(content){
var reg = /\s*#require\s*\(?\s*["']?([a-z0-9_\-\.\/]+)["']?\s*\)?\s*;?/g;
var dep = [];
content.replace(reg,function($0,$1){dep.push($1)});
//console.log(dep)
return dep
}
function findSrc(base) {
if (base === undefined) {
base = '..';
}
if (base === '') {
base = '.';
}
var ret = {};
var srcdir = path.join(process.cwd(), 'src');
if (!file.exists(srcdir)) {
return ret;
}
nico.sdk.file.recurse(srcdir, function (filepath) {
var filename = path.relative(srcdir, filepath);
var key = path.basename(filename);
key = key.replace(/\.js$/, '');
ret[key] = base + '/src/' + filename;
});
return ret;
}
function findCategory(pages, cat) {
var ret = [];
Object.keys(pages).forEach(function (key) {
var item = nico.sdk.post.read(key);
if (item.meta.category === cat) {
ret.push(item);
}
});
ret = ret.sort(function (a, b) {
if (/index$/i.test(a.filename)) {
a.meta.order = 1;
}
if (/index$/i.test(b.filename)) {
b.meta.order = 1;
}
a = a.meta.order || 10;
b = b.meta.order || 10;
return parseInt(a, 10) - parseInt(b, 10);
});
return ret;
}