UNPKG

node-framework

Version:

node-framework

197 lines (166 loc) 5.03 kB
/** * @file wiki.js * @author sekiyika (px.pengxing@gmail.com) * @description * */ var util = require('util'); var fs = require('fs'); var path = require('path'); var marked = require('marked'); var _ = require('lodash'); var Controller = require('../../index').Controller; marked.setOptions({ gfm: true, tables: true, breaks: true, pedantic: false, sanitize: true, smartLists: true, smartypants: true, highlight: function (code, lang) { return require('highlight.js').highlightAuto(code, [lang]).value; } }); var renderer = new marked.Renderer(); renderer.heading = function (text, level) { var escapedText = escape(text); return '<h' + level + '><a name="' + escapedText + '" class="anchor" href="#' + escapedText + '"><span class="icon icon-paragraph"></span></a>' + escapedText + '</h' + level + '>'; }; renderer.tablecell = function (content, flags) { var extraClazzRule = /\s*(.+?)\(@CLASS=(.+?)\)\s*/g; var type = flags.header ? 'th' : 'td'; var tag = flags.align ? '<' + type + ' style="text-align:' + flags.align + '">' : '<' + type + '>'; if (extraClazzRule.test(content)) { var matchArr = content.match(extraClazzRule); content = []; for (var i in matchArr) { var tmp = matchArr[i].match(/\s*(.+?)\(@CLASS=(.+?)\)\s*/); content.push('<span class="' + tmp[2] + '">' + tmp[1] + '</span>'); } content = content.join(''); } if (~content.indexOf('(@BR)')) { content = content.replace(/\(@BR\)/g, '<br/>'); } return tag + content + '</' + type + '>\n'; }; function Wiki() { Controller.apply(this, Array.prototype.slice.call(arguments, 0)); } util.inherits(Wiki, Controller); Wiki.prototype.actionIndex = function () { var filename = this.req.param(0); if (!filename) { filename = 'index'; } var baseDir = this.app.config.global.appdir; filename = filename + '.md'; var filepath = path.join(baseDir, 'docs', filename); if (!fs.existsSync(filepath)) { // TODO 404 this.send('Not Found'); return; } var meta; var index; var list = this.app.scan(); for (var i = 0, l = list.length; i < l; i++) { if (filename === list[i].file) { meta = list[i]; index = i; break; } } var text = fs.readFileSync(filepath).toString(); var data = { previous_page: false, next_page: false }; _.merge(data, this.app.config.wiki); data.page_title = meta.pageTitle; var filenames = filename.split(path.sep); data.current_page = { file: filename, title: meta.pageTitle }; if (filenames.length === 2) { data.current_page.folder = filenames[0]; } if (index > 0) { var item = list[index - 1]; data.previous_page = { title: item.pageTitle, url: '/' + item.file.substring(0, item.file.length - 3) } } if (index < (list.length - 1)) { item = list[index + 1]; data.next_page = { title: item.pageTitle, url: '/' + item.file.substring(0, item.file.length - 3) } } data.nav = this.getNav(); data.content = marked(text, { renderer: renderer }); this.render('base', data); }; Wiki.prototype.getNav = function () { var me = this; var list = me.app.scan(); var result = []; var recordedList = {}; list.forEach(function (item) { var data = { children: [] }; // 文件目录目前最多支持两级 var file = item.file; var files = file.split('/'); if (files.length > 2) { me.app.logger.warn(files + ' exceed two layers.'); return; } else if (files.length === 2) { var folder = files[0]; if (recordedList[folder] === undefined) { recordedList[folder] = result.length; data.title = folder; data.folder = folder; result.push(data); } data = result[recordedList[folder]]; data.children.push({ url: '/' + item.file.substring(0, item.file.length - 3), title: item.pageTitle, file: item.file, tocTree: item.tocTree }); } else { data.url = '/' + item.file.substring(0, item.file.length - 3); data.title = item.pageTitle; data.file = item.file; data.tocTree = item.tocTree; result.push(data); } }); // console.log(result); return result; }; function escape(html) { return String(html) .replace(/&/g,'&amp;') .replace(/</g,'&lt;') .replace(/>/g,'&gt;') .replace(/"/g, "&quot;") .replace(/'/g, "&#39;"); } module.exports = Wiki;