UNPKG

2.81 kBJavaScriptView Raw
1const utils = require('../utils.js');
2const fs = require('fs-extra');
3const MarkdownIt = require('markdown-it');
4const prism = require('prismjs');
5const loadLanguages = require('prismjs/components/index.js');
6const he = require('he');
7utils.md = MarkdownIt({
8 html: true,
9 linkify: false,
10 highlight: function (str, lang) {
11 try {
12 if (lang) {
13 // js => javascript
14 if (lang.toLowerCase() === 'js') {
15 lang = 'javascript';
16 }
17 // html 的高亮使用 haml 语法
18 if (lang.toLocaleLowerCase() === 'html') {
19 lang = 'haml';
20 }
21 loadLanguages([lang]);
22 return prism.highlight(str, prism.languages[lang], lang);
23 }
24 return he.encode(str);
25 } catch (err) {
26 return he.encode(str);
27 }
28 }
29})
30
31exports.loadMarkdownPlugins = function(fn){
32 if(fn && typeof fn === 'function'){
33 fn.call(this, utils.md)
34 }
35}
36
37
38
39/**
40 * 处理 hash 带特殊字符的问题
41 */
42utils.md.use(function (md) {
43 let urlRegexp = /^\[(.*?)\]\((.*?)\)$/;
44 let hashRegexp = /#(.*)/;
45
46 let defaultHtmlRender = md.renderer.rules.html_inline;
47 let defaultTextRender = md.renderer.rules.text;
48
49 md.renderer.rules.text = function (tokens, idx, options, env, self) {
50 let token = tokens[idx];
51 if (!token || !token.content) return defaultTextRender(tokens, idx, options, env, self)
52 let content = token.content.trim();
53 if (!urlRegexp.test(content)) return defaultTextRender(tokens, idx, options, env, self)
54 token.content = content.replace(urlRegexp, function (str, title, url) {
55 if (!url) return str;
56 url = url.replace(hashRegexp, function (str, match) {
57 if(!match) return str;
58 return '#' + utils.hashEncode(match)
59 })
60 return `<a href="${url}" >${title}</a>`;
61 })
62
63 return defaultHtmlRender(tokens, idx, options, env, self);
64 }
65})
66
67/**
68 * 处理外链问题
69 */
70
71utils.md.use(function(md){
72 let defaultRender = md.renderer.rules.link_open || function(tokens, idx, options, env, self) {
73 return self.renderToken(tokens, idx, options);
74 };
75
76 md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
77 let targetIndex = tokens[idx].attrIndex('target');
78 let hrefIndex = tokens[idx].attrIndex('href');
79 let url = tokens[idx].attrGet('href')
80 if (url && /^https?:\/\//.test(url)) {
81 if (targetIndex < 0) {
82 tokens[idx].attrPush(['target', '_blank']); // add new attribute
83 } else {
84 tokens[idx].attrs[targetIndex][1] = '_blank'; // replace value of existing attr
85 }
86 }
87
88 return defaultRender(tokens, idx, options, env, self);
89 };
90})
91
92exports.parseMarkdown = function parseMarkdown(filepath) {
93 const content = fs.readFileSync(filepath, 'utf8');
94 return utils.md.render(content);
95}
\No newline at end of file