From ad0ff7228cc9b09743b135157edb2a83fdce976f Mon Sep 17 00:00:00 2001 From: Shigma <33423008+Shigma@users.noreply.github.com> Date: Sat, 2 Mar 2019 23:50:30 +0800 Subject: [PATCH] feat: plugin container (#1381) --- packages/@vuepress/markdown/index.js | 5 -- packages/@vuepress/markdown/lib/containers.js | 33 -------- packages/@vuepress/markdown/package.json | 1 - .../@vuepress/plugin-container/.npmignore | 3 + packages/@vuepress/plugin-container/README.md | 5 ++ packages/@vuepress/plugin-container/index.js | 48 +++++++++++ .../@vuepress/plugin-container/package.json | 29 +++++++ packages/@vuepress/theme-default/index.js | 10 ++- packages/docs/docs/.vuepress/config.js | 38 ++++----- .../docs/plugin/official/plugin-container.md | 80 +++++++++++++++++++ .../zh/plugin/official/plugin-container.md | 80 +++++++++++++++++++ 11 files changed, 270 insertions(+), 62 deletions(-) delete mode 100644 packages/@vuepress/markdown/lib/containers.js create mode 100644 packages/@vuepress/plugin-container/.npmignore create mode 100644 packages/@vuepress/plugin-container/README.md create mode 100644 packages/@vuepress/plugin-container/index.js create mode 100644 packages/@vuepress/plugin-container/package.json create mode 100644 packages/docs/docs/plugin/official/plugin-container.md create mode 100644 packages/docs/docs/zh/plugin/official/plugin-container.md diff --git a/packages/@vuepress/markdown/index.js b/packages/@vuepress/markdown/index.js index cc8d09fb40..60af7ca865 100644 --- a/packages/@vuepress/markdown/index.js +++ b/packages/@vuepress/markdown/index.js @@ -14,7 +14,6 @@ const lineNumbersPlugin = require('./lib/lineNumbers') const componentPlugin = require('./lib/component') const hoistScriptStylePlugin = require('./lib/hoist') const convertRouterLinkPlugin = require('./lib/link') -const containersPlugin = require('./lib/containers') const markdownSlotsContainersPlugin = require('./lib/markdownSlotsContainers') const snippetPlugin = require('./lib/snippet') const emojiPlugin = require('markdown-it-emoji') @@ -75,10 +74,6 @@ module.exports = (markdown = {}) => { .use(hoistScriptStylePlugin) .end() - .plugin(PLUGINS.CONTAINERS) - .use(containersPlugin) - .end() - .plugin(PLUGINS.MARKDOWN_SLOTS_CONTAINERS) .use(markdownSlotsContainersPlugin) .end() diff --git a/packages/@vuepress/markdown/lib/containers.js b/packages/@vuepress/markdown/lib/containers.js deleted file mode 100644 index 0ee6be8037..0000000000 --- a/packages/@vuepress/markdown/lib/containers.js +++ /dev/null @@ -1,33 +0,0 @@ -const container = require('markdown-it-container') - -module.exports = md => { - md - .use(...createContainer('tip', 'TIP')) - .use(...createContainer('warning', 'WARNING')) - .use(...createContainer('danger', 'WARNING')) - // explicitly escape Vue syntax - .use(container, 'v-pre', { - render: (tokens, idx) => tokens[idx].nesting === 1 - ? `
\n` - : `
\n` - }) - .use(container, 'vue', { - render: (tokens, idx) => tokens[idx].nesting === 1 - ? `
`
-        : `
` - }) -} - -function createContainer (klass, defaultTitle) { - return [container, klass, { - render (tokens, idx) { - const token = tokens[idx] - const info = token.info.trim().slice(klass.length).trim() - if (token.nesting === 1) { - return `

${info || defaultTitle}

\n` - } else { - return `
\n` - } - } - }] -} diff --git a/packages/@vuepress/markdown/package.json b/packages/@vuepress/markdown/package.json index 196639d6ba..14607ebad2 100644 --- a/packages/@vuepress/markdown/package.json +++ b/packages/@vuepress/markdown/package.json @@ -24,7 +24,6 @@ "markdown-it": "^8.4.1", "markdown-it-anchor": "^5.0.2", "markdown-it-chain": "^1.3.0", - "markdown-it-container": "^2.0.0", "markdown-it-emoji": "^1.4.0", "markdown-it-table-of-contents": "^0.4.0", "prismjs": "^1.13.0" diff --git a/packages/@vuepress/plugin-container/.npmignore b/packages/@vuepress/plugin-container/.npmignore new file mode 100644 index 0000000000..13c38ea313 --- /dev/null +++ b/packages/@vuepress/plugin-container/.npmignore @@ -0,0 +1,3 @@ +__tests__ +__mocks__ +.temp diff --git a/packages/@vuepress/plugin-container/README.md b/packages/@vuepress/plugin-container/README.md new file mode 100644 index 0000000000..fc0b2211d2 --- /dev/null +++ b/packages/@vuepress/plugin-container/README.md @@ -0,0 +1,5 @@ +# @vuepress/plugin-container + +> markdown container plugin for vuepress + +See [documentation](https://vuepress.vuejs.org/plugin/official/plugin-container.html). diff --git a/packages/@vuepress/plugin-container/index.js b/packages/@vuepress/plugin-container/index.js new file mode 100644 index 0000000000..4715ae046a --- /dev/null +++ b/packages/@vuepress/plugin-container/index.js @@ -0,0 +1,48 @@ +const container = require('markdown-it-container') + +function call (target, ...args) { + if (typeof target === 'function') { + return target(...args) + } else { + return target + } +} + +module.exports = (options, context) => ({ + multiple: true, + + extendMarkdown (md) { + const { + validate, + marker, + before, + after, + type = '', + defaultTitle = type.toUpperCase() + } = options + if (!type) return + + let { render } = options + if (!render) { + if (before !== undefined && after !== undefined) { + render = (tokens, index) => { + const token = tokens[index] + return token.nesting === 1 ? call(before, token) : call(after, token) + } + } else { + render = (tokens, index) => { + const token = tokens[index] + let title = token.info.trim().slice(type.length).trim() || defaultTitle + if (title) title = `

${title}

` + if (token.nesting === 1) { + return `
${title}\n` + } else { + return `
\n` + } + } + } + } + + md.use(container, type, { render, validate, marker }) + } +}) diff --git a/packages/@vuepress/plugin-container/package.json b/packages/@vuepress/plugin-container/package.json new file mode 100644 index 0000000000..4dfb8d3b19 --- /dev/null +++ b/packages/@vuepress/plugin-container/package.json @@ -0,0 +1,29 @@ +{ + "name": "@vuepress/plugin-container", + "version": "1.0.0-alpha.40", + "description": "markdown container plugin for vuepress", + "main": "index.js", + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/vuejs/vuepress.git", + "directory": "packages/@vuepress/plugin-container" + }, + "keywords": [ + "documentation", + "vue", + "vuepress", + "generator" + ], + "dependencies": { + "markdown-it-container": "^2.0.0" + }, + "author": "Shigma <1700011071@pku.edu.cn>", + "license": "MIT", + "bugs": { + "url": "https://github.com/vuejs/vuepress/issues" + }, + "homepage": "https://github.com/vuejs/vuepress/packages/@vuepress/plugin-container#readme" +} diff --git a/packages/@vuepress/theme-default/index.js b/packages/@vuepress/theme-default/index.js index 3cafe568c0..0f214621ce 100644 --- a/packages/@vuepress/theme-default/index.js +++ b/packages/@vuepress/theme-default/index.js @@ -20,6 +20,14 @@ module.exports = (options, ctx) => ({ plugins: [ '@vuepress/active-header-links', '@vuepress/search', - '@vuepress/plugin-nprogress' + '@vuepress/plugin-nprogress', + ['@vuepress/container', { type: 'tip' }], + ['@vuepress/container', { type: 'warning' }], + ['@vuepress/container', { type: 'danger' }], + ['@vuepress/container', { + type: 'v-pre', + before: '
\n', + after: '
\n' + }] ] }) diff --git a/packages/docs/docs/.vuepress/config.js b/packages/docs/docs/.vuepress/config.js index b56d1334ed..e1a7e0466a 100755 --- a/packages/docs/docs/.vuepress/config.js +++ b/packages/docs/docs/.vuepress/config.js @@ -1,4 +1,4 @@ -const container = require('markdown-it-container') +const { fs, path } = require('@vuepress/shared-utils') module.exports = ctx => ({ dest: '../../vuepress', @@ -74,14 +74,17 @@ module.exports = ctx => ({ ['@vuepress/google-analytics', { ga: 'UA-128189152-1' }], + ['@vuepress/container', { + type: 'vue', + before: '
',
+      after: '
', + }], + ['@vuepress/container', { + type: 'upgrade', + before: ({ info }) => ``, + after: '', + }], ], - extendMarkdown (md) { - md.use(container, 'upgrade', { - render: (tokens, idx) => tokens[idx].nesting === 1 - ? `` - : '' - }) - }, }) function getGuideSidebar (groupA, groupB) { @@ -114,6 +117,10 @@ function getGuideSidebar (groupA, groupB) { ] } +const officalPlugins = fs + .readdirSync(path.resolve(__dirname, '../plugin/official')) + .map(filename => 'official/' + filename.slice(0, -3)) + function getPluginSidebar (pluginTitle, pluginIntro, officialPluginTitle) { return [ { @@ -131,20 +138,7 @@ function getPluginSidebar (pluginTitle, pluginIntro, officialPluginTitle) { { title: officialPluginTitle, collapsable: false, - children: [ - 'official/plugin-search', - 'official/plugin-active-header-links', - 'official/plugin-pwa', - 'official/plugin-blog', - 'official/plugin-pagination', - 'official/plugin-google-analytics', - 'official/plugin-i18n-ui', - 'official/plugin-last-updated', - 'official/plugin-medium-zoom', - 'official/plugin-back-to-top', - 'official/plugin-register-components', - 'official/plugin-clean-urls' - ] + children: officalPlugins, } ] } diff --git a/packages/docs/docs/plugin/official/plugin-container.md b/packages/docs/docs/plugin/official/plugin-container.md new file mode 100644 index 0000000000..359f3a98cf --- /dev/null +++ b/packages/docs/docs/plugin/official/plugin-container.md @@ -0,0 +1,80 @@ +--- +title: container +metaTitle: A plugin of registering markdown containers | VuePress +--- + +# [@vuepress/plugin-container](https://github.com/vuejs/vuepress/tree/master/packages/@vuepress/plugin-container) + +> A plugin of registering markdown containers + +## Install + +```bash +yarn add -D @vuepress/plugin-container +# OR npm install -D @vuepress/plugin-container +``` + +## Usage + +```javascript +module.exports = { + plugins: ['@vuepress/container'] +} +``` + +## Options + +### type + +- Type: `string` +- This is a required option. + +The type for the container. For example, if `type` was set to `foo`, only the following syntax will be parsed as a container: + +```md +::: foo bar +write something here ~ +::: +``` + +### defaultTitle + +- Type: `string` +- Default: the upper case of `type` + +The default title for the container. If no title was provided, `defaultTitle` will be showed as the title of the container. + +### before + +- Type: `string | Function` +- Default: `undefined` + +String to be placed before the block. If specified as a function, a argument `token` will be passed to it. If specified, it will override `defaultTitle`. + +### after + +- Type: `string | Function` +- Default: `undefined` + +String to be placed after the block. If specified as a function, a argument `token` will be passed to it. If specified, it will override `defaultTitle`. + +### validate + +- Type: `Function` +- Default: `undefined` + +A function to validate tail after opening marker, should return `true` on success. + +### render + +- Type: `Function` +- Default: `undefined` + +The renderer function for opening/closing tokens. If specified, it will override `before`, `after` and `defaultTitle`. + +### marker + +- Type: `string` +- Default: `':'` + +The character to use in delimiter. diff --git a/packages/docs/docs/zh/plugin/official/plugin-container.md b/packages/docs/docs/zh/plugin/official/plugin-container.md new file mode 100644 index 0000000000..ed29cccc7a --- /dev/null +++ b/packages/docs/docs/zh/plugin/official/plugin-container.md @@ -0,0 +1,80 @@ +--- +title: container +metaTitle: Markdown 容器插件 | VuePress +--- + +# [@vuepress/plugin-container](https://github.com/vuejs/vuepress/tree/master/packages/@vuepress/plugin-container) + +> Markdown 容器插件 + +## 安装 + +```bash +yarn add -D @vuepress/plugin-container +# OR npm install -D @vuepress/plugin-container +``` + +## 使用 + +```javascript +module.exports = { + plugins: ['@vuepress/container'] +} +``` + +## 选项 + +### type + +- 类型: `string` +- 这是一个必需的选项 + +容器的类型。举个例子,如果 `type` 被设置为 `foo`,则仅有下面的语法会被视为对应的容器: + +```md +::: foo bar +随便写点啥 ~ +::: +``` + +### defaultTitle + +- 类型: `string` +- 默认值: `type` 的大写形式 + +容器的默认标题。如果没有提供标题,则会使用 `defaultTitle` 作为容器的标题。 + +### before + +- 类型: `string | Function` +- 默认值: `undefined` + +要插入在容器前的 HTML。如果设置为一个函数,将传入当前的 `token` 作为第一个参数。如果设置了这个值,它将覆盖 `defaultTitle` 的效果。 + +### after + +- 类型: `string | Function` +- 默认值: `undefined` + +要插入在容器后的 HTML。如果设置为一个函数,将传入当前的 `token` 作为第一个参数。如果设置了这个值,它将覆盖 `defaultTitle` 的效果。 + +### validate + +- 类型: `Function` +- 默认值: `undefined` + +一个用于判定容器是否结束的函数。当认定容器范围结束时应返回一个 `true`。 + +### render + +- 类型: `Function` +- 默认值: `undefined` + +容器开头和结束 token 的渲染函数。如果设置了这个值,它将覆盖 `before`, `after` 和 `defaultTitle` 的效果。 + +### marker + +- 类型: `string` +- 默认值: `':'` + +用于分隔符的字符。