feat(mdx-loader): read image dimensions when processing Markdown (#6339)

This commit is contained in:
Joshua Chen 2022-01-19 19:45:14 +08:00 committed by GitHub
parent 6f892e20b0
commit e5801e49f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 32 additions and 10 deletions

View file

@ -17,8 +17,11 @@ import path from 'path';
import url from 'url';
import fs from 'fs-extra';
import escapeHtml from 'escape-html';
import sizeOf from 'image-size';
import {promisify} from 'util';
import type {Plugin, Transformer} from 'unified';
import type {Image, Literal} from 'mdast';
import logger from '@docusaurus/logger';
const {
loaders: {inlineMarkdownImageFileLoader},
@ -30,7 +33,11 @@ interface PluginOptions {
siteDir: string;
}
function toImageRequireNode(node: Image, imagePath: string, filePath: string) {
async function toImageRequireNode(
node: Image,
imagePath: string,
filePath: string,
) {
const jsxNode = node as Literal & Partial<Image>;
let relativeImagePath = posixPath(
path.relative(path.dirname(filePath), imagePath),
@ -46,13 +53,27 @@ function toImageRequireNode(node: Image, imagePath: string, filePath: string) {
escapePath(relativeImagePath) + search
}").default${hash ? ` + '${hash}'` : ''}`;
const title = node.title ? ` title="${escapeHtml(node.title)}"` : '';
let width = '';
let height = '';
try {
const size = (await promisify(sizeOf)(imagePath))!;
if (size.width) {
width = ` width="${size.width}"`;
}
if (size.height) {
height = ` height="${size.height}"`;
}
} catch (e) {
logger.error`The image at path=${imagePath} can't be read correctly. Please ensure it's a valid image.
${(e as Error).message}`;
}
Object.keys(jsxNode).forEach(
(key) => delete jsxNode[key as keyof typeof jsxNode],
);
(jsxNode as Literal).type = 'jsx';
jsxNode.value = `<img ${alt}src={${src}}${title} />`;
jsxNode.value = `<img ${alt}src={${src}}${title}${width}${height} />`;
}
async function ensureImageFileExist(imagePath: string, sourceFilePath: string) {
@ -124,7 +145,7 @@ async function processImageNode(node: Image, options: PluginOptions) {
}
const imagePath = await getImageAbsolutePath(parsedUrl.pathname, options);
toImageRequireNode(node, imagePath, options.filePath);
await toImageRequireNode(node, imagePath, options.filePath);
}
const plugin: Plugin<[PluginOptions]> = (options) => {

View file

@ -44,7 +44,7 @@ exports[`transformAsset plugin transform md links to <a /> 1`] = `
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[hash].[ext]!./static/staticAsset.pdf').default}>Just staticAsset.pdf</a>, and <a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[hash].[ext]!./static/staticAsset.pdf').default}><strong>awesome</strong> staticAsset 2.pdf &#39;It is really &quot;AWESOME&quot;&#39;</a>, but also <a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[hash].[ext]!./static/staticAsset.pdf').default}>coded <code>staticAsset 3.pdf</code></a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[hash].[ext]!./static/staticAssetImage.png').default}><img alt={\\"Clickable Docusaurus logo\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[hash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/staticAssetImage.png\\").default} /></a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[hash].[ext]!./static/staticAssetImage.png').default}><img alt={\\"Clickable Docusaurus logo\\"} src={require(\\"![CWD]/node_modules/url-loader/dist/cjs.js?limit=10000&name=assets/images/[name]-[hash].[ext]&fallback=[CWD]/node_modules/file-loader/dist/cjs.js!./static/staticAssetImage.png\\").default} width=\\"200\\" height=\\"200\\" /></a>
<a target=\\"_blank\\" href={require('![CWD]/node_modules/file-loader/dist/cjs.js?name=assets/files/[name]-[hash].[ext]!./asset.pdf').default}><span style={{color: \\"red\\"}}>Stylized link to asset file</span></a>
"