UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

310 lines (305 loc) 9.41 kB
'use strict'; 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;