t-comm
Version:
专业、稳定、纯粹的工具库
310 lines (305 loc) • 9.41 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var time_time = require('../time/time.js');
/* eslint-disable @typescript-eslint/no-require-imports */
var DEFAULT_EXTRA_CSS = "\n.nav-separator {\n color: hsl(207, 1%, 60%);\n font-size: 12px;\n display: block;\n}\n\nnav ul a, nav ul a:active {\n font-size: 14px;\n}\n";
function getSeparatorStr(content) {
var maxLen = 14;
var lastLen = parseInt("".concat(maxLen - content.length / 2), 10);
var fill = Array.from({
length: lastLen
}).map(function () {
return '-';
}).join('');
return "".concat(fill, " ").concat(content, " ").concat(fill);
}
/**
* 删除重复的部分
* @ignore
*/
function deleteRepeatedSections($) {
var sections = $('section');
var last = '';
sections.map(function (_, section) {
var html = $(section).html().trim();
if (html === last) {
$(section).remove();
} else {
last = html;
}
});
return $;
}
/**
* 替换footer
* @ignore
* @param $ cheerio
* @param author 作者
*/
function replaceFooter($, author) {
var timezone = new Date().getTimezoneOffset() / -60;
var footerContent = "Documentation generated on ".concat(time_time.timeStampFormat(Date.now(), 'yyyy-MM-dd hh:mm:ss'), " GMT+0").concat(timezone, "00 ").concat(author && " by ".concat(author), ".");
$('footer').html(footerContent);
}
/**
* 找到 Modules 下的导航列表
* @ignore
* @param $ cheerio
*/
function findModuleNav($) {
var titles = $('body nav h3');
var res;
titles.map(function (_, title) {
if ($(title).html().trim() === 'Modules') {
res = $(title).next();
}
});
return res;
}
/**
* 获取nav头部,比如 tools/url => tools
* @ignore
*/
function getNavPrefix(nav) {
if (nav === void 0) {
nav = '';
}
if (nav.indexOf('/') < 0) {
return '';
}
return nav.split('/')[0];
}
/**
* 给 Modules 下的导航列表插入分隔符
* @ignore
* @param $ cheerio
*/
function insertModuleNavSeparator($) {
var module = findModuleNav($);
if (!module) return;
var last = '';
$(module).children('li').map(function (_, li) {
var _a, _b;
var nav = (_b = (_a = $(li).children('a')) === null || _a === void 0 ? void 0 : _a.html()) === null || _b === void 0 ? void 0 : _b.trim();
var prefix = getNavPrefix(nav);
if (prefix && last !== prefix) {
$(li).before("<li class=\"nav-separator\">".concat(getSeparatorStr(prefix), "</li>"));
}
if (prefix) {
last = prefix;
var navList = nav.split('/');
$(li).children('a').html(navList.slice(1).join('/'));
}
});
}
/**
* 插入分隔符
* @ignore
*/
function insertNavSeparator($, sourceMap) {
var naves = $('nav > ul li');
var cur = '';
naves.map(function (_, dom) {
var _a;
var nav = (_a = $(dom).find('a').attr('href')) === null || _a === void 0 ? void 0 : _a.trim();
if (nav && sourceMap[nav] && cur !== sourceMap[nav]) {
$(dom).before("<li class=\"nav-separator\">".concat(sourceMap[nav], "</li>"));
cur = sourceMap[nav];
}
});
}
/**
* 插入script
* @ignore
*/
function insertScript($, script) {
if (script === void 0) {
script = '';
}
if (!script) return;
$('head').children().last().after(script);
}
/**
* 默认处理source的方法,默认仅去掉的文件名
* @ignore
* @param source 文件路径
* @returns 处理后的数据
*/
function defaultNavHandler(source) {
var list = source.split('/');
return list.slice(0, list.length - 1).join('/');
}
var JsDocHandler = /** @class */function () {
/**
* 处理jsdoc的脚本
* 1. 增加导航栏的分隔符
* 2. 增加css
* 3. 处理footer
* @constructor
* @param {object} options 配置
* @param {string} [options.docsPath] 文档所在目录位置,默认为`./docs`
* @param {string} [options.author] 作者,默认为空
* @param {string} [options.extraCss] 额外插入的css,默认为`.nav-separator`的一些样式
* @param {string} [options.extraScript] 额外插入的script
* @param {Function} [options.navHandler] 处理API所在文件的方法
* @param {boolean} [options.isHandleNav] 是否处理导航栏,即插入文件名进行分隔,默认为false
*/
function JsDocHandler(options) {
if (options === void 0) {
options = {};
}
var _a = options.docsPath,
docsPath = _a === void 0 ? './docs' : _a,
_b = options.author,
author = _b === void 0 ? '' : _b,
_c = options.extraCss,
extraCss = _c === void 0 ? DEFAULT_EXTRA_CSS : _c,
_d = options.extraScript,
extraScript = _d === void 0 ? '' : _d,
_e = options.navHandler,
navHandler = _e === void 0 ? defaultNavHandler : _e,
_f = options.isHandleNav,
isHandleNav = _f === void 0 ? false : _f;
this.docsPath = docsPath;
this.author = author;
this.extraCss = extraCss;
this.extraScript = extraScript;
this.navHandler = navHandler;
this.isHandleNav = isHandleNav;
this.fs = this.getFs();
this.path = this.getPath();
}
/**
* 初始化并运行
* @static
* @param {object} options 配置
* @param {string} [options.docsPath] 文档所在目录位置,默认为`./docs`
* @param {string} [options.author] 作者,默认为空
* @param {string} [options.extraCss] 额外插入的css,默认为`.nav-separator`的一些样式
* @param {string} [options.navHandler] 处理API所在文件的方法
* @param {boolean} [options.isHandleNav] 是否处理导航栏,即插入文件名进行分隔,默认为false
* @returns {object} JsDocHandler实例
* @example
*
* JsDocHandler.init({
* author: 'novlan1',
* docsPath: './docs',
* extraCss: '.some-class{}',
* navHandler(nav) {
*
* }
* })
*
*/
JsDocHandler.init = function (options) {
var handler = new JsDocHandler(options);
handler.run();
return handler;
};
JsDocHandler.prototype.run = function () {
var sourceMap = {};
if (this.isHandleNav) {
sourceMap = this.getGlobalSourceMap();
}
this.handleEveryHtml(sourceMap, this.author);
this.appendCSS(this.extraCss);
this.finished();
};
JsDocHandler.prototype.getPath = function () {
return require('path');
};
JsDocHandler.prototype.getFs = function () {
return require('fs');
};
JsDocHandler.prototype.getGlobalSourceMap = function () {
console.log('[Jsdoc] Parsing nav list of global.html ...');
var file = 'global.html';
var sourceMap = this.getSourceMap(file);
return this.parseSourceMap(sourceMap);
};
/**
* 获取sourceMap,形如:
* ```ts
* {
* NUMBER_CHI_MAP: 'base/number/number.ts',
* parseFunction: 'base/function/function.ts',
* flatten: 'base/list/list.ts',
* }
* ```
* @private
* @param {string} content
* @returns {object} sourceMap
*/
JsDocHandler.prototype.getSourceMap = function (file) {
var _this = this;
var html = this.path.resolve(this.docsPath, file);
var content = this.fs.readFileSync(html, {
encoding: 'utf-8'
});
var cheerio = require('cheerio');
var $ = cheerio.load(content);
var sourceMap = {};
var names = $('#main section article h4.name');
names.map(function (_, dom) {
var id = $(dom).attr('id');
var source = $(dom).next().find('dd.tag-source ul.dummy li a').html().trim();
source = _this.navHandler(source);
sourceMap["".concat(file, "#").concat(id)] = source;
});
return sourceMap;
};
JsDocHandler.prototype.handleEveryHtml = function (sourceMap, author) {
var _this = this;
var files = this.fs.readdirSync(this.docsPath);
files.forEach(function (file) {
if (file.endsWith('.html')) {
var filePath = _this.path.resolve(_this.docsPath, file);
var content = _this.fs.readFileSync(filePath, {
encoding: 'utf-8'
});
var html = _this.getParsedHtml(content, sourceMap, author);
_this.fs.writeFileSync(filePath, html, {
encoding: 'utf-8'
});
}
});
};
JsDocHandler.prototype.parseSourceMap = function (sourceMap) {
return Object.keys(sourceMap).reduce(function (acc, key) {
var value = sourceMap[key];
acc[key] = getSeparatorStr(value);
return acc;
}, {});
};
JsDocHandler.prototype.getParsedHtml = function (content, sourceMap, author) {
var cheerio = require('cheerio');
var $ = cheerio.load(content);
var extraScript = this.extraScript;
// 删除重复selection
deleteRepeatedSections($);
// 插入分隔符
insertNavSeparator($, sourceMap);
// Modules下的导航栏插入分隔符
insertModuleNavSeparator($);
// 插入script
insertScript($, extraScript);
// 处理footer
replaceFooter($, author);
return $.html();
};
JsDocHandler.prototype.appendCSS = function (extra) {
console.log('[Jsdoc] Appending extra css ...');
var css = this.path.resolve(this.docsPath, 'styles/jsdoc.css');
var content = this.fs.readFileSync(css, {
encoding: 'utf-8'
});
this.fs.writeFileSync(css, "".concat(content, " \n").concat(extra), {
encoding: 'utf-8'
});
};
JsDocHandler.prototype.finished = function () {
console.log('[Jsdoc] Finished jsdoc local script.');
};
return JsDocHandler;
}();
exports.JsDocHandler = JsDocHandler;