From db1638976e11b66bd5a0d19e098a84ef445d7b0c Mon Sep 17 00:00:00 2001 From: Dennis Reimann Date: Tue, 10 Nov 2020 16:36:54 +0100 Subject: [PATCH] feat($markdown): make page suffix configurable (close #2452) (#2674) --- .../@vuepress/markdown/__tests__/link.spec.js | 28 +++++++++++++++++-- packages/@vuepress/markdown/index.js | 3 +- packages/@vuepress/markdown/lib/link.js | 10 +++---- packages/docs/docs/config/README.md | 7 +++++ packages/docs/docs/guide/markdown.md | 6 ++++ packages/docs/docs/zh/config/README.md | 7 +++++ packages/docs/docs/zh/guide/markdown.md | 6 ++++ 7 files changed, 58 insertions(+), 9 deletions(-) diff --git a/packages/@vuepress/markdown/__tests__/link.spec.js b/packages/@vuepress/markdown/__tests__/link.spec.js index ee144bc16d..410084277d 100644 --- a/packages/@vuepress/markdown/__tests__/link.spec.js +++ b/packages/@vuepress/markdown/__tests__/link.spec.js @@ -2,12 +2,19 @@ import { Md } from './util' import link from '../lib/link.js' import { dataReturnable } from '../index.js' -const mdL = Md().use(link, { +const EXTERNAL_ATTRS = { target: '_blank', rel: 'noopener noreferrer' -}) +} + +const setup = ({ externalAttrs = EXTERNAL_ATTRS, suffix } = {}) => { + const mdL = Md().use(link, EXTERNAL_ATTRS, suffix) + dataReturnable(mdL) -dataReturnable(mdL) + return mdL +} + +const mdL = setup() const internalLinkAsserts = { // START absolute path usage @@ -69,6 +76,21 @@ describe('link', () => { expect(html).toMatchSnapshot() } }) + + test('with custom page suffix should render links correctly', () => { + const suffix = '/' + const mdLSuffix = setup({ suffix }) + + for (const before in internalLinkAsserts) { + const input = `[${before}](${before})` + const output = mdLSuffix.render(input) + const after = getCompiledLink(output) + const value = internalLinkAsserts[before] + const isHtmlLink = value === before + const expected = isHtmlLink ? value : value.replace('.html', suffix) + expect(after).toBe(expected) + } + }) }) function getCompiledLink (output) { diff --git a/packages/@vuepress/markdown/index.js b/packages/@vuepress/markdown/index.js index fae5948ab4..3635359efa 100644 --- a/packages/@vuepress/markdown/index.js +++ b/packages/@vuepress/markdown/index.js @@ -31,6 +31,7 @@ const { module.exports = (markdown = {}) => { const { externalLinks, + pageSuffix, anchor, toc, plugins, @@ -73,7 +74,7 @@ module.exports = (markdown = {}) => { .use(convertRouterLinkPlugin, [Object.assign({ target: '_blank', rel: 'noopener noreferrer' - }, externalLinks)]) + }, externalLinks), pageSuffix]) .end() .plugin(PLUGINS.HOIST_SCRIPT_STYLE) diff --git a/packages/@vuepress/markdown/lib/link.js b/packages/@vuepress/markdown/lib/link.js index 064aa7ae40..9cd84170ae 100644 --- a/packages/@vuepress/markdown/lib/link.js +++ b/packages/@vuepress/markdown/lib/link.js @@ -6,7 +6,7 @@ const url = require('url') const indexRE = /(^|.*\/)(index|readme).md(#?.*)$/i -module.exports = (md, externalAttrs) => { +module.exports = (md, externalAttrs, pageSuffix = '.html') => { let hasOpenRouterLink = false let hasOpenExternalLink = false @@ -28,13 +28,13 @@ module.exports = (md, externalAttrs) => { } } else if (isSourceLink) { hasOpenRouterLink = true - tokens[idx] = toRouterLink(token, link, relativePath) + tokens[idx] = toRouterLink(token, link, relativePath, pageSuffix) } } return self.renderToken(tokens, idx, options) } - function toRouterLink (token, link, relativePath) { + function toRouterLink (token, link, relativePath, suffix) { link[0] = 'to' let to = link[1] @@ -55,8 +55,8 @@ module.exports = (md, externalAttrs) => { to = path + hash } else { to = to - .replace(/\.md$/, '.html') - .replace(/\.md(#.*)$/, '.html$1') + .replace(/\.md$/, suffix) + .replace(/\.md(#.*)$/, `${suffix}$1`) } // markdown-it encodes the uri diff --git a/packages/docs/docs/config/README.md b/packages/docs/docs/config/README.md index 0d99b85dfb..9400f93d35 100644 --- a/packages/docs/docs/config/README.md +++ b/packages/docs/docs/config/README.md @@ -277,6 +277,13 @@ Function for transforming [header](../miscellaneous/glossary.md#headers) texts i Options for [markdown-it-anchor](https://github.com/valeriangalliat/markdown-it-anchor). (Note: prefer `markdown.slugify` to customize header ids.) +### markdown.pageSuffix + +- Type: `string` +- Default: `.html` + +Option to customize internal links to be compatible when using the [vuepress-plugin-clean-urls](https://vuepress.github.io/en/plugins/clean-urls/). + ### markdown.externalLinks - Type: `Object` diff --git a/packages/docs/docs/guide/markdown.md b/packages/docs/docs/guide/markdown.md index 85720eb865..60836a5f00 100644 --- a/packages/docs/docs/guide/markdown.md +++ b/packages/docs/docs/guide/markdown.md @@ -43,6 +43,12 @@ VuePress supports redirecting to clean links. If a link `/foo` is not found, Vue Regardless of whether the permalink and clean-urls plugins are used, your relative path should be defined by the current file structure. In the above example, even though you set the path of `/foo/one.md` to `/foo/one/`, you should still access `/foo/two.md` via `./two.md`. ::: +### Page Suffix + +Pages and internal links get generated with the `.html` suffix by default. + +You can customize this by setting [config.markdown.pageSuffix](../config/README.md#markdown-pagesuffix). + ### External Links Outbound links automatically get `target="_blank" rel="noopener noreferrer"`: diff --git a/packages/docs/docs/zh/config/README.md b/packages/docs/docs/zh/config/README.md index 20878db3c9..4166896228 100644 --- a/packages/docs/docs/zh/config/README.md +++ b/packages/docs/docs/zh/config/README.md @@ -273,6 +273,13 @@ VuePress 提供了一种添加额外样式的简便方法。你可以创建一 [markdown-it-anchor](https://github.com/valeriangalliat/markdown-it-anchor) 的选项。 +### markdown.pageSuffix + +- 类型: `string` +- 默认值: `.html` + +Option to customize internal links to be compatible when using the [vuepress-plugin-clean-urls](https://vuepress.github.io/en/plugins/clean-urls/). + ### markdown.externalLinks - 类型: `Object` diff --git a/packages/docs/docs/zh/guide/markdown.md b/packages/docs/docs/zh/guide/markdown.md index 07cf87b44f..9ab857cb80 100644 --- a/packages/docs/docs/zh/guide/markdown.md +++ b/packages/docs/docs/zh/guide/markdown.md @@ -43,6 +43,12 @@ VuePress 支持重定向到干净链接。如果一个链接 `/foo` 找不到, 无论是否使用了 permalink 和 clean-urls 插件,你的相对路径都应该依赖于当前的文件结构来定义。在上面的例子中,即使你将 `/foo/one.md` 的路径设为了 `/foo/one/`,你依然应该通过 `./two.md` 来访问 `/foo/two.md`。 ::: +### Page Suffix + +Pages and internal links get generated with the `.html` suffix by default. + +You can customize this by setting [config.markdown.pageSuffix](../config/README.md#markdown-pagesuffix). + ### 外部链接 外部的链接将会被自动地设置为 `target="_blank" rel="noopener noreferrer"`: