1 | 'use strict'
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | const Config = require('markdown-it-chain')
|
8 | const highlight = require('./lib/highlight')
|
9 | const { PLUGINS, REQUIRED_PLUGINS } = require('./lib/constant')
|
10 | const highlightLinesPlugin = require('./lib/highlightLines')
|
11 | const preWrapperPlugin = require('./lib/preWrapper')
|
12 | const lineNumbersPlugin = require('./lib/lineNumbers')
|
13 | const componentPlugin = require('./lib/component')
|
14 | const hoistScriptStylePlugin = require('./lib/hoist')
|
15 | const convertRouterLinkPlugin = require('./lib/link')
|
16 | const snippetPlugin = require('./lib/snippet')
|
17 | const emojiPlugin = require('markdown-it-emoji')
|
18 | const anchorPlugin = require('markdown-it-anchor')
|
19 | const tocPlugin = require('markdown-it-table-of-contents')
|
20 | const {
|
21 | slugify: _slugify,
|
22 | parseHeaders,
|
23 | logger, chalk, normalizeConfig,
|
24 | moduleResolver: { getMarkdownItResolver }
|
25 | } = require('@vuepress/shared-utils')
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | module.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 |
|
46 | const slugify = markdown.slugify || _slugify
|
47 |
|
48 |
|
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 |
|
122 | }
|
123 | })
|
124 |
|
125 | afterInstantiate && afterInstantiate(md)
|
126 |
|
127 | module.exports.dataReturnable(md)
|
128 |
|
129 |
|
130 | md.slugify = slugify
|
131 |
|
132 | return md
|
133 | }
|
134 |
|
135 | module.exports.dataReturnable = function dataReturnable (md) {
|
136 |
|
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 |
|
151 | function toDataBlockString (ob) {
|
152 | if (Object.keys(ob).length === 0) {
|
153 | return ''
|
154 | }
|
155 | return `<data>${JSON.stringify(ob)}</data>`
|
156 | }
|
157 |
|
158 | function isRequiredPlugin (plugin) {
|
159 | return REQUIRED_PLUGINS.includes(plugin)
|
160 | }
|
161 |
|
162 | function removePlugin (config, plugin) {
|
163 | logger.debug(`Built-in markdown-it plugin ${chalk.green(plugin)} was removed.`)
|
164 | config.plugins.delete(plugin)
|
165 | }
|
166 |
|
167 | function removeAllBuiltInPlugins (config) {
|
168 | Object.keys(PLUGINS).forEach(key => {
|
169 | if (!isRequiredPlugin(PLUGINS[key])) {
|
170 | removePlugin(config, PLUGINS[key])
|
171 | }
|
172 | })
|
173 | }
|
174 |
|
175 | module.exports.isRequiredPlugin = isRequiredPlugin
|
176 | module.exports.removePlugin = removePlugin
|
177 | module.exports.removeAllBuiltInPlugins = removeAllBuiltInPlugins
|
178 | module.exports.PLUGINS = PLUGINS
|