lintry

使用action处理markdown文件显示

调整md文档目录定义
...@@ -9,7 +9,7 @@ if (!target) { ...@@ -9,7 +9,7 @@ if (!target) {
9 process.exit(1); 9 process.exit(1);
10 } 10 }
11 11
12 -const mdview = new (require('../lib/mdview')), 12 +const mdview = new (require('../lib/mdviewer')),
13 path = require('path'); 13 path = require('path');
14 14
15 const filename = path.resolve(process.cwd(), target); 15 const filename = path.resolve(process.cwd(), target);
......
1 -module.exports = require('./lib/mdview'); 1 +module.exports = require('./lib/mdviewer');
......
...@@ -10,11 +10,11 @@ const configure = customize({ ...@@ -10,11 +10,11 @@ const configure = customize({
10 "bind_port": 8200, 10 "bind_port": 8200,
11 }, 11 },
12 "md": { 12 "md": {
13 - "base_path": "md", 13 + "base_path": {},
14 "default_md": "readme.md", 14 "default_md": "readme.md",
15 "theme": "metro-lake", 15 "theme": "metro-lake",
16 "toc": true 16 "toc": true
17 - } 17 + },
18 }); 18 });
19 19
20 //绑定到全局变量 20 //绑定到全局变量
......
1 +/**
2 + * 处理接口api的action路由
3 + */
4 +/* global global */
5 +/* global process */
6 +"use strict";
7 +
8 +const _ = require('lodash'),
9 + path = require('path'),
10 + express = require('express'),
11 + router = express.Router(),
12 + config = global.config
13 +;
14 +
15 +/**
16 + * markdown文件查看
17 + * @param alias_name 路由别名
18 + * @param md_path markdown文档路径
19 + * @return {*}
20 + * @constructor
21 + */
22 +function MdAction (alias_name, md_path) {
23 + let alias;
24 +
25 + switch (!!alias_name) {
26 + case false: // 没有定义别名,默认为根
27 + alias = '';
28 + break;
29 + case /\/.+/.test(alias_name): // 带根路径别名,直接用
30 + alias = alias_name;
31 + break;
32 + case /[^\/].+/.test(alias_name): // 不带根路径别名,补充根路径
33 + alias = '/' + alias_name;
34 + break;
35 + default: // 只传入根路径,和别名空一样处理
36 + alias = ''
37 +
38 + }
39 +
40 + let doc_path = path.resolve(process.cwd(), md_path || '');
41 +
42 + const MD_REGEXP = new RegExp(`^${alias}\\/([\\/\\w]*)`);
43 +
44 + //根据别名处理文档目录所在的markdown文件
45 + const viewer = new (require('./view-markdown'))(doc_path, config.md);
46 + router.get(/(.*)/, function request (req, res, next) {
47 + let url = req.url, urls = url.match(MD_REGEXP) || [], query = req.query;
48 + if (!urls.length) {
49 + return next();
50 + }
51 + let ext = path.parse(url).ext;
52 + if (ext && ext !== '.md') {
53 + return next();
54 + }
55 +
56 + res.send(viewer.render(urls[1], query.t));
57 + });
58 + //加载文档目录为静态页,别名为空时指向根路径
59 + router.use(alias || '/', express.static(doc_path));
60 +
61 + return router;
62 +}
63 +
64 +module.exports = MdAction;
...@@ -33,12 +33,10 @@ function MarkdownIt (opts) { ...@@ -33,12 +33,10 @@ function MarkdownIt (opts) {
33 try { 33 try {
34 content = fs.readFileSync(filename).toString(); 34 content = fs.readFileSync(filename).toString();
35 result.html = md.render(content); 35 result.html = md.render(content);
36 + result.status = 200;
36 } catch (e) { 37 } catch (e) {
37 - console.error('convert md to html error', e); 38 + // console.error('convert md to html error', e);
38 - result.html = md.render(` 39 + result.status = 404;
39 -# 404
40 -*文件找不到!*
41 -`)
42 } 40 }
43 41
44 try { 42 try {
...@@ -46,10 +44,30 @@ function MarkdownIt (opts) { ...@@ -46,10 +44,30 @@ function MarkdownIt (opts) {
46 result.tokens = md.parse(content, {}); 44 result.tokens = md.parse(content, {});
47 } 45 }
48 } catch (e) { 46 } catch (e) {
49 - console.error('parse md error', e) 47 + // console.warn('parse md error', e)
50 } 48 }
51 49
52 return result; 50 return result;
51 + };
52 +
53 + /**
54 + * 返回渲染文本
55 + * @param src
56 + * @param env
57 + * @return {*}
58 + */
59 + this.render = function (src, env) {
60 + return md.render(src, env)
61 + };
62 +
63 + /**
64 + * 返回解析文本
65 + * @param src
66 + * @param env
67 + * @return {*}
68 + */
69 + this.parse = function (src, env) {
70 + return md.parse(src, env)
53 } 71 }
54 } 72 }
55 73
......
...@@ -5,29 +5,43 @@ ...@@ -5,29 +5,43 @@
5 5
6 const path = require('path'); 6 const path = require('path');
7 7
8 +
8 class ViewMarkdown { 9 class ViewMarkdown {
9 - constructor (options) { 10 + constructor (doc_path, options) {
10 this.options = options || {}; 11 this.options = options || {};
11 - if (!this.options.base_path) { 12 + if (!doc_path) {
12 - throw new Error('no base path for markdown') 13 + throw new Error('document path for markdown not found')
13 } 14 }
15 +
16 + this.doc_path = doc_path;
17 + this.mdviewer = new (require('./mdviewer'))({parseTokens: true, toc: this.options.toc});
14 } 18 }
15 19
20 + /**
21 + * 渲染文件
22 + * @param filename 文件名,绝对路径
23 + * @param theme 主题
24 + * @return {string}
25 + */
16 render (filename, theme) { 26 render (filename, theme) {
17 const options = this.options; 27 const options = this.options;
18 //默认md 28 //默认md
19 if (!filename || filename.match(/.+\/$/)) { 29 if (!filename || filename.match(/.+\/$/)) {
20 - filename = (filename || '') + options.default_md || 'readme.md' 30 + filename = (filename || '') + (options.default_md || 'readme.md')
21 } 31 }
22 - let file = path.resolve(options.base_path, filename); 32 + let file = path.resolve(this.doc_path, filename);
23 if (!path.parse(file).ext) { 33 if (!path.parse(file).ext) {
24 //追加后缀 34 //追加后缀
25 file += '.md' 35 file += '.md'
26 } 36 }
27 - const mdview = new (require('./mdview'))({parseTokens: true, toc: options.toc}); 37 + let result = this.mdviewer.renderFile(file);
28 - let result = mdview.renderFile(file);
29 let tittle = result.tokens && result.tokens[1] && result.tokens[1].content || filename; 38 let tittle = result.tokens && result.tokens[1] && result.tokens[1].content || filename;
30 theme = theme || options.theme; 39 theme = theme || options.theme;
40 + let content = result.status === 404 ? this.mdviewer.render(`
41 +# 404
42 +> **${filename}不存在**
43 +`)
44 + : result.html;
31 return ` 45 return `
32 <!DOCTYPE html> 46 <!DOCTYPE html>
33 <html> 47 <html>
...@@ -40,7 +54,7 @@ class ViewMarkdown { ...@@ -40,7 +54,7 @@ class ViewMarkdown {
40 </head> 54 </head>
41 <body> 55 <body>
42 <div class='markdown ${theme}'> 56 <div class='markdown ${theme}'>
43 - ${result.html} 57 + ${content}
44 </div> 58 </div>
45 </body 59 </body
46 </html> 60 </html>
...@@ -48,4 +62,4 @@ class ViewMarkdown { ...@@ -48,4 +62,4 @@ class ViewMarkdown {
48 } 62 }
49 } 63 }
50 64
51 -module.exports = ViewMarkdown
...\ No newline at end of file ...\ No newline at end of file
65 +module.exports = ViewMarkdown;
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -3,24 +3,19 @@ const app = express(); ...@@ -3,24 +3,19 @@ const app = express();
3 3
4 const config = require('./init/config'); 4 const config = require('./init/config');
5 5
6 -const path = require('path'); 6 +//markdown主题
7 +app.use(express.static(__dirname + '/themes'));
7 8
8 -const MARKDOWN_FILE_BASE = path.resolve(process.cwd(), config.md.base_path);
9 9
10 -app.use(express.static(__dirname + '/themes')); 10 +const MdAction = require('./lib/md-action');
11 -app.use(express.static(MARKDOWN_FILE_BASE));
12 11
13 -function viewMarkdown (req, res, next) { 12 +let base_path = config.md.base_path || {};
14 - let url = req.url, urls = url.match(/^\/([\/\w]+)/) || [], query = req.query; 13 +Object.keys(base_path).forEach(p => {
15 - let ext = path.parse(url).ext; 14 + app.use('/', new MdAction(p, base_path[p]))
16 - if (ext && ext !== 'md') { 15 +});
17 - return next();
18 - }
19 - const viewer = new (require('./lib/view-markdown'))(config.md);
20 - res.send(viewer.render(urls[1], query.t));
21 -}
22 16
23 -app.get('/*', viewMarkdown); 17 +//默认
18 +app.use('/', new MdAction('/', 'md'));
24 19
25 const PORT = config.system.bind_port; 20 const PORT = config.system.bind_port;
26 app.listen(PORT); 21 app.listen(PORT);
......
...@@ -60,28 +60,15 @@ ...@@ -60,28 +60,15 @@
60 } 60 }
61 61
62 .metro-lake h2 { 62 .metro-lake h2 {
63 + width: max-content;
64 + margin: 0.8rem auto;
63 font-size: 1.4rem; 65 font-size: 1.4rem;
64 border-bottom: 1px solid #bbb; 66 border-bottom: 1px solid #bbb;
65 - line-height: 1.6rem; 67 + /*line-height: 1.6rem;*/
66 - padding-bottom: 0.8rem; 68 + padding-bottom: 0.5rem;
67 text-align: center; 69 text-align: center;
68 } 70 }
69 71
70 -.metro-lake h2:before {
71 - content: '══';
72 - font-weight: 100;
73 - letter-spacing: -1px;
74 - padding-right: 1rem;
75 - color: #888
76 -}
77 -.metro-lake h2:after {
78 - content: '══';
79 - font-weight: 100;
80 - letter-spacing: -1px;
81 - padding-left: 1rem;
82 - color: #888
83 -}
84 -
85 .metro-lake blockquote h2:before { 72 .metro-lake blockquote h2:before {
86 content: ''; 73 content: '';
87 padding-right: 0; 74 padding-right: 0;
......