UNPKG

@alauda/doom

Version:

Doctor Doom making docs.

100 lines (99 loc) 4.29 kB
import fs from 'node:fs'; import path from 'node:path'; import { isExternalUrl, removeLeadingSlash } from '@rspress/shared'; import { cloneDeep } from 'es-toolkit'; import { visit } from 'unist-util-visit'; import { RELATIVE_URL_PATTERN } from "./utils.js"; export const normalizeImgSrc = (content, { refSource, localPublicBase, publicBase, sourceBase, targetBase, force, translating, }) => { content = cloneDeep(content); const resolveImgSrc = (src, force) => { if (isExternalUrl(src)) { return src; } if (refSource?.repo) { const targetDir = path.resolve(localPublicBase, '_remotes', refSource.name); let sourcePath; let imageSrc; if (RELATIVE_URL_PATTERN.test(src)) { sourcePath = path.resolve(sourceBase, src); imageSrc = path.relative(sourceBase, sourcePath); } else { imageSrc = removeLeadingSlash(src); sourcePath = path.resolve(publicBase, imageSrc); } const targetPath = path.resolve(targetDir, imageSrc); if (force || !fs.existsSync(targetPath)) { fs.mkdirSync(path.dirname(targetPath), { recursive: true }); fs.copyFileSync(sourcePath, targetPath); } return `/_remotes/${refSource.name}/${imageSrc}`; } else if (!RELATIVE_URL_PATTERN.test(src)) { if (translating) { const { source, target, copy } = translating; const sourcePrefix = `/${source}/`; if (src.startsWith(sourcePrefix)) { const filename = src.slice(sourcePrefix.length); const targetPath = path.resolve(localPublicBase, target, filename); let targetExisted = fs.existsSync(targetPath); if (!targetExisted && copy) { fs.mkdirSync(path.dirname(targetPath), { recursive: true }); fs.copyFileSync(path.resolve(localPublicBase, source, filename), targetPath); targetExisted = true; } if (targetExisted) { return `/${target}/${filename}`; } } } return src; } let sourcePath = path.resolve(sourceBase, src); let targetPath = path.resolve(targetBase, src); if (translating) { const { source, target, copy } = translating; const assetsSourcePrefix = `./assets/${source}/`; if (src.startsWith(assetsSourcePrefix)) { const filename = src.slice(assetsSourcePrefix.length); const targetSrc = `./assets/${target}/${filename}`; const sourceTargetPath = path.resolve(sourceBase, targetSrc); if (fs.existsSync(sourceTargetPath)) { src = targetSrc; sourcePath = sourceTargetPath; targetPath = path.resolve(targetBase, src); } } let targetExisted = fs.existsSync(targetPath); if (!targetExisted && copy) { fs.mkdirSync(path.dirname(targetPath), { recursive: true }); fs.copyFileSync(sourcePath, targetPath); targetExisted = true; } if (targetExisted) { return src; } } const targetSrc = path.relative(targetBase, sourcePath); return RELATIVE_URL_PATTERN.test(targetSrc) ? targetSrc : `./${targetSrc}`; }; visit(content, 'image', (node) => { node.url = resolveImgSrc(node.url, force); }); visit(content, ['mdxJsxFlowElement', 'mdxJsxTextElement'], (node_) => { const node = node_; if (node.name !== 'img') { return; } const srcNode = node.attributes.find((attr) => 'name' in attr && attr.name === 'src'); if (srcNode?.type !== 'mdxJsxAttribute') { return; } const src = srcNode.value; if (typeof src !== 'string') { return; } srcNode.value = resolveImgSrc(src, force); }); return content; };