import fs from 'fs' import path from 'path' import glob from 'fast-glob' import { docRoot, docsDirName, projRoot } from '@element-plus/build-utils' import { REPO_BRANCH, REPO_PATH } from '@element-plus/build-constants' import { getLang, languages } from '../utils/lang' import footerLocale from '../i18n/component/footer.json' import type { Plugin } from 'vite' type Append = Record<'headers' | 'footers' | 'scriptSetups', string[]> export function MarkdownTransform(): Plugin { return { name: 'element-plus-md-transform', enforce: 'pre', async transform(code, id) { if (!id.endsWith('.md')) return const componentId = path.basename(id, '.md') const append: Append = { headers: [], footers: [], scriptSetups: [ `const demos = import.meta.globEager('../../examples/${componentId}/*.vue')`, ], } code = transformVpScriptSetup(code, append) const pattern = `{${[...languages, languages[0]].join(',')}}/component` const compPaths = await glob(pattern, { cwd: docRoot, absolute: true, onlyDirectories: true, }) if (compPaths.some((compPath) => id.startsWith(compPath))) { code = transformComponentMarkdown(id, componentId, code, append) } return combineMarkdown( code, [combineScriptSetup(append.scriptSetups), ...append.headers], append.footers ) }, } } const combineScriptSetup = (codes: string[]) => `\n ` const combineMarkdown = ( code: string, headers: string[], footers: string[] ) => { const frontmatterEnds = code.indexOf('---\n\n') + 4 const firstSubheader = code.search(/\n## \w/) const sliceIndex = firstSubheader < 0 ? frontmatterEnds : firstSubheader if (headers.length > 0) code = code.slice(0, sliceIndex) + headers.join('\n') + code.slice(sliceIndex) code += footers.join('\n') return `${code}\n` } const vpScriptSetupRE = /([\s\S]*)<\/vp-script>/ const transformVpScriptSetup = (code: string, append: Append) => { const matches = code.match(vpScriptSetupRE) if (matches) code = code.replace(matches[0], '') const scriptSetup = matches?.[3] ?? '' if (scriptSetup) append.scriptSetups.push(scriptSetup) return code } const GITHUB_BLOB_URL = `https://github.com/${REPO_PATH}/blob/${REPO_BRANCH}` const GITHUB_TREE_URL = `https://github.com/${REPO_PATH}/tree/${REPO_BRANCH}` const transformComponentMarkdown = ( id: string, componentId: string, code: string, append: Append ) => { const lang = getLang(id) const docUrl = `${GITHUB_BLOB_URL}/${docsDirName}/en-US/component/${componentId}.md` const componentUrl = `${GITHUB_TREE_URL}/packages/components/${componentId}` const componentPath = path.resolve( projRoot, `packages/components/${componentId}` ) const isComponent = fs.existsSync(componentPath) const links = [[footerLocale[lang].docs, docUrl]] if (isComponent) links.unshift([footerLocale[lang].component, componentUrl]) const linksText = links .filter((i) => i) .map(([text, link]) => `[${text}](${link})`) .join(' • ') const sourceSection = ` ## ${footerLocale[lang].source} ${linksText} ` const contributorsSection = ` ## ${footerLocale[lang].contributors} ` append.footers.push(sourceSection, isComponent ? contributorsSection : '') return code }