From 999ae5759c53927d05f2bd8b40f5d3e36f64073b Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Fri, 30 Oct 2020 18:21:58 +0300 Subject: [PATCH] fix(v2): handle multiple asset links in one line properly (#3653) * fix(v2): handle multiple asset links in one line properly * Fixes and improvements * Make TypeScript happy * Use relative path for image link * Add example for JSX element inside asset link --- .../src/remark/rightToc/search.js | 29 +------------ .../__snapshots__/index.test.js.snap | 8 ++-- .../src/remark/transformImage/index.js | 5 ++- .../__snapshots__/index.test.js.snap | 18 +++++--- .../__tests__/fixtures/asset.md | 8 +++- .../fixtures/static/staticAssetImage.png | Bin 0 -> 8722 bytes .../transformLinks/__tests__/index.test.js | 4 +- .../src/remark/transformLinks/index.js | 39 +++++------------- .../src/remark/utils/index.js | 39 ++++++++++++++++++ 9 files changed, 79 insertions(+), 71 deletions(-) create mode 100644 packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/fixtures/static/staticAssetImage.png create mode 100644 packages/docusaurus-mdx-loader/src/remark/utils/index.js diff --git a/packages/docusaurus-mdx-loader/src/remark/rightToc/search.js b/packages/docusaurus-mdx-loader/src/remark/rightToc/search.js index 516dc44d92d6..bafac24e8ed7 100644 --- a/packages/docusaurus-mdx-loader/src/remark/rightToc/search.js +++ b/packages/docusaurus-mdx-loader/src/remark/rightToc/search.js @@ -9,7 +9,7 @@ const toString = require('mdast-util-to-string'); const visit = require('unist-util-visit'); -const escapeHtml = require('escape-html'); +const {toValue} = require('../utils'); /** @typedef {import('@docusaurus/types').MarkdownRightTableOfContents} TOC */ /** @typedef {import('unist').Node} Node */ @@ -23,33 +23,6 @@ const escapeHtml = require('escape-html'); * @property {StringValuedNode[]} children */ -// https://github.com/syntax-tree/mdast#heading -/** - * @param {StringValuedNode | undefined} node - * @returns {string} - */ -function toValue(node) { - if (node && node.type) { - switch (node.type) { - case 'text': - return escapeHtml(node.value); - case 'heading': - return node.children.map(toValue).join(''); - case 'inlineCode': - return `${escapeHtml(node.value)}`; - case 'emphasis': - return `${node.children.map(toValue).join('')}`; - case 'strong': - return `${node.children.map(toValue).join('')}`; - case 'delete': - return `${node.children.map(toValue).join('')}`; - default: - } - } - - return toString(node); -} - // Visit all headings. We `slug` all headings (to account for // duplicates), but only take h2 and h3 headings. /** diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.js.snap b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.js.snap index b8230a895a24..b4af21f6fe0d 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.js.snap +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/__tests__/__snapshots__/index.test.js.snap @@ -12,11 +12,11 @@ exports[`transformImage plugin pathname protocol 1`] = ` exports[`transformImage plugin transform md images to 1`] = ` "![img](https://example.com/img.png) - + -{\\"img\\"} +{\\"img\\"} -{\\"img\\"} {\\"img\\"} +{\\"img\\"} {\\"img\\"} ## Heading @@ -24,6 +24,6 @@ exports[`transformImage plugin transform md images to 1`] = ` ![img](./img.png) \`\`\` -{\\"img\\"} +{\\"img\\"} " `; diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.js b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.js index 65531b4a16fa..20797e3eaded 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.js +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.js @@ -9,6 +9,7 @@ const visit = require('unist-util-visit'); const path = require('path'); const url = require('url'); const fs = require('fs-extra'); +const escapeHtml = require('escape-html'); const {getFileLoaderUtils} = require('@docusaurus/core/lib/webpack/utils'); const {posixPath} = require('@docusaurus/utils'); @@ -18,11 +19,11 @@ const { const createJSX = (node, pathUrl) => { node.type = 'jsx'; - node.value = ``; + }${node.title ? ` title="${escapeHtml(node.title)}"` : ''} />`; if (node.url) { delete node.url; diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/__snapshots__/index.test.js.snap b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/__snapshots__/index.test.js.snap index c7361ffe5bf7..1de13c618b68 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/__snapshots__/index.test.js.snap +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/__snapshots__/index.test.js.snap @@ -10,11 +10,11 @@ exports[`transformAsset plugin pathname protocol 1`] = ` exports[`transformAsset plugin transform md links to 1`] = ` "[asset](https://example.com/asset.pdf) - + -asset +asset -asset ![seet](asset) +asset ## Heading @@ -26,10 +26,16 @@ exports[`transformAsset plugin transform md links to 1`] = ` [assets](/github/!file-loader!/assets.pdf) -asset +asset -staticAsset.pdf +staticAsset.pdf -@site/static/staticAsset.pdf +@site/static/staticAsset.pdf + +Just staticAsset.pdf, and awesome staticAsset 2.pdf 'It is really "AWESOME"', but also coded staticAsset 3.pdf + +{\\"Clickable + +Stylized link to asset file " `; diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/fixtures/asset.md b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/fixtures/asset.md index 8973ba24af34..2cd2ca264931 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/fixtures/asset.md +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/fixtures/asset.md @@ -4,7 +4,7 @@ [asset](./asset.pdf) -[asset](asset.pdf 'Title') ![seet](asset) +[asset](asset.pdf 'Title') ## Heading @@ -21,3 +21,9 @@ [staticAsset.pdf](/staticAsset.pdf) [@site/static/staticAsset.pdf](@site/static/staticAsset.pdf) + +[Just staticAsset.pdf](/staticAsset.pdf), and [**awesome** staticAsset 2.pdf 'It is really "AWESOME"'](/staticAsset.pdf), but also [coded `staticAsset 3.pdf`](/staticAsset.pdf) + +[![Clickable Docusaurus logo](./static/staticAssetImage.png)](/staticAssetImage.png) + +[Stylized link to asset file](./asset.pdf) diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/fixtures/static/staticAssetImage.png b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/fixtures/static/staticAssetImage.png new file mode 100644 index 0000000000000000000000000000000000000000..a8fea3f6545fbba0405683061256aad14c1fb8c4 GIT binary patch literal 8722 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 sRGX@}9UVdlLtUSR#m1-$~f@<0CZRs=l}o! literal 0 HcmV?d00001 diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.js b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.js index 2a0503ffb7a4..836f887b8d5c 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.js +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/__tests__/index.test.js @@ -10,15 +10,15 @@ import remark from 'remark'; import mdx from 'remark-mdx'; import vfile from 'to-vfile'; import plugin from '..'; -import slug from '../../slug'; +import transformImage from '../../transformImage'; const processFixture = async (name, options) => { const path = join(__dirname, 'fixtures', `${name}.md`); const staticDir = join(__dirname, 'fixtures', 'static'); const file = await vfile.read(path); const result = await remark() - .use(slug) .use(mdx) + .use(transformImage, {...options, filePath: path, staticDir}) .use(plugin, {...options, filePath: path, staticDir}) .process(file); diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.js b/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.js index 1960cbdd7c1f..5295acc2ae70 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.js +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.js @@ -11,6 +11,8 @@ const visit = require('unist-util-visit'); const path = require('path'); const url = require('url'); const fs = require('fs-extra'); +const escapeHtml = require('escape-html'); +const {toValue} = require('../utils'); const {getFileLoaderUtils} = require('@docusaurus/core/lib/webpack/utils'); const { @@ -35,7 +37,9 @@ async function ensureAssetFileExist(fileSystemAssetPath, sourceFilePath) { } // transform the link node to a jsx link with a require() call -function toAssetRequireNode({node, index, parent, filePath, requireAssetPath}) { +function toAssetRequireNode({node, filePath, requireAssetPath}) { + /* eslint-disable no-param-reassign */ + let relativeRequireAssetPath = posixPath( path.relative(path.dirname(filePath), requireAssetPath), ); @@ -45,35 +49,18 @@ function toAssetRequireNode({node, index, parent, filePath, requireAssetPath}) { ? relativeRequireAssetPath : `./${relativeRequireAssetPath}`; - const hrefProp = `require('${inlineMarkdownLinkFileLoader}${relativeRequireAssetPath}').default`; + const href = `require('${inlineMarkdownLinkFileLoader}${relativeRequireAssetPath}').default`; + const children = (node.children || []).map((n) => toValue(n)).join(''); + const title = node.title ? `title="${escapeHtml(node.title)}"` : ''; node.type = 'jsx'; - - node.value = ``; - - const linkText = (node.children[0] && node.children[0].value) || ''; - delete node.children; - - parent.children.splice(index + 1, 0, { - type: 'text', - value: linkText, - }); - - parent.children.splice(index + 2, 0, {type: 'jsx', value: ''}); + node.value = `${children}`; } // If the link looks like an asset link, we'll link to the asset, // and use a require("assetUrl") (using webpack url-loader/file-loader) // instead of navigating to such link -async function convertToAssetLinkIfNeeded({ - node, - index, - parent, - staticDir, - filePath, -}) { +async function convertToAssetLinkIfNeeded({node, staticDir, filePath}) { const assetPath = node.url; const hasSiteAlias = assetPath.startsWith('@site/'); @@ -89,8 +76,6 @@ async function convertToAssetLinkIfNeeded({ function toAssetLinkNode(requireAssetPath) { toAssetRequireNode({ node, - index, - parent, filePath, requireAssetPath, }); @@ -117,7 +102,7 @@ async function convertToAssetLinkIfNeeded({ } } -async function processLinkNode({node, index, parent, filePath, staticDir}) { +async function processLinkNode({node, _index, _parent, filePath, staticDir}) { if (!node.url) { // try to improve error feedback // see https://github.com/facebook/docusaurus/issues/3309#issuecomment-690371675 @@ -139,8 +124,6 @@ async function processLinkNode({node, index, parent, filePath, staticDir}) { await convertToAssetLinkIfNeeded({ node, - index, - parent, staticDir, filePath, }); diff --git a/packages/docusaurus-mdx-loader/src/remark/utils/index.js b/packages/docusaurus-mdx-loader/src/remark/utils/index.js new file mode 100644 index 000000000000..0cdf55733bc5 --- /dev/null +++ b/packages/docusaurus-mdx-loader/src/remark/utils/index.js @@ -0,0 +1,39 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const escapeHtml = require('escape-html'); +const toString = require('mdast-util-to-string'); + +/** + * @param {StringValuedNode | undefined} node + * @returns {string} + */ +function toValue(node) { + if (node && node.type) { + switch (node.type) { + case 'text': + return escapeHtml(node.value); + case 'heading': + return node.children.map(toValue).join(''); + case 'inlineCode': + return `${escapeHtml(node.value)}`; + case 'emphasis': + return `${node.children.map(toValue).join('')}`; + case 'strong': + return `${node.children.map(toValue).join('')}`; + case 'delete': + return `${node.children.map(toValue).join('')}`; + default: + } + } + + return toString(node); +} + +module.exports = { + toValue, +};