UNPKG

@sdoc/markdown-loader

Version:

san markdown loader

147 lines (133 loc) 4.79 kB
/** * @file 解析器 * @author ksky521 */ const MdIt = require('markdown-it'); function getCompiler(opt = {}) { // { // anchor // toc // lineNumbers // extend // extractHeaders // } const { link, lineNumbers = false, anchor = {permalink: false, permalinkBefore: false}, extend = () => {}, toc = {includeLevel: [2, 3]}, table = { multiline: false, rowspan: true, headerless: false } } = opt; const preset = opt.preset; // prettier-ignore let parser = preset === 'default' || preset === 'commonmark' || preset === 'zero' ? new MdIt(opt) : new MdIt( Object.assign({ xhtmlOut: true, html: true, highlight: require('./markdown/prismjs')({lineNumbers}) }, preset) ); parser.use(require('markdown-it-cjk-breaks')); parser.use(require('markdown-it-emoji')); parser.use(require('markdown-it-deflist')); parser.use(require('markdown-it-footnote')); parser.use(require('markdown-it-ins')); parser.use(require('markdown-it-anchor'), anchor); parser.use(require('markdown-it-table-of-contents'), toc); parser.use(require('markdown-it-sub')); parser.use(require('markdown-it-imsize')); parser.use(require('markdown-it-sup')); parser.use(require('markdown-it-attrs')); parser.use(require('markdown-it-task-lists')); parser.use(require('markdown-it-multimd-table'), table); parser.use(require('markdown-it-div'), { render(tokens, idx, options, env, slf) { const info = tokens[idx].info.trim(); const m = info.match(/(\]\(["']*\.\/).*(png|gif|jpg)/); console.log('info:', info, m); } }); parser.use(require('markdown-it-div'), { render(tokens, idx, options, env, slf) { const map = { warn: 'warning', danger: 'error', tip: 'info' }; const info = tokens[idx].info.trim(); const m = info.match(/^(warning|error|danger|warn|tip|info|success)\s+(.*)$/); if (tokens[idx].nesting === 1) { // opening tag let rs = ''; if (m) { const cls = map[m[1]] ? map[m[1]] : m[1]; rs += `<div class="${cls}">`; const title = m[2]; if (title) { rs += `<p class="info-title">${parser.utils.escapeHtml(title)}</p>\n`; } return rs; } // add a class to the opening tag const params = info.split(/\s+/); let id = null; let classes = []; for (let i = 0; i < params.length; i++) { let cls = params[i]; if (cls.includes('=')) { let [set0, set1] = cls.split('=', 2); tokens[idx].attrJoin(set0, set1); } else if (cls[0] === '#') { id = cls.slice(1); } else if (cls[0] === '.') { classes.push(cls.slice(1)); } else { classes.push(cls); } } if (id) { tokens[idx].attrJoin('id', id); } if (classes.length > 0) { tokens[idx].attrJoin('class', classes.join(' ')); } return slf.renderToken(tokens, idx, options, env, slf); } // closing tag return '</div>\n'; } }); parser.use(require('./markdown/jsx')); parser.use(require('./markdown/link'), link); parser.use(require('./markdown/snippet')); if (typeof extend === 'function') { extend(parser); } const render = parser.render.bind(parser); parser.render = content => { let result = render(content) .replace(/{{/g, '&#123;&#123;') // 解决 a.md 渲染 /a/index.html 后,图片 ./ 开始的相对路径问题 // css 的图片路径 webpack 会处理 // .replace(/(<img\s+.*src=")(\.\/.*)/mg, '$1.$2'); return result; }; return parser; } module.exports = (text, options = {}) => { text = String(text); const parser = getCompiler(options); let html = parser.render(text); // 解决{{}}被 san 误当成变量解析的情况 // html = html.replace('{{', '&#123;&#123;'); return html; }; module.exports.getCompiler = getCompiler;