amWiki/build/makeNavigation.js

175 lines
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 工作端 - 创建 $navigation.md 导航文件模块
* @author Tevin
*/
const fs = require('fs');
const mngFolder = require('./manageFolder');
const makeNavigation = (function () {
return {
/**
* 刷新导航
* @param {String} editPath - 当前文档的路径
* @returns {String} library文件夹路径
* @public
*/
refresh: function (editPath) {
const path = editPath.replace(/\\/g, '/').split('library')[0] + 'library/';
const [tree, list] = mngFolder.readLibraryTree(path);
if (!tree) {
return '';
}
this.make(path, tree, list);
return path
},
/**
* 创建 .md 导航文件
* @param {String} path - 文库library文件夹路径
* @param {Object} tree - 目录结构树形数据
* @param {Array} list - 目录结构列表数据
* @public
*/
make: function (path, tree, list) {
//先检查id重复
if (this._checkDuplicateId(tree)) {
return;
}
let errorHas = false;
let markdown = '';
//首页链接输出为 Markdown 文本
for (let fileName in tree) {
if (tree.hasOwnProperty(fileName)) {
if (fileName === '首页.md') {
break;
} else if (/^home[-_].*?\.md$/.test(fileName)) {
const [, path, name] = fileName.match(/^(home[-_])(.*?)\.md$/);
markdown += '\n#### [' + name + '](?file=' + path + name + ')\n';
break;
}
}
}
markdown = (markdown === '') ? '\n#### [首页](?file=首页 "返回首页")\n' : markdown;
//导航数据输出为 Markdown 文本
for (let item of list) {
//检查 id 合法性
if (!this._checkFileId(item.name, item.path)) {
errorHas = true;
continue;
}
//转义文件名中包含的语法符号
item.name = item.name
.replace(/'/g, ''') //转义单引号
.replace(/"/g, '"') //转义双引号
.replace(/\(/g, '(') //转义左圆括号
.replace(/\)/g, ')') //转义右圆括号
.replace(/\[/g, '[') //转义左中括号
.replace(/\]/g, ']'); //转义右中括号
//一级目录
if (item.depth === 0) {
//一级目录不允许文件
if (item.type !== 'folder') {
continue;
}
markdown += '\n##### ' + item.name.match(/^\d+(\.\d+)?[-_](.*?)$/)[2] + '\n';
}
//深目录
else {
//层级缩进
markdown += new Array(item.depth).join(' ');
//文件夹和文件分开处理
if (item.type === 'folder') {
markdown += '- **' + item.name.match(/^\d+(\.\d+)?[-_](.*?)$/)[2] + '**\n';
} else if (item.type === 'file') {
//检查名称合法性
if (!this._checkFileName(item.name, item.path)) {
errorHas = true;
continue;
}
const name = item.name.match(/^\d+(\.\d+)?[-_](.*?)\.md$/)[2];
const path = item.path.split('library/')[1] + '/' + item.name.split('.md')[0];
markdown += '- [' + name + '](?file=' + path + ' "' + name + '")\n';
}
}
}
if (!errorHas) {
fs.writeFileSync(path + '$navigation.md', markdown, 'utf-8');
}
},
/**
* 检查id合法性
* @param {String} name
* @param {String} path
* @returns {Boolean}
* @private
*/
_checkFileId: function (name, path) {
if (/^\d+(\.\d+)?[-_](.*?)$/.test(name)) {
return true
} else {
const text = '不合法的排序ID\n请修改排序ID为整数或浮点数且使用连接符或下划线与具体名称相接\n' +
' at path "library/' + path.split('library/')[1] + '"\n' +
' at file "' + name + '"';
alert(text);
return false;
}
},
/**
* 检查名称合法性
* @param {String} name
* @param {String} path
* @returns {Boolean}
* @private
*/
_checkFileName: function (name, path) {
if (/^\d+(\.\d+)?[-_](.*?)\.md$/.test(name)) {
return true
} else {
const errText = '不合法的文件名!\n请将文件名修改为形如 “排序ID-名称.md” 格式的名称\n' +
' at path "library/' + path.split('library/')[1] + '/"\n' +
' at file "' + name + '"';
alert(errText);
return false;
}
},
/**
* 递归检查(某一目录下的同级文件和文件夹的)ID是否存在重复
* @param {Object} tree - 当前层级的目录结构
* @param {String} path - 当前目录所在路径
* @return {Boolean} 如果返回为true则说明存在重复ID
* @private
*/
_checkDuplicateId: function (tree, path = '') {
let duplicate = false;
let idList = {};
for (let name in tree) {
if (tree.hasOwnProperty(name)) {
if (!idList[name.split(/[-_]/)[0]]) {
idList[name.split(/[-_]/)[0]] = name;
} else {
alert('重复的排序ID\n同级目录下存在相同的排序ID(' + name.split('-')[0] + ')请更改为不同的ID\n' +
' at path "library/' + path + '"\n' +
' at file1 "' + idList[name.split('-')[0]] + '"\n' +
' at file2 "' + name + '"');
duplicate = true;
}
//文件夹
if (tree[name]) {
// duplicate 为真后,不再改变其值
if (duplicate) {
this._checkDuplicateId(tree[name], path + name + '/')
}
// duplicate 为否时,接收子级真假值
else {
duplicate = this._checkDuplicateId(tree[name], path + name + '/');
}
}
}
}
return duplicate;
}
};
})();
module.exports = makeNavigation;