UNPKG

4.24 kBJavaScriptView Raw
1'use strict'
2
3/**
4 * Module dependencies.
5 */
6
7const Config = require('markdown-it-chain')
8const highlight = require('./lib/highlight')
9const { PLUGINS, REQUIRED_PLUGINS } = require('./lib/constant')
10const highlightLinesPlugin = require('./lib/highlightLines')
11const preWrapperPlugin = require('./lib/preWrapper')
12const lineNumbersPlugin = require('./lib/lineNumbers')
13const componentPlugin = require('./lib/component')
14const hoistScriptStylePlugin = require('./lib/hoist')
15const convertRouterLinkPlugin = require('./lib/link')
16const snippetPlugin = require('./lib/snippet')
17const emojiPlugin = require('markdown-it-emoji')
18const anchorPlugin = require('markdown-it-anchor')
19const tocPlugin = require('markdown-it-table-of-contents')
20const {
21 slugify: _slugify,
22 parseHeaders,
23 logger, chalk, normalizeConfig,
24 moduleResolver: { getMarkdownItResolver }
25} = require('@vuepress/shared-utils')
26
27/**
28 * Create markdown by config.
29 */
30
31module.exports = (markdown = {}) => {
32 const {
33 externalLinks,
34 pageSuffix,
35 anchor,
36 toc,
37 plugins,
38 lineNumbers,
39 beforeInstantiate,
40 afterInstantiate
41 } = markdown
42
43 const resolver = getMarkdownItResolver()
44
45 // allow user config slugify
46 const slugify = markdown.slugify || _slugify
47
48 // using chainedAPI
49 const config = new Config()
50
51 config
52 .options
53 .html(true)
54 .highlight(highlight)
55 .end()
56
57 .plugin(PLUGINS.COMPONENT)
58 .use(componentPlugin)
59 .end()
60
61 .plugin(PLUGINS.HIGHLIGHT_LINES)
62 .use(highlightLinesPlugin)
63 .end()
64
65 .plugin(PLUGINS.PRE_WRAPPER)
66 .use(preWrapperPlugin)
67 .end()
68
69 .plugin(PLUGINS.SNIPPET)
70 .use(snippetPlugin)
71 .end()
72
73 .plugin(PLUGINS.CONVERT_ROUTER_LINK)
74 .use(convertRouterLinkPlugin, [Object.assign({
75 target: '_blank',
76 rel: 'noopener noreferrer'
77 }, externalLinks), pageSuffix])
78 .end()
79
80 .plugin(PLUGINS.HOIST_SCRIPT_STYLE)
81 .use(hoistScriptStylePlugin)
82 .end()
83
84 .plugin(PLUGINS.EMOJI)
85 .use(emojiPlugin)
86 .end()
87
88 .plugin(PLUGINS.ANCHOR)
89 .use(anchorPlugin, [Object.assign({
90 slugify,
91 permalink: true,
92 permalinkBefore: true,
93 permalinkSymbol: '#'
94 }, anchor)])
95 .end()
96
97 .plugin(PLUGINS.TOC)
98 .use(tocPlugin, [Object.assign({
99 slugify,
100 includeLevel: [2, 3],
101 format: parseHeaders
102 }, toc)])
103 .end()
104
105 if (lineNumbers) {
106 config
107 .plugin(PLUGINS.LINE_NUMBERS)
108 .use(lineNumbersPlugin)
109 }
110
111 beforeInstantiate && beforeInstantiate(config)
112
113 const md = config.toMd(require('markdown-it'), markdown)
114
115 const pluginsConfig = normalizeConfig(plugins || [])
116 pluginsConfig.forEach(([pluginRaw, pluginOptions]) => {
117 const plugin = resolver.resolve(pluginRaw)
118 if (plugin.entry) {
119 md.use(plugin.entry, pluginOptions)
120 } else {
121 // TODO: error handling
122 }
123 })
124
125 afterInstantiate && afterInstantiate(md)
126
127 module.exports.dataReturnable(md)
128
129 // expose slugify
130 md.slugify = slugify
131
132 return md
133}
134
135module.exports.dataReturnable = function dataReturnable (md) {
136 // override render to allow custom plugins return data
137 const render = md.render
138 md.render = (...args) => {
139 md.$data = {}
140 md.$data.__data_block = {}
141 md.$dataBlock = md.$data.__data_block
142 const html = render.call(md, ...args)
143 return {
144 html,
145 data: md.$data,
146 dataBlockString: toDataBlockString(md.$dataBlock)
147 }
148 }
149}
150
151function toDataBlockString (ob) {
152 if (Object.keys(ob).length === 0) {
153 return ''
154 }
155 return `<data>${JSON.stringify(ob)}</data>`
156}
157
158function isRequiredPlugin (plugin) {
159 return REQUIRED_PLUGINS.includes(plugin)
160}
161
162function removePlugin (config, plugin) {
163 logger.debug(`Built-in markdown-it plugin ${chalk.green(plugin)} was removed.`)
164 config.plugins.delete(plugin)
165}
166
167function removeAllBuiltInPlugins (config) {
168 Object.keys(PLUGINS).forEach(key => {
169 if (!isRequiredPlugin(PLUGINS[key])) {
170 removePlugin(config, PLUGINS[key])
171 }
172 })
173}
174
175module.exports.isRequiredPlugin = isRequiredPlugin
176module.exports.removePlugin = removePlugin
177module.exports.removeAllBuiltInPlugins = removeAllBuiltInPlugins
178module.exports.PLUGINS = PLUGINS